Recevoir les webhooks signés

Recevoir, vérifier et traiter les webhooks signés émis par Intram pour les opérations asynchrones.

Quand une opération asynchrone du Merchant API change d'état (payout terminé, paiement reçu, remboursement settled…), Intram fait un POST HTTP signé vers l'URL que vous avez configurée. C'est le moyen recommandé de suivre l'état des opérations — bien plus efficace que du polling.

Configurer un endpoint webhook

Via l'API (recommandé pour automatiser) :

curl -X POST https://api.intram.org/v1/webhooks \
  -H "X-Api-Key: $PUB" -H "X-Timestamp: $TS" -H "X-Signature: $SIG" \
  -H "Idempotency-Key: webhook-setup-1" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://my-app.example.com/intram/webhook",
    "event": "*"
  }'

Le champ event accepte :

Pattern
Comportement

payout.completed

Match exact d'un seul event

payout.*

Tous les events payout.completed, payout.failed, payout.queued

* ou all

Tous les events

Headers d'un webhook entrant

Chaque livraison porte :

  • X-Intram-Signature — HMAC-SHA256 de timestamp.raw_body avec le secret du webhook

  • X-Intram-Timestamp — ISO 8601. Rejette si > 5 minutes

  • X-Intram-Delivery — identifiant unique de la tentative. Utilise-le pour dédupliquer côté toi en cas de double livraison

  • X-Intram-Attempt — numéro de tentative (1 à 5)

Body d'un webhook

Vérifier la signature

Politique de retry

Tentative
Délai après la précédente

1

immédiat

2

1 min

3

5 min

4

30 min

5

2 h

(puis)

12 h

Au-delà de 5

livraison marquée exhausted, abandon

  • Une réponse 2xx acquitte la livraison — pas de retry.

  • Toute autre réponse (4xx, 5xx, timeout > 15 s, connexion refusée) déclenche un retry suivant le calendrier ci-dessus.

  • Les retries portent un X-Intram-Attempt incrémenté mais le même X-Intram-Delivery — c'est ce qui te permet de dédupliquer.

Catalogue des events

Event
Émis quand

payout.completed

Le payout mobile money a été confirmé par le provider

payout.queued

Le payout bancaire a été accepté pour traitement back-office

payout.failed

Le payout a été rejeté (solde, provider, validation)

payment_request.created

La demande de paiement est prête, gateway_url disponible

payment_request.paid

Le client a payé avec succès

payment_request.pending

Le client a initié mais le provider n'a pas confirmé

payment_request.failed

Le flow paiement a échoué côté client ou provider

refund.completed

Le refund a été settled (mobile money succeeded ou Stripe refund created)

refund.pending

Le refund est accepté par le provider mais pas encore settled

refund.failed

Le refund a été rejeté

test.ping

Envoi de test via POST /webhooks/:subscription_id/test

Bonnes pratiques

  1. Réponds rapidement (sous 5 secondes). Si ton handler doit faire du travail lourd, queue-le puis renvoie 200 tout de suite.

  2. Idempotence côté toi : un event peut arriver plusieurs fois (rare mais possible). Dédup sur X-Intram-Delivery.

  3. Endpoint HTTPS uniquement — la création d'un webhook refuse les URLs http://.

  4. Logge les X-Intram-Attempt > 1 — un retry signifie que ton premier renvoi a échoué, c'est un signal de monitoring.

  5. Endpoint de test : utilise POST /webhooks/:id/test pour vérifier que ton handler fonctionne sans déclencher une vraie opération.

Mis à jour