ctx.verify* faz essa verificação em uma linha: lê o header de assinatura, resolve o secret dos seus secrets e lança erro se não corresponder.
Stripe
index.ts
O
event que seu handler recebe já é o corpo validado com Zod. A plataforma consumiu o corpo da requisição para validá-lo, então chamar request.json() dentro do handler lança erro — use o primeiro parâmetro.Provedores suportados
O Stripe também rejeita eventos com mais de 5 minutos, o que impede que alguém reenvie um evento antigo capturado.
Outros serviços
Para Twilio, GitHub, Slack ou qualquer serviço com assinatura HMAC-SHA256, usectx.verifyHmac. O header é obrigatório porque não existe valor padrão:
Rotacionar secrets
Durante uma rotação, aceite o secret antigo e o novo ao mesmo tempo separando-os por vírgula:Tratar a falha
Os verificadores lançamWebhookVerificationError com um código que indica o que aconteceu:
Funções públicas
Webhooks precisam deconfig.public: true para que o serviço externo possa chamá-los sem credenciais da Jelou. É justamente por isso que a verificação de assinatura é obrigatória: é o único controle de acesso que resta.
Testes
Nos testes,createMockContext() deixa cada verificador lançando missing_secret. Para exercitar o resto do handler, desative a verificação:
Funções públicas
Receber requisições sem credenciais da Jelou.
Secrets
Guardar os secrets de cada provedor.
Execuções diferidas
Agendar um follow-up ao receber o webhook.
Receptor de webhooks
Exemplo completo pronto para copiar.