Webhooks Explicados: Payloads Assinados e Estratégias de Retry
Por que Webhooks Falham e Como Corrigir
Você acabou de integrar o webhook de um provedor de pagamentos para atualizar status de pedidos no seu app. Tudo funciona nos testes, mas em produção, alguns eventos nunca chegam, ou pior, você recebe duplicatas. Sem as devidas proteções, webhooks podem se tornar uma fonte de falhas silenciosas e brechas de segurança.
Webhooks são callbacks HTTP acionados por eventos, mas diferentemente de chamadas de API típicas, eles são baseados em push e assíncronos. Isso introduz dois desafios principais: verificar a autenticidade e garantir a entrega. Neste guia, vamos abordar ambos com payloads assinados e retries inteligentes.
O que São Webhooks?
Um webhook é um callback HTTP definido pelo usuário. Quando um evento ocorre em um sistema de origem (ex.: um novo pagamento), ele envia uma requisição HTTP POST para uma URL que você fornece, contendo os dados do evento. Isso permite reações em tempo real sem polling.
Casos de uso comuns incluem notificações de pagamento, gatilhos de CI/CD e integrações de chat. Mas como webhooks trafegam pela internet pública, eles são vulneráveis a falsificação e perda.
Protegendo Webhooks com Payloads Assinados
Como saber se um webhook realmente vem do seu provedor? Assinar o payload com um segredo compartilhado garante integridade e autenticidade.
Como Funcionam as Assinaturas HMAC
O provedor calcula um HMAC (ex.: SHA-256) do corpo da requisição usando uma chave secreta, e envia a assinatura em um header (ex.: X-Signature). Seu servidor recalcula o HMAC e compara usando uma comparação de tempo constante para prevenir ataques de timing.
// Exemplo em Node.js: verificando a assinatura de um webhook
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
const digest = hmac.digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}
Boas práticas:
- Use um segredo forte e único por endpoint de webhook.
- Inclua um timestamp no payload assinado para prevenir ataques de replay; rejeite requisições mais antigas que alguns minutos.
- Sempre use HTTPS para proteger o payload em trânsito.
Implementando Retries Confiáveis
Mesmo com assinaturas, problemas de rede ou indisponibilidade podem causar falha na entrega do webhook. Provedores geralmente tentam novamente com backoff exponencial, mas você também deve lidar com retries do seu lado.
Idempotência: A Chave para Retries Seguros
Retries podem levar a processamento duplicado. Use chaves de idempotência (frequentemente incluídas no payload ou como header) para garantir que cada evento seja processado exatamente uma vez. Armazene IDs de eventos processados e ignore duplicatas.
// Exemplo: handler de webhook idempotente
const processedEvents = new Set();
app.post('/webhook', (req, res) => {
const eventId = req.body.id;
if (processedEvents.has(eventId)) {
return res.status(200).send('Already processed');
}
// process event...
processedEvents.add(eventId);
res.status(200).send('OK');
});
Estratégia de Retry no Lado do Receptor
Se o seu processamento falhar, responda com um status 5xx para acionar o retry do provedor. Para erros transitórios, você também pode implementar sua própria fila de retry com backoff.
| Cenário | Resposta | Ação |
|---|---|---|
| Sucesso | 200 OK | Sem retry |
| Erro de validação | 400 Bad Request | Sem retry (corrija o payload) |
| Erro no servidor | 500 Internal Server Error | Provedor tenta novamente |
| Limite de requisições | 429 Too Many Requests | Provedor tenta novamente após atraso |
Monitoramento e Depuração de Webhooks
Registre todas as requisições de webhook recebidas com headers e payloads (oculte dados sensíveis). Use uma ferramenta como o JSON Formatter para formatar payloads e facilitar a inspeção. Configure alertas para entregas falhas e acompanhe contagens de retry.
FAQ
O que é um payload de webhook assinado?
Um payload assinado inclui uma assinatura criptográfica (geralmente HMAC) que verifica se a requisição veio de uma fonte confiável e não foi adulterada.
Quantas vezes devo tentar novamente um webhook que falhou?
A maioria dos provedores tenta novamente de 3 a 5 vezes com backoff exponencial. Como receptor, responda com códigos de status apropriados e deixe o provedor lidar com os retries.
Posso usar webhooks sem HTTPS?
Não — HTTPS é essencial para criptografar o payload e prevenir ataques man-in-the-middle. Nunca aceite webhooks via HTTP simples.
Pronto para inspecionar e depurar payloads de webhook? Experimente nosso JSON Formatter gratuito para formatar e validar dados JSON instantaneamente.