Orange Money still owns ~38% of mobile payments in Senegal in 2026. Skipping it means a third of your market either pays cash on delivery or abandons cart. But the developer onboarding is less straightforward than Wave.
TL;DR
- Orange developer account: 5–10 business-day approval (plan ahead of the sprint).
- Three key endpoints:
/oauth/token(auth),/webpayment(init),/webpayment/{id}(status).- No reliable public webhook in May 2026 → polling + return redirect.
- Plan 2 hours for a working integration, 4 hours for production-grade.
Step 1 — create the developer account
- Go to
developer.orange.com(notorange.sn). - Subscribe to the "Orange Money Web Payment" API.
- Provide: company name, NINEA, RCCM, settlement IBAN.
- Manual Orange review: 5–10 business days. Be ready to nudge.
Step 2 — fetch an access_token
`ts
// lib/orange-money.ts
const OM_BASE = 'https://api.orange.com/orange-money-webpay/dev/v1';
async function getAccessToken() {
const auth = Buffer.from(
${process.env.OM_CLIENT_ID}:${process.env.OM_CLIENT_SECRET}
).toString('base64');
const res = await fetch(${OM_BASE}/oauth/token, {
method: 'POST',
headers: {
'Authorization': Basic ${auth},
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'grant_type=client_credentials',
});
const { access_token, expires_in } = await res.json();
return { access_token, expires_in };
}
`
Token TTL is 3600s. Cache it (Redis or in-memory with TTL) to avoid regenerating per payment.
Step 3 — init a payment
`ts
async function initPayment(orderId: string, amountXof: number) {
const { access_token } = await getAccessToken();
const res = await fetch(${OM_BASE}/webpayment, {
method: 'POST',
headers: {
'Authorization': Bearer ${access_token},
'Content-Type': 'application/json',
},
body: JSON.stringify({
merchant_key: process.env.OM_MERCHANT_KEY,
currency: 'OUV', // UEMOA unit = XOF
order_id: orderId,
Need a professional website?
Kolonell builds websites that attract clients, optimized for the Sénégalese market. Free quote in 2 minutes.
amount: amountXof,
return_url: https://kolonell.com/checkout/om-return?order=${orderId},
cancel_url: https://kolonell.com/checkout/om-cancel?order=${orderId},
notif_url: https://kolonell.com/api/webhooks/orange-money,
lang: 'fr',
reference: orderId,
}),
});
return res.json(); // { pay_token, payment_url, notif_token }
}
`
User is redirected to payment_url, pays in Orange Money UI, returns to return_url.
Step 4 — verify status on return
The unreliable webhook makes polling mandatory:
`ts
async function verifyPayment(payToken: string) {
const { access_token } = await getAccessToken();
const res = await fetch(${OM_BASE}/webpayment/${payToken}, {
headers: { 'Authorization': Bearer ${access_token} },
});
const { status, txnid } = await res.json();
// status: SUCCESS | FAILED | PENDING | EXPIRED
return { status, txnid };
}
`
On SUCCESS → mark order paid. On PENDING → show "verifying" screen, re-poll every 5s for up to 60s.
Gotchas
| Gotcha | Symptom | Fix |
|---|---|---|
| Caching token past 3600s | 401 on init | Redis TTL = expires_in − 60s |
| Return URL without order_id | Cannot match on return | Always encode order=${id} |
Relying on notif_url alone | Ghost orders | Polling on return + nightly catch-up cron |
| Testing in prod | Cash losses on bugs | Sandbox Orange account + small 100 XOF amounts |
Wrong currency value | 400 error | UEMOA = "OUV" not "XOF" |
Cost
- Merchant fees: 1.5%–2.5% depending on negotiated volume.
- No setup fee on the API side.
- Settlement: T+1 business day to bank account or IBAN.
FAQ
Q: Does Orange Money work with a non-Orange phone number?
A: No. Payer must have an active Orange Money account. Free/Expresso numbers are rejected.
Q: Different integration for Côte d'Ivoire?
A: Yes — OM CI uses a separate endpoint and merchant_keys. Structure your code: one connector per country.
Q: How are refunds handled?
A: See our Wave + OM refund guide →.
Conclusion
Orange Money isn't the most modern provider, but 38% market share justifies the effort. Combined with Wave (~52%) and a card fallback, you cover 95% of preferred payment methods in Senegal.
Mohamed Bah
Fondateur, Kolonell
Passionate about digital and entrepreneurship in Africa, Mohamed has been helping Sénégalese businesses with their digital transformation since 2020. Founder of Kolonell, he believes every SME deserves a professional and accessible online présence.
