Aller au contenu principal

Webhooks

Les webhooks envoient une requête HTTP à votre serveur dès qu'une opération atteint un statut final. C'est le moyen recommandé pour mettre à jour vos commandes et vos soldes, sans interroger l'API en boucle.

Événements​

ÉvénementDéclenché lorsque
mobile_money_deposit.completedUn dépôt mobile money a abouti et votre wallet est crédité
mobile_money_deposit.failedUn dépôt mobile money a échoué
mobile_money_payout.completedUn retrait mobile money a abouti
mobile_money_payout.failedUn retrait mobile money a échoué
crypto_deposit.completedUn dépôt en stablecoins (USDC/USDT) a abouti et votre wallet est crédité
crypto_payout.completedUn retrait en stablecoins a abouti et la transaction blockchain est confirmée
crypto_payout.failedUn retrait crypto a échoué (fonds recrédités sur votre wallet)

Format d'une livraison​

Chaque livraison est une requête POST dont le corps est au format JSON.

En-têteValeur
Content-Typeapplication/json
X-Webhook-EventNom de l'événement, par exemple mobile_money_deposit.completed
X-Webhook-SignatureSignature HMAC-SHA256 du corps de la requête, encodée en hexadécimal
{
"transaction_id": "TXN-VSWC4SQ2",
"type": "mobile_money_deposit",
"status": "completed",
"metadata": {}
}

Répondez avec un code 2xx dès réception. Toute autre réponse, un délai dépassé ou une redirection est traité comme un échec, et la livraison est retentée automatiquement.

Vérifier la signature​

Calculez le HMAC-SHA256 du corps brut de la requête avec le secret de votre abonnement, puis comparez-le à l'en-tête X-Webhook-Signature à l'aide d'une comparaison à temps constant. Rejetez toute requête dont la signature ne correspond pas.

verify-webhook.js
import crypto from 'node:crypto';
import express from 'express';

const app = express();

app.post('/webhooks/trustsend', express.raw({ type: 'application/json' }), (req, res) => {
const expected = crypto
.createHmac('sha256', process.env.REEMITE_WEBHOOK_SECRET)
.update(req.body)
.digest('hex');

const received = Buffer.from(req.get('X-Webhook-Signature') ?? '', 'utf8');
const computed = Buffer.from(expected, 'utf8');

if (received.length !== computed.length || !crypto.timingSafeEqual(received, computed)) {
return res.status(401).end();
}

const event = JSON.parse(req.body.toString('utf8'));
// Traitez l'événement, idéalement de façon asynchrone
res.status(200).end();
});
attention

Calculez la signature sur le corps tel qu'il a été reçu, avant tout parsing JSON : un corps re-sérialisé ne produit pas la même signature.

Créer un abonnement​

POST/api/v1/business/webhooks
ParamètreTypeRequisDescription
urlstringOuiURL de votre serveur, accessible publiquement ; les adresses privées ou internes sont refusées
eventsstring[]OuiListe des événements à recevoir
{
"url": "https://api.maboutique.com/webhooks/trustsend",
"events": ["mobile_money_deposit.completed", "mobile_money_payout.failed"]
}

Réponse 201

{
"data": {
"url": "https://api.maboutique.com/webhooks/trustsend",
"events": ["mobile_money_deposit.completed", "mobile_money_payout.failed"],
"active": true,
"secret": "whsec_4f1c…",
"message": "Webhook subscribed. Store the secret securely — used to verify X-Webhook-Signature on delivery."
}
}
attention

Le secret n'est renvoyé qu'à la création de l'abonnement. Stockez-le de façon sécurisée : il sert à vérifier chaque livraison.

Lister les abonnements​

GET/api/v1/business/webhooks

Réponse 200

{
"data": [
{
"id": 3,
"url": "https://api.maboutique.com/webhooks/trustsend",
"events": ["mobile_money_deposit.completed"],
"active": true,
"created_at": "2026-09-12T10:00:00.000+00:00"
}
]
}

Supprimer un abonnement​

DELETE/api/v1/business/webhooks/:id

Supprime l'abonnement ainsi que son historique de livraisons.

Historique des livraisons​

GET/api/v1/business/webhooks/:id/deliveries

Renvoie les 50 dernières tentatives de livraison, utiles pour diagnostiquer une intégration.

Réponse 200

{
"data": [
{
"id": 100,
"event_type": "mobile_money_deposit.completed",
"status": "success",
"retry_count": 0,
"last_error": null,
"created_at": "2026-09-12T10:00:43.000+00:00",
"updated_at": "2026-09-12T10:00:43.000+00:00"
}
]
}
statusSignification
pendingLivraison en attente d'envoi
retryingTentative échouée, nouvel essai programmé
successLivraison acceptée par votre serveur
failedLivraison abandonnée ; last_error indique la dernière cause
remarque

Nécessite la fonctionnalité webhooks dans votre offre.