GH GambleHub

Webhooks : répétitions et accrochage

1) Modèle de livraison de base

At-least-once (par défaut) : l'événement sera livré ≥1 fois. Les garanties sont assurées exactement ou une fois par l'idempotence du récepteur.
Clavardage (ACK) : n'importe quel 2xx (habituellement 200/204) du destinataire signifie succès. Tout le reste est interprété comme un refus et conduit à une répétition.
ACK rapide : Répondez 2xx après avoir placé l'événement à son tour, plutôt qu'après un traitement complet.

2) Format des événements et titres obligatoires

Charge utile (exemple)

json
{
"id": "evt_01HXYZ",
"type": "order. created",
"occurred_at": "2025-11-03T18:10:12Z",
"sequence": 128374,
"source": "orders",
"data": { "order_id": "o_123", "amount": "49. 90", "currency": "EUR" },
"schema_version": 1
}

Titres de l'expéditeur

"X-Webhook-ID : evt_01HXYZ' - ID d'événement unique (utiliser pour la déduplication).
« X-Webhook-Seq : 128374 » est une séquence monotone (par abonnement/thème).
`X-Signature: sha256=<base64(hmac_sha256(body, secret))>` — HMAC-подпись.
« X-Retry : 0,1,2... » est le numéro de la tentative.
« X-Webhook-Version : 1 » est la version du contrat.
(en option) « Traceparent » est une corrélation de pistes.

Réponse du destinataire

2xx - accepté avec succès (il n'y aura plus de répétitions sur ce 'id').
410 Gone - endpoint est supprimé/inactif → l'expéditeur arrête les répétitions et désabonne.
429/5xx/timaut - l'expéditeur répète sur la politique des retraits.

3) Politique de répétition (retries)

Escalier backoff recommandé (+ jitter)

« 1s, 3s, 10s, 30s, 2m, 10m, 30m, 2h, 6h, 24h » (on s'arrête après une limite, par exemple de 48 à 72 heures).

Règles :
  • Backoff exponentiel + jitter aléatoire (± 20-30 %) pour éviter l'effet « troupeau ».
  • Quorum d'erreur pour les pannes temporelles (par exemple, répétition si 5xx ou temporisation du réseau).
  • Respect 429 : mettez au minimum 'min (titre Retry-After, fenêtre backoff suivante)'.

Délais et tailles

Délai de connexion ≤ 3-5 secondes ; le délai total de réponse est ≤ 10 secondes.
Taille du corps contractuel (par exemple, ≤ 256 Ko), sinon 413 → logique « chunking » ou « pull URL ».

4) Idempotence et déduplication

Application idempotente : le traitement des répétitions du même 'id'doit renvoyer le même résultat et ne pas changer l'état à nouveau.
Stockage dedup sur le côté destinataire : Stocker '(X-Webhook-Id, processed_at, checksum)' avec la TTL ≥ la fenêtre des retraits (24-72 h).
Clé de composition : si plusieurs tops → '(subscription_id, event_id)'.

5) Ordre et « effets exactly-once »

Il est difficile de garantir un ordre strict dans les systèmes distribués. Utilisez :
  • Partition by key : le même ensemble logique (par exemple, 'order _ id') est toujours dans le même « canal » de livraison.
  • Séquence : Rejetez les événements avec l'ancien 'X-Webhook-Seq' et mettez-les dans le « lot de stationnement » avant l'arrivée des manquants.
Les effets Exactly-once sont obtenus par :
  • journal des opérations appliquées (outbox/inbox pattern),
  • transactionnel upsert par 'event _ id' dans la base de données,
  • saga/compensation pour les processus complexes.

6) Résolution des erreurs de code de statut (tableau)

Code de réponseValeur pour l'expéditeurAction
2xxACK obtenuNous considérons livrés, arrêtons les retraits
4xx (sauf 410/429)Erreur persistante (payload/autorisation)Mettre dans DLQ, notifier l'intégration
410Endpoint supprimé/obsolèteArrêter les retraits, désactiver l'abonnement
408/429Surcharge/temporisationRépétition par backoff/Jitter ; prendre en compte 'Retry-After'
5xxErreur temporaire du serveurRépétition par backoff/Jitter
3xxN'utilisez pas de redirect pour les webhooksInterpréter comme une erreur de configuration

7) Sécurité du canal

La signature HMAC de chaque message ; la vérification sur le récepteur avec la « fenêtre temporelle » (attaques mitm et replay).
mTLS pour les domaines sensibles (CUS/paiements).
IP allowlist des adresses sortantes, TLS 1. 2+, HSTS.
PII-minimisation : n'envoyez pas de données personnelles supplémentaires ; masquer dans les loges.
Rotation des secrets : deux clés actives (active/next) et l'en-tête "X-Key-Id'pour indiquer le courant.

8) Files d'attente, DLQ et relais

Les événements sont obligatoirement écrits dans la file d'attente/journal de sortie du côté de l'expéditeur (pour un relais fiable).
Si vous dépassez le maximum de rétroactifs - l'événement passe au DLQ (Dead Letter Queue) avec la raison.
API Replay (pour le destinataire/opérateur) : retransmission par 'id '/plage temporelle/sujet, avec restriction RPS et signature/autorisation supplémentaire.

Exemple d'API Replay (expéditeur) :

POST /v1/webhooks/replay
{ "subscription_id": "sub_123", "from": "2025-11-03T00:00:00Z", "to": "2025-11-03T12:00:00Z" }
→ 202 Accepted

9) Contrat et version

Versez l'événement (« schema _ version ») et le transport (« X-Webhook-Version »).
Ajouter les champs uniquement en option ; lors de la suppression, la migration mineure et la période de transition (dual-write).
Documentez les types d'événements, les exemples, les schémas (JSON Schema), les codes d'erreur.

10) Observabilité et SLO

Mesures clés de l'expéditeur :
  • 'delivery _ success _ rate' (2xx/tous les essais), 'first _ attempt _ success _ rate'
  • `retries_total`, `max_retry_age_seconds`, `dlq_count`
  • `latency_p50/p95` (occurred_at → ack_received_at)
Mesures clés du destinataire :
  • `ack_latency` (receive → 2xx), `processing_latency` (enqueue → done)
  • `duplicates_total`, `invalid_signature_total`, `out_of_order_total`
Exemples de SLO :

99. 9 % des événements reçoivent le premier ACK ≤ 60 secondes (28d).

  • DLQ ≤ 0. 1 % du total ; repli DLQ ≤ 24 h.

11) Temporisation et ruptures de réseau

Utilisez UTC dans les champs de temps ; Synchroniser NTP.
Envoyez 'occurred _ at' et fixez 'delivered _ at' pour compter lag.
En cas de rupture prolongée du réseau/endpoint, accumulez les → dans la file d'attente, limitez la croissance (backpressure + quotas).

12) Limites recommandées et hygiène

RPS d'abonnement (par example 50 RPS, burst 100) + parallélisme (par example 10).
Max. corps : 64-256 Ko ; Pour plus, « notification + URL » et signature de téléchargement.
Noms des événements dans 'snake. case 'ou' dot. type` (`order. created`).
L'idempotence stricte des opérations write du récepteur.

13) Exemples : Expéditeur et destinataire

13. 1 Expéditeur (pseudo-code)

python def send_event(event, attempt=0):
body = json. dumps(event)
sig = hmac_sha256_base64(body, secret)
headers = {
"X-Webhook-Id": event["id"],
"X-Webhook-Seq": str(event["sequence"]),
"X-Retry": str(attempt),
"X-Signature": f"sha256={sig}",
"Content-Type": "application/json"
}
res = http. post(endpoint, body, headers, timeout=10)
if 200 <= res. status < 300:
mark_delivered(event["id"])
elif res. status == 410:
deactivate_subscription()
else:
schedule_retry(event, attempt+1) # backoff + jitter, respect 429 Retry-After

13. 2 Destinataire (pseudo-code)

python
@app. post("/webhooks")
def handle():
body  = request. data headers = request. headers assert verify_hmac(body, headers["X-Signature"], secret)
evt_id = headers["X-Webhook-Id"]
if dedup_store. exists(evt_id):
return, "" 204 enqueue_for_processing (body) # fast path. dedup_store put(evt_id, ttl=723600)
return, "" 202 # or 204

14) Tests et pratiques de chaos

Cas négatifs : signature non valide, 429/5xx, temporisation, 410, gros payload's.
Comportemental : out-of-order, doublons, retards de 1 à 10 minutes, écart de 24 heures.
Charge : burst 10 × ; vérifier la résilience et la résilience du DLQ.
Contrats : JSON Schema, titres obligatoires, types d'événements stables.

15) Chèque de mise en œuvre

  • 2xx = ACK, et retour rapide après l'enquête
  • Exponentielle backoff + jitter, respect de 'Retry-After'
  • Idempotence du récepteur et du dedup selon "X-Webhook-Id' (TTL ≥ retrai)
  • Signatures HMAC, rotation des secrets, optional mTLS
  • API DLQ + Replay, surveillance et alertes
  • Restrictions : Délai, RPS, taille du corps
  • Ordre : partition par clé ou « sequence » + « parking lot »
  • Documentation : schémas, exemples, codes d'erreur, versions
  • Tests de chaos : retards, prises, défaillance du réseau, replay prolongé

16) Mini-FAQ

Dois-je toujours répondre 200 ?
N'importe quel 2xx est considéré comme un succès. 202/204 est une pratique normale pour la « file d'attente ».

Peut-on arrêter les répétitions ?
Oui, par la réponse 410 et/ou via la console/API de l'expéditeur (désactivation de l'abonnement).

Qu'en est-il des grands payload'ami ?
Envoyez une « notification + URL sécurisée », signez votre demande de téléchargement et installez TTL.

Comment assurer l'ordre ?
Partition by key + `sequence`; en cas de divergence - « parking lot » et rejouer.

Résultat

Les webhooks fiables sont une sémantique ACK (2xx) claire, des répétitions intelligentes avec backoff + jitter, une idempotence et une déduplication strictes, une sécurité compétente (HMAC/mTLS), une file d'attente + DLQ + et une observabilité transparente. Fixez le contrat, entrez les limites et les métriques, chassez régulièrement les scénarios de chaos - et vos intégrations cesseront d'éclater au premier crash.

Contact

Prendre contact

Contactez-nous pour toute question ou demande d’assistance.Nous sommes toujours prêts à vous aider !

Commencer l’intégration

L’Email est obligatoire. Telegram ou WhatsApp — optionnels.

Votre nom optionnel
Email optionnel
Objet optionnel
Message optionnel
Telegram optionnel
@
Si vous indiquez Telegram — nous vous répondrons aussi là-bas.
WhatsApp optionnel
Format : +code pays et numéro (ex. +33XXXXXXXXX).

En cliquant sur ce bouton, vous acceptez le traitement de vos données.