Mobile Money Payouts
Initiate and manage payouts to mobile money numbers across supported countries.
This guide explains how to initiate and manage payouts to mobile money numbers across supported countries. It covers how to submit a payout request, check transaction status, and handle real-time updates via webhooks. You’ll learn how to structure requests, format recipient details, and interpret responses to ensure seamless disbursements to services like M-PESA, MTN, Airtel, and others.
1 - Initiate Payout
Field | Type | Required | Description |
---|---|---|---|
amount | Number | ✅ | Amount to be charged (e.g. 1500) |
currency | String | ✅ | Currency code (e.g. KES) |
country | String | ✅ | ISO 3166-1 alpha-2 code (e.g KE) |
externalReference | String | ✅ | Your own unique ID for reconciliation (e.g. invoice number) |
destination | String | ✅ | The destination of the payout (e.g MoMo) |
payoutMethod.accountName | String | ✅ | The user's account name (e.g Clark Kent) |
payoutMethod.accountNumber | String | ✅ | Recipient phone number in E.164 format without the plus (e.g. 254719624551) |
payoutMethod.code | String | ❌ | Mobile-money operator ID (required for all currencies except KES |
debitCurrency | String | ❌ | The wallet you want to be debited from. If missing, we will default to the currency passed. (e.g USD). |
To payout to a customer, collect the required payout information and send it to the payout endpoint. To retrieve the mobile money operator Id, call the get mobile money providers endpoint.
The payload should look like this:
{
"amount": 100,
"currency": "KES",
"country": "KE",
"externalReference": "test",
"payoutMethod": {
"accountName": "John Doe",
"accountNumber": "254719624552"
},
"destination": "MoMo"
}
{
"amount": 100,
"currency": "UGX",
"country": "UG",
"externalReference": "test",
"payoutMethod": {
"accountName": "John Doe",
"accountNumber": "254719624552"
"code": "mtn"
},
"destination": "MoMo"
}
2 - Get Transaction Status
You can fetch the transaction to verify the payments status. Use the get transaction endpoint with either:
- The transactionId from the payout response or
- Your externalReference
Here's an example of charge verification and response:
{
"success": true,
"data": {
"transactionId": "Wguc6R7vMNqXL4RWP3LH",
"amount": 400,
"type": "withdrew",
"currency": "KES",
"senderCurrency": "KES",
"senderAmount": 400,
"receiverCurrency": "KES",
"receiverAmount": 400,
"chargeStatus": "successful",
"status": "SUCCESSFUL",
"method": "momo",
"note": "MPESA Reference: TG46KOM0UU",
"createdAt": 1751298951175,
"externalReference": "test",
"fee": {
"feeAmount": 20,
"currency": "KES"
},
"thirdPartyReference": "TG46KOM0UU",
"payoutMethod": {
"accountName": "Damian Wayne",
"accountNumber": "0712345678"
}
}
}
{
"success": true,
"data": {
"transactionId": "RIyBRn9Qvx4yUCmxBbwD",
"amount": 38301,
"type": "withdrew",
"currency": "KES",
"senderCurrency": "KES",
"senderAmount": 38301,
"receiverCurrency": "KES",
"receiverAmount": 38301,
"chargeStatus": "failed",
"status": "FAILED",
"method": "momo",
"createdAt": 1751298951175,
"externalReference": "Test",
"payoutMethod": {
"accountName": "Billy Batson",
"accountNumber": "0713345678"
}
}
}
3 - Handle Webhooks
Configure webhooks to receive real-time transaction updates instead of polling the status endpoint.
Setup
- Configure your webhook URL in your dashboard account.
- Implement webhook endpoint security and validation.
- Handle the webhook notifications in your application
Here's a sample of the webhook response:
{
"event": "transaction_created",
"data": {
"transactionId": "BeOfXV1NVIcZlsSVeQAF",
"status": "pending",
"type": "withdrew",
"externalReference": "test",
},
"timestamp": "2024-10-03T16:33:14.600Z"
}
{
"event": "transaction_updated",
"data": {
"transactionId": "BeOfXV1NVIcZlsSVeQAF",
"status": "successfull",
"type": "withdrew",
"externalReference": "test",
"method": "momo",
"thirdPartReference": "TEQTEYRU" // optional. e.g Mpesa reference
},
"timestamp": "ISO-8601 timestamp"
}
{
"event": "transaction_updated",
"data": {
"transactionId": "BeOfXV1NVIcZlsSVeQAF",
"status": "failed",
"type": "withdrew",
"externalReference": "test",
"method": "momo",
"note": "Invalid Phone Number" // optional. e.g error message
},
"timestamp": "ISO-8601 timestamp"
}
Updated 21 days ago