O que é um webhook e por que é diferente de uma API REST?
Em uma API REST, você pergunta: sua aplicação faz um GET e espera a resposta. Em um webhook, o sistema avisa você: quando algo acontece (pagamento aprovado, commit realizado, usuário cadastrado), o servidor dispara um POST na URL que você cadastrou.
Essa inversão de controle torna webhooks muito eficientes — sem polling, sem conexão aberta — mas também mais difíceis de testar e debugar.
Stripe / GitHub
Publisher
Publisher
POST →
httpdrop
Inspetor / Relay
Inspetor / Relay
→
Sua API
Consumer
Consumer
Os 5 pilares de um webhook robusto
-
1
Processamento assíncrono — Responda 200 imediatamente e processe o payload em background (fila, worker). Nunca faça operações lentas antes de retornar a resposta.
-
2
Idempotência — O mesmo evento pode chegar mais de uma vez (retry automático). Use o
eventIddo payload para deduplicar: se já processou, retorne 200 sem reprocessar. -
3
Verificação de assinatura HMAC — Valide o header
X-Signature(HMAC-SHA256 do body + secret) antes de processar qualquer payload. -
4
Retry com backoff exponencial — Se sua API retornar 5xx, o publisher deve tentar novamente: 1min → 5min → 30min → 2h. Erros 4xx não devem gerar retry.
-
5
Logs e alertas — Registre cada evento recebido com: eventId, status de processamento, latência e número de tentativas. Alerte quando a taxa de falha superar 5%.
Testando webhooks com httpdrop
O httpdrop funciona como endpoint receptor temporário para inspecionar payloads de webhooks reais — e também como sender de outbound webhooks da sua aplicação de teste.
Inspecionar payload real — Use o URL do httpdrop como webhook URL no Stripe/GitHub durante dev e veja o payload exato que chegará na sua API.
Testar outbound webhooks — Configure o httpdrop como destino dos webhooks da sua aplicação e inspecione se o payload, headers e assinatura HMAC estão corretos.
Replay — Reenvie qualquer webhook capturado com um clique para testar novamente sem precisar triggerar o evento original.
Verificação de assinatura HMAC (Node.js)
const crypto = require('crypto');
function verifyWebhook(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Segurança: Nunca exponha sua URL de webhook em logs públicos ou respostas de API. Trate-a como credencial. Use sempre HTTPS e valide a assinatura antes de processar qualquer dado.