Docs v1.2

Checktion Payment Gateway

Developer Reference · v1.2

JazzCash, EasyPaisa & OneQR — Complete Integration Guide

جاز کیش، ایزی پیسہ اور OneQR — مکمل انٹیگریشن گائیڈ — ڈویلپر ریفرنس

JazzCash MWALLET 1.1 EasyPaisa Official MA OneQR Gateway Base: https://checktion.com/ PKR Only HMAC-SHA256
01

Overview & Architecture

آرکیٹیکچر کا جائزہ

The Checktion Payment Gateway provides a unified REST API to accept payments via JazzCash MWALLET and EasyPaisa MA — two of Pakistan's most widely used mobile wallets. Both share the same two-step flow: first create a payment intent, then charge the customer's wallet.

Checktion Payment Gateway آپ کو JazzCash اور EasyPaisa دونوں موبائل والٹ سے ایک ہی API کے ذریعے ادائیگی قبول کرنے کی سہولت دیتا ہے۔ پہلے پیمنٹ بنائیں، پھر کسٹمر کا والٹ چارج کریں — یہ دو آسان مراحل ہیں۔

Two-Step Payment Flow — دو مرحلوں کا عمل

1

Create Payment Intent

Send payment details to Checktion. Get a flow_id in return. This is your session token.

POST /auth/

پیمنٹ بنائیں اور flow_id حاصل کریں

2

Charge the Wallet

Submit the flow_id along with the customer's mobile number to charge their wallet.

POST /auth/jazzcash-charge/ POST /auth/easypaisa-charge/ POST /auth/oneqr/

کسٹمر کا موبائل نمبر دے کر والٹ چارج کریں

3

Check Status (if needed)

If payment is still processing, poll the inquiry endpoint until a final status is returned.

POST /inquire/v1/

پیمنٹ کی حیثیت چیک کریں

Fulfill the Order

Only fulfill when status: "completed" is confirmed. Never on "processing".

صرف "completed" ملنے پر آرڈر پورا کریں — "processing" پر نہیں

Trailing Slash Required

Always append a trailing slash to every endpoint URL. Requests to /auth (without slash) will fail. Use /auth/, /auth/jazzcash-charge/, /auth/easypaisa-charge/, /auth/oneqr/, and /inquire/v1/

ہر endpoint URL کے آخر میں slash (/) لگانا ضروری ہے — بغیر slash کے request کام نہیں کرے گی

02

Authentication & Signature

تصدیق اور HMAC دستخط

Every API request is authenticated using an HMAC-SHA256 signature. You build a pipe-separated string from specific fields, then sign it with your secret merchant_api_key. The signature formula differs for each endpoint.

ہر API request کو آپ کی secret key سے HMAC-SHA256 الگورتھم سے sign کیا جاتا ہے۔ sign string مختلف fields کو "|" سے جوڑ کر بنائی جاتی ہے۔ یہ key کبھی بھی frontend پر expose نہ کریں — یہ ہمیشہ آپ کے server پر رہنی چاہیے۔

Signature Formulas — دستخط کے فارمولے

PHP / Pseudocode
// ── Step 1: Create Payment (/auth/) ──────────────────────────────
$sign_string = "merchant_mid|amount|currency|web_id|payer_email|timestamp";
// amount must be formatted as 2 decimal places: "1999.99" not "2000"

// ── Step 2a: JazzCash Charge (/auth/jazzcash-charge/) ────────────
$sign_string = "merchant_mid|flow_id|mobile_number|timestamp";

// ── Step 2b: EasyPaisa Charge (/auth/easypaisa-charge/) ──────────
$sign_string = "merchant_mid|flow_id|mobile_number|timestamp";
// Same formula as JazzCash charge

// ── Step 2c: OneQR Generate (/auth/oneqr/) ────────────────────────
$sign_string = "merchant_mid|flow_id|timestamp";
// No mobile_number — OneQR generates a scannable QR, no wallet number needed

// ── Step 3: Status Inquiry (/inquire/v1/) — Single ───────────────
$sign_string = "merchant_mid|flow_id|timestamp";

// ── Step 3: Status Inquiry (/inquire/v1/) — Batch ────────────────
$sorted_ids = sort(["id3", "id1", "id2"]); // alphabetically
$sign_string = "merchant_mid|id1,id2,id3|timestamp";
// comma-joined, no spaces

// ── Final Step: Compute Signature (same for all) ─────────────────
$signature = hash_hmac("sha256", $sign_string, $merchant_api_key);
Security — سیکیورٹی

Never expose your merchant_api_key in frontend JavaScript, mobile apps, or client-side code. Always compute the signature on your server. The timestamp must be within ±10 minutes of server time.

merchant_api_key کبھی بھی frontend یا موبائل app میں نہ رکھیں۔ Signature ہمیشہ اپنے server سے بنائیں۔ Timestamp ±10 منٹ کے اندر ہونا چاہیے۔

03

Step 1 — Create Payment

پہلا مرحلہ — پیمنٹ بنائیں

Before charging any wallet, you must create a payment intent. This endpoint registers the payment in the Checktion system and returns a flow_id — a 32-character hex token you'll use in Step 2.

کوئی بھی والٹ چارج کرنے سے پہلے، /auth/ endpoint پر پیمنٹ بنانا ضروری ہے۔ یہ آپ کو flow_id دیتا ہے جو اگلے مرحلے میں استعمال ہوگا۔

POST /auth/ — Request Body

POST
{
  "merchant_mid": "MID-ABC123XYZ",       // Your Merchant ID
  "amount": 1999.99,                     // PKR amount (number, not string)
  "currency": "PKR",                     // Must be "PKR"
  "payer_email": "buyer@example.com",    // Customer email address
  "web_id": "ORDER-20250315-001",        // Your unique order reference
  "return": "https://yoursite.com/success", // Callback URL
  "timestamp": 1739683200,               // Unix timestamp (seconds)
  "signature": "a3f1c8d2e4b09fa7..."     // HMAC-SHA256 (see Section 2)
}

Request Fields — درخواست کے فیلڈز

FieldTypeRequiredDescription / وضاحت
merchant_midstringRequiredYour merchant identifier, e.g. MID-ABC123XYZ — آپ کا Merchant ID
amountnumberRequiredAmount in PKR. Formatted as 2 decimal places internally — ادائیگی کی رقم
currencystringRequiredMust be "PKR" — صرف PKR قبول ہوگا
payer_emailstringRequiredValid email address of the customer — کسٹمر کا ای میل
web_idstringRequiredUnique order reference (max 100 chars). Duplicate rejected with HTTP 409 — آپ کا منفرد آرڈر نمبر
returnstringRequiredCallback URL after payment. Domain must match registered merchant domain — کامیابی کے بعد redirect URL
timestampintegerRequiredCurrent Unix timestamp in seconds. Within ±10 minutes — موجودہ وقت
signaturestringRequiredHMAC-SHA256 signature — see Section 2 — HMAC دستخط

Success — HTTP 201

201 Created
{
  "status": "ok",
  "flow_id": "a3f1c8d2e4b09fa72c1d...",
  "payment_url": "https://checktion.com/pay/a3f1c8d2e4b09fa72c1d8e3f5b607a91",
  "web_id": "ORDER-20250315-001"
}

Use flow_id in Step 2 (API charge). If you prefer hosted checkout, redirect the customer to payment_url and confirm completion using IPN or /inquire/v1/.

Common Errors

HTTPError Message
400Required fields missing
400Invalid or expired timestamp
401Invalid merchant_mid / signature
403Merchant not active / domain mismatch
409Duplicate web_id for this merchant

Hosted Checkout Redirect — /pay/<flow_id>

If you do not want to collect the customer's mobile number on your side, redirect the user to the Checktion hosted checkout page. This page handles the UI flow and then redirects the customer back to your return URL.

اگر آپ کسٹمر کا موبائل نمبر خود collect نہیں کرنا چاہتے، تو Checktion hosted checkout استعمال کریں۔ کسٹمر کو /pay/<flow_id> پر redirect کریں اور بعد میں IPN یا /inquire/v1/ سے status confirm کریں۔

Do Not Trust Browser Redirect Alone

The return URL redirect is only for customer experience. Always confirm the final result using IPN (recommended) or /inquire/v1/ before fulfilling the order.

صرف browser redirect پر بھروسہ نہ کریں۔ آرڈر صرف IPN یا /inquire/v1/ سے "completed" confirm ہونے کے بعد ہی پورا کریں۔

04

Step 2A — Charge JazzCash Wallet

جاز کیش والٹ چارج کریں

JazzCash MWALLET 1.1

This endpoint directly contacts the JazzCash MWALLET gateway. The response is immediate — either completed (HTTP 200, funds deducted) or processing (HTTP 202, customer receives a USSD/push prompt and must confirm).

یہ endpoint براہ راست JazzCash gateway سے رابطہ کرتا ہے۔ جواب فوری ملتا ہے — یا تو ادائیگی مکمل ہوجاتی ہے یا کسٹمر کو تصدیق کا پیغام جاتا ہے۔

POST /auth/jazzcash-charge/ — Request Body

POST
{
  "merchant_mid": "MID-ABC123XYZ",
  "flow_id": "a3f1c8d2e4b09fa72c1d8e3f5b607a91",  // from /auth/
  "mobile_number": "03001234567",                 // 11 digits, starts with 03
  "timestamp": 1739683260,
  "signature": "d7e2f3a1b4c5..."                  // HMAC of mid|flow_id|mobile|timestamp
}
HTTP 200 Completed

Payment deducted immediately — رقم مل گئی

{
  "success": true,
  "status": "completed",
  "message": "Payment completed successfully",
  "amount": "1999.99",
  "currency": "PKR",
  "transaction_id": "202604031350558459...",
  "ref_no": "T2026040308505404371d"
}
HTTP 202 Processing

Customer must confirm on phone — /inquire/v1/ سے status چیک کریں

{
  "success": true,
  "status": "processing",
  "message": "Payment in processing",
  "amount": "1999.99",
  "currency": "PKR",
  "transaction_id": "202604031350558459...",
  "ref_no": "T2026040308505404371d"
}

JazzCash-Specific Errors

HTTPErrorAction
400Transaction declined - Insufficient balanceNotify customer. Do not retry with same flow_id.
400Invalid mobile_number formatValidate phone (03XXXXXXXXX) before submitting
404Payment not found or not pendingCreate new payment via /auth/
410Payment has expiredCreate new payment via /auth/
On Failure — نئی ادائیگی بنائیں

If /auth/jazzcash-charge/ returns HTTP 400 (failed), do not retry with the same flow_id. You must go back to Step 1 and create a new payment via /auth/.

اگر payment ناکام ہو جائے تو وہی flow_id دوبارہ استعمال نہ کریں — نئی payment بنانے کے لیے /auth/ پر واپس جائیں۔

05

Step 2B — Charge EasyPaisa Wallet

ایزی پیسہ والٹ چارج کریں

EasyPaisa Official MA

This endpoint sends a payment request to the customer's EasyPaisa account. The customer receives an SMS/app notification to confirm. A successful initiation returns HTTP 202 with status "processing". HTTP 200 is only returned when the payment is fully PAID — matching JazzCash behaviour. Poll /inquire/v1/ to confirm completion.

یہ endpoint کسٹمر کے EasyPaisa account کو notify کرتا ہے۔ کسٹمر کو SMS/app notification ملتی ہے۔ شروعات پر HTTP 202 ملتا ہے — HTTP 200 صرف اس وقت آتا ہے جب رقم مکمل ادا ہو جائے، بالکل JazzCash کی طرح۔

POST /auth/easypaisa-charge/ — Request Body

POST
{
  "merchant_mid": "MID-ABC123XYZ",
  "flow_id": "a3f1c8d2e4b09fa72c1d8e3f5b607a91",  // from /auth/
  "mobile_number": "03001234567",                 // EasyPaisa-registered number
  "timestamp": 1739683260,
  "signature": "d7e2f3a1b4c5..."                  // HMAC of mid|flow_id|mobile|timestamp
}
HTTP 200 Completed

Payment confirmed — funds received

{
  "success": true,
  "status": "completed",
  "message": "Payment completed successfully",
  "gateway": "easypaisa",
  "amount": "1999.99",
  "currency": "PKR",
  "transaction_id": "48836361137",
  "ref_no": "VLX20260403140523abc123"
}
HTTP 202 Processing

SMS/notification sent — /inquire/v1/ سے status چیک کریں

{
  "success": true,
  "status": "processing",
  "message": "Payment request sent. Please check your EasyPaisa app / SMS and confirm.",
  "gateway": "easypaisa",
  "amount": "1999.99",
  "currency": "PKR",
  "transaction_id": "VLX20260403140523abc123",
  "ref_no": "VLX20260403140523abc123"
}
EasyPaisa Now Matches JazzCash HTTP Semantics

Both gateways now share the same HTTP code contract: HTTP 200 = payment completed, HTTP 202 = processing. EasyPaisa initiation returns HTTP 202, and only fires HTTP 200 when the IPN confirms a PAID status. You must poll /inquire/v1/ after a 202 to confirm completion.

اب دونوں gateways کا HTTP code ایک جیسا ہے: HTTP 200 = رقم مل گئی، HTTP 202 = کسٹمر کی تصدیق کا انتظار ہے۔ EasyPaisa شروع میں HTTP 202 دیتا ہے اور HTTP 200 صرف PAID ہونے پر آتا ہے۔

06

Step 2C — Generate OneQR Code

OneQR کوڈ بنائیں

OneQR — Scan & Pay

Unlike JazzCash and EasyPaisa charge, OneQR does not push a request to a customer's mobile number. Instead this endpoint generates a scannable QR code tied to the payment. The customer scans it with any QR-enabled banking or wallet app to complete payment. No mobile_number field is required.

JazzCash اور EasyPaisa کے برعکس، OneQR کسٹمر کے موبائل نمبر پر درخواست نہیں بھیجتا۔ یہ endpoint ایک اسکین کے قابل QR کوڈ بناتا ہے۔ موبائل نمبر درکار نہیں۔

POST /auth/oneqr/ — Request Body

POST
{
  "merchant_mid": "MID-ABC123XYZ",
  "flow_id": "a3f1c8d2e4b09fa72c1d8e3f5b607a91",  // from /auth/
  "timestamp": 1739683260,
  "signature": "a1b2c3d4..."                       // HMAC of mid|flow_id|timestamp
}

Signature Formula — دستخط کا فارمولا

PHP / Pseudocode
$sign_string = "merchant_mid|flow_id|timestamp";
$signature   = hash_hmac("sha256", $sign_string, $merchant_api_key);

Response: QR Generated — HTTP 200

200 OK
{
  "success": true,
  "status": "processing",
  "gateway": "oneqr",
  "qr_string": "00020101021226580014PK.COM.ONEQR...",
  "psid": "PSID20260403140523",
  "ref_no": "VLX20260403140523oneqr",
  "amount": "1999.99",
  "currency": "PKR"
}

Render qr_string as a QR image for the customer to scan. Poll /inquire/v1/ using flow_id.

OneQR Response Fields

FieldTypeDescription / وضاحت
successbooleanWhether the QR was generated successfully
statusstring"processing" — awaiting customer scan & confirmation
gatewaystringAlways "oneqr"
qr_stringstringRaw QR payload — render as QR code image
psidstringPayment Session ID assigned by OneQR
ref_nostringChecktion reference number for this transaction
amountstringAmount as 2-decimal string
currencystringAlways "PKR"

OneQR-Specific Errors

HTTPErrorAction
400Required fields missingValidate request body
401Invalid merchant_mid / signatureRecheck HMAC formula: mid|flow_id|timestamp
404Payment not found or wrong merchantCreate new payment via /auth/
410Payment has expiredCreate new payment via /auth/
Generate, Then Poll — QR does not push HTTP 202

Because OneQR is scan-based rather than push-based, a successful call always returns HTTP 200 with status "processing". You must poll /inquire/v1/ — or listen for IPN — until the status becomes completed.

OneQR "push" کی بجائے "scan" پر مبنی ہے، اس لیے کامیاب کال ہمیشہ HTTP 200 اور status: "processing" دیتی ہے۔ آرڈر مکمل کرنے سے پہلے /inquire/v1/ سے "completed" کنفرم کریں یا IPN کا انتظار کریں۔

07

Payment Status Values

ادائیگی کی حیثیت کی اقدار

StatusCodeMeaningNext Action
completed200Payment successfully completed and funds received — ادائیگی مکمل، رقم مل گئی✅ Fulfill the order
processing101Being processed — awaiting customer action — کسٹمر کے تصدیق کا انتظار⏳ Poll /inquire/v1/
pending100Payment created, not yet submitted to gateway — پیمنٹ بنی، چارج نہیں ہوئیProceed to charge endpoint
failed400Payment attempt failed — ادائیگی ناکام رہیCreate new payment via /auth/
expired102Payment expired (25-minute window passed) — پیمنٹ کی مدت ختمCreate new payment via /auth/
cancelled103Cancelled by customer or gateway — کسٹمر یا gateway نے منسوخ کیاCreate new payment if needed
refunded106Amount returned to customer — رقم واپس کی گئیUpdate order status
dropped401Payment abandoned midway — ادائیگی ادھوری چھوڑ دیTreat as failed
08

Check Payment Status

ادائیگی کی حیثیت چیک کریں

Query the current status of any payment at any time. Look up by flow_id or web_id. Supports single and batch lookups (up to 50 IDs).

کسی بھی وقت /inquire/v1/ سے payment کی حیثیت معلوم کریں — flow_id یا web_id سے۔ ایک ساتھ 50 تک IDs بھیج سکتے ہیں۔

POST — Single Lookup by flow_id
{
  "merchant_mid": "MID-ABC123XYZ",
  "flow_id": "a3f1c8d2e4b09fa72c1d8e3f5b607a91",
  "timestamp": 1739683320,
  "signature": "e9a2b3c4..."   // HMAC of mid|flow_id|timestamp
}
POST — Single Lookup by web_id
{
  "merchant_mid": "MID-ABC123XYZ",
  "web_id": "ORDER-20250315-001",  // Use EITHER flow_id OR web_id, not both
  "timestamp": 1739683320,
  "signature": "f1b2c3d4..."        // HMAC of mid|web_id|timestamp
}

Success Response — HTTP 200

200 OK
{
  "status": "ok",
  "payment": {
    "web_id": "ORDER-20250315-001",
    "flow_id": "a3f1c8d2e4b09fa72c1d...",
    "amount": 1999.99,
    "currency": "PKR",
    "status": "completed",
    "status_code": 200,
    "status_description": "The payment was successfully completed and funds received.",
    "create_time": "2026-04-03 08:50:42",
    "update_time": "2026-04-03 08:51:06",
    "payer_email": "buyer@example.com",
    "payment_message": "Transaction processed successfully.",
    "settlement_status": "unsettled",
    "issuer": "JazzCash"   // or "EasyPaisa", "OneQR"
  }
}

Batch Lookup — Up to 50 IDs at Once

POST
{
  "merchant_mid": "MID-ABC123XYZ",
  "flow_id": "a3f1c8d2...,b4e2d9f1...,c5f3e0a2...",  // comma-separated
  "timestamp": 1739683400,
  "signature": "..."  // signed over IDs sorted alphabetically, comma-joined
}

// Response: { "status":"ok", "count":3, "payments":[{...},{...},{...}] }
Batch Signature Rule — بیچ دستخط

For batch requests, sort the IDs alphabetically and join with commas (no spaces) before computing the signature: sort(["c5f3","a3f1","b4e2"]) → "a3f1,b4e2,c5f3".

Batch request میں IDs کو alphabetical ترتیب سے sort کر کے comma سے جوڑیں — پھر اس string سے HMAC بنائیں۔ IDs کے درمیان space نہ ہو۔

09

Merchant IPN (Webhook)

مرچنٹ IPN — محفوظ نوٹیفکیشن

Checktion sends server-to-server IPNs to your merchant IPN URL when a payment status changes. IPNs are delivered in a uniform JSON structure (not raw provider payloads) and are protected using an HMAC-SHA256 signature in the JSON body.

Checktion آپ کے IPN URL پر server-to-server IPN بھیجتا ہے۔ یہ raw provider data نہیں ہوتا بلکہ uniform JSON ہوتا ہے، اور JSON body میں HMAC-SHA256 signature کے ساتھ secure ہوتا ہے۔

When IPN Is Sent

IPNs are sent when Checktion receives a provider update (JazzCash/EasyPaisa IPN) or when the cron job detects a late final status (completed/expired) that was not delivered to your server.

Callback URL

Set your IPN endpoint in your merchant profile (admin panel). Checktion will POST JSON to this URL.

Uniform IPN JSON Payload

Request Body Example
{
  "merchant_mid": "MID-ABC123XYZ",
  "event_id": "12345",
  "timestamp": 1739683200,
  "signature": "2d4b...",
  "flow_id": "a3f1c8d2e4b09fa72c1d8e3f5b607a91",
  "status": "completed",
  "amount": "1999.99",
  "currency": "PKR",
  "web_id": "ORDER-20250315-001",
  "issuer": "1",
  "provider": "jazzcash",
  "reference": "T2026040308505404371d",
  "message": "Payment completed successfully",
  "event_time": "2026-04-03 08:51:06",
  "source": "provider_ipn_jazzcash"
}

Expected IPN ACK (Your Response)

Your endpoint must return a JSON acknowledgment containing the same flow_id and a status of completed, expired, or processing.

HTTP 200 — ACK Body
{
  "flow_id": "a3f1c8d2e4b09fa72c1d8e3f5b607a91",
  "status": "completed"
}

Signature Verification Logic

Signature input format
sign_string = merchant_mid + "|" + flow_id + "|" + status + "|" +
              amount + "|" + currency + "|" + web_id + "|" + timestamp
expected = HMAC_SHA256(sign_string, merchant_api_key)
signature = expected
Retry Rules

If you ACK with completed or expired, Checktion stops retries for that payment status. If you ACK with processing or do not ACK properly, Checktion retries (up to 3 total attempts).

اگر آپ completed یا expired ACK دیں تو retries بند ہو جاتی ہیں۔ processing یا غلط/نہ آنے والی ACK پر Checktion دوبارہ کوشش کرتا ہے (زیادہ سے زیادہ 3 بار)۔

10

Error Reference

خامیوں کا حوالہ

All API errors return a consistent JSON structure. On charge endpoints, errors include a success: false field. On other endpoints, the error is in the error key.

Standard Error Format
{
  "success": false,   // only on charge endpoints
  "error": "Human-readable error message"
}
HTTPMeaningAction
200OK — Charge completed / inquiry successProceed
201Created — Payment record created (/auth/)Proceed to charge
202Accepted — Charge initiated (processing)Poll /inquire/v1/
400Bad Request — Validation or gateway failureFix input or create new payment
401Unauthorized — Invalid merchant_mid or signatureCheck credentials and signature formula
403Forbidden — Inactive merchant or domain mismatchContact support
404Not Found — flow_id not found or wrong merchantCheck flow_id or create new
405Method Not Allowed — Use POSTUse POST method
409Conflict — Duplicate web_idUse a unique web_id
410Gone — Payment expired before chargeCreate new payment via /auth/
500Server Error — Merchant secret not configuredContact support
503Unavailable — Database connection failureRetry after short delay
11

Quick Reference

تیز رہنما

TaskEndpointMethodKey Response
Create payment for any gateway/auth/POSTflow_id in HTTP 201
Hosted checkout (redirect)/pay/<flow_id>GETUse IPN or /inquire/v1/ to confirm
Charge JazzCash wallet/auth/jazzcash-charge/POST200=done, 202=poll, 400=fail
Charge EasyPaisa wallet/auth/easypaisa-charge/POST200=done, 202=poll, 400=fail
Generate OneQR code/auth/oneqr/POST200=QR generated, poll to confirm
Check single payment status/inquire/v1/POSTstatus + status_code
Batch status (up to 50)/inquire/v1/POSTpayments[] array with count
Receive payment webhooksYour IPN URLPOSTVerify HMAC, then ACK {flow_id,status}

Checktion Payment Gateway — Developer Reference v1.2 — 2026

Base URL: https://checktion.com/ · PKR Only · HMAC-SHA256

چیکشن پیمنٹ گیٹ وے — ڈویلپر دستاویز — 2026