GH GambleHub

Webhooks: ripetizioni e ricevute

1) Modello di consegna di base

At-least-once (impostazione predefinita) - L'evento verrà consegnato ≥1 volte. Le garanzie vengono raggiunte esattamente una volta alla volta dall'idipotenza del ricevitore.
Ricevuta (ACK): solo ogni 2xx (di solito 200/204) del destinatario significa successo. Tutto il resto viene interpretato come un rifiuto e porta a ripetersi.
Rapido ACK: rispondere a 2xx dopo aver ospitato l'evento a sua volta, anziché dopo l'elaborazione aziendale completa.

2) Formato eventi e intestazioni obbligatorie

Carico di lavoro utile (esempio)

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
}

Intestazione mittente

«X-Webhook-ID: evt _ 01HXYZ» è un ID evento univoco (utilizzare per la deduplicazione).
«X-Webhook-Seq: 128374» è una sequenza monotona (per abbonamento/argomento).
`X-Signature: sha256=<base64(hmac_sha256(body, secret))>` — HMAC-подпись.
«X-Retry: 0,1,2...» è il numero di tentativo.
X-Webhook-Variante: 1 - Versioning del contratto.
(opzionale) «Traceparent» è una correlazione tra le piste.

Risposta del destinatario

2xx - Accettata correttamente (non ci saranno più ripetizioni per questo «id»).
410 Gone - endpoint rimosso/inattivo, il mittente interrompe le ripetizioni e disattiva l'abbonamento.
429/5xx/timeout - il mittente ripete per la politica dei retrai.

3) Criterio di ripetizione (retries)

Scala backoff consigliata (+ jitter)

'1s, 3s, 10s, 30s, 2m, 10m, 30m, 2h, 6h, 24h' (per esempio, 48-72 ore).

Regole:
  • Backoff esponenziale + jitter casuale (© 20-30%) per evitare «effetto gregge».
  • Quorum di errore per i guasti temporanei (ad esempio ripetizione se 5xx o timeout della rete).
  • Respect 429 - Imposta il minimo dì min (titolo Retry-After, prossima finestra backoff) '.

Timeout e quote

Timeout connessione 3-5 secondi; Il tempo totale della risposta è di 10 secondi.
Dimensioni del corpo sotto contratto (ad esempio, 256 KB), altrimenti 413 la logica «chunking» o «pull URL».

4) Idampotenza e deduplicazione

Idipotente: l'elaborazione di ripetizioni dello stesso «id» deve restituire lo stesso risultato e non modificare nuovamente lo stato.
Storage di deduplicazione lato destinatario: memorizza '(X-Webhook-Id, processed _ at, checksum)' con TTL dalla finestra dei retrai (24-72 ore).
Chiave composita: se ci sono più topic «(subscrizione _ id, event _ id)».

5) Ordine e effetti «exactly-once»

Garantire un ordine rigoroso è difficile nei sistemi distribuiti. Usa:
  • Partition by key: la stessa moltitudine logica (ad esempio, «order _ id») è sempre nello stesso canale di consegna.
  • Sequence: rifiuta gli eventi con il vecchio «X-Webhook-Seq» e inseriscili in «parcheggio lot» prima che arrivino quelli mancanti.
Gli effetti exactly-once si ottengono attraverso:
  • registro delle operazioni applicate (outbox/inbox pattern),
  • upsert transazionale per «event _ id» nel database,
  • sagra/compensi per processi complessi.

6) Risoluzione degli errori di stato-codice (tabella)

Codice di rispostaValore per il mittenteAzione
2xxACK ricevutoPensiamo che sia stato consegnato, fermiamo i retrai
4xx (tranne 410/429)Errore permanente (payload/autorizzazione)Inserisci in DLQ, notifica integrazione
410Endpoint rimosso/obsoletoInterrompi i retrai, disattiva l'abbonamento
408/429Sovraccarico temporaneo/timeoutRipetizione backoff/jitter; Tenere conto dì Retry-After '
5xxErrore temporaneo del serverRipetizione backoff/jitter
3xxNon usare ready per webhoopInterpretazione come errore di configurazione

7) Sicurezza canale

Firma HMAC di ogni messaggio; verifica del ricevitore con «finestra di tempo» (mitm e attacchi replay).
mTLS per domini sensibili (CUS/pagamenti).
IP allowlist indirizzi in uscita, TLS 1. 2+, HSTS.
Riduzioni PII: non inviare dati personali superflui mascherarlo nei cassetti.
Rotazione dei segreti: due chiavi attive (active/next) e l'intestazione «X-Key-ID» per specificare la chiave corrente.

8) Code, DLQ e repliche

Gli eventi devono essere scritti nella coda di output/registro sul lato mittente (per una replica affidabile).
Se si supera il massimo dei retrai, l'evento viene inviato al DLQ (Dead Letter Queue) con la causa.
Replay API (per destinatario/operatore): invio ripetuto per «id »/intervallo di tempo/argomento, con vincolo RPS e firma/autorizzazione aggiuntiva.

Esempio API Replay (mittente):

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

9) Contratto e versione

Versionare l'evento (campo «schema _ variante») e il trasporto («X-Webhook-Variante»).
Aggiungere i campi solo come opzionali; all'eliminazione: migrazione minore e periodo di transizione (dual-write).
Documentare i tipi di eventi, gli esempi, gli schemi (JSON Schema), i codici di errore.

10) Osservabilità e SLO

Metriche chiave mittente:
  • "delivery _ success _ rate" (2xx/tutti i tentativi), "first _ attempt _ success _ rat'
  • `retries_total`, `max_retry_age_seconds`, `dlq_count`
  • `latency_p50/p95` (occurred_at → ack_received_at)
Metriche chiave destinatario:
  • `ack_latency` (receive → 2xx), `processing_latency` (enqueue → done)
  • `duplicates_total`, `invalid_signature_total`, `out_of_order_total`
SLO esempi:

99. Il 9% degli eventi riceve la prima ACK da 60 secondi (28d).

  • DLQ ≤ 0. 1% del totale; repliche DLQ da 24 ore

11) Timing e interruzioni di rete

Utilizzare UTC nei campi temporali sincronizzare NTP.
Invia «occurred _ at» e fissa «delivered _ at» per contare la lega.
In caso di interruzioni prolungate della rete/endpoint, accumulare in coda, limitare la crescita (backpressure + quote).

12) Limiti e igiene consigliati

RPS per abbonamento (ad esempio 50 RPS, burst 100) + parallelismo (ad esempio 10).
Max. corpo: 64-256 KB; per di più: «notifica + URL» e firma per il download.
Nomi degli eventi in'snake. case'o'dot. type` (`order. created`).
Idampotenza rigorosa delle operazioni write del ricevitore.

13) Esempi: mittente e destinatario

13. 1 Mittente (pseudocode)

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 Destinatario (pseudo-codice)

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) Test e pratiche di caos

Valigette negative: firma nefalide, 429/5xx, timeout, 410, big payload.
Comportamento: out-of-order, duplicati, ritardo di 1-10 minuti, interruzione di 24 ore.
Carichi di lavoro: burst 10 x; verificare la stabilità del DLQ e backpressure.
Contratti: JSON Schema, titoli obbligatori, eventi stabili.

15) Assegno-foglio di implementazione

  • 2xx = ACK, e rapido ritorno dopo encue
  • Backoff esponenziale + jitter, rispettò Retry-After "
  • Idampotenza del ricevitore e deducibilità dì X-Webhook-ID '(TTL-retrai)
  • Firme HMAC, rotazione dei segreti, optional
  • DLQ + Replay API, monitoraggio e alert
  • Vincoli: timeout, RPS, dimensioni del corpo
  • Ordine: partition by key o «sequence» + «parcheggio lot»
  • Documentazione: schemi, esempi, codifica degli errori, versioni
  • Test di caos: ritardi, riprese, guasto di rete, replay prolungato

16) Mini FAQ

Dobbiamo sempre rispondere a 200?
Ogni 2xx è considerato un successo. 202/204 - Pratica normale per «accettata in fila».

Possiamo fermare le ripetizioni?
Sì, con la risposta 410 e/o tramite la console/API del mittente (disattivare l'abbonamento).

Come si fa con i grandi payload?
Inviare «notifica + secure URL», firmare la richiesta di download e installare TTL.

Come mantenere l'ordine?
Partition by key + `sequence`; in caso di discontinuità, «parcheggio lot» e ripetizione.

Totale

I webhoop affidabili sono una netta semantica ACK (2xx), ripetizioni intelligenti con backoff + jitter, idampotenza e deduplicazione rigorosa, sicurezza corretta (HMAC/mTLS), code + DLQ + repliche e osservabilità trasparente. Fissare il contratto, immettere limiti e metriche, scansionare regolarmente gli script di caos e le integrazioni smetteranno di sfocare al primo guasto.

Contact

Mettiti in contatto

Scrivici per qualsiasi domanda o richiesta di supporto.Siamo sempre pronti ad aiutarti!

Avvia integrazione

L’Email è obbligatoria. Telegram o WhatsApp — opzionali.

Il tuo nome opzionale
Email opzionale
Oggetto opzionale
Messaggio opzionale
Telegram opzionale
@
Se indichi Telegram — ti risponderemo anche lì, oltre che via Email.
WhatsApp opzionale
Formato: +prefisso internazionale e numero (ad es. +39XXXXXXXXX).

Cliccando sul pulsante, acconsenti al trattamento dei dati.