M-Pesa Mobile Money Payout (Kenya)

This guide explains how to integrate mobile money payouts to M-Pesa wallets in Kenya using PayOS.

Overview

M-Pesa is Kenya’s leading mobile money service, enabling businesses to send payouts directly to recipient mobile wallets. By integrating M-Pesa payouts with PayOS, you can efficiently disburse funds to recipients across Kenya.

Supported Currency & Country

CurrencyCodeCountry
Kenyan ShillingKESKenya (KEN)

Request Structure

M-Pesa payouts in Kenya require the following structure:

Required Fields

Top-Level Fields:

  • merchantId: Your merchant identifier
  • merchantReference: Unique reference for this payout (UUID recommended)
  • destinationValue.minorAmount: Amount in minor units (e.g., 2000 = 20.00 KES)
  • destinationValue.currency: Currency code (KES)
  • paymentMethodId: Set to "mobilemoney"
  • paymentLocation: Set to "KEN" for Kenya
  • attributes: Can be an empty object {} or contain additional attributes

Recipient Fields:

  • recipient.type: Set to "mobile_money"
  • recipient.name: Full name of the recipient
  • recipient.operator: Set to "mpesa"
  • recipient.country: Set to "KEN" for Kenya
  • recipient.phoneNumber: Recipient’s M-Pesa registered phone number

Sender Details (Required)

Kenya payouts require sender information for regulatory compliance. The sender object must be included in the request.

Required Fields:

FieldTypeDescriptionExample
fullNamestringSender’s full name"Jane Smith"
phoneNumberstringSender’s phone number"27821234567"
nationalitystringISO 3-letter country code"ZAF"
identitystringDocument type: "passport" or "government issued id""passport"
identityNumberstringIdentity document number"A12345678"
dateOfBirthstringDate of birth (YYYY-MM-DD)"1990-01-15"
purposeOfFundsstringPurpose of the transfer"salary"
sourceOfFundsstringSource of funds"business income"
relationshipstringRelationship to recipient"employer"

Note: If nationality is not provided, the system falls back to country, countryCode, or the merchant’s configured home country.

Usage Examples

Individual Sender

1{
2 "merchantId": "your-merchant-id",
3 "merchantReference": "PAYOUT_550e8400-e29b-41d4-a716-446655440000",
4 "destinationValue": {
5 "minorAmount": 2000,
6 "currency": "KES"
7 },
8 "paymentMethodId": "mobilemoney",
9 "paymentLocation": "KEN",
10 "attributes": {},
11 "recipient": {
12 "type": "mobile_money",
13 "name": "John Doe",
14 "operator": "mpesa",
15 "country": "KEN",
16 "phoneNumber": "254723993187"
17 },
18 "sender": {
19 "fullName": "Jane Smith",
20 "phoneNumber": "27821234567",
21 "nationality": "ZAF",
22 "identity": "passport",
23 "identityNumber": "A12345678",
24 "dateOfBirth": "1990-01-15",
25 "purposeOfFunds": "salary",
26 "sourceOfFunds": "business income",
27 "relationship": "employer"
28 }
29}

Company Sender

When the sender is a company, use the company’s registered details for the sender fields:

1{
2 "merchantId": "your-merchant-id",
3 "merchantReference": "PAYOUT_660e8400-e29b-41d4-a716-446655440001",
4 "destinationValue": {
5 "minorAmount": 50000,
6 "currency": "KES"
7 },
8 "paymentMethodId": "mobilemoney",
9 "paymentLocation": "KEN",
10 "attributes": {},
11 "recipient": {
12 "type": "mobile_money",
13 "name": "John Doe",
14 "operator": "mpesa",
15 "country": "KEN",
16 "phoneNumber": "254723993187"
17 },
18 "sender": {
19 "fullName": "Acme Corporation Ltd",
20 "phoneNumber": "27110001234",
21 "nationality": "ZAF",
22 "identity": "company registration number",
23 "identityNumber": "2020/123456/07",
24 "dateOfBirth": "2015-03-20",
25 "purposeOfFunds": "vendor payment",
26 "sourceOfFunds": "business revenue",
27 "relationship": "business"
28 }
29}

Note for company senders: Use the company’s registered name as fullName, the company registration number as identityNumber, "company registration number" as the identity type, and the date of incorporation as dateOfBirth.

Expected Response:

1{
2 "transactionId": "019b024f-8c57-777f-a97c-fa21a2bdbb40",
3 "status": "RECEIVED",
4 "message": "Transaction queried successfully",
5 "merchantReference": "PAYOUT_db605861-8725-460b-be00-a0740b889944",
6 "identifiers": {},
7 "paymentAttributes": {
8 "merchant_type": "sandbox"
9 },
10 "paymentMethodId": "mobilemoney"
11}

Phone Number Format

Phone numbers are automatically normalized to the required international format (e.g., adding the country code if missing, stripping + prefix). You can provide numbers in either local (e.g., 07...) or international (e.g., +254... or 254...) format.

Valid Phone Number Formats

Input FormatNormalized Result
0723993187254723993187
+254723993187254723993187
254723993187254723993187

Amount Limits

M-Pesa enforces the following limits on payouts:

Limit TypeValue
Minimum Amount10 KES
Maximum Amount150,000 KES per transaction

Note: Amounts are specified in minor units. For KES, the minor unit is cents, so 2000 represents 20.00 KES.

Error Codes

The following error codes may be returned for M-Pesa payout failures:

CodeDescription
PAYOUT_RECIPIENT_INVALID_ACCOUNTThe recipient phone number is not registered with M-Pesa or the account is in an invalid state
PAYOUT_RECIPIENT_LIMIT_EXCEEDEDThe recipient’s wallet balance limit has been reached or the amount exceeds transaction limits
PAYOUT_INSUFFICIENT_FUNDSInsufficient funds in the payout source account
INVALID_DATAInvalid recipient information provided
NETWORK_ERRORRequest timed out while processing
DOWNSTREAM_ERRORAn error occurred with the payment provider

Important Notes

  1. Operator Code: Always use "mpesa" as the operator code for M-Pesa payouts in Kenya.

  2. Country Code: Use the 3-letter ISO country code "KEN" for both paymentLocation and recipient.country.

  3. Currency: Only KES (Kenyan Shilling) is supported for M-Pesa payouts in Kenya.

  4. Asynchronous Processing: Payouts are processed asynchronously. After submission, the initial status will be Pending. Monitor the final status via webhooks or by polling the transaction status endpoint.

  5. Idempotency: Use unique merchantReference values for each payout request. Duplicate references will be rejected to prevent duplicate payouts.

  6. Sender Details: The sender object is required for Kenya payouts. Requests missing required sender fields will be rejected with a validation error.

Best Practices

  • Monitor Webhook Events: Ensure your webhook handlers correctly process status updates for both successful and failed payouts.

  • Validate Phone Numbers: Before submitting payouts, validate that recipient phone numbers are in a valid format to reduce failed transactions.

Next Steps

Contact your account manager to enable M-Pesa payouts for your merchant account.