Mobile money at checkout in Africa: M-Pesa, MTN MoMo and Wave

At checkout the customer enters their mobile money number, the provider sends a payment prompt to the phone, and the customer approves it with their PIN. The result arrives later by callback, so the order stays pending until then. M-Pesa limits payments to KES 250,000 each and KES 500,000 a day. Wave sends the customer to its app through a launch URL. Refunds and payouts need a reversal, B2C or refund route set up before launch.

Topic
Local methods
Published
Updated
Reading time
8 min

In 30 seconds

  • A mobile money payment is approved on the customer's phone, so the order stays pending until a callback or status query confirms the result.
  • M-Pesa caps payments at KES 250,000 and KES 500,000 a day, and Wave checkout sessions expire after 30 minutes by default.
  • Refunds and payouts need their own setup: a reversal or B2C route for M-Pesa, and a refund call for Wave checkouts.
  • 9 sources cited
Talk to us
On this page9 sections

A merchant that adds Kenya or Ghana to its checkout soon learns that the card form is not where most customers pay. They pay from a phone: they type their number, a prompt appears on the handset, and they approve it with a PIN. The money moves in seconds, but the merchant’s website finds out only when a callback arrives, and the customer may have walked away from the screen in the meantime.

This article explains how mobile money works at an online checkout, using M-Pesa in Kenya, MTN MoMo in Ghana and Wave in francophone West Africa as examples: the prompt, the asynchronous result, limits and fees, refunds and payouts, phone number handling and the mistakes that cost conversion. Which providers to choose in each market is covered in choosing payment providers for Africa.

Why does mobile money matter for an online store?

Because in several African markets it is how most people pay. The GSMA’s State of the Industry Report on Mobile Money 2026 counts 2.3 billion registered accounts in 2025, 268 million more than a year earlier, and 593 million accounts active in the past 30 days. More than USD 2 trillion flowed through mobile money in 2025, and most new accounts came from Sub-Saharan Africa.

Merchant payments are the fastest-growing use. The GSMA reports that they grew by almost half to USD 155 billion in 2025, with East Africa accounting for three quarters of that growth. Online merchant payments are still less frequent than in-person ones, but their value grew by a third between September 2024 and June 2025.

In Kenya, the Central Bank of Kenya counted 95.31 million registered mobile money accounts in August 2026, and our Kenya guide shows how far M-Pesa leads. Wave said in June 2025 that it served more than 20 million monthly active users in eight markets, mainly in West Africa, with Senegal and Côte d’Ivoire among its key markets.

How does a mobile money payment work online?

The customer approves the payment on their phone, not on your page. The three examples use different mechanics:

MethodHow the customer is askedHow they approveHow the merchant learns the result
M-Pesa Express (STK push)A prompt on the Safaricom phone, with amount and reference filled inM-Pesa PINCallback to the merchant’s URL; status query as backup
MTN MoMo through a providerA prompt on the phone linked to the number enteredPIN, sometimes with a one-time passwordProvider notification
Wave CheckoutA Wave launch URL that opens the Wave appPIN in the appRedirect to a success or error URL, and a webhook

M-Pesa Express. Safaricom’s Daraja documentation describes the sequence. The merchant sends a request with its shortcode, the amount, the customer’s number and a callback URL. Safaricom acknowledges it at once, pushes a prompt to the customer’s phone, and the customer enters their PIN. M-Pesa then debits the customer, credits the merchant and sends the result to the callback URL, and the customer gets an SMS. Safaricom notes that this reduces wrong payments, because the customer no longer types the paybill or till number, amount or account reference.

MTN MoMo and other networks. Paystack’s support article describes the flow for its mobile money channel: the customer enters their number, picks the provider, receives a prompt on the phone, and completes the authorisation with a one-time password and their PIN. It lists MTN, AT (Airtel/Tigo) and Telecel in Ghana, Safaricom and Airtel Money in Kenya, and Wave, Orange and MTN in Côte d’Ivoire.

Wave. Wave’s Checkout API works by redirect. The merchant creates a checkout session and sends the customer to the returned wave_launch_url. Wave’s documentation says this URL must be opened by the customer’s browser, and that mobile apps should not open it in a webview. Through Paystack, the Wave customer confirms in the Wave app and then returns to the checkout to say they have completed the payment.

Why is the result asynchronous, and how do you confirm it?

Because the customer acts on another device, in their own time. The first response from Safaricom only says the request was accepted for processing; it is not a payment. The final result arrives at the callback URL with a result code: 0 means success, and Safaricom’s own example of a failure is 1032, request cancelled by user. A successful callback carries the amount, the M-Pesa receipt number, the date and the phone number.

Build the order flow around that:

  1. Create the order as pending when the prompt is sent, and show the customer a clear waiting screen.
  2. Fulfil only on the final result. Use the callback, or your provider’s webhook, as the source of truth, never the browser.
  3. Query when nothing arrives. Safaricom’s M-Pesa Express Query API returns the status of a request by its CheckoutRequestID; Safaricom’s FAQ notes that callbacks fail when the URL is not publicly reachable.
  4. Expire stale sessions. Wave checkout sessions expire 30 minutes after creation by default and accept no payments afterwards, and the merchant can expire an open session earlier.
  5. Do not fire a second prompt immediately. Safaricom lists an error for a customer who already has a transaction in progress and advises waiting at least one minute between requests.

Our guide to webhooks and idempotency covers duplicate and out-of-order notifications.

What limits and fees apply?

Limits are set by the network and the customer’s account; fees mostly fall on the merchant. The table uses Safaricom’s published M-Pesa figures and the providers’ public pages; other networks and providers set their own.

ItemFigureSource
M-Pesa maximum per transactionKES 250,000Safaricom
M-Pesa daily limit and maximum balanceKES 500,000 eachSafaricom
M-Pesa Express minimumKES 1Safaricom Daraja
Buy Goods charge to the customerFreeSafaricom
Buy Goods charge to the merchantFree to KES 500; 0.55% from KES 501 to 36,363; KES 200 aboveSafaricom
Paystack mobile money fee1.95% per transaction; 1.5% in KenyaPaystack
Wave in-person merchant paymentsFirst 20,000 CFA a day free, then 1%Wave

The limits matter for larger baskets. A KES 300,000 order cannot be paid in one M-Pesa payment, so the checkout should offer a card or bank transfer above the cap rather than fail at the last step. The balance limit matters too: a customer cannot top up beyond it to pay. For Wave, amounts in XOF must be whole numbers, as its documentation does not allow decimal places.

How do refunds, reversals and payouts work?

Each network has its own route, and none is a card refund. Safaricom’s FAQ for M-Pesa Express confirms that a payment can be reversed with its Reversal API, which needs an operator with the reversals role on the merchant’s M-Pesa organisation account. Sending money to a customer, for a refund after the fact or a marketplace payout, is a separate B2C product with its own shortcode and API role.

Wave’s Checkout API has a refund call on the checkout session. Its documentation says a repeated refund does not create a second transaction, and that normal restrictions such as monthly limits or blocked accounts still apply. Ask every provider which of these it supports for each network, and whether partial refunds are possible. Our article on refunds across local methods compares the wider picture.

How should the checkout handle phone numbers and networks?

Normalise the number before you send it. Safaricom’s M-Pesa Express API expects the customer’s number in international format, 2547XXXXXXXX, without a plus sign or leading zero, so a customer who types 07… needs converting first. Validate the length on the page, not after the prompt fails.

Let the customer confirm the network. Paystack’s checkout asks the customer to choose the provider after entering the number, which avoids guessing from a prefix. Show the networks you support, and hide those you do not.

Make the prompt recognisable. Safaricom displays the account reference in the customer’s prompt and caps it at 12 characters, with 13 for the transaction description. A short order number or shop name tells the customer what they are approving.

Worked example: recovering prompts that time out

Example figures, for illustration only.

An online fashion retailer in Kenya sends 10,000 M-Pesa Express prompts a month, with an average order of KES 2,000. It pays the Buy Goods merchant charge of 0.55%, or KES 11 per order.

OutcomePrompts beforePrompts after the changes
Paid7,2007,810
No response before the prompt expired1,300780
Cancelled by the customer (1032)900810
Other failures600600
Total10,00010,000

The retailer makes two changes. It shows a “send the prompt again” button after a short wait, which recovers 520 of the 1,300 unanswered prompts, and it shows paybill instructions to customers who cancel, which recovers 90 of the 900. Paid orders rise by 610, from 72% to 78.1%. At KES 2,000 per order that is KES 1,220,000 more a month, for KES 6,710 in extra merchant charges.

What are the common mistakes?

  • Treating the API acknowledgement as payment. “Accepted for processing” means the prompt was sent, not that money moved. Wait for the callback.
  • Sending prompts on every click. A second request while the first is open fails; Safaricom advises waiting at least a minute between requests.
  • No status query. Callbacks get lost. Query the status before you cancel an order that looks unpaid.
  • Opening Wave in a webview. Wave’s documentation says the launch URL must open in the customer’s browser.
  • Ignoring the caps. Orders above KES 250,000 cannot be paid in one M-Pesa payment; offer another method.
  • Promising refunds without a route. Set up reversals, B2C or the provider’s refund call before launch.

How does Omno handle mobile money at checkout?

Omno can show mobile money next to cards in the hosted checkout, through the providers you connect. Routing and PSP eligibility rules by country, method, currency and customer group decide which provider sends each request, and if a provider is unavailable or rejects the request, the payment moves to the next provider in the rule until one accepts. If you build your own checkout, your mobile money button can link to an Omno Direct Link, which splits payments between several mobile money providers by share or priority. The final status of every payment and payout arrives by webhook, which is the source of truth. The hosted checkout page covers the setup.

Key facts

  • Mobile money had 2.3 billion registered and 593 million 30-day active accounts in 2025, and more than USD 2 trillion flowed through it (GSMA State of the Industry Report on Mobile Money 2026).
  • Mobile money merchant payments grew by almost half to USD 155 billion in 2025, and online merchant payment value grew by a third between September 2024 and June 2025 (GSMA).
  • Kenya had 95.31 million registered mobile money accounts in August 2026 (Central Bank of Kenya).
  • M-Pesa allows up to KES 250,000 per transaction, KES 500,000 a day and a KES 500,000 balance; Buy Goods payments are free for the customer (Safaricom).
  • Wave checkout sessions expire 30 minutes after creation by default, and XOF amounts cannot have decimal places (Wave developer docs).

Changelog

  • First published.
  • Updated for Card Fields and Direct Links.

Frequently asked questions

How long does a customer have to approve a mobile money prompt?

It depends on the network and the provider, and Safaricom's M-Pesa Express documentation does not publish a figure. Wave checkout sessions expire 30 minutes after creation by default. Ask each provider for its timeout, show a countdown or a clear waiting state, and query the status when no callback arrives rather than assuming the payment failed.

Who pays the fee on a mobile money payment?

Usually the merchant. Safaricom's tariff for Lipa na M-Pesa Buy Goods shows no customer charge, and a merchant charge of 0.55% for payments between KES 501 and KES 36,363, capped at KES 200 above that. Payment providers add their own fee: Paystack lists 1.95% per transaction on its mobile money channel, and 1.5% in Kenya.

Can a mobile money payment be refunded?

Yes, but the route depends on the network and provider. Safaricom says an M-Pesa Express payment can be reversed with its Reversal API, and M-Pesa payouts to customers use a separate B2C shortcode. Wave's checkout API has a refund call that does not create a second transaction if repeated. Check the route for each network before you promise refunds.

Can customers pay subscriptions with mobile money?

Not automatically through a standard checkout. Paystack's support article says recurring payments are not currently possible on its mobile money channel. Each payment needs the customer to approve a new prompt, so subscription businesses usually send a payment request at each renewal or keep a card on file as the main method.

esc
↑↓ to move ↵ to open All results