SUCCESS. Responses are shortened to the fields this tutorial uses.
Prerequisites
- A Bitnob business account, created at app.bitnob.com, with payouts enabled by the compliance team.
- Your
CLIENT_IDandCLIENT_SECRETfrom Settings → API Keys. The secret is shown once; store it securely. - A signing helper that adds the four
X-Auth-*headers to every request. Build one with Authentication; it has reference implementations in Node.js, Go, and Python.
https://api.bitnob.com. Sandbox and production share that URL; the secret you sign with selects the environment. Test in sandbox first.
1
Pick a destination and validate the beneficiary
Look up what your destination country needs before you quote. The short version:Confirm the lookup returns
is_verified: true and the account_name you expect. Ghana bank accounts can’t be looked up yet, so skip this step for them and have your user confirm the account name. The full walkthrough, including mobile money destinations, is in Validate a beneficiary.2
Create a quote
A quote locks the exchange rate and fees. Provide one side of the conversion: Save
source decides where the funds come from: offchain charges your Bitnob balance, onchain gives you a deposit address to pay per transaction.settlement_amount (what the beneficiary receives) or amount (what you pay in from_asset). chain is required when source is onchain.The response returns the payout record in status QUOTE:quote_id. Note expires_at: the window is minutes, so continue promptly. Full schema: Create quote.3
Initialize with the beneficiary
Attach the recipient to the quote. The What For Ghana mobile money, set
beneficiary shape depends on the country; it is exactly what step 1’s country requirements returned.callback_url is where webhook events for this payout are sent; set it.For onchain funding the response moves the record to PENDING_ADDRESS_DEPOSIT and carries the funding instruction in address:address contains depends on chain: a BOLT11 invoice for lightning (lnbc… in production, lntb… testnet invoices in sandbox), a BTC address for bitcoin, or a deposit address on the relevant chain for stablecoins. With source: "offchain" there is no address and the record moves to INITIATED instead.Beneficiaries for other corridors
Only thebeneficiary object changes between corridors. Read the exact fields from country requirements in step 1. For example:network to mtn, vodafone (Telecel Cash) or airtel (AirtelTigo Money) to match the recipient’s number.Each quote can be initialized once. A second initialize on the same quote fails with 400 “Quote ’…’ has already been initialized”, so use a fresh quote for each payout.Full schema: Initialize payout.4
Finalize (offchain payouts)
Finalize commits an offchain payout. It takes no request body, so sign an empty body string.Your balance is debited here. Skip this step for onchain payouts: your deposit finalizes the payout automatically, and calling finalize before funding returns
400. Full schema: Finalize payout.5
Fund it
Onchain: pay the
address from the initialize response before expires_at. For Lightning, pay the invoice from any Lightning wallet; for bitcoin and stablecoins, send the full deposit_amount from the initialize response to the deposit address. It is the quoted amount plus fees, and a shorter deposit is refused. Once the payment confirms, settlement proceeds on its own.Offchain: nothing to do, the payout is already proceeding.6
Track it to SUCCESS
Two ways, and production systems use both:
- Webhooks arrive at your
callback_urlas the payout advances:payouts.initialized,payouts.processing, thenpayouts.withdrawal.successon delivery,payouts.withdrawal.failedif delivery fails, orpayouts.withdrawal.expiredif funding never arrived. Verify every signature; see Receive payout webhooks. - Polling covers the transitions that have no event:
SUCCESS is the only success state. A FAILED payout emits payouts.withdrawal.failed. Webhooks can be missed, so also schedule reconciliation sweeps with List payouts. The full status vocabulary is on Statuses and webhook events.Where to go next
- How payouts settle, if you have not yet chosen between balance funding and per-transaction funding.
- Handle payout failures, before you take this to production.
- Send a SWIFT payout for destinations with no local rail.