Client libraries
PHP & Laravel
Integrate ShadhinPay from PHP or Laravel today, and track the official package.
Official package — Planned
A first-party Composer package (with a Laravel service provider) is on the roadmap. Until it ships, the cURL / Guzzle examples below work in any PHP app.
Create a payment
<?php
$base = 'https://api.shadhinpay.pay/api/v1';
$ch = curl_init("$base/payments");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Client-Id: ' . getenv('SHADHINPAY_CLIENT_ID'),
'Business-Id: ' . getenv('SHADHINPAY_BUSINESS_ID'),
'X-Api-Key: ' . getenv('SHADHINPAY_API_KEY'),
'X-Idempotency-Key: ' . bin2hex(random_bytes(16)),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => '500.00',
'currency' => 'BDT',
'merchantTxnId' => 'order-7831',
'callbackUrl' => 'https://shop.example.com/return',
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($body['status'] ?? null) !== 'success') {
throw new RuntimeException($body['errorType'] ?? 'request_failed'); // see /docs/developers/errors
}
$payment = $body['data']; // ['paymentId' => ..., 'paymentUrl' => ..., ...]
// redirect the customer to $payment['paymentUrl']Verify a webhook
Use the raw request body (php://input), not a re-encoded array:
<?php
function shadhinpay_verify(string $raw, string $header, string $secret): bool
{
parse_str(str_replace(',', '&', $header), $parts); // t=...,v1=... -> t / v1
$t = (int) ($parts['t'] ?? 0);
if ($t === 0 || abs(time() - $t) > 300) {
return false; // replay protection
}
$expected = hash_hmac('sha256', "t={$t}.{$raw}", $secret);
return hash_equals($expected, $parts['v1'] ?? '');
}
$raw = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_SHADHINPAY_SIGNATURE'] ?? '';
if (! shadhinpay_verify($raw, $header, getenv('SHADHINPAY_WEBHOOK_SECRET'))) {
http_response_code(400);
exit;
}
$event = json_decode($raw, true);
// dedupe on $event['eventId'], handle $event['eventType']
http_response_code(200);
echo json_encode(['status' => 'received']);In Laravel, read the raw body with $request->getContent() and the header with
$request->header('X-ShadhinPay-Signature'). The signing scheme is documented in
Webhooks.