Aller au contenu
AfriContext

Orange Money

Orange Money - Web Payment

Obtient un jeton OAuth, initie un paiement web Orange Money et valide la notification avec notif_token.

Vérifié sur la doc officielle • Vérifié sur la doc officielle • 10.10.26API v1

Même prompt, avec et sans ce contexte

Les passages barrés sont ceux que l'IA a inventés. Basculez pour voir la sortie avec le contexte.

› Intègre Orange Money Web Payment au Sénégal dans mon backend Node.

1const token = await fetch("https://api.orange.com/oauth/v2/token", {2  method: "POST",3  body: JSON.stringify({ client_id, client_secret }),4});5const pay = await fetch("https://api.orange.com/orange-money/v1/payment", {6  method: "POST",7  body: JSON.stringify({ phone_number: "+221770000000", amount: 5000, currency: "XOF" }),8});
404 Resource not found4 inventions de l'IAModèle testé : GPT-4o, CursorDocumentation source

Testez le code généré avant de le brancher sur la vraie API

Une sandbox Orange Money répond comme l'API et envoie un webhook signé.

Ouvrir la sandbox Orange Money

Authentification

  • Étape 1 : POST https://api.orange.com/oauth/v3/token avec Authorization: Basic <base64(client_id:client_secret)>.
  • Corps application/x-www-form-urlencoded : grant_type=client_credentials.
  • Réponse : access_token, expires_in (secondes). Mettre le jeton en cache jusqu'à expiration.
  • Étape 2 : Authorization: Bearer <access_token> sur les appels Web Payment.

Endpoints

  • POST https://api.orange.com/orange-money-webpay/dev/v1/webpayment initie un paiement.
    • Requis : merchant_key, currency, order_id, amount, return_url, cancel_url, notif_url, lang, reference.
    • Réponse 201 : status, message, pay_token, payment_url, notif_token.
  • POST https://api.orange.com/orange-money-webpay/dev/v1/transactionstatus avec order_id, amount, pay_token.
  • En production, le segment dev est remplacé par le code pays du contrat marchand (ex. cm, ml).

Erreurs

  • 401 jeton expiré : renouveler le jeton puis rejouer une seule fois.
  • 400 champ manquant ou order_id déjà utilisé.
  • 403 application non abonnée à l'API Web Payment.
  • 5xx réessayer avec backoff, en gardant le même order_id.

Webhooks

  • Orange appelle notif_url en POST JSON : status (SUCCESS ou FAILED), notif_token, txnid.
  • Vérifier que notif_token est égal à celui reçu à l'initiation et stocké avec la commande.
  • Répondre 200 rapidement, traiter ensuite.

Idempotence et limites

  • order_id est unique par marchand : le réutiliser pour un nouveau paiement provoque un rejet.
  • Le payment_url a une durée de vie limitée : en recréer un si le client revient tard.

Pièges courants

Ce que les LLMs inventent le plus souvent pour Orange Money.

  • Le jeton ne vient pas de /oauth/v2/token ni de /token : c'est /oauth/v3/token.
  • En environnement dev, la devise est OUV, pas XOF.
  • Le merchant_key n'est pas le client_id.
  • Il n'existe pas de champ phone_number à l'initiation : le client saisit son numéro sur payment_url.
  • Le retour sur return_url ne prouve pas le paiement. Seule la notification ou transactionstatus fait foi.

Exemple minimal

1type OmInit = { pay_token: string; payment_url: string; notif_token: string };2 3async function getOrangeToken(): Promise<string> {4  const basic = Buffer.from(process.env.ORANGE_CLIENT_ID + ":" + process.env.ORANGE_CLIENT_SECRET).toString("base64");5  const res = await fetch("https://api.orange.com/oauth/v3/token", {6    method: "POST",7    headers: { Authorization: "Basic " + basic, "Content-Type": "application/x-www-form-urlencoded" },8    body: "grant_type=client_credentials",9  });10  const data = (await res.json()) as { access_token: string };11  return data.access_token;12}13 14export async function initOrangePayment(orderId: string, amount: number): Promise<OmInit> {15  const token = await getOrangeToken();16  const res = await fetch("https://api.orange.com/orange-money-webpay/dev/v1/webpayment", {17    method: "POST",18    headers: { Authorization: "Bearer " + token, "Content-Type": "application/json" },19    body: JSON.stringify({20      merchant_key: process.env.ORANGE_MERCHANT_KEY,21      currency: "OUV",22      order_id: orderId,23      amount,24      return_url: process.env.APP_URL + "/paiement/retour",25      cancel_url: process.env.APP_URL + "/paiement/annule",26      notif_url: process.env.APP_URL + "/api/webhooks/orange",27      lang: "fr",28      reference: "Boutique",29    }),30  });31  if (res.status !== 201) throw new Error("Orange Money " + res.status);32  return res.json();33}

Variables d'environnement

  • ORANGE_CLIENT_ID
  • ORANGE_CLIENT_SECRET
  • ORANGE_MERCHANT_KEY
  • APP_URL