Websites10 min read

Orange Money Senegal API: step-by-step integration in 2 hours (May 2026)

Mohamed Bah·Fondateur, Kolonell
May 5, 2026
Share:
Orange Money Senegal API: step-by-step integration in 2 hours (May 2026)

Orange Money Senegal API: step-by-step integration in 2 hours (May 2026)

Websites

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 (not orange.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

GotchaSymptomFix
Caching token past 3600s401 on initRedis TTL = expires_in − 60s
Return URL without order_idCannot match on returnAlways encode order=${id}
Relying on notif_url aloneGhost ordersPolling on return + nightly catch-up cron
Testing in prodCash losses on bugsSandbox Orange account + small 100 XOF amounts
Wrong currency value400 errorUEMOA = "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.

Tags:#Orange Money#API#Payments#Senegal#Tutorial#Mobile Money
Share:

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.