Catalogue de référence des événements webhook. Pour la mise en place (signature, retry, idempotence), voir le guide Webhooks.

Enveloppe commune

Tout webhook partage la même enveloppe :
Lisez vos champs dans data.object, pas dans data. data ne porte que les identifiants (intentId, merchantId, …) ; l’état de la ressource est dans data.object. data.status n’existe pas — c’est data.object.status.
Deux headers accompagnent chaque livraison : X-IziPay-Signature et X-IziPay-Timestamp. Vérifiez toujours la signature avant de traiter.

Trois règles qui évitent des bugs

object est figé. C’est l’état au moment de l’émission, pas l’état courant. Les tentatives de retry rejouent le corps octet pour octet — sans quoi la signature ne serait plus valable — donc un webhook reçu après plusieurs heures porte toujours l’ancien instantané. Pour l’état actuel, faites un GET /v1/<ressource>/{id}. Les champs vides sont omis. Un champ null n’est pas envoyé du tout. Testez la présence de la clé, pas sa valeur. Les montants sont des chaînes. Jamais des nombres JSON : un montant crypto peut porter 18 décimales, qu’un float arrondirait silencieusement. Voir Montants et précision.

Les objets embarqués

data.object prend six formes selon le domaine de l’événement.

PaymentIntent

payment_intent.* · dispute.*
customerRefundAddress n’est jamais exposé dans un webhook — donnée sensible, server-only.

Payin

payin.* · merchant_deposit.completed id, paymentIntentId, amountGross, feeAmount, assetCode, senderAddress, txid (hash on-chain, votre référence canonique), status, createdAt.

Payout

payout.*

BatchPayout

batch_payout.completed id, label, lineCount, status, executionState, createdAt, et payouts[] (chaque ligne : id, status, amount, assetCode, destinationAddress).

Settlement

settlement.*

Invoice

invoice.* id, customerEmail, customerName, amount, currency, description, status, paymentIntentId, merchantReference, meta, expiresAt, createdAt.

Paiements

payment_intent.expired ne signifie pas toujours « rien reçu ». Un sous-paiement hors tolérance produit lui aussi un intent expired, avec de l’argent réellement reçu et en attente de votre décision. Vérifiez data.object.irregularStatus avant de conclure à un abandon. Voir Traiter un paiement irrégulier.

Dépôts on-chain


Litiges — paiements irréguliers

Un paiement sous-payé ou sur-payé hors tolérance devient un irrégulier : la part rejetée attend votre décision — encaisser ou rembourser.
Après un encaissement, l’intent reste expired — c’est irregularStatus qui porte la vérité (encashed). Si vous n’écoutez que payment_intent.completed, cet argent n’apparaîtra jamais dans votre système alors qu’il a bien été crédité. Abonnez-vous à dispute.encashed.
Le montant crédité est data.object.amountEncashed, net de frais. Guide complet : Traiter un paiement irrégulier.

Retraits crypto

batch_payout.completed signale la fin du lot, pas son succès. Un lot peut se terminer avec des lignes en échec : lisez data.failed et l’état de chaque ligne dans data.object.payouts[].

Règlements fiat


Factures


Sous-portefeuilles (WaaS)

Ces événements n’ont pas de data.object : tous leurs champs sont directement dans data.
Voir Wallet-as-a-Service.

Récapitulatif

Les 25 types souscriptibles. S’abonner à un type absent de cette liste renvoie une erreur 400.

Voir aussi

Guide Webhooks

Signature, retry, idempotence côté receveur, debugging.

Paiement irrégulier

Encaisser ou rembourser un sous/sur-paiement.

Vérifier la signature

HMAC-SHA256, anti-replay, rejeu octet pour octet.

Montants et précision

Pourquoi les montants sont des chaînes.