Mobile Money Payments
Accept payments from M-Pesa, MTN Mobile Money, Airtel Money, and other mobile wallets used across Africa and emerging markets.
What is Mobile Money?
Mobile money lets people send and receive money using their phone number. Instead of a bank account, they have a mobile money account linked to their phone.
It's very popular in Africa, where many people don't have bank accounts but do have mobile phones. Services like M-Pesa in Kenya have over 50 million users.
When a customer pays with mobile money, they get a prompt on their phone. They enter their PIN to confirm, and the money moves from their mobile wallet to your account.
Supported Providers
| Provider | Countries | Currency |
|---|---|---|
| M-Pesa | Kenya, Tanzania, DRC, Ghana, Mozambique, Egypt | KES, TZS, CDF, GHS, MZN, EGP |
| MTN Mobile Money | Ghana, Uganda, Rwanda, Cameroon, Ivory Coast | GHS, UGX, RWF, XAF, XOF |
| Airtel Money | Kenya, Uganda, Tanzania, Nigeria, Zambia | KES, UGX, TZS, NGN, ZMW |
| Orange Money | Senegal, Mali, Ivory Coast, Cameroon | XOF, XAF |
| Vodacom M-Pesa | South Africa, Tanzania, DRC | ZAR, TZS, CDF |
How Mobile Money Payments Work
Here's what happens when a customer pays with mobile money:
- Customer starts checkout - They enter their phone number and choose mobile money as the payment method.
- You create a payment - Your server sends the amount, currency, and phone number to ClapPay.
- Customer gets a prompt - An STK Push (SIM Toolkit Push) appears on their phone asking them to confirm the payment.
- Customer enters PIN - They enter their mobile money PIN to authorize the payment.
- Payment completes - ClapPay receives confirmation and sends you a webhook.
The whole process usually takes 15-30 seconds.
Accept an M-Pesa Payment
Here's how to accept an M-Pesa payment in Kenya:
Create an M-Pesa payment (Node.js)
const clappay = require('@clappay/sdk')('sk_live_...');
// Create a mobile money payment
const payment = await clappay.paymentIntents.create({
amount: 1000, // 1000 KES
currency: 'kes',
payment_method_types: ['mobile_money'],
payment_method_data: {
type: 'mobile_money',
mobile_money: {
provider: 'mpesa',
phone_number: '+254712345678', // Customer's number
}
},
confirm: true, // Send STK push immediately
});
// The customer will receive an STK push on their phone
console.log('Payment status:', payment.status);
// 'requires_action' means waiting for customer to enter PINAfter creating the payment, the customer has about 60 seconds to enter their PIN. If they don't respond, the payment expires.
Payment Status
Mobile money payments go through these statuses:
| Status | What It Means |
|---|---|
| requires_action | Waiting for customer to enter PIN on their phone |
| succeeded | Customer confirmed and payment is complete |
| failed | Customer declined or entered wrong PIN |
| expired | Customer didn't respond in time |
Listen for Webhooks
Since mobile money payments happen on the customer's phone, you need webhooks to know when they complete:
// Handle mobile money payment webhook
app.post('/webhooks/clappay', async (req, res) => {
const event = req.body;
if (event.type === 'payment_intent.succeeded') {
const payment = event.data.object;
// Check if it's a mobile money payment
if (payment.payment_method_types.includes('mobile_money')) {
console.log('Mobile money payment received!');
console.log('Amount:', payment.amount);
console.log('Provider:', payment.charges.data[0].payment_method_details.mobile_money.provider);
// Fulfill the order
await fulfillOrder(payment.metadata.order_id);
}
}
res.status(200).send('OK');
});Common Issues
Customer didn't receive the prompt
- • Check the phone number format (include country code: +254...)
- • Make sure the phone has network signal
- • The customer's phone might need to be unlocked
- • Wait a few seconds and try again
Payment failed with "insufficient funds"
- • Customer doesn't have enough money in their mobile wallet
- • Ask customer to add funds or use a different payment method
- • Consider offering smaller payment amounts
Payment timed out
- • Customer took too long to enter their PIN (usually 60 seconds)
- • Show a message asking them to try again
- • Consider prompting them to have their phone ready before checkout
Best Practices
- Tell customers what to expect - Let them know they'll receive a prompt on their phone and should have it ready.
- Show a waiting screen - Display a message like "Waiting for you to confirm on your phone..." while they enter their PIN.
- Handle timeouts gracefully - If the payment expires, offer to resend the prompt.
- Use the right currency - Mobile money payments must be in the local currency. You can't charge M-Pesa in USD.
- Verify phone numbers - Consider sending an OTP to verify the phone number before charging.