Cash Agent API

Integrate Zexabit's Cash Agent payment system into your existing platform. Cashagents handle manual deposit/withdrawal for your users.

💡 This API uses the cpay channel — a human cash agent network. Supports BDT, INR, PKR, and Crypto (USDT/BTC/ETH/TRX). Transactions are approved manually by your assigned cashagent.
🏦

How It Works

  1. Your server creates a deposit/withdrawal via API
  2. Zexabit assigns a cashagent to the transaction
  3. Cashagent confirms cash received / sends cash
  4. Webhook fires to your callback URL

Quick Start

  1. Request a Partner API key from admin
  2. Map your users to Zexabit user IDs
  3. Set your webhook callback URL
  4. Call deposit/withdrawal endpoints

🔐 Authentication

All API requests must include a Bearer token in the Authorization header. Get your API key from the Partner Management section in the admin dashboard.

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
⚠️ Never expose your API key in frontend code. All calls must be server-to-server only.

🌐 Base URL

https://api.portal.zexabit.com

All endpoints below are relative to this base URL.

👤 User Management

POST /partner/users Register a new user

Creates a linked user account in Zexabit. Store the returned userId on your side for future calls.

Request Body

FieldTypeRequiredDescription
externalUserIdstringRequiredYour platform's user ID
usernamestringRequiredUnique username (4–20 chars)
emailstringOptionalUser's email address
phonestringOptionalPhone number

Example Request

POST /partner/users
{
  "externalUserId": "usr_abc123",
  "username": "john_doe",
  "email": "john@example.com"
}

Response

{
  "success": true,
  "userId": "68abc40f199dcff85e123456",   // Store this!
  "username": "john_doe",
  "balance": 0
}
GET /partner/users/:userId/balance Get user balance

Response

{
  "success": true,
  "userId": "68abc40f199dcff85e123456",
  "balance": 1500.00,
  "depositBalance": 3200.00,
  "withdrawBalance": 1700.00
}

💰 Deposits

POST /partner/deposits Initiate a deposit
💡 Channel is always cpay. The system auto-assigns an available cashagent for the chosen payment method.

Request Body

FieldTypeRequiredDescription
userIdstringRequiredZexabit user ID from /partner/users
amountnumberRequiredAmount in user's currency (min varies by method)
paymentMethodstringRequiredSee Supported Methods below
paymentNumberstringRequiredAgent's account/wallet address (from /deposit-agent)
transactionIdstringOptionalUser's TrxID / blockchain tx hash for verification

Example Request

POST /partner/deposits
{
  "userId": "68abc40f199dcff85e123456",
  "amount": 500,
  "paymentMethod": "bkash",
  "paymentNumber": "01712345678",
  "transactionId": "TRX8B7K9M2"
}

Response

{
  "success": true,
  "depositId": "dep_68xyz...",
  "status": "pending",
  "message": "Deposit submitted. Awaiting cashagent approval.",
  "estimatedTime": "5-15 minutes"
}
GET /partner/deposits/:depositId Check deposit status

Response

{
  "success": true,
  "depositId": "dep_68xyz...",
  "status": "completed",   // pending | completed | rejected
  "amount": 500,
  "userId": "68abc40f...",
  "completedAt": "2026-03-08T10:30:00Z",
  "agentName": "Demo Cashagent"
}
GET /partner/payment-methods List available payment methods

Returns all payment methods configured for your partner account. Methods vary by region/currency.

Response

{
  "success": true,
  "methods": [
    { "method": "bkash", "label": "bKash", "currency": "BDT", "minAmount": 100, "maxAmount": 50000 },
    { "method": "nagad", "label": "Nagad", "currency": "BDT", "minAmount": 100, "maxAmount": 50000 },
    { "method": "rocket", "label": "Rocket", "currency": "BDT", "minAmount": 100, "maxAmount": 25000 },
    { "method": "upay", "label": "Upay", "currency": "BDT", "minAmount": 100, "maxAmount": 25000 },
    { "method": "upi", "label": "UPI", "currency": "INR", "minAmount": 100, "maxAmount": 100000 },
    { "method": "phonepe", "label": "PhonePe", "currency": "INR", "minAmount": 100, "maxAmount": 100000 },
    { "method": "gpay", "label": "Google Pay", "currency": "INR", "minAmount": 100, "maxAmount": 100000 },
    { "method": "paytm", "label": "Paytm", "currency": "INR", "minAmount": 100, "maxAmount": 100000 },
    { "method": "imps", "label": "IMPS Bank Transfer", "currency": "INR", "minAmount": 500, "maxAmount": 500000 },
    { "method": "easypaisa", "label": "EasyPaisa", "currency": "PKR", "minAmount": 500, "maxAmount": 100000 },
    { "method": "jazzcash", "label": "JazzCash", "currency": "PKR", "minAmount": 500, "maxAmount": 100000 },
    { "method": "bank_pk", "label": "Bank Transfer (PK)", "currency": "PKR", "minAmount": 1000, "maxAmount": 500000 },
    { "method": "usdt_trc20", "label": "USDT (TRC-20)", "currency": "USDT", "minAmount": 5, "maxAmount": 50000 },
    { "method": "usdt_erc20", "label": "USDT (ERC-20)", "currency": "USDT", "minAmount": 20, "maxAmount": 50000 },
    { "method": "usdt_bep20", "label": "USDT (BEP-20)", "currency": "USDT", "minAmount": 5, "maxAmount": 50000 },
    { "method": "btc", "label": "Bitcoin", "currency": "BTC", "minAmount": 0.0001, "maxAmount": 10 },
    { "method": "eth", "label": "Ethereum", "currency": "ETH", "minAmount": 0.005, "maxAmount": 100 },
    { "method": "trx", "label": "TRON (TRX)", "currency": "TRX", "minAmount": 10, "maxAmount": 500000 }
  ]
}

Supported Payment Methods by Currency

CurrencyMethod KeyLabelType
BDTbkashbKashMobile Wallet
BDTnagadNagadMobile Wallet
BDTrocketRocketMobile Wallet
BDTupayUpayMobile Wallet
INRupiUPIInstant Pay
INRphonepePhonePeMobile Wallet
INRgpayGoogle PayMobile Wallet
INRpaytmPaytmMobile Wallet
INRimpsIMPS Bank TransferBank Transfer
PKReasypaisaEasyPaisaMobile Wallet
PKRjazzcashJazzCashMobile Wallet
PKRbank_pkBank Transfer (PK)Bank Transfer
Cryptousdt_trc20USDT (TRC-20)Stablecoin
Cryptousdt_erc20USDT (ERC-20)Stablecoin
Cryptousdt_bep20USDT (BEP-20)Stablecoin
CryptobtcBitcoinCryptocurrency
CryptoethEthereumCryptocurrency
CryptotrxTRON (TRX)Cryptocurrency
💡 Available methods depend on your partner configuration. Contact admin to enable specific currencies and methods for your account.
GET /partner/agent-number/:method Get cashagent number / wallet address

Returns an available active cashagent's account number or crypto wallet address for the specified payment method. Show this to your user so they know where to send funds.

Example — Mobile Wallet (BDT)

GET /partner/agent-number/bkash

{
  "success": true,
  "method": "bkash",
  "accountNumber": "01712345678",
  "agentName": "Demo Cashagent",
  "instructions": "Send exactly the requested amount to this bKash number and include your TrxID when submitting the deposit."
}

Example — UPI (INR)

GET /partner/agent-number/upi

{
  "success": true,
  "method": "upi",
  "accountNumber": "agent@ybl",
  "agentName": "INR Cashagent",
  "instructions": "Send the exact amount to this UPI ID. Note the UTR number for verification."
}

Example — Crypto (USDT)

GET /partner/agent-number/usdt_trc20

{
  "success": true,
  "method": "usdt_trc20",
  "accountNumber": "TXrk...7vB9",
  "agentName": "Crypto Cashagent",
  "instructions": "Send USDT on the TRC-20 network to this address. Include the tx hash when submitting."
}

💸 Withdrawals

POST /partner/withdrawals Initiate a withdrawal
⚠️ The user's balance must be ≥ amount. The amount is debited immediately upon submission.

Request Body

FieldTypeRequiredDescription
userIdstringRequiredZexabit user ID
amountnumberRequiredAmount in user's currency
paymentMethodstringRequiredSee Supported Methods
accountNumberstringRequiredUser's account number to receive cash

Example Request

POST /partner/withdrawals
{
  "userId": "68abc40f199dcff85e123456",
  "amount": 300,
  "paymentMethod": "bkash",
  "accountNumber": "01898765432"
}

Response

{
  "success": true,
  "withdrawalId": "wdr_68xyz...",
  "status": "pending",
  "message": "Withdrawal submitted. Cashagent will send within 15 minutes."
}
GET /partner/withdrawals/:withdrawalId Check withdrawal status

Response

{
  "success": true,
  "withdrawalId": "wdr_68xyz...",
  "status": "completed",   // pending | completed | rejected
  "amount": 300,
  "completedAt": "2026-03-08T11:00:00Z"
}

🔔 Webhooks

When a cashagent approves or rejects a transaction, Zexabit fires an HTTP POST to your registered callback URL. Set your callback URL in the Partner Management section of the admin dashboard.

Always respond with HTTP 200 to acknowledge the webhook. Failed deliveries are retried 3 times with exponential backoff (1min, 5min, 30min).

Webhook Events

EventTrigger
deposit.completedCashagent approved the deposit — user balance credited
deposit.rejectedCashagent rejected the deposit
withdrawal.completedCashagent sent cash — user balance debited
withdrawal.rejectedCashagent rejected — balance refunded to user

Payload Structure

POST https://your-site.com/webhook/zexabit
Content-Type: application/json
X-Zexabit-Signature: sha256=<hmac>

{
  "event": "deposit.completed",
  "timestamp": "2026-03-08T10:30:00Z",
  "data": {
    "transactionId": "dep_68xyz...",
    "externalUserId": "usr_abc123",   // Your platform's user ID
    "userId": "68abc40f...",
    "amount": 500,
    "paymentMethod": "bkash",
    "status": "completed",
    "newBalance": 1500.00
  }
}

Signature Verification

Verify the X-Zexabit-Signature header using your webhook secret to ensure the request is from Zexabit.

// Node.js example
const crypto = require('crypto');

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

// Express handler
app.post('/webhook/zexabit', express.json(), (req, res) => {
  const sig = req.headers['x-zexabit-signature'];
  if (!verifyWebhook(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const { event, data } = req.body;

  if (event === 'deposit.completed') {
    // Credit user balance on your platform
    await creditUserBalance(data.externalUserId, data.amount);
  }

  res.status(200).send('ok');
});

❌ Error Codes

HTTP StatusCodeDescription
400INVALID_REQUESTMissing or invalid required fields
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENPartner account suspended
404NOT_FOUNDUser/transaction not found
409INSUFFICIENT_BALANCEUser balance too low for withdrawal
422NO_AGENT_AVAILABLENo cashagent available for the method right now
429RATE_LIMITEDToo many requests — max 100/min per partner
500INTERNAL_ERRORContact us on WhatsApp

Error Response Format

{
  "success": false,
  "error": "INSUFFICIENT_BALANCE",
  "message": "User balance (200 BDT) is less than requested amount (500 BDT)"
}

📋 Changelog

VersionDateChanges
v1.0Mar 2026Initial release — deposits, withdrawals, webhooks, partner management
📧 Need help integrating? Chat with us on WhatsApp or visit zexabit.com