ITSkillsCenter
Business Digital

API Orange Money Sénégal et Côte d’Ivoire 2026 : tutoriel intégration complet

7 min de lecture

Orange Money est l’opérateur Mobile Money le plus mature en Afrique de l’Ouest, présent dans tous les pays francophones de la zone CEDEAO/UEMOA et au-delà. Au Sénégal et en Côte d’Ivoire spécifiquement, il reste un acteur incontournable malgré la montée de Wave : nombreux utilisateurs n’utilisent pas Wave, et certains segments B2B passent toujours majoritairement par Orange Money. L’API marchand officielle, exposée via la plateforme Orange Developer, permet d’accepter des paiements directement. Voici le tutoriel complet d’intégration en 2026, valable Sénégal et Côte d’Ivoire.

Ce tutoriel s’inscrit dans notre série Mobile Money. Pour le panorama global, voir notre guide complet API Mobile Money 2026.

L’écosystème Orange Developer

Orange expose plusieurs APIs via developer.orange.com :

  • Orange Money Web Payment — checkout via redirection web, le plus simple à intégrer, équivalent à Wave Checkout
  • Orange Money B2B Payment — paiement de factures B2B avec validation manuelle
  • Orange Money Cash-In / Cash-Out — pour les agrégateurs ou agents
  • SMS API — utile pour notifications de paiement
  • USSD API — paiement par code USSD pour clients sans smartphone

Pour la majorité des projets e-commerce et SaaS, Orange Money Web Payment est l’API recommandée. C’est ce que couvre ce tutoriel.

Prérequis

  • Compte Orange Developer (gratuit, inscription en ligne)
  • Application créée dans le portail avec accès Sandbox
  • Pour la production : compte marchand Orange Money B2B (KYC + contrat agence Orange Money locale)
  • Node.js 20+ ou Bun
  • Domaine HTTPS pour notification (callback)
  • Niveau attendu : intermédiaire
  • Temps : 1 journée pour MVP, 1 semaine pour intégration complète et passage en prod

Étape 1 — Inscription Orange Developer

  1. Inscription sur developer.orange.com
  2. Vérification email
  3. Création d’une application : choisissez « Orange Money Web Payment Senegal » (ou Côte d’Ivoire selon pays cible)
  4. Récupérez le Client ID et Client Secret
  5. Notez la Merchant Key sandbox fournie automatiquement

Étape 2 — Authentification OAuth2

L’API Orange Money utilise OAuth2 client credentials. Vous échangez Client ID + Secret contre un access token, valable ~1h, à mettre en cache.

// src/orange-auth.ts
let cachedToken: { value: string; expiresAt: number } | null = null;

export async function getOrangeAccessToken(): Promise<string> {
  // Cache encore valide ?
  if (cachedToken && cachedToken.expiresAt > Date.now() + 60_000) {
    return cachedToken.value;
  }

  const credentials = Buffer.from(
    `${process.env.ORANGE_CLIENT_ID}:${process.env.ORANGE_CLIENT_SECRET}`,
  ).toString("base64");

  const res = await fetch("https://api.orange.com/oauth/v3/token", {
    method: "POST",
    headers: {
      "Authorization": `Basic ${credentials}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: "grant_type=client_credentials",
  });

  if (!res.ok) throw new Error(`Auth Orange échouée: ${res.status}`);
  const data = await res.json();

  cachedToken = {
    value: data.access_token,
    expiresAt: Date.now() + data.expires_in * 1000,
  };
  return cachedToken.value;
}

Étape 3 — Initier un paiement Web

// src/orange-payment.ts
import { getOrangeAccessToken } from "./orange-auth";

const OM_BASE = process.env.ORANGE_API_BASE
  ?? "https://api.orange.com/orange-money-webpay/dev/v1";

export async function createOrangePayment(params: {
  amount: number;
  orderId: string;
  customerId: string;
  returnUrl: string;
  cancelUrl: string;
  notifUrl: string;
}) {
  const token = await getOrangeAccessToken();

  const res = await fetch(`${OM_BASE}/webpayment`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
      "Accept": "application/json",
    },
    body: JSON.stringify({
      merchant_key: process.env.ORANGE_MERCHANT_KEY,
      currency: "XOF",
      order_id: params.orderId,
      amount: params.amount,
      return_url: params.returnUrl,
      cancel_url: params.cancelUrl,
      notif_url: params.notifUrl,
      lang: "fr",
      reference: params.customerId,
    }),
  });

  if (!res.ok) {
    const err = await res.text();
    throw new Error(`Orange Money création échouée: ${res.status} ${err}`);
  }

  // Réponse type :
  // { status, message, pay_token, payment_url, notif_token }
  return res.json();
}

L’utilisateur est ensuite redirigé vers payment_url qui ouvre la page Orange Money pour valider avec son code PIN.

Étape 4 — Notification (callback)

Orange Money envoie une notification HTTP POST à votre notif_url à la fin de la transaction (succès ou échec). Contrairement à Wave, Orange n’utilise pas de signature HMAC standard — l’authentification se fait via un notif_token que vous recevez à la création et qui doit matcher.

app.post("/webhooks/orange-money", async (c) => {
  const body = await c.req.json();

  // Récupérer la commande et vérifier le notif_token
  const order = await db.select().from(orders)
    .where(eq(orders.id, body.order_id))
    .limit(1);

  if (!order.length) return c.text("Order not found", 404);

  if (order[0].orangeNotifToken !== body.notif_token) {
    console.warn("Notif token mismatch", body.order_id);
    return c.text("Invalid notif_token", 401);
  }

  // Idempotence : statut déjà final ?
  if (order[0].status === "paid" || order[0].status === "failed") {
    return c.text("Already processed", 200);
  }

  // Mettre à jour le statut
  if (body.status === "SUCCESS") {
    await db.update(orders).set({
      status: "paid",
      orangeTransactionId: body.txnid,
      paidAt: new Date(),
    }).where(eq(orders.id, body.order_id));
    await sendReceiptEmail(body.order_id);
  } else if (body.status === "FAILED" || body.status === "CANCELLED") {
    await db.update(orders).set({ status: "failed" })
      .where(eq(orders.id, body.order_id));
  }

  return c.text("OK", 200);
});

Étape 5 — Vérification proactive (status)

Comme avec Wave, doublez le webhook par un polling proactif pour les commandes pending de plus de 15 minutes :

export async function checkOrangePaymentStatus(payToken: string) {
  const token = await getOrangeAccessToken();

  const res = await fetch(`${OM_BASE}/transactionstatus`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      order_id: orderId,
      amount: amount,
      pay_token: payToken,
    }),
  });

  return res.json();
  // { status: "SUCCESS" | "FAILED" | "PENDING" | "INITIATED", txnid?, message }
}

Étape 6 — Spécificités Sénégal vs Côte d’Ivoire

  • URL endpoints : différents selon le pays. Sénégal utilise orange-money-webpay/dev/v1 en sandbox et orange-money-webpay/sn/v1 en prod ; Côte d’Ivoire utilise /ci/v1
  • Devise : XOF dans les deux cas (UEMOA)
  • Numéros de téléphone : préfixe +221 (Sénégal) ou +225 (CI)
  • Frais et plafonds : varient selon le contrat marchand local
  • Support : agences Orange Money B2B locales différentes — au Sénégal Orange Sonatel, en Côte d’Ivoire Orange CI

Étape 7 — Passage en production

  1. Validation de votre intégration en sandbox avec tests complets (succès, échec, timeout, double soumission)
  2. Demande de bascule prod via le dashboard Orange Developer + dossier KYC complet auprès de l’agence Orange Money locale
  3. Réception des credentials production et de la Merchant Key production
  4. Mise à jour des variables d’environnement, changement du OM_BASE URL
  5. Tests progressifs avec petits montants (1000 FCFA) avant ouverture publique

Délai total : 2-4 semaines selon la réactivité de l’agence Orange Money locale. Démarrez tôt.

Étape 8 — Bonnes pratiques production

  • Rotation des clefs : régénérer Client Secret tous les 6 mois
  • Cache du token : ne pas refetch à chaque appel — économie de latence et conformité aux rate limits
  • Retry avec backoff exponentiel : Orange API a parfois des 5xx transitoires
  • Monitoring du taux de succès : alerte si taux d’échec > 10 % sur une heure
  • Logs sans secrets : ne pas logger les tokens, ni les pay_token complets

Comparaison Wave vs Orange Money

CritèreWaveOrange Money
UX intégrationPlus moderne, RESTfulOAuth2 + endpoints structurés
DocumentationExcellenteCorrecte mais parfois datée
Webhooks signésHMAC SHA-256 natifnotif_token
SandboxImmédiateImmédiate via Orange Developer
Délai prod1-2 semaines2-4 semaines
Frais~1 %~2-3 %
Pénétration utilisateursTrès forte Sénégal/CIUniverselle Afrique francophone

Recommandation : intégrer les deux pour maximiser la conversion. Wave domine en zone urbaine/jeunes, Orange Money est dominant pour B2B et population non-Wave.

Adaptation Afrique de l’Ouest

Pour un marchand au Sénégal qui vise la conversion maximum, l’intégration Wave + Orange Money couvre ~95 % des utilisateurs Mobile Money. Pour un marchand en Côte d’Ivoire, ajoutez MTN MoMo qui est important sur ce marché.

Erreurs fréquentes

ErreurCauseSolution
403 sur tokenApplication pas encore validéeVérifier statut sur dashboard Orange Developer
« Invalid merchant_key »Mauvaise clef sandbox vs prodDistinguer ENV correctement
Notification jamais reçueURL non HTTPS ou inaccessibleTester avec ngrok ou Cloudflare Tunnel
Token expiré en plein appelPas de cacheImplémenter le cache avec marge 60s
Double traitementIdempotence manquanteVérifier statut avant update
Délai bascule prod longKYC incompletCommencer KYC dès le début du projet

Pour aller plus loin

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité