Webhooks
Les webhooks vous notifient en temps réel des changements de statut. Configurez l’URL (HTTPS, publique) et récupérez le secretwhsec_... dans le dashboard, par application (Développeurs → Webhooks, jusqu’à 16 endpoints). Chaque endpoint a un mode : test, live ou les deux. Un événement de test n’est livré qu’aux endpoints test, un événement live qu’aux endpoints live. Sans secret configuré, SahelPay n’envoie aucun webhook.
Événements
Paiements
payment.cancelled figure au catalogue mais un paiement n’a pas de statut « annulé » : un abandon finit en payment.expired.Remboursements et paiement sécurisé
Autres
Format du payload (paiement)
data.idest l’identifiant du paiement SahelPay ;data.reference_idvaut votreclient_reference, ou l’idà défaut.data.metadatane contient quedescriptionetmarketplace: vos métadonnées personnalisées ne sont pas renvoyées. Utilisezclient_referencepour retrouver votre commande.
Headers
Vérification de signature
v1 = hex(HMAC_SHA256(webhook_secret, "<t>.<corps brut>")). Vérifiez toujours sur le corps brut reçu, avant tout parsing JSON.
sahelpay.webhooks.constructEvent() (JS), client.webhooks.construct_event() (Python), $sahelpay->webhooks->constructEvent() (PHP).
Retry automatique
En cas d’échec (réponse non 2xx ou timeout), SahelPay retente avec un backoff exponentiel :
Après 5 tentatives, le webhook est marqué comme
FAILED. Vous pouvez consulter les livraisons et relancer depuis le dashboard ou via l’API (Livraisons).
Un même événement peut arriver plus d’une fois (relance, rejeu) : son id est stable, dédupliquez dessus.
La rotation du secret d’un endpoint est immédiate, sans période de grâce pour
l’ancien secret. Une livraison déjà en transit peut encore porter l’ancien secret ;
chaque nouvelle tentative utilise le secret courant. Coordonnez le changement avec le récepteur : le SDK vérifie le
corps brut avec le secret que vous lui fournissez. Les reprises gardent le même
identifiant d’événement ; dédupliquez-le après vérification de la signature.
Tester les webhooks
webhook.test vers l’URL configurée. Pour recevoir un vrai payment.success ou payment.failed sans appel opérateur, créez un paiement simulé (metadata.sahelpay_mock: true, hosted_checkout: false) puis appelez GET /v1/payments/{id}/status : voir Tests.
Bonnes pratiques
Répondre rapidement
Répondre rapidement
Répondez
200 OK en quelques secondes. Si le traitement est long, faites-le en asynchrone.Gérer l'idempotence
Gérer l'idempotence
Un même événement peut arriver plusieurs fois : dédupliquez sur
X-SahelPay-Event-ID (ou id du payload).Ne pas suivre de redirection
Ne pas suivre de redirection
SahelPay n’en suit aucune : votre endpoint doit répondre directement, en HTTPS, sur une adresse publique.