Le contrat d’intégration canonique (statuts, commission, vérification de
signature,
--no-verify-jwt, Inngest local vs cloud) vit dans l’Integration
Guide — la source de vérité. Webhook qui ne se déclenche
pas en dev local, réconciliation sur net_amount, USER_CANCELLED terminal… la
FAQ & tips d’intégration répond aux pièges les plus courants.Événements
| Événement | Quand |
|---|---|
payment.completed | La transaction a atteint son statut final (succès ou échec). |
Pour l’instant un seul événement est émis :
payment.completed. Le statut final (SUCCESS, PIN_INVALID, TIMEOUT, …) est porté par le champ status du payload, pas par le nom de l’événement.Le SDK
@sandpay/node expose webhooks.parseEvent(body) qui renvoie un WebhookPayload typé après vérification. Voir SDK Node.Configuration
Depuis/webhooks dans le dashboard :
- Ajoutez l’URL HTTPS de votre endpoint.
- SandPay génère un signing secret (
whsec_...) — copiez-le, il ne sera plus affiché. - Activez l’endpoint. Vous pouvez le mettre en pause à tout moment.
Format du payload
Le champ raw
Le champ raw contient la réponse native de l’opérateur, synthétisée pour reproduire la shape réelle (_simulated: true est posé au top-level pour que vous puissiez détecter les payloads sandbox).
Ce design vous permet d’écrire votre code d’intégration (ex. payload.raw.financialTransactionId pour MTN, payload.raw.responseCode pour Moov) directement contre le sandbox.
Le champ
raw est additif : si vous ne le lisez pas, votre handler webhook continue de fonctionner comme avant. Les anciennes lignes (avant la sortie du raw passthrough) renvoient raw: null.Vérification de signature
Chaque livraison est signée. L’en-tête est :JSON.parse).
Avec le SDK Node
Vérification manuelle
Politique de retry
SandPay tente la livraison jusqu’à 5 fois avec un backoff exponentiel géré par Inngest. Chaque tentative a un timeout de 10 secondes. Si la 5e tentative échoue :- La livraison est marquée
faileddans/webhooks/deliveries. - L’owner de l’organisation reçoit un email d’alerte.
- Vous pouvez rejouer manuellement la livraison depuis l’UI.
2xx est considéré comme une réussite. Les 3xx ne sont pas suivis automatiquement — renvoyez bien un 200.