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

FieldTypeRequiredDescription
amountNumberAmount to be charged (e.g. 1500)
currencyStringCurrency code (e.g. KES)
countryStringISO 3166-1 alpha-2 code (e.g KE)
externalReferenceStringYour own unique ID for reconciliation (e.g. invoice number)
destinationStringThe destination of the payout (e.g MoMo)
payoutMethod.accountNameStringThe user's account name (e.g Clark Kent)
payoutMethod.accountNumberStringRecipient phone number in E.164 format without the plus (e.g. 254719624551)
payoutMethod.codeStringMobile-money operator ID (required for all currencies except KES
debitCurrencyStringThe 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

  1. Configure your webhook URL in your dashboard account.
  2. Implement webhook endpoint security and validation.
  3. 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"
}