Payout
Send money from your Chapa balance to bank accounts or mobile money wallets.
Payouts allow you to send money from your Chapa balance to a bank account or mobile money wallet.
This feature is commonly used for:
- Vendor payouts
- Customer withdrawals
- Partner settlements
- Internal fund disbursement
Payouts are asynchronous. A successful API response means the payout was created, not completed.
Endpoint
POST /v2/payouts
Host: api.chapa.coAuthentication
Headers
| Name | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <PRIVATE_API_KEY> |
Content-Type | Yes | application/json |
Idempotency-Key | No | Prevents duplicate payout creation on retries |
Request Body
Required Fields
| Field | Type | Description |
|---|---|---|
amount | number | Amount to transfer |
currency | string | ISO currency code (ETB, USD, UGX, DJF — availability depends on payout method) |
account | object | Destination account details |
Optional Fields
| Field | Type | Description |
|---|---|---|
merchant_reference | string | Merchant-generated payout reference |
reason | string | Description of the payout |
meta | object | Custom metadata for internal tracking |
Account Object
| Field | Description |
|---|---|
account_name | Name on the receiving account |
account_number | Bank account or wallet identifier |
bank_slug | Short bank or wallet identifier |
bank_name | Display name of the bank or wallet |
Example Request
POST https://api.chapa.co/v2/payouts
Authorization: Bearer CHAPA_TEST_xxxxxxxxxxxxx
Content-Type: application/json{
"amount": 150000,
"currency": "ETB",
"account": {
"account_name": "Customer Name",
"account_number": "123567890987",
"bank_slug": "cbe",
"bank_name": "Commercial Bank of Ethiopia"
},
"merchant_reference": "PAYOUT_20251107_001",
"reason": "Vendor payout for services",
"meta": {
"order_id": "ORD-7823",
"requested_by": "customer_support"
}
}Example Response
{
"status": "success",
"message": "Payout initialized successfully",
"data": {
"chapa_reference": "CP123456789",
"status": "pending"
},
"created_at": "2025-11-07T11:06:00Z",
"updated_at": "2025-11-08T11:06:00Z"
}At this stage, the payout is pending, not completed.
Payout Status Lifecycle
A payout may move through the following states:
| Status | Meaning |
|---|---|
pending | Created but not yet processed |
processing | Being processed |
success / completed | Funds delivered successfully |
failed | Payout failed |
blocked | Blocked due to risk or compliance |
auth_needed | Additional authorization required |
otp_needed | OTP verification required |
reversed | Funds reversed after processing |
Status changes are delivered via webhooks and can be checked via verification.
Verification (Optional)
To check the current status of a payout:
GET /v2/payouts/{reference}/verifyVerification is useful for:
- Payout confirmation
- Reconciliation
- Customer support inquiries
- Dispute resolution
Webhook Handling (Recommended)
Payout lifecycle events are sent via webhooks:
payout.successpayout.failedpayout.reversedpayout.blockedpayout.auth_neededpayout.otp_needed
Your system should:
- Update payout state idempotently
- Store
chapa_referenceandmerchant_reference - Log reasons and timestamps
- Avoid duplicate processing
Best Practices
- Always generate a unique
merchant_reference - Use
Idempotency-Keywhen retrying payout requests - Validate bank and account details before initiating
- Handle payout status asynchronously via webhooks
- Never assume success immediately after initialization
Common Errors
| HTTP | Error Code | Description |
|---|---|---|
| 400 | INVALID_FORMAT | Invalid bank slug or account number |
| 404 | NOT_FOUND | Payout not found |
| 500 | PROCESSING_FAILED | Failed to create payout |
Next Steps
- Verify Payout - Check payout status
- Bulk Payout - Send multiple payouts at once
- Bank List - Get supported banks
- Webhooks - Handle payout events