Aller au contenu

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 eventsCe 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 ["*"]

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.

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.

VerbeSignification
createdLa ressource existe désormais
updatedUn champ a changé
deletedLa ressource a été supprimée, ou anonymisée
processingTransmise à 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énementSe déclenche quandQue faire
payment.createdLe paiement existe et attend le payeurRien, enregistrez l'id
payment.processingL'opérateur a accepté la demande de débitAffichez un état en attente
payment.succeededLes fonds sont capturésLivrez la commande ici
payment.failedL'opérateur ou l'émetteur de la carte a refuséLibérez la réservation, prévenez le client
payment.cancelledLe payeur a refusé, ou vous avez appelé DELETE /payments/{id}Libérez la réservation
payment.expiredLe délai du paiement s'est écoulé avant la confirmationLibé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.

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énementSe déclenche quand
payment.split.processingUne tranche a été envoyée à l'opérateur
payment.split.succeededCette tranche a été encaissée
payment.split.failedCette tranche a été refusée

data contient le paiement complet, plus un objet split qui indique de quelle tranche il s'agit.

L'objet split ajouté au payload du paiement
"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.

Remboursements

ÉvénementSe déclenche quandQue faire
refund.createdLe remboursement a été accepté pour traitementEnregistrez-le, ne créditez pas encore
refund.processingLe prestataire l'exécuteRien
refund.succeededL'argent a quitté votre soldeCréditez le client ici
refund.failedLe prestataire l'a rejetéLisez failure_reason, décidez manuellement
refund.cancelledLe remboursement a été arrêté avant exécutionRien

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énementSe déclenche quandQue faire
transfer.createdLe transfert a été accepté et a débité votre solde disponibleEnregistrez l'id
transfer.processingTransmis au prestataire de payoutRien
transfer.succeededLe bénéficiaire a été payéMarquez le payout comme réglé
transfer.failedLe prestataire n'a pas pu payerLisez failure_reason, le montant revient sur votre solde

Clients

ÉvénementSe déclenche quand
customer.createdUne fiche client a été créée, y compris implicitement par un paiement
customer.updatedUn champ du client a changé
customer.deletedDELETE /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énementSe déclenche quand
beneficiary.createdUne destination de payout a été enregistrée
beneficiary.updatedSes informations ont changé
beneficiary.deletedElle a été supprimée
ÉvénementSe déclenche quand
link.createdUn lien de paiement a été créé
link.updatedSon montant, son expiration ou son état a changé
link.deletedIl 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énementSe déclenche quand
invoice.createdUne facture a été émise
invoice.updatedUne ligne, un statut ou une date d'échéance a changé
invoice.deletedElle 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énementSe déclenche quandQue faire
dispute.createdUn litige a été ouvert sur un paiementCommencez à rassembler des preuves
dispute.updatedUn champ a changé, ou un message a été ajoutéLisez data.messages
dispute.closedLe litige s'est terminé sans qu'un gagnant soit enregistréRien
dispute.wonLa décision vous est favorableGardez les fonds
dispute.lostLa décision vous est défavorableLe montant est débité
dispute.deletedL'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énementSe déclenche quand
account.createdUn marchand s'est connecté à votre plateforme
account.updatedSes informations ou sa tarification ont changé
account.deauthorizedLa connexion a pris fin, par suppression ou parce que le marchand l'a révoquée
account.payment_activatedLe marchand peut désormais accepter des paiements live
account.payment_suspendedSa 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énementSe déclenche quandPayload
balance.updatedVotre solde a bougéLe mouvement, pas les nouveaux totaux
fee.chargedWajub vous a débité des fraisLes frais
fee.receivedUne plateforme Sync a perçu ses frais sur un marchand connectéLes frais, plus account

balance.updated envoie le mouvement lui-même, c'est ce qu'il vous faut pour un registre.

Un payload balance.updated
{
"currency": "XAF",
"amount": 24250,
"direction": "credit",
"balance_type": "available",
"balance_before": 1840000,
"balance_after": 1864250,
"reason": "payment_settlement",
"sandbox": false
}

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énementSe déclenche quand
compliance.submittedVotre dossier de vérification a été soumis pour examen
compliance.verifiedLe compte est vérifié, les paiements live deviennent possibles
compliance.rejectedLe dossier a été refusé
compliance.changes_requestedUn analyste a besoin d'autre chose de votre part
compliance.inquiry.createdUne question précise a été posée sur votre dossier
compliance.inquiry.resolvedCette 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énementSe déclenche quand
provider.activatedUn prestataire a été activé sur votre compte
provider.deactivatedUn prestataire a été désactivé
provider.channel_activatedUn canal d'un prestataire est devenu disponible
provider.channel_deactivatedUn 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énementSe déclenche quand
webhook_endpoint.createdUn endpoint a été enregistré
webhook_endpoint.updatedSon URL, ses abonnements ou son état ont changé
webhook_endpoint.deletedIl 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.

Une livraison payment.succeeded complète
{
"id": "evt_aio5DpN577tNU2vOxdmuZGhT",
"event": "payment.succeeded",
"livemode": true,
"created": "2026-01-15T10:32:41+00:00",
"api_version": "2026-09-01",
"pending_webhooks": 1,
"request": {
"id": null,
"idempotency_key": "idem_kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0"
},
"data": {
"id": "trx_CSUGajfv9xh0XQ5wu2lx",
"reference": "order-4172",
"amount": 25000,
"amount_paid": 25000,
"currency": "XAF",
"status": "succeeded",
"channel": "cm.mtn",
"payment_method": {
"channel": "cm.mtn",
"account": "+237670000000"
},
"customer": {
"id": "cus_4tRb3nP8sZcXvK2mQ9wL",
"name": "Amina Nkem",
"email": "amina@example.com",
"phone": "+237670000000"
},
"sandbox": false,
"credited_at": "2026-01-15T10:32:41+00:00",
"created_at": "2026-01-15T10:30:00+00:00",
"updated_at": "2026-01-15T10:32:41+00:00"
}
}

Les événements qu'on cherche et qui n'existent pas

Vous attendiezCe qui existe réellement
payment.refundedrefund.succeeded
payment.partially_refundedrefund.succeeded, comparez data.amount au paiement
invoice.paidpayment.succeeded, puis invoice.updated
transfer.reviewRien. 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.completedpayment.succeeded
account.deletedaccount.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é.

TypePourquoi
payment.checkout_page_openedEnregistré dans le journal des événements de Konsole, jamais envoyé aux endpoints
payment.redirected_to_callbackPareil, 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 :

  • livemode vaut false en sandbox et true en live.
  • Les ids d'événement sont préfixés evt_test_ en sandbox et evt_ 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.

Ce que la copie de la plateforme ajoute à data
"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.

Que pensez-vous de ce contenu ?