Aller au contenu

Checkout Mobile Money

Ce qui se passe entre l'invite et la confirmation, et comment adapter votre intégration.

Un paiement Mobile Money est confirmé par une personne sur son téléphone : il prend du temps et peut échouer pour des raisons humaines. Ce guide montre comment gérer l'attente, les échecs et les nouvelles tentatives ; les appels d'API se trouvent dans le Démarrage rapide Paiements.

Déroulement réel

Quatre acteurs interviennent entre votre requête et l'argent. Seul le premier vous appartient.

Les trois étapes intermédiaires peuvent prendre de dix secondes à plusieurs minutes. Vous n'en contrôlez aucune. Votre interface doit le présenter clairement au lieu de rester bloquée sur un indicateur de chargement.

Le numéro de téléphone détermine l'opérateur

Vous n'indiquez pas à Wajub quel opérateur doit effectuer le débit. Vous envoyez le numéro du client au format E.164 et Wajub en déduit l'opérateur.

curl https://api.wajub.com/payments \
  -H "Authorization: sk_test.xxxxxxxxxxxxxxxx…" \
  -H "Idempotency-Key: order-9041" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 15000,
    "currency": "XAF",
    "customer": {
      "name": "Amina Nkosi",
      "phone": "+237670000000",
      "email": "amina@example.com"
    },
    "description": "Order #9041",
    "reference": "order-9041",
    "callback": "https://shop.example.com/orders/9041/return"
  }'

La réponse contient authorization_url. Redirigez le client vers cette URL. Wajub affiche le choix de l'opérateur, les instructions de l'invite et l'écran de résultat en anglais ou en français selon votre paramètre régional.

Les montants possèdent un plafond plus bas que prévu

Mobile Money limite un débit à 500 000 XAF, et au même montant en XOF. L'API accepte toutefois les paiements jusqu'à 2 000 000 XAF. Ces deux plafonds diffèrent. Une charge au-dessus de 500 000 XAF est refusée avec un 422 et le client doit choisir un montant plus faible ou un autre moyen de paiement.

MontantExpérience du client
Jusqu'à 500 000 XAFUne invite, un code PIN
Au-dessus de 500 000 XAFErreur 422 à la charge, aucune invite
Au-dessus de 2 000 000 XAFErreur 422 à la création, avec le plafond dans errors.amount

Votre page pendant la confirmation

Le client quitte votre site le temps de trouver son téléphone. À son retour, le paiement possède très souvent encore le statut processing.

Ne présentez pas ce statut comme une erreur et n'interrogez pas l'API en boucle serrée. Effectuez une seule requête au chargement de la page, affichez honnêtement l'état et laissez le webhook gérer la suite. La route de retour est détaillée dans Accepter un paiement, guide complet. Elle doit gérer les trois cas suivants.

Statut au retourMessage à afficher
succeededConfirmation et prochaine étape
pending, processing, partialL'invite a été envoyée, la confirmation fonctionne encore et vous enverrez un e-mail
failed, expired, cancelledAucun débit n'a été effectué, avec un bouton pour réessayer

La page d'attente est souvent mal conçue. Elle doit expliquer la réalité : l'invite a été envoyée, sa validation sur le téléphone fonctionne encore et la commande se mettra à jour automatiquement. Envoyez ensuite la confirmation par e-mail à la réception du webhook afin que personne ne doive rester sur cette page.

Les causes d'échec et le message à afficher

Un échec provient généralement d'une personne ou du réseau, pas d'un bug. Le paiement contient une valeur failure_reason que vous pouvez enregistrer. Cette raison désigne un problème sur lequel une personne peut agir.

Problème rencontréMessage à afficher au client
Solde insuffisant dans le portefeuilleRechargez votre portefeuille et réessayez, la commande est toujours disponible
Invite refuséeAucun débit n'a été effectué, réessayez lorsque vous êtes prêt
Délai de l'invite dépasséL'opérateur n'a pas reçu de réponse à temps, réessayez
Numéro incorrect ou non pris en chargeVérifiez le numéro au format international complet
Opérateur indisponibleProposez un autre opérateur au lieu d'une nouvelle tentative avec le même

`failure_reason` est un diagnostic, pas une énumération

De nouvelles valeurs peuvent apparaître sans préavis. Basez les branches de votre code sur status. Utilisez failure_reason dans les logs et pour choisir une phrase compréhensible dans une table qui prévoit une valeur par défaut. Consultez Cycle de vie d'un paiement pour en savoir plus.

Une nouvelle tentative crée un nouveau paiement

Vous ne pouvez pas renvoyer une invite pour un paiement existant. Un paiement échoué ou expiré est terminé. Réessayer signifie en créer un autre pour la même commande.

Cette règle entraîne une conséquence importante. Le nouveau paiement exige une nouvelle clé d'idempotence. La réutilisation de l'ancienne clé renvoie l'ancien paiement échoué au lieu d'ouvrir une nouvelle tentative.

curl https://api.wajub.com/payments \
  -H "Authorization: sk_test.xxxxxxxxxxxxxxxx…" \
  -H "Idempotency-Key: order-9041-attempt-2" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 15000,
    "currency": "XAF",
    "customer": { "phone": "+237670000000" },
    "reference": "order-9041",
    "callback": "https://shop.example.com/orders/9041/return"
  }'

La commande pointe désormais vers le paiement le plus récent. Conservez les anciens identifiants quelque part si vous souhaitez disposer d'un historique complet. Wajub ne relie pas les différentes tentatives d'une même commande.

Prise en charge des frais

Par défaut, les frais sont déduits du montant que vous recevez. Définissez bearer sur customer pour les ajouter au montant. La page hébergée affiche alors clairement le montant, les frais et le total réellement débité.

Facturer les frais au client
{
"amount": 15000,
"currency": "XAF",
"customer": {
"phone": "+237670000000"
},
"bearer": "customer"
}

Le client confirme le total sur son téléphone. Vous devez donc faire ce choix avant l'envoi de l'invite. Il ne peut pas être modifié ensuite.

Tester chaque cas sans opérateur

Dans la sandbox, les six derniers chiffres du numéro déterminent le résultat. Le préfixe sélectionne le pays et l'opérateur, tandis que le suffixe détermine le résultat. Tous les codes PIN sont acceptés.

SuffixeRésultatWebhook reçu
000000Le client confirmepayment.succeeded
000001Solde insuffisant dans le portefeuilleAucun. La charge répond 422 et le paiement reste pending
000002L'opérateur refusepayment.failed
000003L'opérateur ne répond paspayment.failed
000004Le client refuse l'inviteAucun. Le paiement finit cancelled
000009Le paiement réussit, mais tous les remboursements échouentpayment.succeeded

Pour MTN au Cameroun, le préfixe +23767 suivi de 000001 donne +237670000001. Ce numéro reproduit systématiquement un échec pour fonds insuffisants. Tous les préfixes de pays et d'opérateurs figurent dans Scénarios de test.

Retenez le numéro qui se termine par 000009. C'est le seul moyen de tester la gestion d'un échec de remboursement, autrement impossible à déclencher volontairement.

Suivez le paiement pendant son exécution

Ouvrez Konsole › Webhooks › Événements avant de déclencher un paiement de test. La réponse de l'opérateur et le résultat final apparaissent au fur et à mesure.

Que pensez-vous de ce contenu ?