Documentationv2.0
Open console
SwapnoPay for developers

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.

Start integrating

Platform Mechanism & Architecture

SwapnoPay unifies carrier MFS SMS verification on Android, merchant databases, and web checkouts into a high-speed settlement pipeline.

bolt Atomic Pattern Matching

Merchant Android workers intercept raw carrier MFS SMS (bKash, Nagad, Rocket, Upay) and perform atomic regex extraction of Transaction ID, amount, and sender phone.

lock Central HMAC & Ledger

Platform Owner Admin Supabase database manages API key peppered HMAC digests, platform fee accounting, idempotency guards, and centralized payment telemetry.

rss_feed Real-Time WebSockets

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.

POST /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"
}
Response (200 OK):
{
  "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"
  }
}
POST /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"
}
GET /v1/payment/status/{orderId}

Inspect live settlement status (PAID, PENDING, EXPIRED).

POST /v1/hosted-form/submit

Dynamic hosted form submission supporting custom date pickers, dropdowns, and file upload attachments.

⚠️ API Error Codes Reference
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.

Loading...

Production SDK Code Examples

Copy-paste production integrations for your tech stack.

🟢 Node.js / Express
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);
}
code Python (FastAPI / Requests)
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())
code PHP (cURL / Laravel)
<?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));
?>
phone_android Kotlin (Android OkHttp)
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())
}