laravel
Laravel HTTP client guide
How to consume published compliance credentials from a Laravel application using the HTTP facade, including config binding, retry/backoff strategy, error handling and safe secret storage.
Why the HTTP facade
Laravel's Http facade wraps Guzzle with a fluent, testable API — it gives you retries, timeouts, fakes for testing, and clean exception handling without hand-rolling cURL option arrays. For any Laravel application consuming Pay Engineers technical parameters, this is the recommended approach over raw cURL.
Configuration
Bind the processor's base URL and key into config/services.php rather than reading env() directly inside application code — this keeps configuration cacheable and testable:
// config/services.php
return [
'processor' => [
'base_url' => env('PROCESSOR_BASE_URL'),
'key' => env('PROCESSOR_API_KEY'),
],
];
PROCESSOR_BASE_URL=https://sandbox.example.com
PROCESSOR_API_KEY=sk_sandbox_xxxxxxxxxxxxxxxx
Laravel example
use Illuminate\Support\Facades\Http;
$response = Http::withToken(config('services.processor.key'))
->acceptJson()
->timeout(10)
->retry(3, 200)
->get(config('services.processor.base_url').'/v1/ping');
if ($response->failed()) {
report(new RuntimeException(
"Processor call failed with status {$response->status()}: {$response->body()}"
));
abort_if($response->clientError(), 422, 'Invalid request to processor.');
abort(502, 'Processor is currently unavailable.');
}
$data = $response->json();
Retries and backoff
The retry(3, 200) call above retries up to three times with a 200ms base delay between attempts, and only on connection-level failures or 5xx responses by default. Be deliberate about which calls you retry — retrying a POST that creates a resource without an idempotency key can create duplicates, so prefer idempotent GET calls for automatic retries, or pass an idempotency key on writes if the processor supports one.
Error handling patterns
- Use
$response->successful(),->failed(),->clientError()and->serverError()instead of manually comparing status codes — it reads more clearly in code review. - Wrap outbound calls in a dedicated service class (e.g.
ProcessorClient) rather than scatteringHttp::calls through controllers — this makes it trivial to swap inHttp::fake()in tests. - Log the response body on failure, but scrub any sensitive fields (PANs, tokens) before writing to application logs.
Testing
Laravel's Http::fake() lets you assert against processor calls without ever hitting the sandbox in CI:
Http::fake([
'sandbox.example.com/*' => Http::response(['status' => 'ok'], 200),
]);
Security notes
- Keep
PROCESSOR_API_KEYout of version control and out of.env.example— commit only placeholder names, never real values. - Rotate the key stored in
config/services.phpimmediately if it is ever exposed in a log, error report, or support ticket. - If you queue outbound calls via Laravel Horizon or queue workers, make sure queue payloads do not serialize the raw key — resolve it from config at execution time instead.