Skip to content

Mobile money ​

Paiement mobile money (MTN MoMo, Airtel, connecteur sandbox) initié depuis le checkout hébergé ou embed. Le SI ministry ne collecte pas le numéro de téléphone, ne choisit pas l'opérateur et n'appelle pas les routes de collecte du checkout citoyen.

Audience ​

ActeurAutoriséInterdit
Backend SI (sk_ ministry / eGouv)POST /checkout/sessions, webhooks, GET / cancel / verify-completionCollecte téléphone, choix d'offre, offers / attempts
Checkout Epayment (hosted / SDK)Affiche les offres, saisit le numéro, déclenche la collecteClé sk_

La collecte (push USSD, instructions citoyen, next_action) est interne au checkout Epayment. Elle n'appartient pas au contrat HTTP ministry documenté dans Référence API.

Pourquoi : le SI ne doit pas se coupler au comportement d'un rail (push USSD, redirect, QR, etc.). Epayment abstrait le traitement de paiement : demain un autre prestataire mobile money ou un schéma GIMAC peut remplacer le push actuel sans forcer un nouveau contrat côté SI. Un « direct push » depuis le backend ministry créerait un contrat fort (téléphone + offre + séquence d'attempts) incompatible avec ce swap.

Parcours SI supportés : checkout hébergé ou checkout embarqué + webhook / verify-completion.

Offres côté citoyen ​

Sur la page checkout (hors API ministry), le citoyen voit des offres. Identifiants observables en recette / support :

IdentifiantLibellé typiqueCanal
momoMTN MoMoMobile money
airtelAirtel MoneyMobile money
fakePaiement testSandbox (recette uniquement)
cash_agencyAgenceAgence (voir Paiement agence)
paddleCarteCarte (voir Paiement par carte ; devise session compatible uniquement)

Le SI ne sélectionne pas ces identifiants et ne construit pas de corps de collecte. Frais de service éventuels : le webhook et order_id restent basés sur le montant dû initial (voir Frais de service).

Connecteur sandbox (Paiement test) ​

Offre checkout fake, libellé citoyen Paiement test. Disponible uniquement avec une clé sk_test_* (environnement sandbox). Aucun débit réel : le numéro saisi sur le checkout (hosted ou embed) pilote le résultat simulé.

Règle : les quatre derniers chiffres du numéro mobile money (format E.164, ex. +242…) déterminent l'issue du collect.

Suffixe (4 derniers chiffres)Résultat simuléExemple E.164Webhook attendu (session MM)
0002Refus+242066000002checkout.failed (collect.rejected)
0003Timeout+242066000003checkout.failed (timeout collect)
Tout autre suffixeAccepté+242061234567checkout.completed (paid: true)

Exemples de recette côté opérateur (UI checkout, pas appel SI) :

  1. Succès : saisir 066 000 000 (ou tout numéro ne se terminant pas par 0002 / 0003) sur l'offre Paiement test.
  2. Refus : saisir un numéro se terminant par 0002 (ex. 066 000 002).
  3. Timeout : saisir un numéro se terminant par 0003 (ex. 066 000 003).

Le SI ministry ne transmet pas ce numéro. Pour valider les webhooks côté backend, l'opérateur ouvre checkout_url (ou l'embed) et exécute ces trois scénarios manuellement.

Voir aussi Recette ministry (scénarios MM sandbox).

Collecte (orchestrée par le checkout) ​

Après création de session, le citoyen choisit une offre mobile money et saisit son numéro sur le checkout Epayment. Epayment déclenche alors la collecte auprès du connecteur (souvent une demande d'approbation sur le téléphone) et pilote l'attente / le timeout.

Le SI ministry :

  • ne poste pas de numéro de paiement ;
  • n'appelle pas de route …/attempts avec sk_ ;
  • ne parse pas de next_action métier ;
  • attend checkout.completed ou checkout.failed (et verify-completion en embed).

Délai d'approbation ​

Pendant un collect MM en attente de validation citoyen sur le téléphone :

AspectValeur
Attente typiqueDemande USSD / push sur le téléphone
Délai d'approbation (défaut)90 s
À expiration sans approbationSession failed ; webhook checkout.failed avec failure_code: collect.approval_timeout

Message citoyen (FR) : « Délai de confirmation dépassé. Aucun montant débité. Réessayez. »

Échecs et webhook checkout.failed ​

Payload checkout.failed :

ChampTypeDescription
session_idstringSession clôturée
order_idstringDossier ministry
notice_idUUIDNotice
paidfalseToujours false
failure_codestring | nullCode normalisé (max 64 car.)
metadatarecord | nullEcho session
service_code / service_labeloptionnelsSi service résolu

Codes failure_code documentés ​

CodeSignification
collect.rejectedRefus citoyen ou rejet PSP
collect.approval_timeoutDélai d'approbation MM dépassé
collect.abandonedAbandon (navigation, timeout session collect)
collect.unavailableConnecteur indisponible
collect.exceptionErreur technique collect

Idempotence webhook côté SI : (session_id, checkout.failed).

Après un échec MM ​

Session terminale failed : le checkout hébergé ne permet pas de réessayer sur la même session. Le SI crée une nouvelle session (Idempotency-Key neuve, même order_id autorisé). Même payment_ref si la notice est réutilisée.

Pour le paiement par carte, refus et timeout ne clôturent pas la session : voir Paiement par carte.

Connecteur indisponible ​

Sur le checkout, une collecte peut aboutir à une indisponibilité connecteur (message citoyen). L'offre agence peut rester disponible sur la même session si configurée. Le SI réagit via webhook ou nouvelle session selon le cas.

Confirmation ministry ​

Chemin principal : webhook checkout.completed (paid: true).

Mode embed : compléter par POST /checkout/sessions/verify-completion pour UX synchrone ; conserver le webhook comme file durable.

Le SI n'appelle jamais directement un PSP. Toute confirmation passe par Epayment.

Plateforme d'orchestration de paiement DPI. Les fonds ne transitent pas par Epayment.