Catalogue des événements
Chaque événement émis par Wajub, ce qui le déclenche et ce qu'il transporte.
Konsole propose 60 types d'événements auxquels vous abonner. 57 d'entre eux atteignent
réellement un endpoint, et les trois qui ne l'atteignent pas sont nommés en bas de cette page. Ils
arrivent tous dans la même enveloppe, décrite dans Webhooks ; seul
data change de l'un à l'autre, et data contient toujours la ressource complète, identique à ce
que renvoie l'endpoint REST de cette ressource.
Cette page est la liste complète, regroupée par sujet, avec ce qu'il vaut la peine de faire à la réception de chaque événement.
Comment un endpoint décide de se déclencher
La correspondance des abonnements est une simple comparaison de chaînes avec le tableau events
que vous avez enregistré. Trois cas, pas un de plus.
Votre tableau events | Ce que vous recevez |
|---|---|
["payment.succeeded", "refund.failed"] | Exactement ces deux types |
["*"] | Tous les événements de paiement, remboursement, transfert, client, litige, facture, lien, compte, solde, frais et endpoint |
[] | La même chose que ["*"] |
Une faute de frappe dans l'API est acceptée et ne se déclenche jamais
Konsole vérifie ce que vous cochez par rapport à une liste de noms valides. POST /webhooks ne le
fait pas : il vérifie seulement que events est un tableau non vide. payment.succeded,
payment.SUCCEEDED et payment.* sont tous enregistrés sans broncher, ne correspondent à rien, et
votre endpoint reste muet pour toujours. Copiez les noms depuis cette page.
Les jokers de préfixe n'existent pas. payment.* est une chaîne littérale à laquelle aucun
événement n'est jamais égal. Si vous voulez tout ce qui concerne une ressource, listez ses types.
`*` ne couvre pas les événements de conformité et de prestataires
Ces deux familles sont émises par une autre partie de la plateforme, qui ne fait correspondre les
abonnements que sur le nom exact. Un endpoint enregistré avec ["*"] reçoit tout le reste et
aucun de ces événements. Listez explicitement les types compliance.* et provider.* si vous les
voulez.
Comment les noms sont construits
resource.verb, le verbe au passé, le tout en minuscules. Les verbes sont les mêmes d'une ressource
à l'autre, ce qui rend la liste plus courte à retenir qu'il n'y paraît.
| Verbe | Signification |
|---|---|
created | La ressource existe désormais |
updated | Un champ a changé |
deleted | La ressource a été supprimée, ou anonymisée |
processing | Transmise à un prestataire, résultat inconnu |
succeeded | État terminal, l'opération a réussi |
failed | État terminal, l'opération a échoué |
cancelled | État terminal, arrêtée volontairement |
expired | État terminal, le délai est écoulé |
Trois orthographes font perdre un après-midi : c'est succeeded, jamais completed ni complete ;
c'est cancelled avec deux l ; et Sync utilise deauthorized avec un z alors que tout le reste
de la plateforme suit l'orthographe britannique.
Paiements
Les six états que traverse un paiement. Seul payment.succeeded signifie que l'argent est là.
| Événement | Se déclenche quand | Que faire |
|---|---|---|
payment.created | Le paiement existe et attend le payeur | Rien, enregistrez l'id |
payment.processing | L'opérateur a accepté la demande de débit | Affichez un état en attente |
payment.succeeded | Les fonds sont capturés | Livrez la commande ici |
payment.failed | L'opérateur ou l'émetteur de la carte a refusé | Libérez la réservation, prévenez le client |
payment.cancelled | Le payeur a refusé, ou vous avez appelé DELETE /payments/{id} | Libérez la réservation |
payment.expired | Le délai du paiement s'est écoulé avant la confirmation | Libérez la réservation |
payment.failed transporte failure_reason dans data. Le champ est absent, et non null, quand il
n'y a aucun motif à donner.
Il n'existe pas de `payment.refunded`
Un remboursement ne produit jamais d'événement de paiement. Il produit des événements refund.*
sur l'objet remboursement. Le status du paiement lui-même devient refunded ou
partially_refunded en base de données, et vous verrez cette valeur la prochaine fois que vous
lirez le paiement, mais aucun événement de paiement n'est émis pour ce changement.
Paiements fractionnés
Émis quand un même paiement est débité en plusieurs tranches, via split_count ou split_amounts
sur POST /payments.
| Événement | Se déclenche quand |
|---|---|
payment.split.processing | Une tranche a été envoyée à l'opérateur |
payment.split.succeeded | Cette tranche a été encaissée |
payment.split.failed | Cette tranche a été refusée |
data contient le paiement complet, plus un objet split qui indique de quelle tranche il s'agit.
"split": {
"id": "splt_9mWvL2xR7tB5nY4hC6dF",
"split_number": 2,
"amount": 500000,
"currency": "XAF",
"split_currency": "XAF",
"status": "succeeded",
"reference": "order-4172-2",
"provider_reference": "MP260115.1032.B41209",
"initiated_at": "2026-01-15T10:32:04+00:00",
"succeeded_at": "2026-01-15T10:32:41+00:00"
}Le paiement parent n'atteint payment.succeeded qu'une fois toutes les tranches réussies. Compter
vous-même les payment.split.succeeded pour décider que la commande est complète, c'est le meilleur
moyen de livrer une commande à moitié payée.
Le fractionnement ne fonctionne qu'en sandbox pour l'instant
En sandbox, split_count et split_amounts sont pris en compte et ces trois événements se
déclenchent. En live, un paiement Mobile Money au-dessus du plafond par transaction est refusé avec
un 422 dont le message vous demande de le fractionner, et le fractionnement n'est pas exécuté. En
attendant, gardez vos débits live sous le plafond indiqué dans Plafonds et quotas.
Remboursements
| Événement | Se déclenche quand | Que faire |
|---|---|---|
refund.created | Le remboursement a été accepté pour traitement | Enregistrez-le, ne créditez pas encore |
refund.processing | Le prestataire l'exécute | Rien |
refund.succeeded | L'argent a quitté votre solde | Créditez le client ici |
refund.failed | Le prestataire l'a rejeté | Lisez failure_reason, décidez manuellement |
refund.cancelled | Le remboursement a été arrêté avant exécution | Rien |
data.transaction est l'id du paiement remboursé, sous forme de chaîne, pas d'objet imbriqué.
Transferts
Les payouts depuis votre solde, que ce soit vers un portefeuille Mobile Money, un compte bancaire ou une carte.
| Événement | Se déclenche quand | Que faire |
|---|---|---|
transfer.created | Le transfert a été accepté et a débité votre solde disponible | Enregistrez l'id |
transfer.processing | Transmis au prestataire de payout | Rien |
transfer.succeeded | Le bénéficiaire a été payé | Marquez le payout comme réglé |
transfer.failed | Le prestataire n'a pas pu payer | Lisez failure_reason, le montant revient sur votre solde |
Un transfert en revue n'émet rien
review est un vrai statut de transfert : un payout au-dessus de 1 000 000 XAF, votre premier
payout live, ou un payout plus de cinq fois supérieur à votre propre moyenne est mis de côté pour
une décision humaine. Aucun événement n'est émis quand il passe en revue. Vous apprenez le résultat
par transfer.succeeded ou transfer.failed, qui peuvent arriver des heures plus tard, ou en
lisant le transfert. Construisez l'état d'attente sur le statut, pas sur le silence.
Clients
| Événement | Se déclenche quand |
|---|---|
customer.created | Une fiche client a été créée, y compris implicitement par un paiement |
customer.updated | Un champ du client a changé |
customer.deleted | DELETE /customers/{id} a été exécuté, et la fiche a été anonymisée |
Le payload de customer.deleted est le client après anonymisation : le nom devient
Deleted User <pseudonym>, et l'e-mail, le téléphone et la date de naissance ont disparu. Si vous
avez besoin des valeurs d'origine pour vos propres données, vous devez les avoir conservées.
Bénéficiaires
| Événement | Se déclenche quand |
|---|---|
beneficiary.created | Une destination de payout a été enregistrée |
beneficiary.updated | Ses informations ont changé |
beneficiary.deleted | Elle a été supprimée |
Liens de paiement
| Événement | Se déclenche quand |
|---|---|
link.created | Un lien de paiement a été créé |
link.updated | Son montant, son expiration ou son état a changé |
link.deleted | Il a été supprimé |
Un paiement effectué via un lien émet payment.*, pas link.*. Les événements de lien concernent
l'objet lien lui-même.
link.expired apparaît dans le sélecteur de Konsole mais appartient au système de webhooks propre à
chaque lien, pas aux endpoints de votre compte. S'y abonner sur un endpoint de compte ne produit
rien.
Factures
| Événement | Se déclenche quand |
|---|---|
invoice.created | Une facture a été émise |
invoice.updated | Une ligne, un statut ou une date d'échéance a changé |
invoice.deleted | Elle a été supprimée |
Il n'existe pas de `invoice.paid`
Quand une facture est réglée, ce qui se déclenche est payment.succeeded pour le paiement qui l'a
réglée, suivi de invoice.updated quand le statut de la facture change. Faites le rapprochement
sur le paiement, et utilisez la référence de facture que vous avez mise dans les métadonnées du
paiement pour relier les deux.
Litiges
Rétrofacturations et réclamations. Ce sont les événements assortis des délais les plus courts.
| Événement | Se déclenche quand | Que faire |
|---|---|---|
dispute.created | Un litige a été ouvert sur un paiement | Commencez à rassembler des preuves |
dispute.updated | Un champ a changé, ou un message a été ajouté | Lisez data.messages |
dispute.closed | Le litige s'est terminé sans qu'un gagnant soit enregistré | Rien |
dispute.won | La décision vous est favorable | Gardez les fonds |
dispute.lost | La décision vous est défavorable | Le montant est débité |
dispute.deleted | L'enregistrement du litige a été supprimé | Rien |
Comptes, pour les plateformes Sync
Ces événements décrivent un marchand connecté à une plateforme Sync, pas votre propre compte.
| Événement | Se déclenche quand |
|---|---|
account.created | Un marchand s'est connecté à votre plateforme |
account.updated | Ses informations ou sa tarification ont changé |
account.deauthorized | La connexion a pris fin, par suppression ou parce que le marchand l'a révoquée |
account.payment_activated | Le marchand peut désormais accepter des paiements live |
account.payment_suspended | Sa capacité à accepter des paiements a été suspendue |
account.deauthorized se déclenche aussi bien pour une suppression que pour une révocation. Il
n'existe pas de account.deleted distinct.
Solde et frais
| Événement | Se déclenche quand | Payload |
|---|---|---|
balance.updated | Votre solde a bougé | Le mouvement, pas les nouveaux totaux |
fee.charged | Wajub vous a débité des frais | Les frais |
fee.received | Une plateforme Sync a perçu ses frais sur un marchand connecté | Les frais, plus account |
Un débit de frais n'est pas un `balance.updated`
Les débits de frais sont volontairement exclus de balance.updated et remontés à la place sous
forme de fee.charged. Si vous additionnez les mouvements balance.updated pour tenir un registre
local, vous dépasserez exactement du montant des frais. Abonnez-vous aux deux.
balance.updated envoie le mouvement lui-même, c'est ce qu'il vous faut pour un registre.
Les huit montants que renvoie GET /balance ne figurent pas dans ce payload. Appelez l'endpoint
quand vous avez besoin des totaux.
Conformité
Émis pendant la vérification de votre compte, puis chaque fois que votre dossier change d'état.
| Événement | Se déclenche quand |
|---|---|
compliance.submitted | Votre dossier de vérification a été soumis pour examen |
compliance.verified | Le compte est vérifié, les paiements live deviennent possibles |
compliance.rejected | Le dossier a été refusé |
compliance.changes_requested | Un analyste a besoin d'autre chose de votre part |
compliance.inquiry.created | Une question précise a été posée sur votre dossier |
compliance.inquiry.resolved | Cette question a été clôturée |
Pour une plateforme qui inscrit des marchands, compliance.verified est le signal qu'un compte
connecté peut commencer à accepter des paiements live. Ne le déduisez de rien d'autre.
Prestataires
Émis quand l'ensemble des prestataires et des canaux disponibles sur votre compte change.
| Événement | Se déclenche quand |
|---|---|
provider.activated | Un prestataire a été activé sur votre compte |
provider.deactivated | Un prestataire a été désactivé |
provider.channel_activated | Un canal d'un prestataire est devenu disponible |
provider.channel_deactivated | Un canal a été retiré |
Utile si vous mettez en cache la liste des canaux au lieu d'appeler GET /channels à chaque
checkout.
Endpoints de webhook
| Événement | Se déclenche quand |
|---|---|
webhook_endpoint.created | Un endpoint a été enregistré |
webhook_endpoint.updated | Son URL, ses abonnements ou son état ont changé |
webhook_endpoint.deleted | Il a été supprimé |
Utile sur un compte plateforme où plusieurs personnes peuvent modifier la configuration. Notez que l'endpoint qui reçoit cet événement peut être celui qui vient d'être modifié.
Ce que contient réellement data
data est la ressource sérialisée par le même code que celui qui sert l'endpoint REST, avec deux
conséquences à connaître.
Les champs null sont retirés, pas envoyés à null. Un paiement sans description n'a tout
simplement pas de clé description. Lisez avec une valeur par défaut, ne supposez jamais que la clé
existe.
Le payload est toujours dans la dernière version de l'API. La version fixée s'applique à
vos appels API, pas aux livraisons de webhooks : l'api_version de l'enveloppe est la version
courante de la plateforme au moment où l'événement a été enregistré, et le corps est structuré pour
cette version. Épingler votre compte sur 2026-08-01 ne change pas ce que reçoit votre endpoint.
`request.idempotency_key` n'est pas votre clé
Les événements portent une valeur idem_… générée pour l'événement lui-même, et request.id vaut
null. Aucun de ces deux champs ne reflète l'en-tête Idempotency-Key que vous avez envoyé en
créant le paiement. Pour relier un événement à votre propre commande, utilisez data.reference,
qui est la reference que vous avez fournie, ou data.metadata.
Les événements qu'on cherche et qui n'existent pas
| Vous attendiez | Ce qui existe réellement |
|---|---|
payment.refunded | refund.succeeded |
payment.partially_refunded | refund.succeeded, comparez data.amount au paiement |
invoice.paid | payment.succeeded, puis invoice.updated |
transfer.review | Rien. Lisez le statut du transfert |
payout.* | transfer.*, les payouts sont des transferts dans l'API |
subscription.* | invoice.*, la facturation récurrente émet des événements de facture |
checkout.session.completed | payment.succeeded |
account.deleted | account.deauthorized |
transaction.* | Télémétrie interne du checkout. Jamais livré, même aux abonnés à * |
Trois types auxquels vous pouvez vous abonner mais qui n'arrivent jamais
Konsole vous laisse les cocher. Rien n'est jamais livré.
| Type | Pourquoi |
|---|---|
payment.checkout_page_opened | Enregistré dans le journal des événements de Konsole, jamais envoyé aux endpoints |
payment.redirected_to_callback | Pareil, c'est une entrée de la chronologie du checkout |
link.expired | Émis par le système de webhooks propre à chaque lien, pas par les endpoints de compte |
Les deux premiers sont visibles dans Événements, vous pouvez donc toujours auditer un checkout après coup. Vous ne pouvez simplement pas en être notifié.
Sandbox et live sont deux flux séparés
Un endpoint appartient à un seul environnement. Un endpoint sandbox ne reçoit que des événements sandbox, et un endpoint live que des événements live. Deux choses changent dans le payload :
livemodevautfalseen sandbox ettrueen live.- Les ids d'événement sont préfixés
evt_test_en sandbox etevt_en live.
Un handler qui code en dur la longueur d'un id ou qui retire un préfixe cassera dès qu'il rencontrera l'autre environnement.
Les plateformes Sync reçoivent une copie
Quand un paiement, un remboursement ou un transfert appartient à un marchand connecté via Sync,
l'événement est livré deux fois : une fois aux endpoints du marchand, et une fois à ceux de la
plateforme, sous forme d'événement distinct avec son propre id. La copie de la plateforme porte un
objet account supplémentaire pour que vous sachiez de quel marchand connecté elle provient.
"account": {
"id": "acc_7Yh2MpL4tRb3nP8sZcXv",
"reference": "boutique-akwa"
}Dédupliquez sur l'id de l'événement, pas sur l'id du paiement : les deux copies décrivent le même paiement et portent volontairement deux ids d'événement différents.
Pages associées
- WebhooksL'enveloppe, les en-têtes et les trois règles.
- Nouvelles tentatives et ordrePourquoi le même événement arrive deux fois, et sur quoi vous appuyer.
- Cycle de vie d'un paiementQuels changements d'état émettent un événement, et lesquels non.
- Déclencher un événementProduisez neuf de ces événements à la demande depuis votre terminal.