Search pages in the SMS Pay documentation.
The payment flow is intent-first. A payment intent is created before the customer pays. The SMS event is only the confirmation signal. This separation keeps checkout, SMS ingestion, reconciliation, and fulfillment predictable.
Loading diagram...
Your backend creates a payment intent with amount, BDT currency, customer reference, idempotency key, optional customer fields, and optional receiving wallet override.
POST /v1/payments/intents
X-Api-Key: sk_test_xxxxxxxxxxxxxxxxx
The server sets:
status: PENDINGexpiresAt, default 5 minutes from creationreceiverMsisdn, the merchant wallet numbercheckoutUrl, the hosted payment pageThe checkout page displays:
The public checkout endpoint is read-only:
GET /v1/checkout/:id
The customer sends the exact amount to the displayed merchant wallet number and includes the displayed reference when the wallet app supports a reference field.
In live mode, the Android SMS Agent forwards the provider SMS to:
POST /v1/sms-events/incoming
X-Api-Key: sk_live_xxxxxxxxxxxxxxxxx
X-Signature: sha256=<hmac>
In sandbox, the Visual SMS Simulator or raw simulator endpoint sends an equivalent sandbox SMS event.
Primary instant match requires:
If these checks pass, the intent becomes PAID and a payment.paid webhook is queued.
If the customer enters a transaction ID on checkout, the server compares it against stored SMS events. The fallback confirms only when:
async function createCheckout(order: { id: string; total: number }) {
const response = await fetch("https://api.smspaybd.com/v1/payments/intents", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": process.env.SMS_PAY_SANDBOX_KEY!,
},
body: JSON.stringify({
amount: order.total,
currency: "BDT",
customerReference: order.id,
idempotencyKey: `order_${order.id}`,
ttlSeconds: 300
}),
});
if (!response.ok) throw new Error("Could not create payment intent");
return response.json();
}
Checkout details:
GET /v1/checkout/b5012f33-207e-4999-bf8d-5a1ebb10988e
{
"id": "b5012f33-207e-4999-bf8d-5a1ebb10988e",
"amount": "500",
"currency": "BDT",
"status": "PENDING",
"environment": "SANDBOX",
"customerReference": "ORDER-10045",
"receiverMsisdn": "01700000001",
"expiresAt": "2026-05-05T10:05:00.000Z"
}
Fallback confirmation:
POST /v1/checkout/b5012f33-207e-4999-bf8d-5a1ebb10988e/confirm
Content-Type: application/json
{
"trxId": "ABCD1234"
}
{
"matched": true,
"paymentIntentId": "b5012f33-207e-4999-bf8d-5a1ebb10988e",
"smsEventId": "c90a5751-a3ca-483e-871b-e3a094ea7523",
"reason": "manual_trx_id_confirmed"
}
REVIEW_REQUIRED.