The integration flow at a glance
The pattern is the same one you'd see with Stripe, Adyen or Razorpay — and it works identically for JazzCash, easypaisa, Raast and cards. There's no per-wallet code path.
- Your backend creates a payment intent via POST /v1/payments — you specify amount, currency (PKR), customer, and the methods you accept.
- We return a checkout URL. Redirect your customer there (or embed it in an iframe).
- The customer picks JazzCash or easypaisa, completes the OTP / wallet PIN, and is redirected back to your
return_url. - Asynchronously, we send a signed webhook to your
webhook_urlwith the final status (succeeded, failed, refunded). - Your backend verifies the HMAC signature, updates the order, and you're done.
Before you write any code
- Talk to sales at rapidgateway.pk/contact to get your merchant account approved (10 min call + KYC).
- Sandbox keys arrive in your inbox the same day — you can build against them immediately.
- Live keys are issued once KYC is verified, usually within an hour of the sales call.
- The full API reference, with auth and request schemas, ships with your sandbox kit. We don't publish secret keys publicly — every merchant gets a dedicated pair.
Step 1 — Create a payment intent (server-side)
On your backend, POST to the payments endpoint with the order details. Always do this server-side — never expose your secret key in the browser.
Node.js example
const res = await fetch('https://api.rapidgateway.pk/v1/payments', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + process.env.RG_SECRET_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': order.id
},
body: JSON.stringify({
amount: 4250, // PKR (in major units)
currency: 'PKR',
methods: ['easypaisa', 'jazzcash', 'card'],
customer: { phone: '+923XXXXXXXXX' },
return_url: 'https://yourstore.pk/order/' + order.id,
webhook_url: 'https://yourstore.pk/webhooks/rg'
})
});
const { id, checkout_url } = await res.json();
// Redirect the customer to checkout_url
PHP example
$res = $client->post('https://api.rapidgateway.pk/v1/payments', [
'headers' => [
'Authorization' => 'Bearer ' . $_ENV['RG_SECRET_KEY'],
'Idempotency-Key' => $order->id,
],
'json' => [
'amount' => 4250,
'currency' => 'PKR',
'methods' => ['easypaisa', 'jazzcash'],
'return_url' => "https://yourstore.pk/order/{$order->id}",
'webhook_url' => 'https://yourstore.pk/webhooks/rg',
],
]);
Step 2 — Redirect the customer to checkout
The checkout_url we return is a hosted page styled with your brand. Your customer sees JazzCash, easypaisa, Raast, Visa and Mastercard side by side, picks one, and pays. PCI and PII never touch your servers — huge compliance win.
Step 3 — Handle the webhook
Don't trust the success page redirect for fulfillment — users close tabs, networks drop. Always wait for the webhook before marking an order paid.
- We POST a JSON body to your
webhook_urlwith the final status. - Every request includes an
X-RG-Signatureheader: an HMAC-SHA256 of the raw body using your webhook secret. - Verify the signature before doing anything with the payload.
- Return HTTP 2xx within 5 seconds — we'll retry on failure with exponential backoff for up to 24 hours.
Webhook handler (Node.js)
import crypto from 'crypto';
app.post('/webhooks/rg', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-rg-signature'];
const expected = crypto.createHmac('sha256', process.env.RG_WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (sig !== expected) return res.status(401).end();
const event = JSON.parse(req.body.toString());
if (event.type === 'payment.succeeded') {
markOrderPaid(event.data.id);
}
res.sendStatus(200);
});
Step 4 — Test in sandbox, then go live
- Use sandbox keys + the
+92 300 0000001test phone number — every payment will auto-succeed. - Try
+92 300 0000002for an auto-fail (use this to test your retry path). - Hit your
/orderpage in the browser and walk the full flow end-to-end. - Inspect your webhook handler with a tool like ngrok or smee.io — confirm the signature verification works.
- When you're ready, swap
RG_SECRET_KEYfor your live key. No code changes needed. - Make one small live transaction (we recommend PKR 100 to your own account) — verify it settles to your bank on T+1.
Common gotchas
- Idempotency: always set the
Idempotency-Keyheader to your order ID. Without it, double-submits create duplicate payments. - Amount units: amounts are in PKR major units (whole rupees), not paisa.
4250means Rs. 4,250. - Timezone: settlement T+1 is Pakistan Standard Time business days — Saturday transactions settle Monday.
- Phone format: customer phone should be E.164 (
+92...). The wallet apps reject other formats. - Webhook retries: if your endpoint returns 5xx, we retry. Make sure your handler is idempotent — process the same event_id only once.
No-code option for WordPress / Shopify
If you're not on a custom stack, our WooCommerce, Shopify and Wix plugins do the entire integration for you. Install, paste your live key, save. JazzCash and easypaisa show up at checkout automatically — both bundled in your single Rapid Gateway account, no separate wallet onboarding.
Get your credentials
Sandbox credentials and the full API spec come with your sales onboarding — a 15-minute call with our team. Most merchants go from first call to live transactions within an hour. Start the conversation or call +92 315 4020909.