Skip to content
StableAudienceDevOwner@partners-teamDernière revue2026-05-24

Recevoir les webhooks

Les webhooks sont la manière dont Nex vous notifie en temps réel des événements qui vous concernent (paiements, changements de connexion à venir). Cette page explique le format et les garanties. Pour le code receiver complet, voir le Guide implémentation receiver.

Pourquoi des webhooks

Sans webhook, vous devriez poller GET /orders/<id> toutes les N secondes pour savoir si un paiement a abouti — coûteux côté API, latence variable, mauvaise UX. Le webhook inverse le flux : Nex vous prévient dès que ça arrive, en quelques centaines de millisecondes.

Format générique d'un event

Tous les webhooks Nex partagent la même enveloppe :

json
{
  "event": "order.paid",
  "id": "evt-uuid-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "createdAt": "2026-05-24T12:02:34.567Z",
  "data": { /* spécifique au type d'event */ }
}
ChampTypeDescription
eventstringType de l'event (order.paid, autres à venir).
idUUID v4Identifiant unique de cet event. Clé d'idempotence côté votre receiver (voir plus bas).
createdAtISO 8601Moment où Nex a produit l'event. Indicatif.
dataobjectCharge utile spécifique au type. Champs garantis stables (additions non-breaking, retraits via deprecation).

Headers HTTP envoyés

Chaque POST contient :

http
POST /votre-endpoint HTTP/1.1
Host: api.maishapay.cd
Content-Type: application/json
User-Agent: Nex-Webhooks/1.0
Nex-Signature: t=1716553354,v1=5e7c1a3f4b8d2c9e6f1a2b3c4d5e6f...
Nex-Event: order.paid
Nex-Event-Id: evt-uuid-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Content-Length: 287
HeaderÀ quoi ça sert
Nex-SignatureHMAC SHA256 du payload. Vous devez vérifier, sinon n'importe qui peut forger.
Nex-EventType — utile pour router rapidement vers le bon handler sans parser le body.
Nex-Event-IdUUID v4 identique au id du body. Clé d'idempotence.
User-AgentPréfixé Nex-Webhooks/ — utile pour filtrer côté WAF.

Catalogue des events V1

EventQuandPayload data
order.paidUn de vos QR a été payé par un client final. Émis après le commit ledger (l'argent est arrivé).{ orderId, transactionId, amount, currencyCode, paidAt, externalReference?, description? }

D'autres events viendront (connection.activated, connection.revoked_by_merchant, order.expired…). Quand un nouveau type est ajouté, votre receiver doit l'ignorer proprement (retourner 200 même si vous ne savez pas le traiter), pas crasher.

Garanties Nex

GarantieDétail
At-least-once deliverySi votre endpoint répond >= 400 ou timeout, Nex retry 7 fois avec backoff exponentiel (30s → 32 min, ~1h cumulé).
Pas de doublon côté NexUn event est dispatch au plus une fois pendant 24h grâce à un dedup store Redis.
Signature HMAC SHA256Garantit l'authenticité (vient de Nex) et l'intégrité (payload non altéré).
Pas de garantie d'ordreSi 2 commandes sont payées dans la même seconde, les webhooks peuvent arriver dans un ordre quelconque. Si l'ordre importe, utilisez paidAt.

Pas de garantie exactly-once

Le dedup côté Nex échoue fail-open si Redis est HS — vous pourriez recevoir un doublon en cas d'incident infra. C'est votre receiver qui doit garantir l'idempotence finale via Nex-Event-Id. Voir le guide receiver.

Les 4 règles vitales côté votre receiver

Si vous ne respectez qu'une seule chose, respectez ces 4 points. Le guide receiver donne le code complet.

1. Vérifier la signature HMAC

text
expected = HMAC_SHA256(webhook_secret, "${t}.${rawBody}")

t et v1 sont parsés du header Nex-Signature. Comparez en temps constant (crypto.timingSafeEqual en Node, équivalent dans votre langage) — jamais === (timing attack).

2. Rejeter les requêtes anciennes (anti-rejeu)

Si now - t > 5 min, retournez 400. Empêche un attaquant qui aurait capturé une requête signée valide de la rejouer plus tard.

3. Idempotence via Nex-Event-Id

Maintenez une table webhook_events_seen(event_id PK, processed_at). INSERT ... ON CONFLICT DO NOTHING : si l'event_id existe déjà, vous ignorez et retournez 200.

4. Répondre 200 rapidement

Timeout Nex = 5 secondes. Si votre logique métier (déblocage marchandise, impression ticket…) prend plus, enqueue le payload en interne et acquittez 200 immédiatement.

Tester votre receiver localement

En développement, utilisez un tunnel HTTPS public pour exposer votre endpoint local :

  • ngrok : ngrok http 3000 → URL https://xxxx.ngrok-free.app à transmettre à Nex
  • Cloudflare Tunnel : cloudflared tunnel --url http://localhost:3000

L'équipe Nex peut mettre à jour temporairement votre webhook URL côté CMMS pour pointer vers votre tunnel. Ne pas pointer le webhook prod vers un tunnel personnel : utilisez une intégration staging dédiée.

Voir aussi

Nex — Plateforme fintech CEMAC