Webhooks Explicados: Payloads Assinados e Retentativas

Backend2026-11-09TryQuickToolBox

Você acabou de integrar 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 desafios críticos: verificar se a requisição realmente vem do remetente e garantir que os eventos não sejam perdidos se seu servidor estiver temporariamente indisponível. Este artigo explica como implementar payloads assinados e mecanismos de retentativa para construir um receptor de webhook robusto.

O que são Webhooks?

Um webhook é um callback HTTP: em vez de sua aplicação fazer polling de uma API para obter atualizações, o serviço envia uma requisição HTTP POST para uma URL que você fornece sempre que um evento ocorre. Esse modelo push reduz a latência e a carga do servidor. No entanto, como a requisição se origina de um serviço externo, você deve tratá-la como entrada não confiável.

Por que assinar payloads?

Sem verificação, qualquer pessoa que descubra seu endpoint de webhook pode enviar eventos falsos, potencialmente acionando ações não autorizadas. Assinar payloads com um segredo compartilhado permite confirmar a identidade do remetente e garantir que o payload não foi adulterado. O método mais comum é o HMAC (Hash-based Message Authentication Code) usando SHA-256.

Como funciona a assinatura HMAC

O remetente calcula um digest HMAC do corpo bruto da requisição usando uma chave secreta e o inclui em um cabeçalho (por exemplo, X-Signature). Seu servidor recalcula o HMAC com o mesmo segredo e o compara com a assinatura recebida. Se corresponderem, a requisição é autêntica.

// 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');
  // Use timingSafeEqual para prevenir ataques de temporização
  return crypto.timingSafeEqual(
    Buffer.from(digest, 'hex'),
    Buffer.from(signature, 'hex')
  );
}

Importante: Sempre use uma função de comparação de tempo constante (como timingSafeEqual) para evitar vazamento de informações por diferenças de temporização. Além disso, calcule o HMAC sobre o corpo bruto, não sobre o JSON parseado, pois a re-serialização pode alterar a sequência de bytes.

Implementando Retentativas

Mesmo com assinaturas, problemas de rede ou erros de servidor podem fazer com que a entrega do webhook falhe. Um remetente confiável tentará novamente entregas falhas, tipicamente com backoff exponencial. Como receptor, você deve projetar seu endpoint para ser idempotente e retornar códigos de status apropriados.

Estratégia de retentativa do ponto de vista do remetente

Projetando um receptor idempotente

Como as retentativas podem causar entregas duplicadas, seu receptor deve lidar com o mesmo evento várias vezes sem efeitos adversos. Inclua um ID de evento único no payload (ou cabeçalho) e armazene os IDs processados. Se um ID de evento já foi processado, retorne 200 OK imediatamente sem reprocessar.

// Pseudocódigo para manipulação idempotente de webhook
function handleWebhook(event) {
  if (processedEvents.has(event.id)) {
    return { status: 200, body: 'Already processed' };
  }
  // Process event...
  processedEvents.add(event.id);
  return { status: 200, body: 'Success' };
}

Melhores práticas para segurança e confiabilidade de webhooks

Comparação: Polling vs. Webhooks

AspectoPollingWebhooks
LatênciaDepende do intervaloQuase em tempo real
Carga no servidorAlta (requisições frequentes)Baixa (apenas em eventos)
ComplexidadeSimples de implementarRequer verificação de assinatura e tratamento de retentativas
ConfiabilidadeVocê controla as retentativasDepende da política de retentativa do remetente

FAQ

Como verifico a assinatura de um webhook?

Calcule um HMAC do corpo bruto da requisição usando o segredo compartilhado e compare-o com a assinatura no cabeçalho usando uma função de comparação de tempo constante.

O que meu endpoint de webhook deve retornar?

Retorne um código de status 2xx (por exemplo, 200 OK) assim que receber o evento. Se retornar 4xx ou 5xx, o remetente pode retentar ou marcar a entrega como falha.

Posso usar webhooks sem assinaturas?

Não é recomendado. Sem assinaturas, você não pode verificar o remetente, deixando seu endpoint vulnerável a requisições falsas. Sempre use assinaturas em produção.

Ao depurar payloads de webhook, a formatação JSON é essencial. Use nosso formatador JSON para imprimir e validar rapidamente os dados JSON recebidos.