If you sell anything online in Cameroon, Mobile Money is not a payment option — it is the payment method. Cards are a rounding error for most of our clients. So the integration question arrives early, and it is usually framed as a choice between MTN MoMo and Orange Money.
The honest answer is that you will probably need both. But you will start with one, and that decision has consequences worth understanding.
Start with wherever your customers already are
This sounds obvious and is routinely ignored in favour of whichever API looks nicer to a developer. It should not be. Look at how your existing customers pay you today — if four in five already send MTN, integrate MTN first and add Orange when the volume justifies it.
If you genuinely do not know, that is worth finding out before you spend anything on engineering.
What the integrations have in common
Both follow the same shape, and understanding it removes most of the mystery:
- 1Your server asks the provider to collect a given amount from a given number.
- 2The customer receives a prompt on their handset and enters their PIN.
- 3The provider tells you the outcome — by calling a webhook on your server, by you polling for status, or both.
- 4You mark the order paid and fulfil it.
Step three is where every real problem lives. Steps one and two are the easy part, and they are the part that demos well.
Where they differ in practice
| MTN MoMo | Orange Money | |
|---|---|---|
| Developer sandbox | Public, self-service, usable the same day | Usually arranged through your account contact |
| Onboarding | Portal signup, then commercial approval | More relationship-driven; expect meetings |
| Documentation | Broadly good, occasionally lags the live API | Thinner; your integration contact matters more |
| Getting live | Days to weeks after paperwork | Often longer — plan for it |
Terms, fees and onboarding steps change, and they differ by business type and volume. Treat the table above as orientation and confirm the current specifics with each provider — anyone quoting you exact rates from a blog post is guessing.
The failure modes nobody warns you about
This is the section worth the read. Every one of these has bitten a project we have taken over from someone else.
The customer pays and your site never finds out
The webhook fails to arrive, or arrives while your server is restarting. The customer has been debited and sees an unpaid order. Never rely on the webhook alone. Poll for status as a backstop, and reconcile pending transactions on a schedule.
The same webhook arrives twice
Providers retry. If your handler is not idempotent you will fulfil the order twice, or credit a wallet twice. Key every incoming notification on the provider's transaction id and ignore ones you have already processed.
The customer walks away mid-payment
Prompts expire. An order left pending forever is a support call and, worse, stock held for a sale that never happened. Decide the expiry window and enforce it with a scheduled job that releases the order and lets the customer retry cleanly.
Phone number formats
Customers type `677 12 34 56`, `+237677123456`, `237 677123456` and `00237677123456`. Normalise on input; do not make the provider reject it for you.
Anyone can call your webhook
A webhook URL is a public endpoint. If it marks orders paid without verifying that the notification genuinely came from the provider, someone can mark their own order paid by sending you a request. Verify signatures where available, and always confirm the transaction independently before releasing goods.
Treat every incoming payment notification as a hint that something happened — then go and check for yourself.
Should you use an aggregator instead?
Aggregators — Maviance and similar — give you one integration covering both networks, and absorb some of the onboarding. You pay a margin for that, and you inherit their uptime.
Our rule of thumb:
- Low volume, want to launch quickly: use an aggregator. The margin costs less than the delay.
- High volume, payments are the core of the business: integrate directly. At scale the margin becomes the largest line item you control.
- Anything in between: start with an aggregator and keep your payment code behind a clean interface, so switching later is a change in one place rather than a rewrite.
The one design decision that matters most
Whatever you choose, put a single payment interface in front of it in your own code — `initiatePayment`, `checkStatus`, `handleNotification` — and let each provider be an implementation behind it. Every project we have rescued that was painful to change had provider-specific code scattered through its checkout, its admin panel and its reporting.
Get that boundary right and adding the second network later is a week. Get it wrong and it is a rewrite.
We have integrated both networks, and cleaned up several integrations that were done in a hurry. If you would like a second opinion on an existing one, we are happy to look.
Talk to us about payments