Payouts
- get/v1/bank_accountsList payout destinations
- post/v1/bank_accountsRegister a payout destination
- get/v1/payoutsList payouts
- post/v1/payoutsPay out to a registered bank account
- get/v1/payouts/{id}Retrieve a payout
- post/v1/payouts/{id}/cancelCancel a payout before it is sent
- get/v1/payouts/quoteWhat a payout would cost, and whether the balance covers it
- get/v1/usdtUSDT settlement: whether it's on, Biftpay's rules, your wallets and the one automatic settlement uses
- get/v1/usdt/previewBefore sending: dollars available, the fee, and the USDT the wallet should receive
- get/v1/usdt/payoutsYour USDT payouts, newest first
- post/v1/usdt/payoutsSend dollars as USDT to one of your wallets (added and cleared in the dashboard)
List payout destinations
get/v1/bank_accounts
curl https://sandbox.api.biftpay.com/v1/bank_accounts \
-H "Authorization: Bearer bp_test_..."Responses
- 200Registered bank accountsobject
Fields
object"list"requireddataarray of BankAccountrequiredFields of data
idstring (uuid)requiredobject"bank_account"requiredlivemodebooleanrequiredbank_codestringrequiredbank_namestringrequiredaccount_number_last4stringrequiredaccount_namestringrequiredAs returned by the bank's name enquiry.
verified_atstring (date-time)requiredcreated_atstring (date-time)requiredhas_morebooleanrequired - 401Missing or invalid API key
Register a payout destination
post/v1/bank_accounts
The account is checked with the bank (name enquiry) before it is saved, and the
account name the bank returns is what is stored and shown. Adding the same
account again returns the existing one. In test mode, account numbers ending in
0000 fail name enquiry.
Parameters
Idempotency-Keystringin headerrequiredA unique key per logical request, for example a UUID. Up to 255 characters.
up to 255 characters
Body
bank_codestringrequiredaccount_numberstringrequired10-digit NUBAN
curl -X POST https://sandbox.api.biftpay.com/v1/bank_accounts \
-H "Authorization: Bearer bp_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"bank_code": "999",
"account_number": "0123456789"
}'Responses
- 201The verified bank accountBankAccount
Fields
idstring (uuid)requiredobject"bank_account"requiredlivemodebooleanrequiredbank_codestringrequiredbank_namestringrequiredaccount_number_last4stringrequiredaccount_namestringrequiredAs returned by the bank's name enquiry.
verified_atstring (date-time)requiredcreated_atstring (date-time)required - 400Invalid request
- 401Missing or invalid API key
- 409The object is in a state that doesn't allow this
List payouts
get/v1/payouts
Parameters
limitintegerin query1 to 100 · default 20
starting_afterstring (uuid)in queryThe id of the last item on the previous page.
curl https://sandbox.api.biftpay.com/v1/payouts \
-H "Authorization: Bearer bp_test_..."Responses
- 200A page of payoutsPayoutList
Fields
object"list"requireddataarray of PayoutrequiredFields of data
idstring (uuid)requiredAlso the reference sent to the bank.
object"payout"requiredlivemodebooleanrequiredamountintegerrequiredMinor units (kobo, cents).
at least 0
feeintegerrequiredMinor units (kobo, cents).
at least 0
vatintegerrequiredMinor units (kobo, cents).
at least 0
total_debitedintegerrequiredamount + fee + vat
at least 0
currencyNGN | USDrequiredstatusawaiting_approval | queued | processing | paid | failed | canceledrequiredawaiting_approval(Biftpay is reviewing it first, e.g. a large amount) ->queued->processing(sent, waiting for the bank's confirmation) ->paidorfailed.canceledis only possible before sending.narrationstring | nullbrandstring (uuid)The brand whose balance pays it.
review_reasonsarray of amount | new_bank_account | account_review | security_change | unusualWhy Biftpay is checking it before it's sent (status awaiting_approval); empty otherwise. new_bank_account - the first payout to an account added in the last 24 hours; account_review - the business or brand is under review, or several disputes arrived this week; security_change - a password or authenticator change by the requester, or a settlement account change, in the last 24 hours; unusual - far larger than this merchant has paid out before, or most of the balance after 30 quiet days; amount - over an approval threshold Biftpay set for this merchant.
bank_accountobjectrequiredFields of bank_account
idstring (uuid)requiredbank_namestringrequiredaccount_number_last4stringrequiredaccount_namestringrequiredapproved_atstring (date-time) | nullfailure_codestring | nullcreated_atstring (date-time)requiredpaid_atstring (date-time) | nullfailed_atstring (date-time) | nullcanceled_atstring (date-time) | nullhas_morebooleanrequired - 401Missing or invalid API key
Pay out to a registered bank account
post/v1/payouts
Moves amount + fee + VAT from available to payout_in_flight in the same step
that records the payout, so a short balance fails with 409 insufficient_funds
and nothing is written. Payouts at or above the merchant's approval threshold
wait for Biftpay's review (awaiting_approval). The outcome is settled
only from the bank's status query: paid, or failed with the money returned
to available.
In test mode, account numbers ending in 9999 fail after sending, 7777 are
rejected by the provider, and 8888 stay processing.
Parameters
Idempotency-Keystringin headerrequiredA unique key per logical request, for example a UUID. Up to 255 characters.
up to 255 characters
Body
amountintegerrequiredat least 1
currencyNGN | USDrequiredbank_account_idstring (uuid)requiredA registered, name-checked destination account.
narrationstringup to 100 characters
brandstring (uuid)Pay out of this brand's balance. Defaults to the business's own brand.
otpobject or objectRequired when a signed-in user (not an API key) requests the payout. From POST /v1/payouts/otp.
curl -X POST https://sandbox.api.biftpay.com/v1/payouts \
-H "Authorization: Bearer bp_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": 500000,
"currency": "NGN",
"bank_account_id": "…"
}'Responses
- 201CreatedPayout
Fields
idstring (uuid)requiredAlso the reference sent to the bank.
object"payout"requiredlivemodebooleanrequiredamountintegerrequiredMinor units (kobo, cents).
at least 0
feeintegerrequiredMinor units (kobo, cents).
at least 0
vatintegerrequiredMinor units (kobo, cents).
at least 0
total_debitedintegerrequiredamount + fee + vat
at least 0
currencyNGN | USDrequiredstatusawaiting_approval | queued | processing | paid | failed | canceledrequiredawaiting_approval(Biftpay is reviewing it first, e.g. a large amount) ->queued->processing(sent, waiting for the bank's confirmation) ->paidorfailed.canceledis only possible before sending.narrationstring | nullbrandstring (uuid)The brand whose balance pays it.
review_reasonsarray of amount | new_bank_account | account_review | security_change | unusualWhy Biftpay is checking it before it's sent (status awaiting_approval); empty otherwise. new_bank_account - the first payout to an account added in the last 24 hours; account_review - the business or brand is under review, or several disputes arrived this week; security_change - a password or authenticator change by the requester, or a settlement account change, in the last 24 hours; unusual - far larger than this merchant has paid out before, or most of the balance after 30 quiet days; amount - over an approval threshold Biftpay set for this merchant.
bank_accountobjectrequiredFields of bank_account
idstring (uuid)requiredbank_namestringrequiredaccount_number_last4stringrequiredaccount_namestringrequiredapproved_atstring (date-time) | nullfailure_codestring | nullcreated_atstring (date-time)requiredpaid_atstring (date-time) | nullfailed_atstring (date-time) | nullcanceled_atstring (date-time) | null - 400Invalid request
- 401Missing or invalid API key
- 409The object is in a state that doesn't allow this
- 422Idempotency-Key reused with a different request
Retrieve a payout
get/v1/payouts/{id}
Parameters
idstring (uuid)in pathrequiredcurl https://sandbox.api.biftpay.com/v1/payouts/{id} \
-H "Authorization: Bearer bp_test_..."Responses
- 200The payoutPayout
Fields
idstring (uuid)requiredAlso the reference sent to the bank.
object"payout"requiredlivemodebooleanrequiredamountintegerrequiredMinor units (kobo, cents).
at least 0
feeintegerrequiredMinor units (kobo, cents).
at least 0
vatintegerrequiredMinor units (kobo, cents).
at least 0
total_debitedintegerrequiredamount + fee + vat
at least 0
currencyNGN | USDrequiredstatusawaiting_approval | queued | processing | paid | failed | canceledrequiredawaiting_approval(Biftpay is reviewing it first, e.g. a large amount) ->queued->processing(sent, waiting for the bank's confirmation) ->paidorfailed.canceledis only possible before sending.narrationstring | nullbrandstring (uuid)The brand whose balance pays it.
review_reasonsarray of amount | new_bank_account | account_review | security_change | unusualWhy Biftpay is checking it before it's sent (status awaiting_approval); empty otherwise. new_bank_account - the first payout to an account added in the last 24 hours; account_review - the business or brand is under review, or several disputes arrived this week; security_change - a password or authenticator change by the requester, or a settlement account change, in the last 24 hours; unusual - far larger than this merchant has paid out before, or most of the balance after 30 quiet days; amount - over an approval threshold Biftpay set for this merchant.
bank_accountobjectrequiredFields of bank_account
idstring (uuid)requiredbank_namestringrequiredaccount_number_last4stringrequiredaccount_namestringrequiredapproved_atstring (date-time) | nullfailure_codestring | nullcreated_atstring (date-time)requiredpaid_atstring (date-time) | nullfailed_atstring (date-time) | nullcanceled_atstring (date-time) | null - 401Missing or invalid API key
- 404Not found, or not visible to this key
Cancel a payout before it is sent
post/v1/payouts/{id}/cancel
Only awaiting_approval and queued payouts can be canceled. The held money returns to available.
Parameters
idstring (uuid)in pathrequiredIdempotency-Keystringin headerrequiredA unique key per logical request, for example a UUID. Up to 255 characters.
up to 255 characters
curl -X POST https://sandbox.api.biftpay.com/v1/payouts/{id}/cancel \
-H "Authorization: Bearer bp_test_..." \
-H "Idempotency-Key: $(uuidgen)"Responses
- 200The canceled payoutPayout
Fields
idstring (uuid)requiredAlso the reference sent to the bank.
object"payout"requiredlivemodebooleanrequiredamountintegerrequiredMinor units (kobo, cents).
at least 0
feeintegerrequiredMinor units (kobo, cents).
at least 0
vatintegerrequiredMinor units (kobo, cents).
at least 0
total_debitedintegerrequiredamount + fee + vat
at least 0
currencyNGN | USDrequiredstatusawaiting_approval | queued | processing | paid | failed | canceledrequiredawaiting_approval(Biftpay is reviewing it first, e.g. a large amount) ->queued->processing(sent, waiting for the bank's confirmation) ->paidorfailed.canceledis only possible before sending.narrationstring | nullbrandstring (uuid)The brand whose balance pays it.
review_reasonsarray of amount | new_bank_account | account_review | security_change | unusualWhy Biftpay is checking it before it's sent (status awaiting_approval); empty otherwise. new_bank_account - the first payout to an account added in the last 24 hours; account_review - the business or brand is under review, or several disputes arrived this week; security_change - a password or authenticator change by the requester, or a settlement account change, in the last 24 hours; unusual - far larger than this merchant has paid out before, or most of the balance after 30 quiet days; amount - over an approval threshold Biftpay set for this merchant.
bank_accountobjectrequiredFields of bank_account
idstring (uuid)requiredbank_namestringrequiredaccount_number_last4stringrequiredaccount_namestringrequiredapproved_atstring (date-time) | nullfailure_codestring | nullcreated_atstring (date-time)requiredpaid_atstring (date-time) | nullfailed_atstring (date-time) | nullcanceled_atstring (date-time) | null - 404Not found, or not visible to this key
- 409The object is in a state that doesn't allow this
What a payout would cost, and whether the balance covers it
get/v1/payouts/quote
The fee and VAT go on top of the amount and come from the same available balance (the
brand's, with brand). max_amount is the most that can be paid out now. Creating the
payout checks again.
Parameters
amountintegerin queryrequiredat least 1
currencyNGNin querybrandstring (uuid)in querycurl https://sandbox.api.biftpay.com/v1/payouts/quote \
-H "Authorization: Bearer bp_test_..."Responses
- 200The quoteobject
Fields
object"payout_quote"requiredcurrencyNGNrequiredamountintegerrequiredMinor units (kobo, cents).
at least 0
feeintegerrequiredMinor units (kobo, cents).
at least 0
vatintegerrequiredMinor units (kobo, cents).
at least 0
total_debitedintegerrequiredMinor units (kobo, cents).
at least 0
availableintegerrequiredMinor units (kobo, cents).
at least 0
max_amountintegerrequiredMinor units (kobo, cents).
at least 0
max_reasonbalance | per_payout | dailyrequiredWhat holds max_amount where it is.
sufficientbooleanrequiredThe balance covers amount + fee + VAT.
within_limitsbooleanrequiredlimitsobjectrequiredFields of limits
tierstringrequiredcustombooleanrequiredper_payoutintegerrequireddailyintegerrequiredused_todayintegerrequired - 400Invalid request
USDT settlement: whether it's on, Biftpay's rules, your wallets and the one automatic settlement uses
get/v1/usdt
curl https://sandbox.api.biftpay.com/v1/usdt \
-H "Authorization: Bearer bp_test_..."Responses
- 200OKobject
Fields
object"usdt"requiredenabledbooleanrequiredsettle_walletstring | nullrequiredsettingsUsdtSettingsrequiredFields of settings
enabledbooleanrequiredcooling_hoursintegerrequiredmin_usdintegerrequiredmax_usdinteger | nullrequiredupdated_bystringrequiredupdated_atstring (date-time)requiredwalletsarray of CryptoWalletrequiredFields of wallets
idstring (uuid)requiredobject"crypto_wallet"requiredasset"USDT"requirednetworktron | ethereum | polygon | bscrequirednetwork_labelstringrequiredaddressstringrequiredlabelstring | nullrequiredusablebooleanrequiredPast the cooling-off period: can receive payouts.
usable_fromstring (date-time)requiredcreated_atstring (date-time)required
Before sending: dollars available, the fee, and the USDT the wallet should receive
get/v1/usdt/preview
Parameters
usd_amountintegerin queryCents.
at least 1
brandstring (uuid)in querycurl https://sandbox.api.biftpay.com/v1/usdt/preview \
-H "Authorization: Bearer bp_test_..."Responses
- 200OKUsdtPreview
Fields
object"usdt_preview"requiredusd_availableintegerrequiredmin_usdintegerrequiredmax_usdinteger | nullrequiredavailable_nowbooleanrequiredUSDT payouts are on and a partner is connected.
usd_amountintegerfeeintegervatintegernet_usdintegerusdt_estimatestringUSDT the wallet should receive.
Your USDT payouts, newest first
get/v1/usdt/payouts
curl https://sandbox.api.biftpay.com/v1/usdt/payouts \
-H "Authorization: Bearer bp_test_..."Responses
- 200OKobject
Fields
object"list"requireddataarray of CryptoPayoutrequiredFields of data
idstring (uuid)requiredobject"crypto_payout"requiredlivemodebooleanrequiredwalletstring (uuid)requirednetworkstringaddressstringusd_amountintegerrequiredfeeintegerrequiredvatintegerrequirednet_usdintegerrequiredusdt_amountstring | nullrequiredUSDT the wallet received, as the partner reports it.
statusqueued | processing | paid | failedrequiredtx_hashstring | nullrequiredThe on-chain transaction.
failure_codestring | nullrequiredcreated_atstring (date-time)requiredpaid_atstring (date-time) | nullrequiredhas_morebooleanrequired
Send dollars as USDT to one of your wallets (added and cleared in the dashboard)
post/v1/usdt/payouts
The amount (cents) leaves your USD balance; Biftpay's fee and VAT come out of it and the partner sends the rest as USDT, 1 USDT per dollar. Held until the partner confirms, returned if it fails.
Parameters
Idempotency-Keystringin headerrequiredA unique key per logical request, for example a UUID. Up to 255 characters.
up to 255 characters
Body
usd_amountintegerrequiredat least 1
walletstring (uuid)requiredbrandstring (uuid)otpobject or objectcurl -X POST https://sandbox.api.biftpay.com/v1/usdt/payouts \
-H "Authorization: Bearer bp_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"usd_amount": 1,
"wallet": "…"
}'Responses
- 201QueuedCryptoPayout
Fields
idstring (uuid)requiredobject"crypto_payout"requiredlivemodebooleanrequiredwalletstring (uuid)requirednetworkstringaddressstringusd_amountintegerrequiredfeeintegerrequiredvatintegerrequirednet_usdintegerrequiredusdt_amountstring | nullrequiredUSDT the wallet received, as the partner reports it.
statusqueued | processing | paid | failedrequiredtx_hashstring | nullrequiredThe on-chain transaction.
failure_codestring | nullrequiredcreated_atstring (date-time)requiredpaid_atstring (date-time) | nullrequired - 400Invalid request
- 409The object is in a state that doesn't allow this