Skip to Content
👋 Welcome to 100Pay Developers
DocsCustomersWithdrawals & Transfers

Withdrawals & Transfers

Move customer funds out of their dedicated wallet: withdraw to any Nigerian bank account, or transfer internally to your merchant NGN wallet (instant, atomic, zero fee).

Preflight First

Get a non-committal quote — fee, balance projection, limits, and a verdict — without touching the provider or reserving anything:

const quote = await client.customer.wallet.preflightWithdrawal( customerId, walletId, { amount: 5000 } ); console.log(quote.data.fee); // "15" console.log(quote.data.balance.projectedAfter); // balance after amount + fee console.log(quote.data.limits.rolling24hRemaining); // headroom under the daily cap console.log(quote.data.allowed, quote.data.reasons); // e.g. ["insufficient_balance"]

Withdraw to a Bank Account

const withdrawal = await client.customer.wallet.withdraw( customerId, walletId, { amount: 5000, beneficiaryBankCode: "100004", beneficiaryAccountNumber: "8135155549", narration: "Wallet payout", externalReference: `payout-${orderId}`, // your stable reference saveBeneficiary: true, // reuse via beneficiaryId next time }, { idempotencyKey: crypto.randomUUID() } ); console.log(withdrawal.data.status); // "pending" console.log(withdrawal.data.reference); // poll with this — it is stable

Poll by reference, not transactionReference. The transaction reference starts as a preliminary pre-… hash and is replaced by the provider session ID once the transfer is accepted.

Track the Withdrawal

const status = await client.customer.wallet.getWithdrawal( customerId, walletId, withdrawal.data.reference ); // status.data.status → "pending" | "successful" | "failed" | "reversed" // Failed withdrawals are automatically reversed — funds return to the wallet.

Reuse Saved Beneficiaries

const saved = await client.customer.beneficiaries.list(); await client.customer.wallet.withdraw( customerId, walletId, { amount: 2000, beneficiaryId: saved.data[0].id }, { idempotencyKey: crypto.randomUUID() } );

Beneficiaries are scoped to your app — shared across your customers, never customer-owned.

Transfer to Your Merchant Wallet

Atomically debit the customer wallet and credit your main NGN wallet — both legs commit together, no provider, no fee:

const transfer = await client.customer.wallet.transferToMerchant( customerId, walletId, { destination: "merchant", amount: 2000 }, { idempotencyKey: crypto.randomUUID() } ); console.log(transfer.data.status); // "successful"

Transfer Limits

Every transfer is checked against a versioned limit policy: per-transaction min/max plus a rolling 24-hour cap per bucket (external withdrawals and internal transfers are independent). You can cap individual customers below the platform policy:

// View effective limits + rolling usage const limits = await client.customer.transferLimits.get(customerId); // Lower-only per-customer caps; values above the policy are rejected await client.customer.transferLimits.set(customerId, { external: { perTransactionMax: 50000, rolling24hMax: 200000 }, });
Rejection codeMeaning
VALIDATION_ERRORBelow the minimum or above the per-transaction maximum
DAILY_LIMIT_EXCEEDEDWould exceed the rolling 24-hour cap
LIMIT_ABOVE_POLICYTried to set a per-customer cap above the platform policy
Last updated on