OmniPayDocs
Integration guides

Withdrawals

Create a payout, track its status, and process terminal withdrawal webhooks safely.

Withdrawals use bearer authentication and complete asynchronously. Create the payout from your backend, persist both identifiers, and fulfill your business workflow from the status endpoint or a verified webhook.

Create a withdrawal

curl --fail-with-body --request POST \
  --url https://omnipay.page/api/v1/withdraws \
  --header "Authorization: Bearer $OMNIPAY_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "amount": "1000.00",
    "phone": "01712345678",
    "payment_method": "bkash",
    "merchant_id": "payout-123",
    "metadata": {
      "beneficiary_id": "beneficiary-42"
    }
  }'

For mobile-wallet payouts, phone is the recipient's Bangladesh mobile number. For payment_method: "bank", the same field contains the destination bank account number.

Payment methodAllowed amount
bkash, nagad, upayBDT 100–25,000
bankBDT 50,000–300,000

A successful create returns HTTP 201:

{
  "id": "cm7withdraw01",
  "phone": "01712345678",
  "payment_method": "bkash",
  "amount": "1000.00",
  "status": "processing",
  "metadata": {
    "beneficiary_id": "beneficiary-42"
  },
  "merchant_id": "payout-123"
}

merchant_id must be unique within your organization. A duplicate returns 409; do not generate a new ID unless you intend to create another payout.

Read the status

curl --fail-with-body \
  --url https://omnipay.page/api/v1/withdraws/cm7withdraw01 \
  --header "Authorization: Bearer $OMNIPAY_API_KEY"
StatusMeaningYour action
processingPayout is still in progressKeep polling with backoff or wait for a webhook
succeededPayout completedMark the payout complete exactly once
failedPayout did not completeStop polling and follow your failure workflow

Handle webhooks

Subscribe to withdraw.created, withdraw.succeeded, and withdraw.failed. Verify the Svix signature before parsing the event and make the consumer idempotent.

Never mark a payout complete from the create response alone. Use a verified withdraw.succeeded event or an authenticated status response.

Common errors

ErrorWhat to check
403 insufficient_balanceAvailable balance must cover the amount and commission
403 forbiddenWithdrawals must be enabled for the organization
409 merchant_id_existsThe business ID was already used
503 method_unavailableThe requested payout method is temporarily unavailable

View the withdrawal API reference →

On this page