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.
When To Use This
Use this guide when the recipient should receive funds in a mobile money wallet. For bank account, Paybill, Till, external-account, or multi-currency payout examples, use the main Payouts guide.
Happy Path
-
Confirm the recipient's country, currency, phone number, and account name.
-
Retrieve the mobile money operator ID when the country or currency requires
payoutMethod.code. -
Submit the payout request with
destinationset toMoMo. -
Store the returned
transactionIdand yourexternalReference. -
Reconcile the final result from webhook updates or the transaction status endpoint.
1 - Initiate Payout
| Field | Type | Required | Description |
|---|---|---|---|
| amount | Number | ✅ | Amount to be paid out (e.g. 1500) |
| currency | String | ✅ | Currency the recipient receives (e.g. KES, UGX) |
| country | String | ✅ | ISO 3166-1 alpha-2 country code (e.g. KE) |
| externalReference | String | ✅ | Your own unique ID for reconciliation (e.g. invoice number) |
| destination | String | ✅ | Set to MoMo for mobile money payouts |
| payoutMethod.accountName | String | ✅ | The user's account name (e.g. Clark Kent) |
| payoutMethod.accountNumber | String | ✅ | Recipient phone number with country code, no plus sign (e.g. 254719624551) |
| payoutMethod.code | String | ❌ | Mobile money operator ID when operator selection is required |
| debitCurrency | String | ❌ | The wallet you want to be debited from. If missing, we will default to the currency passed. (e.g USD). |
| debitCountry | String | Conditional | Country scope of the wallet being debited. Required whenever debitCurrency is XOF, even for same-currency payouts. Optional for other debit currencies, including USD; omit when debitCurrency is absent. |
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 mobile money providers endpoint before creating the payout.
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 payout status. Use the get transaction endpoint with either:
- The transactionId from the payout response or
- Your externalReference
Here's an example of payout 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": "successful",
"type": "withdrew",
"externalReference": "test",
"method": "momo",
"thirdPartyReference": "TEQTEYRU"
},
"timestamp": "ISO-8601 timestamp"
}{
"event": "transaction_updated",
"data": {
"transactionId": "BeOfXV1NVIcZlsSVeQAF",
"status": "failed",
"type": "withdrew",
"externalReference": "test",
"method": "momo",
"note": "Invalid Phone Number"
},
"timestamp": "ISO-8601 timestamp"
}Updated 4 days ago
