API Reference
Disbursements API
Send money out of your Infinity Africa balance — to a Selcom Pesa wallet, a mobile money number, or a bank account. Available balance is validated before anything is created.
Withdrawals vs. Disbursements
disbursements for payment-provider compatibility.Endpoints
/v1/disbursements/selcom-pesaPayout to a Selcom Pesa wallet — fastest, zero-fee route.
Idempotency-Key required/v1/disbursements/mobile-moneyPayout to a mobile money number.
Idempotency-Key required/v1/disbursements/bank-accountPayout to a bank account (bank_name required).
Idempotency-Key required/v1/disbursementsList disbursements (merchant_id required as a query param).
dashboard or API key/v1/disbursements/{id}Get a disbursement.
dashboard or API key/v1/disbursements/{id}/approveApprove a payout held for high-value review.
super admin/v1/disbursements/{id}/rejectReject it.
super adminRequest a payout
{
"merchant_id": "5c1f0b2a-3e21-4b9a-9c33-2f6a1d0e8b71",
"amount": "80000.00",
"destination_name": "Grace Mwakalinga",
"destination_identifier": "+255754221908",
"network": "M-Pesa"
}{
"success": true,
"data": {
"id": "c9d8e7f6-...",
"merchant_id": "5c1f0b2a-3e21-4b9a-9c33-2f6a1d0e8b71",
"method": "MOBILE_MONEY",
"amount": "80000.00",
"currency": "TZS",
"destination_name": "Grace Mwakalinga",
"destination_identifier": "+255754221908",
"bank_name": null,
"status": "SUCCESS",
"requires_approval": false,
"approved_by": null,
"approved_at": null,
"provider_reference": "MOCK-SELCOM-9F3A1C2B",
"transaction_reference": "TXN-...",
"fee_amount": "0.00",
"net_amount": "80000.00",
"initiated_at": "2026-08-14T09:00:00Z",
"completed_at": "2026-08-14T09:00:02Z",
"created_at": "2026-08-14T09:00:00Z",
"updated_at": "2026-08-14T09:00:02Z"
}
}For a bank account payout, add bank_name and set destination_identifier to the account number. network is optional and mobile-money-specific — omit it and Selcom detects the network automatically.
Insufficient balance
Before anything is created, Infinity Africa checks the amount against your current available balance. If it's not enough, you get a 409 and nothing is reserved or deducted:
{
"success": false,
"error": {
"code": "insufficient_balance",
"message": "Insufficient balance: available TZS 45,000, requested TZS 80,000",
"details": null
}
}Unverified merchant
Withdrawals are only available to merchants who have completed onboarding verification. A merchant that isn't yet active/verified gets the same 409 shape, before any balance check runs:
{
"success": false,
"error": {
"code": "withdrawal_restricted",
"message": "Withdrawals require a verified, active merchant account. Complete onboarding verification first.",
"details": null
}
}Status lifecycle
| Status | Meaning |
|---|---|
| PENDING | Created. Held for approval if above the high-value threshold. |
| PROCESSING | Balance reserved, payout sent to the provider. |
| SUCCESS | Funds delivered. Terminal. |
| FAILED | Provider declined — the balance reservation was automatically reversed. |
| REVERSED | A previously-SUCCESS payout was later reversed. |
High-value approval
Large payouts are held for manual review
PENDING with requires_approval: true and is not sent to the provider until a super admin approves it. Poll GET .../disbursements/{id} or listen for disbursement.success/disbursement.failed to know the outcome.