Événements
Chaque valeur de Jeko-Event, le corps qui l'accompagne, et quel abonnement le reçoit
Tous ces événements partent par le même POST. L'en-tête Jeko-Event dit lequel. Le corps change. Seul l'escrow répète event dans le JSON. Pour les autres, ce champ n'existe pas.
events: null sur un abonnement (le défaut) reçoit chaque événement routé vers cet abonnement. Une liste qui ne contient que TRANSACTION_COMPLETED laisse tomber les autres.
Qui reçoit
Deux abonnements peuvent être appelés pour le même événement :
- Entreprise (
storeIdabsent), plus l'URL legacy du Dashboard. Elle est candidate pour chaque événement. - Magasin, seulement si l'expéditeur vise ce
storeId.
| Événement | Magasin visé |
|---|---|
TRANSACTION_COMPLETED | Le magasin de la transaction. Magasin du marchand, ou magasin dédié si la clé plateforme a encaissé là |
SERVICE_PROVIDER_LINK_REQUEST | Le magasin dédié du Service Provider. Les autres magasins du marchand ne le reçoivent pas |
ESCROW_HELD, ESCROW_RELEASED, ESCROW_REFUNDED, ESCROW_COLLECT_FAILED, ESCROW_EXPIRED | Le magasin du pot. Avec une clé plateforme, c'est le magasin dédié |
COMPLIANCE_VERIFICATION_COMPLETED | Le magasin dédié du Service Provider qui a ouvert la vérification |
TRANSACTION_COMPLETED
Paiement complété, ou transfert complété ou échoué. Un paiement qui échoue n'envoie pas cet événement. L'absence de notification ne distingue pas un échec d'un paiement encore en cours.
Un encaissement retenu en escrow envoie ESCROW_HELD au paiement, pas TRANSACTION_COMPLETED. TRANSACTION_COMPLETED part à la libération (manuelle ou à holdUntil), avec la ligne type=escrow du solde opérable. Un remboursement n'envoie jamais TRANSACTION_COMPLETED. Une intégration qui n'attend que TRANSACTION_COMPLETED ne voit donc un paiement sous escrow qu'une fois libéré. Voir Escrow.
Le corps est la transaction, sans champ event. Les champs sont détaillés dans Intégration.
{
"id": "txn_1234567890",
"amount": { "amount": 10000, "currency": "XOF" },
"fees": { "amount": 100, "currency": "XOF" },
"status": "success",
"counterpartLabel": "John Doe",
"counterpartIdentifier": "+2250701234567",
"paymentMethod": "wave",
"transactionType": "payment",
"businessName": "Ma Boutique",
"storeId": "01a0b1c2-d3e4-7f89-a0b1-c2d3e4f5a6b7",
"storeReference": "STORE-001",
"storeName": "Magasin Principal",
"description": "Payment for order #12345",
"executedAt": "2024-01-15 14:30:25",
"transactionDetails": {
"id": "d22c81f3-ee04-4ec5-8bd2-cd8af5dabcfc",
"reference": "PAY-2024-001",
"paymentLinkId": "abc123def456"
}
}transactionType vaut payment ou transfer. status vaut pending, success ou error.
Pour un reversement, transactionDetails.id est l'ID du transfert, y compris quand reference n'a pas été envoyée. transactionDetails.reference n'est présent que si vous avez envoyé reference.
SERVICE_PROVIDER_LINK_REQUEST
Demande de rattachement, puis ses changements de statut. Ce n'est pas une transaction : pas de amount, pas de fees. Le détail du parcours est dans Rattacher un marchand.
{
"id": "c1e15642-cdb5-404a-b028-26a51c94059b",
"status": "pending",
"merchantBusinessId": "59ae202a-f583-4a15-970f-9e99bd1e0baa",
"merchantBusinessName": "Magasin de Jean",
"serviceProviderBusinessId": "a0b1c2d3-e4f5-6789-abcd-ef0123456789",
"serviceProviderBusinessName": "Ma Marketplace",
"ownerPhone": "+22507012345",
"expiresAt": "2026-08-30T12:00:00.000Z",
"createdAt": "2026-08-23T12:00:00.000Z",
"serviceProviderMemberId": null
}serviceProviderMemberId est renseigné quand le marchand a approuvé. L'idempotence se fait sur id.
Événements escrow
ESCROW_HELD, ESCROW_RELEASED, ESCROW_REFUNDED, ESCROW_COLLECT_FAILED et ESCROW_EXPIRED envoient tous le même corps : le pot tel que le renvoie (avec ses blocs collect, release et refund), précédé de event et escrowId, suivi de businessName, storeName et walletAvailableBalance. ESCROW_RELEASED ajoute transactionId. Le détail des blocs est dans Escrow.
Jeko-Event dit lequel. Le corps répète event. Lisez l'en-tête d'abord. walletAvailableBalance est le solde opérable : il ne bouge pas pendant le hold.
| Événement | Quand | Statut du pot |
|---|---|---|
ESCROW_HELD | Le client a payé, les fonds sont retenus. Pas une transaction dépensable : reste vide pour ce job | held |
ESCROW_COLLECT_FAILED | La demande de paiement du pot a échoué ou expiré. Vous pouvez relancer /collect | failed |
ESCROW_RELEASED | Libération manuelle ou à holdUntil. Le solde opérable est crédité. transactionId est la ligne type=escrow de | released |
ESCROW_REFUNDED | Remboursement au payeur, envoyé quand il est lancé. refund.status peut encore être pending | refunded |
ESCROW_EXPIRED | holdUntil est passé sans paiement | expired |
Exemple ESCROW_RELEASED (frais payés par le marchand) :
{
"event": "ESCROW_RELEASED",
"escrowId": "7c2d1a90-0b1e-4c3a-9f11-2e8c4d6a1b20",
"transactionId": "a1b2c3d4-e5f6-7890-abcd-ef0123456789",
"id": "7c2d1a90-0b1e-4c3a-9f11-2e8c4d6a1b20",
"storeId": "59ae202a-f583-4a15-970f-9e99bd1e0baa",
"status": "released",
"holdUntil": "2026-09-14T20:00:00.000Z",
"amount": { "amount": 50000, "currency": "XOF" },
"createdAt": "2026-09-07T20:00:00.000Z",
"collect": {
"type": "payment_request",
"status": "success",
"errorReason": null,
"reference": "ORDER-1042",
"redirectUrl": null,
"link": null,
"amount": { "amount": 50000, "currency": "XOF" },
"fees": { "amount": 800, "currency": "XOF" },
"paymentMethod": "wave",
"counterpartIdentifier": "+2250700000000"
},
"release": {
"amount": { "amount": 49200, "currency": "XOF" },
"fees": { "amount": 800, "currency": "XOF" },
"autoRelease": false
},
"refund": null,
"businessName": "Boutique Example",
"storeName": "Cocody",
"walletAvailableBalance": { "amount": 49200, "currency": "XOF" }
}Exemple ESCROW_COLLECT_FAILED :
{
"event": "ESCROW_COLLECT_FAILED",
"escrowId": "7c2d1a90-0b1e-4c3a-9f11-2e8c4d6a1b20",
"id": "7c2d1a90-0b1e-4c3a-9f11-2e8c4d6a1b20",
"storeId": "59ae202a-f583-4a15-970f-9e99bd1e0baa",
"status": "failed",
"holdUntil": "2026-09-14T20:00:00.000Z",
"amount": null,
"createdAt": "2026-09-07T20:00:00.000Z",
"collect": {
"type": "payment_request",
"status": "failed",
"errorReason": "Insufficient balance",
"reference": "ORDER-1042",
"redirectUrl": null,
"link": null,
"amount": { "amount": 50000, "currency": "XOF" },
"fees": null,
"paymentMethod": "wave",
"counterpartIdentifier": null
},
"release": null,
"refund": null,
"businessName": "Boutique Example",
"storeName": "Cocody",
"walletAvailableBalance": { "amount": 0, "currency": "XOF" }
}paymentRequestId et paymentLinkId ne font plus partie du corps : lisez collect.
COMPLIANCE_VERIFICATION_COMPLETED
Vérification KYC ou KYB d'un marchand rattaché à un Service Provider, quand le statut devient succeeded ou failed. Le sondage GET reste valable. Voir Conformité.
{
"id": "fc86b752-c92e-44cb-a1c5-73d5ec256982",
"type": "kyc",
"status": "succeeded",
"merchantBusinessId": "59ae202a-f583-4a15-970f-9e99bd1e0baa"
}type vaut kyc ou kyb. status vaut succeeded ou failed.