Webhooks Explicados: Payloads Assinados e Retentativas

Backend2026-11-06TryQuickToolBox

Você integrou um gateway de pagamento ou um serviço de CI/CD e agora precisa receber eventos em tempo real. Webhooks são a solução padrão, mas vêm com dois grandes desafios: verificar se a requisição realmente veio do remetente esperado e lidar com falhas quando seu endpoint está fora do ar ou lento. Este artigo explica como implementar payloads assinados e lógica de retentativa robusta, com exemplos práticos de código.

O que são Webhooks?

Um webhook é um callback HTTP definido pelo usuário. Em vez de sua aplicação consultar uma API periodicamente para obter atualizações, o provedor envia uma requisição HTTP POST para uma URL que você especifica sempre que um evento ocorre. Isso torna as integrações eficientes e quase em tempo real.

No entanto, webhooks são baseados em push, o que significa que seu endpoint deve ser publicamente acessível, lidar com carga inesperada e lidar com requisições duplicadas ou maliciosas. É aí que entram a assinatura e as retentativas.

Por que assinar payloads de webhook?

Sem verificação, qualquer pessoa que conheça a URL do seu webhook pode enviar eventos falsos. Assinar payloads com um segredo compartilhado permite autenticar o remetente e garantir que o payload não foi adulterado.

A abordagem mais comum é HMAC (Hash-based Message Authentication Code) usando SHA-256. O provedor calcula uma assinatura sobre o corpo bruto da requisição usando uma chave secreta e a inclui em um cabeçalho (por exemplo, X-Signature). Seu servidor recalcula a assinatura e as compara.

Implementando a verificação HMAC

Aqui está um exemplo simples em Node.js usando Express:

const crypto = require('crypto');
const express = require('express');
const app = express();

// Use raw body for signature verification
app.use(express.raw({ type: 'application/json' }));

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-signature'];
  const secret = process.env.WEBHOOK_SECRET;
  const payload = req.body; // Buffer

  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(401).send('Invalid signature');
  }

  // Process the event
  const event = JSON.parse(payload);
  console.log('Received event:', event.type);
  res.status(200).send('OK');
});

app.listen(3000, () => console.log('Webhook server running'));

Pontos-chave:

Lidando com retentativas: tornando webhooks confiáveis

Redes falham, servidores quebram e implantações causam indisponibilidade. Um sistema de webhook confiável deve retentar entregas falhas. Mas retentativas ingênuas podem causar processamento duplicado e sobrecarregar seu sistema.

Estratégias de retentativa

Padrões comuns de retentativa incluem:

A maioria dos provedores implementa algo como: retentar até 5 vezes com backoff exponencial ao longo de 24 horas.

Idempotência: a chave para retentativas seguras

Como as retentativas podem entregar o mesmo evento várias vezes, seu endpoint deve ser idempotente. Inclua um ID de evento único no payload e armazene os IDs processados para ignorar duplicatas.

Exemplo usando um conjunto simples em memória (use um banco de dados em produção):

const processedEvents = new Set();

app.post('/webhook', (req, res) => {
  // ... signature verification ...
  const event = JSON.parse(payload);
  if (processedEvents.has(event.id)) {
    return res.status(200).send('Already processed');
  }
  // Process event
  processedEvents.add(event.id);
  res.status(200).send('OK');
});

Para produção, use um banco de dados com uma restrição de unicidade no ID do evento.

Melhores práticas para consumidores de webhook

Comparação de políticas de retentativa

Política Prós Contras
Intervalo fixo Simples de implementar Pode sobrecarregar um sistema em recuperação
Backoff exponencial Reduz a carga durante indisponibilidades Atrasa a entrega se a falha for transitória
Backoff exponencial com jitter Evita retentativas sincronizadas Um pouco mais complexo

Perguntas frequentes

Como verifico a assinatura de um webhook?

Calcule o HMAC do corpo bruto da requisição usando o segredo compartilhado e compare-o com o cabeçalho de assinatura usando uma função timing-safe. Nunca compare com igualdade simples.

O que devo fazer se meu endpoint de webhook estiver fora do ar?

O provedor deve retentar com backoff exponencial. Garanta que seu endpoint retorne 2xx rapidamente e processe eventos de forma assíncrona para minimizar o impacto da indisponibilidade.

Posso usar webhooks sem assinatura?

Não é recomendado. Sem assinaturas, você não pode verificar o remetente, tornando seu endpoint vulnerável a eventos falsos. Sempre use assinaturas quando disponíveis.

Ao testar payloads de webhook, você pode precisar inspecionar dados JSON. Use o JSON Formatter para formatar e validar payloads rapidamente.