ZexaPay API

Automated payment processing — mobile money & crypto smart contracts

v1.0 Stable

ZexaPay provides a RESTful API for automated payment processing. Accept deposits via mobile money (bKash, Nagad, GCash, etc.) with real-time transaction matching, or generate unique crypto payment addresses with smart contract forwarding.

💡 New to ZexaPay? Create an account to get your API key.

Authentication

All API requests require your API key in the X-API-Key header.

curl -H "X-API-Key: zpay_live_abc123..." \
  https://secure-pay.zexabit.com/api/v1/client/deposit
⚠ Keep your API key secure. Never expose it in client-side code.

Base URL

https://secure-pay.zexabit.com/api/v1
EnvironmentBase URL
Productionhttps://secure-pay.zexabit.com/api/v1

Create Deposit Request

Create a pending deposit that will be auto-matched when payment is received.

POST /client/deposit Create pending deposit

Request Body

FieldTypeRequiredDescription
amountnumberRequiredDeposit amount in local currency
externalIdstringRequiredYour unique reference ID for this deposit
customerNamestringOptionalCustomer name for reference
callbackUrlstringOptionalOverride default webhook URL

Example Request

curl -X POST https://secure-pay.zexabit.com/api/v1/client/deposit \
  -H "X-API-Key: zpay_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1000,
    "externalId": "order_12345",
    "customerName": "John Doe"
  }'

Response

{
  "depositId": "665f1a2b3c4d5e6f7a8b9c0d",
  "amount": 1000,
  "externalId": "order_12345",
  "status": "pending",
  "expiresAt": "2026-04-11T01:30:00.000Z",
  "paymentNumber": "+8801XXXXXXXXX",
  "provider": "bkash"
}

Check Deposit Status

GET /client/deposit/:externalId/status Get deposit status

Response

{
  "externalId": "order_12345",
  "status": "matched",
  "amount": 1000,
  "matchedAt": "2026-04-11T01:25:12.000Z",
  "trxID": "ABC123XYZ",
  "senderPhone": "+8801712345678"
}

Status Values

StatusDescription
pendingWaiting for payment
matchedPayment received and matched
expiredDeposit expired (not paid in time)

List Deposits

GET /client/deposits?status=matched&page=1&limit=20 Paginated deposit list

Query Parameters

ParamTypeDefaultDescription
statusstringallFilter: pending, matched, expired
pagenumber1Page number
limitnumber20Items per page (max 100)

Generate Crypto Payment Address

Generate a unique payment address for crypto payments. Funds are auto-forwarded to your treasury wallet via smart contracts.

POST /dashboard/crypto-wallets/generate-address Generate unique address

Request Body

FieldTypeRequiredDescription
networkstringRequiredBlockchain network (BEP-20, ERC-20, Polygon, etc.)
amountnumberOptionalExpected amount in cents (USD * 100)
referencestringOptionalYour order/invoice reference

Example

curl -X POST https://secure-pay.zexabit.com/api/v1/dashboard/crypto-wallets/generate-address \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "BEP-20",
    "amount": 10000,
    "reference": "invoice-456"
  }'

Response

{
  "address": "0x3a9f7b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a",
  "paymentId": "665f1a2b3c4d5e6f7a8b9c0d",
  "network": "BEP-20",
  "tokens": [
    { "symbol": "USDT", "contractAddress": "0x55d3...", "decimals": 18 },
    { "symbol": "USDC", "contractAddress": "0x8AC7...", "decimals": 18 }
  ],
  "amount": 10000,
  "reference": "invoice-456"
}
🛡 Each address is unique and secured by a smart contract. Funds auto-forward to your treasury wallet. No private key risk.

Check Crypto Payment Status

GET /dashboard/crypto-payments?status=swept List crypto payments

Status Flow

StatusDescription
pendingAddress generated, waiting for payment
fundedFunds detected at address
sweepingSweeping funds to treasury
sweptFunds delivered to your treasury wallet

Supported Networks

NetworkChainTokensSweep Cost
BEP-20BNB Smart ChainUSDT, USDC, BUSD, BNB~$0.01
ERC-20EthereumUSDT, USDC, DAI, ETH~$3-5
PolygonPolygonUSDT, USDC, MATIC~$0.01
ArbitrumArbitrum OneUSDT, USDC, ETH~$0.01
BaseBaseUSDC, ETH~$0.01
OptimismOptimismUSDT, USDC, ETH~$0.01
AvalancheAvalanche C-ChainUSDT, USDC, AVAX~$0.02

List Wallets

GET /dashboard/wallets List payment numbers

Returns all configured mobile payment numbers for your tenant.

Add Wallet

POST /dashboard/wallets Add payment number
FieldTypeRequired
numberstringRequired
providerstringRequired
labelstringOptional

Supported Providers

bkash, nagad, rocket, upay, paytm, phonepe, gpay, upi, jazzcash, easypaisa, gcash, maya, gopay, ovo, dana, touch-n-go, boost, promptpay, truemoney, momo, zalopay, esewa, khalti, frimi, ez-cash

Webhooks

ZexaPay sends webhook notifications to your configured URL when payment events occur.

Configure your webhook URL in the dashboard.

Webhook Payload

POST https://your-app.com/webhook
Headers:
  X-ZexaPay-Signature: sha256=abc123...
  X-ZexaPay-Event: deposit.matched
  Content-Type: application/json

{
  "event": "deposit.matched",
  "depositId": "665f1a2b...",
  "externalId": "order_12345",
  "amount": 1000,
  "trxID": "ABC123XYZ",
  "senderPhone": "+8801712345678",
  "matchedAt": "2026-04-11T01:25:12.000Z"
}

Webhook Events

EventDescription
deposit.matchedMobile money deposit received and matched
deposit.expiredPending deposit expired without payment
crypto.fundedCrypto funds detected at forwarder address
crypto.sweptCrypto funds swept to treasury wallet

Signature Verification

Verify webhook authenticity using HMAC-SHA256 with your webhook secret.

const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Error Codes

CodeDescription
400Bad Request — missing or invalid parameters
401Unauthorized — invalid or missing API key
403Forbidden — security check failed (Turnstile)
404Not Found — resource doesn't exist
409Conflict — duplicate externalId
429Too Many Requests — rate limit exceeded
500Server Error — try again later

Rate Limits

EndpointLimit
/client/*120 requests/minute
/dashboard/*120 requests/minute
/auth/send-otp3 per email per 10 minutes
💡 Rate limits are per API key / IP address. Contact support if you need higher limits.