API MolediPay
Encaissez et payez par mobile money dans 21 pays africains avec une seule intégration. Utilisez l'orchestrateur (MolediPay choisit la passerelle et bascule en cas de panne) ou appelez directement la passerelle de votre choix.
Présentation
Orchestrateur
/v1/deposits, /v1/links, /v1/payouts : MolediPay choisit la passerelle selon le routage de votre application et bascule si elle refuse.
PawaPay
/v1/pawapay/… : 13 pays, opérateur détecté automatiquement.
Swychr
/v1/swychr/… : 18 pays, opérateur à préciser quand le pays en a plusieurs.
Même format partout
Mêmes champs, même réponse, mêmes webhooks signés, quelle que soit l'adresse utilisée.
Authentification
Toutes les requêtes portent la clé API de votre application. URL de base : https://moledipay.com/v1.
Authorization: Bearer mp_votre_cle_api
Sécurité
- HTTPS obligatoire ; clés API stockées uniquement sous forme d'empreinte.
- Les notifications des passerelles ne sont jamais crues sur parole : MolediPay redemande le statut à la passerelle avant toute mise à jour.
- Webhooks sortants signés (HMAC-SHA256 + horodatage) ; un statut final ne change plus jamais.
- 300 requêtes par minute et par application ; une application suspendue est refusée.
Toutes les adresses
| Opération | Orchestrateur | PawaPay uniquement | Swychr uniquement |
|---|---|---|---|
| Encaissement direct | POST/v1/deposits | POST/v1/pawapay/deposits | POST/v1/swychr/deposits |
| Lien de paiement | POST/v1/links | POST/v1/pawapay/links | POST/v1/swychr/links |
| Retrait | POST/v1/payouts | POST/v1/pawapay/payouts | POST/v1/swychr/payouts |
| Moyens de paiement | GET/v1/methods | GET/v1/pawapay/methods | GET/v1/swychr/methods |
| Soldes | GET/v1/balance | GET/v1/pawapay/balance | GET/v1/swychr/balance |
| Consulter un paiement | GET/v1/payments/{id ou reference} | ||
| Générique | POST/v1/payments — tous les champs dans le corps (type, mode, provider). | ||
Orchestrateur : comment il choisit
- Il détermine le pays (
country, ou l'indicatif du numéro) et l'opérateur (network, ou détection à partir du numéro). - Il prend les passerelles dans l'ordre défini pour ce pays, cet opérateur et cette opération : règle de votre application, sinon de la plateforme, sinon la moins chère.
- Il écarte celles hors service (surveillance toutes les 5 minutes) et place en dernier celles dégradées.
- Il essaie la première ; si elle refuse immédiatement, il essaie la suivante. Les essais sont listés dans
attempts.
Champs
| Champ | Description |
|---|---|
amountobligatoire | Montant dans la devise du pays (XAF, XOF, KES…). |
referenceobligatoire | Votre identifiant unique (100 caractères max). La même référence renvoie le paiement existant, sans doublon. |
phone | Numéro du client ou du bénéficiaire, avec ou sans indicatif. Obligatoire sauf pour un lien PawaPay. |
country | Code ISO (CM, CI, SN…). Facultatif si le numéro contient l'indicatif. |
network | Opérateur : MTN, ORANGE, WAVE, MOOV, AIRTEL, MPESA… Détecté quand c'est possible, exigé sinon. |
currency | Facultatif : devise attendue, vérifiée. |
customer_name, customer_email | Facultatifs ; nom du bénéficiaire recommandé pour un retrait. |
description | Motif affiché au client quand la passerelle le permet. |
callback_url | URL https recevant le webhook de ce paiement (sinon celle de l'application). |
return_url | Liens : page où revient le client après paiement. |
Encaissement orchestré
POST/v1/deposits
curl -X POST https://moledipay.com/v1/deposits \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"country":"CM","amount":5000,"phone":"670000000","reference":"CMD-1042","description":"Commande 1042"}'
Lien de paiement orchestré
POST/v1/links — la passerelle est choisie par la règle du pays pour les liens ; la réponse contient payment_url.
curl -X POST https://moledipay.com/v1/links \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"country":"CI","amount":10000,"phone":"0707000000","customer_name":"Awa Koné","reference":"CMD-1043"}'
Retrait orchestré
POST/v1/payouts — refusé (INSUFFICIENT_BALANCE) si aucune passerelle possible n'a assez de solde pour votre application dans ce pays, frais compris.
curl -X POST https://moledipay.com/v1/payouts \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"country":"SN","network":"WAVE","amount":20000,"phone":"771234567","customer_name":"Moussa Diop","reference":"RETRAIT-88"}'
Retraits groupés (tout-ou-rien)
POST/v1/payouts/batch — plusieurs retraits (jusqu'à 20) envoyés ensemble. MolediPay vérifie d'abord que chaque retrait est couvert par un portefeuille de votre application, frais compris et en cumulant les parts qui tombent sur le même portefeuille. Si une seule part n'est pas couverte, tout le lot est refusé (BATCH_NOT_COVERED) et aucun retrait n'est envoyé. Chaque retrait garde sa propre reference ; le lot entier partage batch_reference (idempotent).
curl -X POST https://moledipay.com/v1/payouts/batch \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"reference":"RETRAIT-GROUPE-12","items":[
{"reference":"RG12-A","country":"CM","network":"MTN","amount":10000,"phone":"670000000","customer_name":"Awa"},
{"reference":"RG12-B","country":"CM","network":"MTN","amount":1000,"phone":"670000000","customer_name":"Awa"}]}'
Node.js
const res = await fetch("https://moledipay.com/v1/deposits", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.MOLEDIPAY_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ country: "CM", amount: 5000, phone: "670000000", reference: orderId }),
});
const payment = await res.json();
if (!res.ok && !payment.id) throw new Error(`${payment.code} : ${payment.error}`);
PHP
$ch = curl_init('https://moledipay.com/v1/deposits');
curl_setopt_array($ch, [
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('MOLEDIPAY_API_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['country' => 'CM', 'amount' => 5000, 'phone' => '670000000', 'reference' => $orderId]),
]);
$payment = json_decode(curl_exec($ch), true);
Python
import os, requests
payment = requests.post("https://moledipay.com/v1/deposits",
headers={"Authorization": f"Bearer {os.environ['MOLEDIPAY_API_KEY']}"},
json={"country": "CM", "amount": 5000, "phone": "670000000", "reference": order_id}, timeout=30).json()
Réponse
HTTP/1.1 201 Created
{
"id": "4806bd66-9565-48d6-885f-59c34d021832", "reference": "CMD-1042",
"type": "deposit", "mode": "direct", "routing": "auto",
"provider": "pawapay", "operator": "MTN", "network": "MTN_MOMO_CMR",
"status": "PENDING", "amount": 5000, "fee": 87.5, "fee_source": "grid", "currency": "XAF", "country": "CM",
"phone": "237670000000", "payment_url": null, "failure_reason": null,
"attempts": [ { "provider": "pawapay", "outcome": "PENDING", "provider_status": "ACCEPTED" } ],
"created_at": "2026-09-28T10:00:00.000Z"
}
201: créé ·200+"idempotent": true: référence déjà utilisée ·422+"status": "FAILED": refusé par la ou les passerelles.routing:auto(orchestrateur) oudirect(passerelle imposée).fee: frais estimés selon la grille ;fee_source: "actual"quand ils ont été relevés chez la passerelle.
PawaPay
Ces adresses utilisent uniquement PawaPay, sans bascule vers une autre passerelle. L'opération est fixée par l'adresse : n'envoyez pas type, mode ni provider.
| Adresse | Rôle |
|---|---|
| POST/v1/pawapay/deposits | Encaissement direct : demande de validation envoyée sur le téléphone du client. |
| POST/v1/pawapay/links | Lien de paiement à transmettre au client. |
| POST/v1/pawapay/payouts | Retrait : envoi d'argent vers un compte mobile money. |
| GET/v1/pawapay/methods | Pays, opérateurs et frais PawaPay activés pour votre application. |
| GET/v1/pawapay/balance | Soldes de votre application chez PawaPay, par pays. |
Particularités PawaPay
- 13 pays. L'opérateur est détecté automatiquement à partir du numéro ;
networkest facultatif (MTN,ORANGE, ou le code PawaPay, ex.MTN_MOMO_CMR). - Numéro avec ou sans indicatif ; PawaPay le valide et le normalise.
- Lien : page de paiement PawaPay hébergée, téléphone facultatif (le client choisit son opérateur sur la page), retour vers
return_url. Un lien non utilisé est clôturé enFAILEDau bout d'une heure. - Montants sans décimales pour les francs CFA ; limites propres à chaque opérateur (tableau ci-dessous).
- Frais : frais de l'opérateur + 1 % PawaPay, déduits du montant encaissé ; frais de retrait ajoutés au montant envoyé.
Encaissement direct
curl -X POST https://moledipay.com/v1/pawapay/deposits \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"country":"CM","amount":5000,"phone":"670000000","reference":"CMD-2001","description":"Commande 2001"}'
Lien de paiement
curl -X POST https://moledipay.com/v1/pawapay/links \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"country":"CM","amount":5000,"reference":"CMD-2002","description":"Commande 2002","return_url":"https://monsite.com/merci"}'
Retrait
curl -X POST https://moledipay.com/v1/pawapay/payouts \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"country":"CM","amount":10000,"phone":"690000000","customer_name":"Paul Mbarga","reference":"RET-2003"}'
Pays, opérateurs et valeurs de network
| Pays | Opérateur | network | Devise | Encaissement | Retrait | Limites (par opération) |
|---|---|---|---|---|---|---|
| Cameroun CM · +237 | MTN Mobile Money | MTN_MOMO_CMR | XAF | ✓ | ✓ | 1 – 1000000 |
| Orange Money | ORANGE_CMR | XAF | ✓ | ✓ | 1 – 1000000 | |
| Côte d'Ivoire CI · +225 | MTN Mobile Money | MTN_MOMO_CIV | XOF | ✓ | ✓ | 1 – 2000000 |
| Orange Money | ORANGE_CIV | XOF | ✓ | ✓ | 1 – 1500000 | |
| Sénégal SN · +221 | Free Money / YAS | FREE_SEN | XOF | ✓ | ✓ | 5 – 2000000 |
| Orange Money | ORANGE_SEN | XOF | ✓ | ✓ | 2 – 2000000 | |
| Bénin BJ · +229 | Moov Money | MOOV_BEN | XOF | ✓ | ✓ | 100 – 2000000 |
| MTN Mobile Money | MTN_MOMO_BEN | XOF | ✓ | ✓ | 1 – 2000000 | |
| Gabon GA · +241 | Airtel Money | AIRTEL_GAB | XAF | ✓ | ✓ | 100 – 500000 |
| Congo-Brazzaville CG · +242 | Airtel Money | AIRTEL_COG | XAF | ✓ | ✓ | 10 – 1500000 |
| MTN Mobile Money | MTN_MOMO_COG | XAF | ✓ | ✓ | 1 – 2000000 | |
| RD Congo CD · +243 | Airtel Money | AIRTEL_COD | CDF | ✓ | ✓ | 100 – 6250000 |
| Airtel Money | AIRTEL_COD | USD | ✓ | ✓ | 0.1 – 2500 | |
| Orange Money | ORANGE_COD | CDF | ✓ | ✓ | 10 – 1000000 | |
| Orange Money | ORANGE_COD | USD | ✓ | ✓ | 0.01 – 2500 | |
| M-Pesa | VODACOM_MPESA_COD | CDF | ✓ | ✓ | 500 – 1000000 | |
| M-Pesa | VODACOM_MPESA_COD | USD | ✓ | ✓ | 0.5 – 2500 | |
| Kenya KE · +254 | M-Pesa | MPESA_KEN | KES | ✓ | ✓ | 1 – 250000 |
| Ouganda UG · +256 | Airtel Money | AIRTEL_OAPI_UGA | UGX | ✓ | ✓ | 500 – 5000000 |
| MTN Mobile Money | MTN_MOMO_UGA | UGX | ✓ | ✓ | 500 – 5000000 | |
| Rwanda RW · +250 | Airtel Money | AIRTEL_RWA | RWF | ✓ | ✓ | 100 – 1500000 |
| MTN Mobile Money | MTN_MOMO_RWA | RWF | ✓ | ✓ | 5 – 2000000 | |
| Zambie ZM · +260 | MTN Mobile Money | MTN_MOMO_ZMB | ZMW | ✓ | ✓ | 1 – 20000 |
| Zamtel Kwacha | ZAMTEL_ZMB | ZMW | ✓ | ✓ | 1 – 20000 | |
| Mozambique MZ · +258 | M-Pesa | VODACOM_MOZ | MZN | ✓ | ✓ | 0.01 – 125000 |
| Sierra Leone SL · +232 | Orange Money | ORANGE_SLE | SLE | ✓ | ✓ | 1 – 15000 |
Swychr
Ces adresses utilisent uniquement Swychr, sans bascule vers une autre passerelle. L'opération est fixée par l'adresse : n'envoyez pas type, mode ni provider.
| Adresse | Rôle |
|---|---|
| POST/v1/swychr/deposits | Encaissement direct : demande de validation envoyée sur le téléphone du client. |
| POST/v1/swychr/links | Lien de paiement à transmettre au client. |
| POST/v1/swychr/payouts | Retrait : envoi d'argent vers un compte mobile money. |
| GET/v1/swychr/methods | Pays, opérateurs et frais Swychr activés pour votre application. |
| GET/v1/swychr/balance | Soldes de votre application chez Swychr, par pays. |
Particularités Swychr
- 18 pays.
networkest exigé quand le pays a plusieurs opérateurs (sauf au Cameroun, où il est déduit du préfixe). Valeurs : colonnenetworkci-dessous (ex.Wave,Orange,MTN) ou l'opérateur commun (WAVE). - Numéro au format national du pays (colonne « Format »), avec ou sans indicatif.
- Lien : le téléphone du client est obligatoire.
- Frais d'encaissement inclus : le client paie le montant, Swychr crédite montant ÷ (1 + taux). Exemple Cameroun 2,5 % : 10 000 payés → 9 756 crédités.
- Frais de retrait : un pourcentage avec un minimum par pays, prélevé en plus du montant envoyé. Exemple Cameroun 1,5 %, minimum 450 XAF : un retrait de 5 000 coûte 450 (pas 75) ; au-delà de 30 000, c'est 1,5 %. Un retrait échoué est remboursé, frais compris.
Encaissement direct
curl -X POST https://moledipay.com/v1/swychr/deposits \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"country":"CI","network":"WAVE","amount":5000,"phone":"0707000000","customer_name":"Awa Koné","reference":"CMD-3001"}'
Lien de paiement
curl -X POST https://moledipay.com/v1/swychr/links \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"country":"CM","amount":5000,"phone":"690000000","customer_name":"Jean Nkodo","reference":"CMD-3002"}'
Retrait
curl -X POST https://moledipay.com/v1/swychr/payouts \
-H "Authorization: Bearer mp_votre_cle" -H "Content-Type: application/json" \
-d '{"country":"SN","network":"WAVE","amount":20000,"phone":"771234567","customer_name":"Moussa Diop","reference":"RET-3003"}'
Pays, opérateurs et valeurs de network
| Pays | Opérateur | network | Devise | Encaissement | Retrait | Format du numéro |
|---|---|---|---|---|---|---|
| Cameroun CM · +237 | Orange Money | ORANGE | XAF | ✓ | ✓ | 2376XXXXXXXX (9 chiffres) |
| MTN Mobile Money | MTN | XAF | ✓ | ✓ | 2376XXXXXXXX (9 chiffres) | |
| Côte d'Ivoire CI · +225 | Wave | Wave | XOF | ✓ | ✓ | 05XXXXXXXX (10 chiffres) |
| Moov Money | Moov | XOF | ✓ | ✓ | 01XXXXXXXX (10 chiffres) | |
| MTN Mobile Money | MTN | XOF | ✓ | ✓ | 05XXXXXXXX (10 chiffres) | |
| Orange Money | Orange | XOF | ✓ | ✓ | 07XXXXXXXX (10 chiffres) | |
| Sénégal SN · +221 | Orange Money | Orange | XOF | ✓ | ✓ | 7XXXXXXXXX (9 chiffres) |
| Free Money / YAS | Free | XOF | ✓ | ✓ | 7XXXXXXXXX (9 chiffres) | |
| Wave | Wave | XOF | ✓ | ✓ | 7XXXXXXXXX (9 chiffres) | |
| Bénin BJ · +229 | MTN Mobile Money | MTN | XOF | ✓ | ✓ | 6XXXXXXX (8 chiffres) |
| Moov Money | Moov | XOF | ✓ | ✓ | 9XXXXXXX (8 chiffres) | |
| Togo TG · +228 | T-Money | Tmoney | XOF | ✓ | ✓ | 9XXXXXXX (8 chiffres) |
| Moov Money | Moov | XOF | ✓ | ✓ | 9XXXXXXX (8 chiffres) | |
| Burkina Faso BF · +226 | Moov Money | Moov | XOF | ✓ | ✓ | 7XXXXXXX (8 chiffres) |
| Orange Money | Orange | XOF | ✓ | ✓ | 7XXXXXXX (8 chiffres) | |
| TouchCash | TouchCash | XOF | ✓ | ✓ | 7XXXXXXX (8 chiffres) | |
| Mali ML · +223 | Orange Money | Orange | XOF | ✓ | ✓ | 7XXXXXXX (8 chiffres) |
| Moov Money | Moov | XOF | ✓ | ✓ | 7XXXXXXX (8 chiffres) | |
| Wave | Wave | XOF | ✓ | ✓ | 7XXXXXXX (8 chiffres) | |
| Niger NE · +227 | Airtel Money | Airtel | XOF | ✓ | ✓ | — |
| Guinée GN · +224 | MTN Mobile Money | MTN | GNF | ✓ | ✓ | 6XXXXXXXX (9 chiffres) |
| Orange Money | Orange | GNF | ✓ | ✓ | 6XXXXXXXX (9 chiffres) | |
| Gabon GA · +241 | Airtel Money | Airtel | XAF | ✓ | ✓ | 09XXXXXXX (9 chiffres) |
| Moov Money | Moov | XAF | ✓ | ✓ | 06XXXXXXX (9 chiffres) | |
| Congo-Brazzaville CG · +242 | MTN Mobile Money | MTN | XAF | ✓ | ✓ | — |
| Airtel Money | Airtel | XAF | ✓ | ✓ | — | |
| RD Congo CD · +243 | Airtel Money | AIRTEL | CDF | ✓ | ✓ | 8XXXXXXXX (9 chiffres) |
| Afrimoney | AFRIMONEY | CDF | ✓ | ✓ | 8XXXXXXXX (9 chiffres) | |
| M-Pesa | Mpesa | CDF | ✓ | ✓ | 8XXXXXXXX (9 chiffres) | |
| Orange Money | Orange | CDF | ✓ | ✓ | 8XXXXXXXX (9 chiffres) | |
| Kenya KE · +254 | M-Pesa | MPESA | KES | ✓ | ✓ | 7XXXXXXXXX (9 chiffres) |
| Airtel Money | AIRTEL | KES | ✓ | ✓ | 7XXXXXXXXX (9 chiffres) | |
| Ouganda UG · +256 | MTN Mobile Money | MTN | UGX | ✓ | ✓ | 7XXXXXXXXX (9 chiffres) |
| Airtel Money | AIRTEL | UGX | ✓ | ✓ | 7XXXXXXXXX (9 chiffres) | |
| Tanzanie TZ · +255 | T-Pesa (TTCL) | TTCL | TZS | ✓ | ✓ | — |
| M-Pesa | MPESA | TZS | ✓ | ✓ | 7XXXXXXXX (9 chiffres) | |
| Airtel Money | AIRTEL | TZS | ✓ | ✓ | 6XXXXXXXX (9 chiffres) | |
| Tigo Pesa / Mixx | TIGO PESA | TZS | ✓ | ✓ | 6XXXXXXXX (9 chiffres) | |
| Ezy Pesa | EZY PESA | TZS | ✓ | ✓ | XXXXXXXXX (9 chiffres) | |
| Halo Pesa | HALO PESA | TZS | ✓ | ✓ | 6XXXXXXXX (9 chiffres) | |
| Rwanda RW · +250 | MTN Mobile Money | MTN | RWF | ✓ | ✓ | — |
| Airtel Money | Airtel | RWF | ✓ | ✓ | — | |
| Ghana GH · +233 | Telecel Cash | Vodafone | GHS | ✓ | ✓ | 233XXXXXXXXX (9 chiffres) |
| MTN Mobile Money | MTN | GHS | ✓ | ✓ | 233XXXXXXXXX (9 chiffres) | |
| Airtel Money | Airtel | GHS | ✓ | ✓ | 233XXXXXXXXX (9 chiffres) | |
| Nigeria NG · +234 | Virement bancaire | All Banks Transfer | NGN | ✓ | ✓ | 234XXXXXXXXXX (10 chiffres) |
Consulter un paiement
GET/v1/payments/{id ou reference} — s'il est en attente, MolediPay interroge la passerelle avant de répondre. À utiliser en secours ; le webhook reste la méthode normale.
Moyens de paiement
GET/v1/methods (ou /v1/pawapay/methods, /v1/swychr/methods) — pays et opérateurs activés pour votre application, avec pour chaque opération les passerelles dans l'ordre de routage, leur état et leurs frais.
[ { "country": "CM", "name": "Cameroun", "operators": [
{ "operator": "ORANGE", "name": "Orange Money",
"deposit": { "available": true, "providers": [
{ "provider": "pawapay", "network": "ORANGE_CMR", "currency": "XAF", "status": "UP",
"fees": { "deposit_percent": 1.77, "payout_percent": 1, "payout_min": 0, "payout_fixed": 0, "inclusive": false } },
{ "provider": "swychr", "network": "ORANGE", "currency": "XAF", "status": "UP",
"fees": { "deposit_percent": 2.5, "payout_percent": 1.5, "payout_min": 450, "payout_fixed": 0, "inclusive": true } } ] },
"payout": { "available": true, "providers": [ … ] } } ] } ]
Soldes
GET/v1/balance (ou /v1/pawapay/balance, /v1/swychr/balance) — un solde par portefeuille (passerelle + pays + devise). L'argent encaissé via une passerelle dans un pays se retire depuis cette même passerelle, dans ce même pays.
[ { "provider": "pawapay", "country": "CM", "currency": "XAF",
"collected": 150000, "fees": 2625, "paid_out": 50000, "reserved": 0, "available": 97375, "withdrawable": 96125 } ]
available: encaissé − frais − payé − retraits en cours.withdrawable: plus gros retrait possible, ses propres frais déduits (minimums compris).
Frais
- Encaissement : déduit du montant encaissé. Chez Swychr il est inclus : crédité = montant ÷ (1 + taux).
- Retrait : ajouté au montant envoyé et prélevé sur votre solde. Il peut comporter un minimum : chez Swychr au Cameroun, 1,5 % avec un minimum de 450 XAF. Un retrait de 1 000 XAF coûte donc 450 XAF de frais, et il faut au moins 451 XAF de solde pour retirer 1 XAF.
- Les taux appliqués à votre application sont renvoyés par
/v1/methods.
Webhooks
À chaque changement de statut, MolediPay envoie un POST JSON à l'URL de webhook de votre application (ou au callback_url du paiement).
POST https://votre-site.com/webhooks/moledipay
X-MolediPay-Event: payment.updated
X-MolediPay-Delivery: 1289
X-MolediPay-Timestamp: 1790343528
X-MolediPay-Signature: 5f2b1c…
{ "event": "payment.updated", "created_at": "…", "data": { "id": "…", "reference": "CMD-1042", "status": "SUCCESSFUL", "amount": 5000, "fee": 87.5, "provider": "pawapay", … } }
- Répondez
2xxen moins de 15 secondes, puis traitez en arrière-plan. - Sans
2xx, nouvelles tentatives pendant environ 12 heures (8 essais). - Traitez chaque événement une seule fois (clé :
data.id+data.status).
Vérifier la signature
Signature = HMAC-SHA256 hexadécimal de {timestamp}.{corps brut} avec votre secret whsec_…. Rejetez toute signature invalide ou tout horodatage de plus de 5 minutes.
import crypto from "node:crypto";
app.post("/webhooks/moledipay", express.raw({ type: "application/json" }), (req, res) => {
const ts = req.get("X-MolediPay-Timestamp"), sig = req.get("X-MolediPay-Signature") || "";
const expected = crypto.createHmac("sha256", process.env.MOLEDIPAY_WEBHOOK_SECRET).update(`${ts}.${req.body}`).digest("hex");
const ok = Math.abs(Date.now() / 1000 - Number(ts)) < 300 && expected.length === sig.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
if (!ok) return res.status(401).end();
res.status(200).end();
const event = JSON.parse(req.body);
});
<?php
$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_MOLEDIPAY_TIMESTAMP'] ?? ''; $sig = $_SERVER['HTTP_X_MOLEDIPAY_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $ts . '.' . $raw, getenv('MOLEDIPAY_WEBHOOK_SECRET'));
if (abs(time() - (int) $ts) > 300 || !hash_equals($expected, $sig)) { http_response_code(401); exit; }
http_response_code(200);
$event = json_decode($raw, true);
import hmac, hashlib, time
def verify(raw_body: bytes, ts: str, sig: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
return abs(time.time() - int(ts)) < 300 and hmac.compare_digest(expected, sig)
Statuts
PENDING | En attente de validation par le client ou de confirmation de la passerelle. |
SUCCESSFUL | Argent reçu (encaissement) ou envoyé (retrait). Définitif. |
FAILED | Refusé, annulé ou expiré (voir failure_reason). Définitif. |
Erreurs
Format : { "error": "message", "code": "CODE", "details": … }
| HTTP | code | Signification |
|---|---|---|
| 401 | UNAUTHORIZED | Clé API absente ou invalide. |
| 403 | APP_SUSPENDED | Application suspendue. |
| 403 | METHOD_NOT_ENABLED | Passerelle non activée pour ce pays sur votre application. |
| 400 | INVALID_REQUEST | Champs manquants ou invalides (details). |
| 400 | COUNTRY_REQUIRED | Pays impossible à déduire. |
| 422 | NETWORK_REQUIRED | Opérateur impossible à déduire (details.operators). |
| 422 | NO_ROUTE | Aucune passerelle disponible pour ce pays, cet opérateur et cette opération. |
| 422 | INVALID_PAYMENT | Numéro ou opérateur invalide pour ce pays. |
| 422 | INVALID_CURRENCY | Devise différente de celle du pays. |
| 422 | AMOUNT_OUT_OF_RANGE | Montant hors limites de l'opérateur. |
| 422 | INSUFFICIENT_BALANCE | Retrait supérieur au solde disponible, frais compris. |
| 429 | RATE_LIMITED | Plus de 300 requêtes par minute. |
| 404 | NOT_FOUND | Paiement introuvable. |
Couverture complète
Lue en direct chez les passerelles. La colonne « Opérateur » donne la valeur network pour l'orchestrateur ; les autres colonnes, la valeur propre à chaque passerelle.
| Pays | Opérateur · network (orchestrateur) | PawaPay · network | Swychr · network |
|---|---|---|---|
| Cameroun CM · +237 · XAF | MTN Mobile Money MTN | MTN_MOMO_CMRencaissement · retrait | MTNencaissement · retrait |
| Orange Money ORANGE | ORANGE_CMRencaissement · retrait | ORANGEencaissement · retrait | |
| Côte d'Ivoire CI · +225 · XOF | Moov Money MOOV | — | Moovencaissement · retrait |
| MTN Mobile Money MTN | MTN_MOMO_CIVencaissement · retrait | MTNencaissement · retrait | |
| Orange Money ORANGE | ORANGE_CIVencaissement · retrait | Orangeencaissement · retrait | |
| Wave WAVE | — | Waveencaissement · retrait | |
| Sénégal SN · +221 · XOF | Free Money / YAS FREE | FREE_SENencaissement · retrait | Freeencaissement · retrait |
| Orange Money ORANGE | ORANGE_SENencaissement · retrait | Orangeencaissement · retrait | |
| Wave WAVE | — | Waveencaissement · retrait | |
| Bénin BJ · +229 · XOF | Moov Money MOOV | MOOV_BENencaissement · retrait | Moovencaissement · retrait |
| MTN Mobile Money MTN | MTN_MOMO_BENencaissement · retrait | MTNencaissement · retrait | |
| Togo TG · +228 · XOF | Moov Money MOOV | — | Moovencaissement · retrait |
| T-Money TMONEY | — | Tmoneyencaissement · retrait | |
| Burkina Faso BF · +226 · XOF | Moov Money MOOV | — | Moovencaissement · retrait |
| Orange Money ORANGE | — | Orangeencaissement · retrait | |
| TouchCash TOUCHCASH | — | TouchCashencaissement · retrait | |
| Mali ML · +223 · XOF | Moov Money MOOV | — | Moovencaissement · retrait |
| Orange Money ORANGE | — | Orangeencaissement · retrait | |
| Wave WAVE | — | Waveencaissement · retrait | |
| Niger NE · +227 · XOF | Airtel Money AIRTEL | — | Airtelencaissement · retrait |
| Guinée GN · +224 · GNF | MTN Mobile Money MTN | — | MTNencaissement · retrait |
| Orange Money ORANGE | — | Orangeencaissement · retrait | |
| Gabon GA · +241 · XAF | Airtel Money AIRTEL | AIRTEL_GABencaissement · retrait | Airtelencaissement · retrait |
| Moov Money MOOV | — | Moovencaissement · retrait | |
| Congo-Brazzaville CG · +242 · XAF | Airtel Money AIRTEL | AIRTEL_COGencaissement · retrait | Airtelencaissement · retrait |
| MTN Mobile Money MTN | MTN_MOMO_COGencaissement · retrait | MTNencaissement · retrait | |
| RD Congo CD · +243 · CDF | Afrimoney AFRIMONEY | — | AFRIMONEYencaissement · retrait |
| Airtel Money AIRTEL | AIRTEL_CODencaissement · retrait | AIRTELencaissement · retrait | |
| M-Pesa MPESA | VODACOM_MPESA_CODencaissement · retrait | Mpesaencaissement · retrait | |
| Orange Money ORANGE | ORANGE_CODencaissement · retrait | Orangeencaissement · retrait | |
| Kenya KE · +254 · KES | Airtel Money AIRTEL | — | AIRTELencaissement · retrait |
| M-Pesa MPESA | MPESA_KENencaissement · retrait | MPESAencaissement · retrait | |
| Ouganda UG · +256 · UGX | Airtel Money AIRTEL | AIRTEL_OAPI_UGAencaissement · retrait | AIRTELencaissement · retrait |
| MTN Mobile Money MTN | MTN_MOMO_UGAencaissement · retrait | MTNencaissement · retrait | |
| Tanzanie TZ · +255 · TZS | Airtel Money AIRTEL | — | AIRTELencaissement · retrait |
| Ezy Pesa EZYPESA | — | EZY PESAencaissement · retrait | |
| Halo Pesa HALOPESA | — | HALO PESAencaissement · retrait | |
| M-Pesa MPESA | — | MPESAencaissement · retrait | |
| Tigo Pesa / Mixx TIGOPESA | — | TIGO PESAencaissement · retrait | |
| T-Pesa (TTCL) TTCL | — | TTCLencaissement · retrait | |
| Rwanda RW · +250 · RWF | Airtel Money AIRTEL | AIRTEL_RWAencaissement · retrait | Airtelencaissement · retrait |
| MTN Mobile Money MTN | MTN_MOMO_RWAencaissement · retrait | MTNencaissement · retrait | |
| Ghana GH · +233 · GHS | Airtel Money AIRTEL | — | Airtelencaissement · retrait |
| MTN Mobile Money MTN | — | MTNencaissement · retrait | |
| Telecel Cash VODAFONE | — | Vodafoneencaissement · retrait | |
| Nigeria NG · +234 · NGN | Virement bancaire ALLBANKSTRANSFER | — | All Banks Transferencaissement · retrait |
| Zambie ZM · +260 · ZMW | MTN Mobile Money MTN | MTN_MOMO_ZMBencaissement · retrait | — |
| Zamtel Kwacha ZAMTEL | ZAMTEL_ZMBencaissement · retrait | — | |
| Mozambique MZ · +258 · MZN | M-Pesa MPESA | VODACOM_MOZencaissement · retrait | — |
| Sierra Leone SL · +232 · SLE | Orange Money ORANGE | ORANGE_SLEencaissement · retrait | — |
Bonnes pratiques
- Une
referenceunique par paiement, réutilisée en cas de nouvel essai réseau. - N'accordez le service qu'à réception d'un webhook
SUCCESSFULvérifié. - Proposez uniquement les opérateurs renvoyés par
/v1/methods. - Vérifiez
withdrawableavant de proposer un retrait à vos utilisateurs.