# Quando um webhook nunca chega

Source: https://help.didit.me/pt-PT/integration/webhook-troubleshooting
Updated: 2026-10-12

Percorre o problema por ordem: registo de entregas, nome do evento, firewall, assinatura. Deliveries diz logo se a Didit o enviou, o que divide o problema.

Começa pelo separador **Deliveries** do destino. Se a Didit nunca tentou a
entrega, é um problema de subscrição ou de destino. Se tentou e falhou, o
código de resposta diz-te qual: **404** significa que a tua rota não estava
acessível nesse URL, uma discrepância de assinatura significa que assinaste
os bytes errados.

## Passo 1: a Didit tentou enviá-lo?

Abra Programadores e Webhooks, selecione o endpoint e abra Entregas para ler o pedido e a resposta de cada tentativa. Reenvie após corrigir. Confirme a aplicação, ambiente, eventos subscritos e se o endpoint está ativo.

![A página de webhooks na consola Didit a mostrar o estado de entrega por destino](https://help.didit.me/screenshots/webhooks-light.webp)

*Tudo o que é preciso para distinguir um evento em falta de um endpoint a falhar está nesta página.*

Essa única verificação divide o problema ao meio:

- **Nenhuma tentativa registada** → o evento nunca foi gerado para esse destino. Passa ao passo 2.
- **Tentativa registada, falhou** → a Didit enviou-o e o teu lado rejeitou-o ou não o recebeu. Passa ao passo 3.
- **Tentativa registada, 2xx** → foi entregue com sucesso. O problema está dentro do teu handler, não na entrega.

## Passo 2: nenhuma tentativa foi registada

Por ordem de probabilidade:

1. **O evento não está subscrito.** Não existe wildcard - cada família de eventos tem de ser listada explicitamente. E um nome que não existe (`session.status.updated`, `kyc.completed`) não recebe nada, silenciosamente. Verifica na [lista de eventos](https://help.didit.me/pt-PT/integration/webhooks-basics).
2. **Aplicação errada.** Os destinos pertencem a uma aplicação. Se as tuas sessões correrem numa aplicação diferente da do destino, nenhum evento chegará alguma vez até ele. Esta é a causa mais comum quando tudo parece corretamente configurado.
3. **Nada mudou de facto.** Os webhooks disparam por alteração. Uma sessão que não avançou, ou uma re-triagem de monitorização AML que não encontrou nada acima do limiar, produz corretamente nenhum evento.
4. **O estado que estás à espera ainda não aconteceu.** Uma sessão em In Progress não está terminada. Consulta [quando uma sessão nunca termina](https://help.didit.me/pt-PT/verification-sessions/session-not-finished).

## Passo 3: a entrega foi tentada e falhou

**Um 404** significa que o pedido chegou a algo que não tinha a tua rota. Verifica:

- O caminho exato, incluindo uma barra final. Uma framework que redireciona `/hook` para `/hook/` pode transformar um endpoint que funciona num 404 ou num corpo perdido.
- Se o URL é público. Um anfitrião local ou de staging que não é acessível a partir da internet falha desta forma.
- Se um proxy, balanceador de carga, ou router baseado em caminho à frente da tua aplicação está a enviar esse caminho para outro lado.

**Um 5xx** significa que o teu handler rebentou. Regista o corpo em bruto antes de o analisares, para veres o que ele realmente recebeu.

**Um timeout** significa que não respondeste suficientemente depressa. Devolve 2xx primeiro, processa depois.

**Nada de todo / ligação recusada** significa que o teu edge o bloqueou. A Didit entrega a partir do IP estático **18.203.201.92** com um user agent `DiditWebhook/2.0`. Se estiveres atrás do Cloudflare ou de uma WAF com uma postura de negação por defeito, permite esse IP para o nome do anfitrião recetor.

## O clássico: a entrega automática dá 404 mas o Resend funciona

Este surge com frequência suficiente para merecer nome próprio. A entrega automatizada falha com um 404, e depois clicar em **Resend** no mesmo evento tem sucesso.

Essa combinação significa que o payload e o teu endpoint estão ambos bem - por isso a diferença é de tempo ou de caminho, não de conteúdo. Verifica:

- **Um deploy ou reinício** no momento da entrega original. O Resend tem sucesso mais tarde porque a aplicação já está de novo em pé.
- **Um cold start** que excedeu o timeout da tua plataforma - comum em serverless com uma primeira invocação lenta.
- **Um encaminhamento baseado em caminho que mudou** entre as duas tentativas, ou uma regra que só corresponde a alguns pedidos.
- **Limitação de taxa ou proteção contra bots no teu edge** que deixou passar o reenvio manual porque chegou sozinho em vez de numa rajada.

O separador Deliveries tem ambas as tentativas com os respetivos carimbos de hora - compara-os com os teus próprios registos de deploy e de erro desse minuto.

## A verificação de assinatura a falhar

Quase sempre uma destas três coisas:

1. **Assinaste JSON re-serializado.** Faz o HMAC dos bytes **em bruto** do pedido, exatamente como recebidos. Analisar e voltar a converter em string muda os espaços e a ordem das chaves, e a assinatura não vai corresponder. A maioria das frameworks precisa de configuração explícita para te dar o corpo em bruto.
2. **Segredo errado.** O segredo de assinatura é **por destino**, e não é a tua chave de API. Dois destinos têm dois segredos diferentes.
3. **Suposição de codificação errada.** Se não tiveres a certeza se o segredo é usado como string literal ou descodificado primeiro, não adivinhes - segue exatamente [a referência de verificação de assinatura](https://docs.didit.me/integration/webhooks#signature-verification), e regista o corpo em bruto enquanto depuras, para poderes comparar.

> **Warning:** Nunca "corrijas" uma discrepância de assinatura saltando a verificação. Um
> endpoint de webhook não verificado vai aceitar uma aprovação forjada de
> qualquer pessoa que encontre o URL, o que transforma um atalho de depuração
> num caminho para a apropriação da conta.

## Duas repetições não são uma fila

Nas respostas 5xx ou 404, a Didit tenta novamente duas vezes, após cerca de um minuto e depois quatro. Um tempo limite de 5 segundos ou falha de ligação não é repetido automaticamente. Use Reenviar em Entregas após corrigir; uma falha definitiva gera um alerta.

Constrói um caminho de reconciliação: no arranque, faz polling ao endpoint de decisão para qualquer sessão para a qual não tenhas um estado terminal. Trata os webhooks como o caminho rápido e o polling como a rede de segurança.

## Testar sem correr verificações

[Video: Configurar chaves de API e testar os seus webhooks - Didit Academy](https://www.youtube.com/watch?v=thOMIGbNLP0&t=140)

**Envie um evento de teste** na página do destino envia um evento totalmente formado do tipo que escolheres - aprovado, recusado, em revisão, KYB, entidade, transação. Usa-o para comprovar que o teu endpoint, a verificação de assinatura e o handler funcionam antes de uma sessão real depender deles.

O sandbox é a outra metade disto: uma sessão em sandbox emite webhooks reais com `"environment": "sandbox"`, por isso consegues exercitar todo o caminho, de ponta a ponta, sem custos. Consulta [testar em sandbox](https://help.didit.me/pt-PT/getting-started/sandbox-and-testing).
