Suivre un paiement
Un paiement passe par plusieurs statuts au fil de sa vie. Vous pouvez être prévenu automatiquement (Webhooks, la méthode recommandée) ou l’interroger vous-même.
Les statuts
| Statut | Signification | Que faire ? |
|---|---|---|
PENDING |
Le paiement vient d’être créé, MafPay contacte l’opérateur. | Attendre (très bref). |
PROCESSING |
L’opérateur a le paiement, le client n’a pas encore payé. | Afficher le lien / QR code, attendre. |
SUCCESS |
Payé. L’argent est confirmé par l’opérateur. | Livrer la commande. |
FAILED |
Le paiement a échoué (solde insuffisant, refus…). | Proposer de réessayer. |
CANCELLED |
Le client a annulé. | Proposer de réessayer. |
EXPIRED |
Le délai est dépassé sans paiement. | Proposer de recommencer (nouveau paiement). |
REFUNDED |
Le paiement a été remboursé. | Annuler / marquer la commande remboursée. |
PENDING ──► PROCESSING ──► SUCCESS ──► REFUNDED │ ├──► FAILED │ ├──► CANCELLED │ └──► EXPIRED └──► FAILED, CANCELLED ou EXPIRED (si l'opérateur n'a jamais répondu)Les statuts FAILED, CANCELLED et EXPIRED sont définitifs : un paiement échoué ne redevient jamais réussi. SUCCESS est définitif lui aussi, sauf pour un éventuel remboursement (REFUNDED). Pour réessayer un paiement échoué, créez un nouveau paiement (une nouvelle reference).
Consulter le statut
/api/v1/{endpoint_key}/payments/{reference}/status/curl "$MAFPAY_URL/api/v1/$ENDPOINT_KEY/payments/MAFPAY-W7VOB6J6/status/" \ -H "X-Api-Key: $MAFPAY_PK" \ -H "X-Api-Secret: $MAFPAY_SK"async function getPaymentStatus(reference) { const response = await fetch( `${process.env.MAFPAY_URL}/api/v1/${process.env.MAFPAY_ENDPOINT_KEY}/payments/${reference}/status/`, { headers: { "X-Api-Key": process.env.MAFPAY_PK, "X-Api-Secret": process.env.MAFPAY_SK } } ); const body = await response.json(); if (!response.ok) throw new Error(body.message); return body;}
const payment = await getPaymentStatus("MAFPAY-W7VOB6J6");console.log(payment.status); // SUCCESSdef get_payment_status(reference): response = requests.get( f"{os.environ['MAFPAY_URL']}/api/v1/{os.environ['MAFPAY_ENDPOINT_KEY']}/payments/{reference}/status/", headers={"X-Api-Key": os.environ["MAFPAY_PK"], "X-Api-Secret": os.environ["MAFPAY_SK"]}, timeout=15, ) body = response.json() if not response.ok: raise RuntimeError(body["message"]) return bodyRéponse
{ "transaction_uuid": "dcea6fb6-4786-456f-85cc-0450bdccc0a7", "reference": "MAFPAY-W7VOB6J6", "provider": "WAVE_SN", "environment": "sandbox", "amount": "5000.00", "currency": "XOF", "status": "SUCCESS", "provider_reference": "cos-sandbox-efbbcc6513fe489d9b04", "paid_at": "2026-09-25T13:34:17.612928Z", "expired_at": null, "error_message": null, "created_at": "2026-09-25T13:34:17.515299Z"}| Champ | Signification |
|---|---|
status |
Le statut actuel. |
paid_at |
Date du paiement (rempli si SUCCESS). |
expired_at |
Date d’expiration (rempli si EXPIRED). |
error_message |
Le motif si le paiement a échoué (FAILED), sinon null. |
Si la référence n’existe pas (ou appartient à une autre application, ou à l’autre environnement), vous recevez 404 « Transaction introuvable. ».
Webhook ou interrogation : que choisir ?
| Webhook (notification) | Interroger le statut | |
|---|---|---|
| Principe | MafPay vous appelle dès que ça change | vous demandez régulièrement |
| Réactivité | immédiate | dépend de votre fréquence |
| Charge | aucune | requêtes répétées (attention au quota) |
| Recommandé | oui, en méthode principale | en secours (page de retour du client, rattrapage) |
Le bon usage : recevez les webhooks pour valider les commandes, et servez-vous de l’interrogation pour la page où le client revient (« Vérification de votre paiement… ») ou pour rattraper une notification manquée.
Si vous interrogez en boucle, espacez les requêtes (toutes les 3 à 5 secondes) et arrêtez-vous dès qu’un statut définitif apparaît ou que expires_at est dépassé.