PHP 7.4+ · HMAC-SHA256 · cURL
Overview
This guide shows how to integrate SabPaisa Payment Gateway directly from PHP using the REST API. No SDK required — generate the HMAC-SHA256 checksum, POST the payload, and redirect the customer to the returned checkoutUrl.
Requirements
Merchant Credentials
SabPaisa will issue three credentials during onboarding. Store them in environment variables or a secrets manager — never commit them.
| Credential | Used For |
|---|---|
| Merchant ID | Identifies your account in every request |
| API Key | Sent as the X-Api-Key header |
| Secret Key | HMAC-SHA256 signing — server-only |
1$merchantId = 'YOUR_MERCHANT_ID';
2$apiKey = 'YOUR_API_KEY';
3$secretKey = 'YOUR_SECRET_KEY';API Endpoint
https://staging-sb-merchant-api.sabpaisa.in/api/v2/paymentshttps://merchant-api.sabpaisa.in/api/v2/paymentshttps://staging-sb-checkout.sabpaisa.in/checkoutGenerate Transaction ID
Each payment needs a unique merchant transaction ID. Use a timestamp, UUID, or your own order ID.
1$merchantTxnId = 'TXN_' . time();Generate Timestamp
Unix timestamp (seconds). Goes into both the checksum string and the request payload.
1$timestamp = time();Generate Checksum
Concatenate the fields with a pipe (|) separator and HMAC-SHA256 them using your secret key. The result is sent as the checksum field.
1$checksumString =
2 $merchantId . '|' .
3 $merchantTxnId . '|' .
4 $amount . '|INR|' .
5 $timestamp;
6
7$checksum = hash_hmac('sha256', $checksumString, $secretKey);merchantId | merchantTxnId | amount | currency | timestamp. Any reordering will fail signature verification.Create Payment Payload
1$payload = [
2 'merchantId' => $merchantId,
3 'merchantTxnId' => $merchantTxnId,
4 'amount' => 10000,
5 'currency' => 'INR',
6 'customerName' => 'Vivek Kumar',
7 'customerEmail' => '[email protected]',
8 'customerPhone' => '9999999999',
9 'returnUrl' => 'http://localhost/payment-response.php',
10 'description' => 'SabPaisa Test Payment',
11 'checksum' => $checksum,
12 'timestamp' => $timestamp,
13];Equivalent JSON
1{
2 "merchantId": "YOUR_MERCHANT_ID",
3 "merchantTxnId": "TXN_12345",
4 "amount": 10000,
5 "currency": "INR",
6 "customerName": "Vivek Kumar",
7 "customerEmail": "[email protected]",
8 "customerPhone": "9999999999",
9 "returnUrl": "http://localhost/payment-response.php",
10 "description": "SabPaisa Test Payment",
11 "checksum": "xxxxxxxx",
12 "timestamp": 1747828272
13}10000 = ₹100. 50000 = ₹500.Call Payment API
POST the JSON payload with your API key in the X-Api-Key header.
1$ch = curl_init();
2curl_setopt_array($ch, [
3 CURLOPT_URL => 'https://staging-sb-merchant-api.sabpaisa.in/api/v2/payments',
4 CURLOPT_RETURNTRANSFER => true,
5 CURLOPT_POST => true,
6 CURLOPT_POSTFIELDS => json_encode($payload),
7 CURLOPT_HTTPHEADER => [
8 'Content-Type: application/json',
9 'X-Api-Key: ' . $apiKey,
10 ],
11]);
12
13$response = curl_exec($ch);
14curl_close($ch);
15
16$responseData = json_decode($response, true);API Response
1{
2 "success": true,
3 "paymentId": "sppay_xxxxx",
4 "checkoutUrl": "https://staging-sb-checkout.sabpaisa.in/checkout/sppay_xxxxx",
5 "status": "PENDING",
6 "amount": 10000,
7 "currency": "INR",
8 "merchantTxnId": "TXN_12345",
9 "clientSecret": "xxxxx"
10}Redirect To Checkout
Append the clientSecret from the response as a query parameter and send the customer to the checkoutUrl.
1$checkoutUrl = $responseData['checkoutUrl'];
2$clientSecret = $responseData['clientSecret'];
3
4header('Location: ' . $checkoutUrl . '?clientSecret=' . $clientSecret);
5exit;Final URL
https://staging-sb-checkout.sabpaisa.in/checkout/sppay_xxxxx?clientSecret=xxxxxCallback Handling
After payment, SabPaisa redirects the customer to the returnUrl with a status query parameter.
http://localhost/payment-response.php?status=SUCCESSHandle Payment Response
1$status = $_GET['status'] ?? '';
2
3if ($status === 'SUCCESS') {
4 echo 'Payment Successful';
5} else {
6 echo 'Payment Failed';
7}Production Best Practices
Never expose Secret Key publicly
It signs every request — leak it and anyone can act as you. Keep it in server-only env vars.
Always generate checksum on the backend
Never compute HMAC in browser JS. PHP-server-only signing is correct here.
Verify payment via webhook or enquiry
?status=SUCCESS in the return URL is not authoritative — confirm server-side.
Use HTTPS in production
All endpoints (returnUrl + your backend) must be HTTPS for live transactions.
Store transaction logs securely
Persist merchantTxnId + paymentId for every session — they're the only way to enquiry later.
Validate callback before updating orders
Always re-check status before marking the order paid/failed.
Need Help?
For integration support, contact the SabPaisa technical team with your merchant ID and the failing request payload (redact the Secret Key).
Was this page helpful?