Laravel Service Integration Blueprint for Sharia-Compliant Finance APIs
A production-ready pattern for Laravel 11 / PHP 8.3 teams building zakat, sukuk, and takaful flows on top of KhaleejiAPI. The examples below keep API credentials on the server, convert coverage amounts into AED before pricing takaful, and return a clean finance payload your app can store or render.
Authorization header with the Bearer scheme. Do not use x-api-key in documentation or application code.1. Store credentials in Laravel config
Keep the API key in your server-side environment and expose only a tiny config surface to the rest of the app. Put the config file at config/khaleejiapi.php.
# .envKHALEEJIAPI_API_KEY=your_api_key_hereKHALEEJIAPI_BASE_URL=https://khaleejiapi.dev/api/v1<?php return [ 'api_key' => env('KHALEEJIAPI_API_KEY'), 'base_url' => env('KHALEEJIAPI_BASE_URL', 'https://khaleejiapi.dev/api/v1'), 'timeout' => env('KHALEEJIAPI_TIMEOUT', 5),];2. Build a reusable service wrapper
This service centralizes timeouts, retries, JSON defaults, and authentication headers for the three Islamic Finance endpoints plus exchange-rate conversion. A natural home is app/Services/KhaleejiApiService.php.
<?php namespace App\Services; use Illuminate\Http\Client\PendingRequest;use Illuminate\Support\Facades\Http; class KhaleejiApiService{ public function client(): PendingRequest { return Http::baseUrl(config('khaleejiapi.base_url')) ->acceptJson() ->contentType('application/json') ->timeout((int) config('khaleejiapi.timeout', 5)) ->retry(2, 250) ->withToken(config('khaleejiapi.api_key')); } public function getExchangeRates(string $base = 'AED'): array { return $this->client() ->get('/exchange/rates', ['base' => $base]) ->throw() ->json('data'); } public function calculateZakat(array $assets, string $currency = 'AED'): array { return $this->client() ->post('/zakat/calculate', [ 'assets' => $assets, 'currency' => $currency, ]) ->throw() ->json('data'); } public function listSukuk(array $filters = []): array { return $this->client() ->get('/sukuk/list', $filters) ->throw() ->json('data'); } public function calculateTakaful(array $query): array { return $this->client() ->get('/takaful/calculate', $query) ->throw() ->json('data'); }}- /exchange/rates supplies the conversion rate you can use before calling the takaful estimator in AED.
- /zakat/calculate supports multi-asset POST bodies and returns eligibility plus per-asset breakdowns.
- /sukuk/list can enrich dashboards or portfolio screens with GCC sukuk reference data.
3. Controller flow: validate, convert currency, then calculate
The controller below validates user input, converts the customer's requested coverage into AED, then combines zakat and takaful results into one response. That keeps your business rules in Laravel while letting KhaleejiAPI handle live finance data. Save it as app/Http/Controllers/IslamicFinanceController.php.
<?php namespace App\Http\Controllers; use App\Services\KhaleejiApiService;use Illuminate\Http\JsonResponse;use Illuminate\Http\Request;use Illuminate\Validation\Rule; class IslamicFinanceController extends Controller{ public function __construct(private readonly KhaleejiApiService $khaleejiApi) { } public function quote(Request $request): JsonResponse { $payload = $request->validate([ 'currency' => ['required', 'string', 'size:3'], 'assets' => ['required', 'array', 'min:1'], 'assets.*.type' => ['required', 'string', Rule::in([ 'cash', 'gold', 'silver', 'stocks', 'business', 'mutual_funds', 'crypto', 'real_estate', ])], 'assets.*.value' => ['required', 'numeric', 'min:0'], 'assets.*.weight' => ['nullable', 'numeric', 'min:0'], 'coverage' => ['required', 'numeric', 'min:1000'], 'takaful_type' => ['required', 'string', Rule::in([ 'health', 'motor', 'property', 'life', 'travel', 'business', ])], 'country' => ['nullable', 'string', 'size:2'], ]); $rates = $this->khaleejiApi->getExchangeRates('AED'); // When base=AED, rates[currency] is the quoted currency amount per 1 AED. $quotedCurrencyPerAed = $rates['rates'][$payload['currency']] ?? 1; $coverageInAed = round($payload['coverage'] / $quotedCurrencyPerAed, 2); $zakat = $this->khaleejiApi->calculateZakat( $payload['assets'], $payload['currency'], ); $takaful = $this->khaleejiApi->calculateTakaful([ 'type' => $payload['takaful_type'], 'coverage' => $coverageInAed, 'currency' => 'AED', 'country' => $payload['country'] ?? 'AE', 'model' => 'wakalah_mudarabah', ]); return response()->json([ 'data' => [ 'requestedCurrency' => $payload['currency'], 'coverage' => [ 'original' => $payload['coverage'], 'convertedToAed' => $coverageInAed, ], 'zakat' => $zakat['calculation'], 'takaful' => $takaful['estimate'], 'shariaChecks' => [ 'zakatEligible' => $zakat['calculation']['eligible'], 'takafulModel' => $takaful['model']['name'], 'takafulShariaCompliant' => $takaful['model']['shariaCompliant'], ], ], ]); }}4. Register an application route
<?php use App\Http\Controllers\IslamicFinanceController;use Illuminate\Support\Facades\Route; Route::post('/finance/islamic/quote', [IslamicFinanceController::class, 'quote']);5. Test the Laravel endpoint locally
curl -X POST "https://your-app.test/api/finance/islamic/quote" \ -H "Content-Type: application/json" \ -d '{ "currency": "SAR", "coverage": 150000, "country": "SA", "takaful_type": "health", "assets": [ { "type": "cash", "value": 50000 }, { "type": "gold", "value": 11250, "weight": 32.1 }, { "type": "stocks", "value": 20000 } ] }'{ "data": { "requestedCurrency": "SAR", "coverage": { "original": 150000, "convertedToAed": 146850.15 }, "zakat": { "totalWealth": 81250, "nisabThreshold": 2367.68, "eligible": true, "zakatRate": 2.5, "zakatDue": 2031.25, "currency": "SAR" }, "takaful": { "type": "health", "coverage": 146850.15, "currency": "AED", "annualContribution": 6241.13, "monthlyContribution": 520.09 }, "shariaChecks": { "zakatEligible": true, "takafulModel": "Wakalah-Mudarabah", "takafulShariaCompliant": true } }}6. Sharia-compliant implementation notes
- Use the returned
zakat.calculation.eligibleflag andzakatDueamount as display or workflow inputs, not as a substitute for a scholar's advice in edge cases. - Keep takaful pricing in AED when you want a stable regional baseline, but return the original requested currency in your Laravel response so customers can reconcile the numbers.
- Cache
/exchange/ratesand/sukuk/listresponses for short periods when a page fans out across many customers or portfolios.
Next steps
After the Laravel wrapper is in place, pair it with the endpoint references for field-by-field details and live examples.