GH GambleHub

Webhooks: repetições e recibos

1) Modelo básico de entrega

At-least-once (padrão): o evento será entregue ≥1 vezes. As garantias são uma ou outra vez alcançadas pela idimpotência do receptor.
Recibo (ACK): Somente qualquer 2xx (normalmente 200/204) do destinatário significa sucesso. Tudo o resto é interpretado como uma rejeição e leva a uma repetição.
ACK rápido: responda 2xx após a inserção do evento por sua vez, e não após o processamento completo do negócio.

2) Formato de evento e títulos obrigatórios

Carga útil (exemplo)

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
}

Cabeçalhos do remetente

'X-Webhook-Id: evt _ 01XYZ' é um ID de evento exclusivo (use para deduplicar).
'X-Webhook-Seq: 128374' é uma sequência monótona (por assinatura/tema).
`X-Signature: sha256=<base64(hmac_sha256(body, secret))>` — HMAC-подпись.
'X-Retry: 0,1,2...' é o número da tentativa.
'X-Webhook-Versão: 1' - Versão do contrato.
(opcional) 'Traceparent' - correlação de trilhos.

Resposta do destinatário

2xx - aceito com êxito (não haverá mais repetições sobre este 'id').
410 Gone - endpoint removido/inativo → o remetente interrompe as repetições e desativará a assinatura.
429/5xx/timeout - o remetente repete a política de retrações.

3) Política de repetição (retries)

Escada recomendada backoff (+ jitter)

'1s, 3s, 10s, 30s, 2m, 10m, 30m, 2h, 6h, 24h' (paramos após o limite, por exemplo, 48-72 horas).

Regras:
  • Backoff exponencial + jitter aleatório (£20-30%) para evitar «efeito rebanho».
  • Quórum de erro para falhas temporárias (por exemplo, repetição, se 5xx ou tempo de rede).
  • Respect 429: coloque o mínimo 'min' (título Retry-After, próxima janela backoff) '.

Temporizações e tamanhos

Tempo de conexão ≤ 3-5 segundos; tempo total de resposta ≤ 10 segundos.
Tamanho corporal por contrato (por exemplo, ≤ 256 KB), senão 413 → a lógica «chunking» ou «pull URL».

4) Idempotidade e dedução

Aplicação Idumpotente: O processamento de repetições do mesmo 'id' deve devolver o mesmo resultado e não alterar novamente o status.
Armazenamento do lado do destinatário: armazenar '(X-Webhook-Id, processed _ at, checksum)' s TTL ≥ retais (24-72 h).
Chave composta: se vários topics → '(subscrição _ id, event _ id)'.

5) Ordem e efeitos «exactly-once»

Garantir uma ordem rigorosa é difícil em sistemas distribuídos. Use:
  • Partition by key: O mesmo conjunto lógico (por exemplo, 'order _ id') está sempre no mesmo canal de entrega.
  • Sequence: Rejeite os eventos com o antigo 'X-Webhook-Seq' e coloque-os em 'check lot' antes que os faltosos cheguem.
Efeitos exactly-once são alcançados através de:
  • registro de operações aplicadas (outbox/inbox pattern),
  • upsert transacionado por 'event _ id' no banco de dados,
  • sagas/compensações para processos complexos.

6) Solução de erros de status de código (tabela)

Código de respostaValor do remetenteAção
2xxACK recebidoAchamos que foi entregue, paramos os retais
4xx (exceto 410/429)Erro permanente (payload/autorização)Colocar no DLQ, notificar integração
410Endpoint removido/obsoletoParar retraí, desativar subscrição
408/429Sobrecarga de tempo/tempoRepetição por backoff/Jitter; Considerar 'Retry-After'
5xxErro temporário do servidorRepetição por backoff/Jitter
3xxNão use redirets para webhooksInterpretar como erro de configuração

7) Segurança do canal

A assinatura HMAC de cada mensagem; verificação em um receptor com «janela de tempo» (mitm e ataques replay).
mTLS para domínios sensíveis (CUS/pagamentos).
IP allowlist endereços de saída, TLS 1. 2+, HSTS.
PII Minimização: Não envie mais dados pessoais; disfarce nos logs.
Rotação de segredos: duas chaves válidas (ative/next) e o cabeçalho 'X-Key-Id' para especificar a chave atual.

8) Filas, DLQ e réplicas

Os eventos são necessariamente escritos na fila de saída/registro no lado do remetente (para uma réplica confiável).
Se ultrapassar o máximo de retrações, o evento vai para o DLQ (Dead Letter Queue) com a causa.
API replay (para destinatário/operador): reenviação por 'id '/intervalo de tempo/tema, com RPS restrito e assinatura/autorizada adicional.

Exemplo da API Replay (remetente):

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

9) Contrato e versão

Versionize o evento (campo 'schema _ versão') e o transporte ('X-Webhook-Versão').
Adicione os campos apenas como opcionais; quando removida, migração menor e transição (dual-write).
Documente os tipos de evento, exemplos, esquemas (JSON Schema), códigos de erro.

10) Observabilidade e SLO

Métricas-chave do remetente:
  • 'delivery _ sucess _ rate' (2xx/todas as tentativas), 'first _ attempt _ sucess _ rate'
  • `retries_total`, `max_retry_age_seconds`, `dlq_count`
  • `latency_p50/p95` (occurred_at → ack_received_at)
Métricas-chave do destinatário:
  • `ack_latency` (receive → 2xx), `processing_latency` (enqueue → done)
  • `duplicates_total`, `invalid_signature_total`, `out_of_order_total`
SLO exemplos:

99. 9% dos eventos recebem o primeiro ACK ≤ 60 segundos (28d).

  • DLQ ≤ 0. 1% do total; réplicas DLQ ≤ 24 h.

11) Timing e quebras de rede

Use UTC nos campos de tempo; sincronize o NTP.
Envie 'occurred _ at' e anote 'delivered _ at' para contar a liga.
Em caso de interrupções prolongadas de rede/endpoint → acumule na fila e limite o crescimento (backpressure + quotas).

12) Limites recomendados e higiene

RPS para assinatura (por exemplo, 50 RPS, burst 100) + paralelismo (por exemplo, 10).
Max. corpo: 64-256 KB; para mais - «notificação + URL» e assinatura para download.
Nomes de evento em 'snake. case 'ou' dot. type` (`order. created`).
Idempotidade rigorosa das operações write do receptor.

13) Exemplos: remetente e destinatário

13. 1 Remetente (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 Destinatário (pseudocode)

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) Testes e práticas de caos

Maletas negativas: assinatura de nevalida, 429/5xx, tempo, 410, grande payload's.
Comportamentos: out-of-order, duplicados, atrasos de 1 a 10 minutos, separação de 24 horas.
Cargas: burst 10 x; verifique o backpressure e a estabilidade do DLQ.
Contratos: JSON Schema, títulos obrigatórios, eventos estáveis.

15) Folha de cheque de implementação

  • 2xx = ACK, e retorno rápido após enqueê
  • Backoff exponencial + jitter, respeito 'Retry-After'
  • Idempotidade do receptor e dedução por 'X-Webhook-Id' (TTL ≥ retraí)
  • Assinaturas HMAC, rotação de segredos, optional mTLS
  • DLQ + Replay API, monitoramento e alertas
  • Limitações: timeout, RPS, tamanho do corpo
  • Ordem: partition by key ou 'sequence' + 'parcelamento lot'
  • Documentação: esquemas, exemplos, codificações de erro, versões
  • Testes de caos: atrasos, duplicações, falhas de rede, replay prolongado

16) Mini-FAQ

Devemos sempre responder 200?
Qualquer 2xx é considerado um sucesso. 202/204 - Prática normal para «aceito na fila».

Podemos parar as repetições?
Sim, a resposta 410 e/ou através do console/API do remetente (desativar a assinatura).

Como estar com os grandes payload 'ami?
Envie «notificação + secure URL», assine o pedido de download e instale o TTL.

Como garantir a ordem?
Partition by key + `sequence`; Quando a discrepância é «estacionamento lot» e reaproximação.

Resultado

Webhooks confiáveis são uma semântica ACK clara (2xx), repetições razoáveis com backoff + jitter, idempotação rigorosa e dedução, segurança adequada (HMAC/mTLS), filas + DLQ + réplicas, e observabilidade transparente. Fixe o contrato, insira limites e métricas, execute os cenários de caos regularmente e as suas integrações deixam de ser erodidas na primeira falha.

Contact

Entrar em contacto

Contacte-nos para qualquer questão ou necessidade de apoio.Estamos sempre prontos para ajudar!

Iniciar integração

O Email é obrigatório. Telegram ou WhatsApp — opcionais.

O seu nome opcional
Email opcional
Assunto opcional
Mensagem opcional
Telegram opcional
@
Se indicar Telegram — responderemos também por lá.
WhatsApp opcional
Formato: +indicativo e número (ex.: +351XXXXXXXXX).

Ao clicar, concorda com o tratamento dos seus dados.