Your guide to better
payment integrations.
Integrate SwapnoPay payments into your website or app. Explore the payment API, understand webhook delivery, and get started with practical code examples for Bangladesh’s MFS ecosystem.
Platform Mechanism & Architecture
SwapnoPay unifies carrier MFS SMS verification on Android, merchant databases, and web checkouts into a high-speed settlement pipeline.
Merchant Android workers intercept raw carrier MFS SMS (bKash, Nagad, Rocket, Upay) and perform atomic regex extraction of Transaction ID, amount, and sender phone.
Platform Owner Admin Supabase database manages API key peppered HMAC digests, platform fee accounting, idempotency guards, and centralized payment telemetry.
Express.js + Socket.io server emits instant payment_status events (PAID, FAILED, CANCELLED) to listening web checkout widgets.
System Sequence & Flowchart
End-to-end payment lifecycle from checkout initialization to carrier match and webhook dispatch.
┌─────────────────┐ ┌────────────────────┐ ┌────────────────────────┐
│ Customer Web │ │ SwapnoPay Backend │ │ Merchant Android Phone │
│ Checkout Widget │ │ (Node + Socket.io) │ │ (Carrier SMS Receiver) │
└────────┬────────┘ └─────────┬──────────┘ └───────────┬────────────┘
│ │ │
1. Join Order Room │ │
├─────────────────────────>│ │
│ │ │
2. Customer Sends Money (bKash) │ │
│ │ │
3. Android Worker Intercepts SMS │ │
│ │ 4. Regex Pattern Match │
│ │ TxID, Amount, Phone │
│ │<─────────────────────────────┤
│ │ 5. POST /v1/payment/verify │
│ │ │
6. Socket.io 'payment_status' │ │
(Status = PAID, Redirect URL) │ │
│<─────────────────────────┤ │
│ │ │
7. Instant Redirect to Success Page│ │
│ │ │
Authentication & Headers
Authenticate API calls using your Secret Key and protect against duplicate transactions with idempotency.
| Header Name | Type | Description |
|---|---|---|
| X-Admin-Secret | string | Your merchant API Secret Key starting with sk_live_... |
| Idempotency-Key | string (UUID) | Unique client request token to guarantee each charge is executed exactly once. |
| Content-Type | string | Must be set to application/json. |
Core API Endpoints Reference
Production HTTP endpoints for payment creation, instant verification, status queries, and dynamic hosted forms.
/v1/payment/create
Creates a new payment checkout session and generates the hosted payment link.
{
"order_id": "ORD-2026-9812",
"amount": 1250.00,
"currency": "BDT",
"customer_name": "Tanvir Hasan",
"customer_phone": "01712963652",
"customer_email": "tanvir@example.com",
"payment_method": "bKash",
"redirect_url": "https://merchant.example.com/checkout/success",
"cancel_url": "https://merchant.example.com/checkout/cancel"
}
{
"status": "SUCCESS",
"code": 200,
"data": {
"order_id": "ORD-2026-9812",
"payment_url": "https://pay.swapnopay.top/pay/ORD-2026-9812",
"assigned_gateway_number": "01784992118",
"payable_amount": 1250.00,
"expires_at": "2026-09-07T21:15:00Z"
}
}
/v1/payment/verify
Invoked by the carrier SMS receiver to verify transaction parameters and settle order.
{
"order_id": "ORD-2026-9812",
"tran_id": "9H8B7G6F5E",
"sender_phone": "01712963652",
"amount": 1250.00,
"payment_method": "bKash"
}
/v1/payment/status/{orderId}
Inspect live settlement status (PAID, PENDING, EXPIRED).
/v1/hosted-form/submit
Dynamic hosted form submission supporting custom date pickers, dropdowns, and file upload attachments.
| Error Code | HTTP | Description & Resolution |
|---|---|---|
| ERR_INVALID_HMAC | 401 | HMAC-SHA256 signature verification failed. Check your webhook secret. |
| ERR_ORDER_EXPIRED | 400 | Order payment lifetime (default 10 min) elapsed before payment completion. |
| ERR_DUPLICATE_IDEMPOTENCY | 409 | Request with this Idempotency-Key was already processed. Read cached order. |
| ERR_INSUFFICIENT_AMOUNT | 422 | Customer paid less than order invoice. Transaction flagged for manual appeal. |
| ERR_GATEWAY_OFFLINE | 503 | No Android receiver phone currently online for requested payment gateway. |
Webhooks & HMAC Signature Security
SwapnoPay signs all webhook notifications with HMAC-SHA256 in the X-Signature header.
Node.js Signature Verification:
const crypto = require('crypto');
function verifySwapnoPayWebhook(rawBody, signatureHeader, webhookSecret) {
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', webhookSecret)
.update(rawBody, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(expectedSignature), Buffer.from(signatureHeader));
}
Python Signature Verification:
import hmac
import hashlib
def verify_swapnopay_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode('utf-8'), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header)
Official Video Integration Tutorials
Step-by-step video guides managed dynamically from the Admin Panel CMS.
Production SDK Code Examples
Copy-paste production integrations for your tech stack.
const axios = require('axios');
const crypto = require('crypto');
async function createSwapnoPayOrder() {
const response = await axios.post('https://pay.swapnopay.top/v1/payment/create', {
order_id: 'ORD-2026-9812',
amount: 1250.00,
customer_phone: '01712963652',
payment_method: 'bKash',
redirect_url: 'https://mysite.com/success'
}, {
headers: {
'X-Admin-Secret': 'sk_live_your_api_secret',
'Idempotency-Key': crypto.randomUUID()
}
});
console.log('Redirect checkout URL:', response.data.data.payment_url);
}
import requests
import uuid
response = requests.post(
"https://pay.swapnopay.top/v1/payment/create",
headers={
"X-Admin-Secret": "sk_live_your_api_secret",
"Idempotency-Key": str(uuid.uuid4())
},
json={
"order_id": "ORD-2026-9812",
"amount": 1250.00,
"customer_phone": "01712963652",
"payment_method": "bKash",
"redirect_url": "https://mysite.com/success"
}
)
print(response.json())
<?php
$ch = curl_init('https://pay.swapnopay.top/v1/payment/create');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'X-Admin-Secret: sk_live_your_api_secret',
'Idempotency-Key: ' . uniqid()
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'order_id' => 'ORD-2026-9812',
'amount' => 1250.00,
'customer_phone' => '01712963652',
'payment_method' => 'bKash',
'redirect_url' => 'https://mysite.com/success'
]));
$response = curl_exec($ch);
print_r(json_decode($response, true));
?>
val client = OkHttpClient()
val json = JSONObject().apply {
put("order_id", "ORD-2026-9812")
put("amount", 1250.00)
put("customer_phone", "01712963652")
put("payment_method", "bKash")
put("redirect_url", "https://mysite.com/success")
}
val request = Request.Builder()
.url("https://pay.swapnopay.top/v1/payment/create")
.addHeader("X-Admin-Secret", "sk_live_your_api_secret")
.addHeader("Idempotency-Key", java.util.UUID.randomUUID().toString())
.post(json.toString().toRequestBody("application/json".toMediaType()))
.build()
client.newCall(request).execute().use { response ->
println(response.body?.string())
}