Search pages in the SMS Pay documentation.
SMS Pay is a hosted payment orchestration system. The API server owns payment intent lifecycle, SMS events are evidence, reconciliation decides the outcome, and webhooks notify merchant systems.
Loading diagram...
| Component | Responsibility |
|---|---|
| API Server | Authenticates API keys, creates payment intents, stores SMS events, exposes checkout data, dispatches webhooks. |
| Checkout UI | Public page that shows payment amount, receiver wallet, reference, expiry, and fallback transaction ID input. |
| Android SMS Agent | Reads trusted wallet SMS messages on the merchant device and sends them to the backend. |
| Sandbox Simulator | Sends sandbox SMS events for testing. It never creates payment intents. |
| Matching engine | Compares SMS amount, receiver, reference, and transaction ID with active payment intents. |
| Reconciliation dashboard | Lets merchant admins inspect exceptions and manually resolve ambiguous cases. |
| Webhook dispatcher | Sends signed payment events to verified merchant endpoints. |
PENDING and returns a checkoutUrl.receiverMsisdn.Android-style ingestion uses a signed request:
import crypto from "node:crypto";
const body = JSON.stringify({
sender: "bKash",
message: "You have received payment Tk 500.00 from 01711111111. Ref ORDER-10045. Fee Tk 0.00. Balance Tk 10000.00. TrxID ABCD1234",
receiverMsisdn: "01700000001",
receivedAt: new Date().toISOString(),
deviceId: "android-device-01"
});
const signature =
"sha256=" + crypto.createHmac("sha256", process.env.SMS_PAY_LIVE_KEY!).update(body).digest("hex");
POST /v1/sms-events/incoming
X-Api-Key: sk_live_xxxxxxxxxxxxxxxxx
X-Signature: sha256=<hmac>
Content-Type: application/json
{
"sender": "bKash",
"message": "You have received payment Tk 500.00 from 01711111111. Ref ORDER-10045. Fee Tk 0.00. Balance Tk 10000.00. TrxID ABCD1234",
"receiverMsisdn": "01700000001",
"receivedAt": "2026-05-05T10:00:00.000Z",
"deviceId": "android-device-01"
}
{
"id": "sms_123",
"status": "RECEIVED",
"queued": true,
"duplicate": false
}