ZAP-API
PreçosCasos de UsoBlogDocsLogin
Começar grátis
  1. Blog
  2. Webhook WhatsApp seguro: HMAC, retry exponencial e DLQ
Tutorial

Webhook WhatsApp seguro: HMAC, retry exponencial e DLQ

Como usar webhook WhatsApp em produção com assinatura HMAC-SHA256, retry com backoff exponencial e Dead Letter Queue. Exemplos em Node.js.

30 de abril de 2026·11 min de leitura·Equipe Editorial ZAP API

Webhook é a espinha dorsal de qualquer integração WhatsApp séria — é por ele que sua aplicação recebe mensagens em tempo real, status de entrega, cliques em botão e mudanças de presença. Mas a maioria das APIs trata webhook como "POST e esquece": se cair, você perde o evento; se um atacante descobrir a URL, ele pode forjar mensagens; se sua API ficar 30s lenta, o provider desiste.

Na ZAP API a plataforma de webhooks foi reconstruída em 2026 com 3 garantias que diferenciam um webhook "amador" de um webhook de produção: assinatura HMAC-SHA256, retry com backoff exponencial e Dead Letter Queue (DLQ) com replay one-click.

Por que isso importa

Um webhook sem essas três proteções é uma mina terrestre técnica:

  • Sem assinatura: qualquer pessoa que descobrir a URL pode disparar eventos forjados — cobranças falsas, mensagens fantasmas, scripts maliciosos.
  • Sem retry: se sua aplicação cair por 5 minutos durante um deploy, você perde todas as mensagens recebidas naquela janela. Para sempre.
  • Sem DLQ: quando um payload específico falhar (ex: bug no seu parser), você não tem como reprocessar depois de corrigir o código.

1. Assinatura HMAC-SHA256 — provando que veio da ZAP API

Toda chamada de webhook envia o header X-ZapApi-Signature com o HMAC-SHA256 do corpo bruto, calculado com o seu webhook secret (gerado quando você cadastra a URL no painel).

// Node.js / Express
const crypto = require('crypto');
const express = require('express');
const app = express();

const WEBHOOK_SECRET = process.env.ZAPAPI_WEBHOOK_SECRET;

// IMPORTANTE: use raw body para o HMAC bater
app.post(
  '/webhook/zap',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const signature = req.headers['x-zapapi-signature'];
    const expected = crypto
      .createHmac('sha256', WEBHOOK_SECRET)
      .update(req.body)
      .digest('hex');

    // timingSafeEqual evita timing attack
    const ok = crypto.timingSafeEqual(
      Buffer.from(signature || '', 'hex'),
      Buffer.from(expected, 'hex')
    );

    if (!ok) {
      return res.status(401).json({ error: 'invalid_signature' });
    }

    const event = JSON.parse(req.body.toString());
    console.log('Evento autenticado:', event.type);

    // Responda 2xx em até 5s — qualquer outra coisa entra em retry
    res.status(200).json({ ok: true });
  }
);

app.listen(3000);

Regra de ouro: nunca confie em payload de webhook sem validar a assinatura. Mesmo que a URL pareça "secreta", basta um log mal redactado, um header vazado em screenshot, ou um proxy mal configurado para que a URL seja descoberta.

2. Retry com exponential backoff + jitter

Quando sua aplicação retorna qualquer coisa que não seja 2xx (ou demora mais de 5 segundos), a ZAP API reagenda a entrega com a sequência:

  • Tentativa 1: imediata
  • Tentativa 2: 1s depois (+ jitter aleatório)
  • Tentativa 3: 2s depois
  • Tentativa 4: 4s depois
  • Tentativa 5: 8s depois
  • Tentativa 6: 16s depois

O jitter (variação aleatória) evita o thundering herd — se 1.000 webhooks falharem ao mesmo tempo (típico em outage parcial), o retry não bate todos juntos no mesmo segundo.

Por que parar em 5 retries? Porque depois disso, ou o seu sistema está fora do ar há mais de 30 segundos (intervenção humana necessária), ou o payload tem algum bug específico (precisa de inspeção manual). Continuar tentando indefinidamente só queima recursos.

3. Dead Letter Queue (DLQ) — segunda chance, no seu tempo

Depois das 5 tentativas falhas, o evento vai para a DLQ — uma fila de "entregas mortas" que ficam disponíveis no painel /dashboard/webhooks por 30 dias.

De lá, com um clique no botão "Replay", você reenvia a entrega — útil quando:

  • Você acabou de fazer deploy do fix e quer reprocessar a fila.
  • Um cliente reclamou que "não recebeu a confirmação de pedido" — você acha o evento na DLQ, replay, problema resolvido sem precisar ressincronizar do zero.
  • Quer testar localmente com um payload real de produção — replay para um endpoint de staging.

Listando a DLQ via API

// Listar entregas falhas
GET /v1/webhooks/deliveries?status=failed&limit=50
Authorization: Bearer tk_seu_token

// Resposta
{
  "deliveries": [
    {
      "id": "del_abc123",
      "instanceId": "inst_xxx",
      "event": "message.received",
      "url": "https://meu-app.com/webhook",
      "status": "failed",
      "attempts": 5,
      "lastError": "ECONNREFUSED",
      "payload": { /* ...corpo original... */ },
      "createdAt": "2026-04-30T12:34:56Z"
    }
  ],
  "nextCursor": "..."
}

// Reprocessar uma entrega específica
POST /v1/webhooks/deliveries/del_abc123/replay
Authorization: Bearer tk_seu_token

Padrões de implementação que evitam dor de cabeça

Idempotência: cada evento traz um event_id único

Mesmo com retry, a ZAP API pode entregar o mesmo evento mais de uma vez (ex: sua aplicação respondeu 200 mas a conexão caiu antes). Salve o event.id em uma tabela e ignore duplicatas:

const seen = await db.events.findOne({ where: { eventId: event.id } });
if (seen) {
  return res.status(200).json({ ok: true, duplicate: true });
}
await db.events.create({ eventId: event.id, payload: event });
// ...processar...

Acknowledge primeiro, processe depois

Não rode lógica pesada antes de retornar 200. Coloque o evento em uma fila interna (BullMQ, Redis Streams, SQS) e responda imediatamente:

app.post('/webhook/zap', async (req, res) => {
  // 1. Valida HMAC (rápido)
  if (!validSignature(req)) return res.status(401).end();

  // 2. Enfileira (rápido)
  await queue.add('process-webhook', JSON.parse(req.body));

  // 3. Responde (rápido)
  res.status(200).json({ ok: true });
});

Esse padrão derruba seu p99 de webhook de "1500ms quando o banco está lento" para "8ms sempre".

Eventos disponíveis

A ZAP API entrega 21 tipos de evento via webhook:

  • message.received, message.sent, message.status, message.read, message.reaction, message.edited, message.deleted
  • instance.connected, instance.disconnected, instance.qrcode, instance.test
  • group.join, group.leave, group.update
  • contact.update, presence.update
  • call.received, call.rejected
  • status.viewed, label.update, newsletter.update

Você escolhe quais quer receber em cada instância, no painel ou via PUT /v1/instances/:id/webhook.

FAQ

  • Posso ter mais de uma URL de webhook por instância?
    Sim — configure URLs diferentes por categoria de evento (ex: mensagens vs status de instância) ou aponte tudo para um único endpoint que faz fan-out interno.
  • O HMAC é obrigatório?
    O header é sempre enviado. Validar do seu lado é opcional, mas fortemente recomendado em produção.
  • O que acontece se eu não habilitar webhook?
    Você pode usar polling (GET /v1/instances/:id/messages), mas perde latência (5-30s) e gasta mais quota de API.
  • Há rate limit no webhook?
    Não há rate limit de saída — entregamos tudo. O limite é só na sua aplicação aguentar receber.
  • Quanto tempo a DLQ retém entregas?
    30 dias. Depois disso são apagadas (LGPD).

Criar conta e configurar webhooks com HMAC, retry e DLQ — trial 7 dias, sem cartão.

Experimente a ZAP API gratuitamente

7 dias de trial sem precisar de cartão. A partir de R$29/mês*.

Criar instância grátis
EE
Equipe Editorial ZAP APIRevisão técnica

Desenvolvedores e especialistas em integrações WhatsApp. Todo conteúdo passa por revisão técnica para garantir precisão e aplicabilidade.

Ver perfil completoDocumentaçãoTrial grátis

Leia também

Tutorial · 06 de jun. de 2026 · 10 min

Webhook WhatsApp: receba mensagens em tempo real com Node.js, Python e PHP (2026)

Configure um endpoint que recebe cada mensagem do WhatsApp em tempo real, valida a assinatura HMAC-SHA256 e processa com retry automático. Exemplos completos nas 3 linguagens.

Tutorial · 05 de mar. de 2026 · 10 min

Webhook WhatsApp: Integração e Configuração Fácil

Descubra como configurar webhook WhatsApp e receba mensagens em tempo real. Integre agora com ZAP API! Cadastre-se grátis.

Tutorial · 17 de mai. de 2026 · 12 min

Console de webhooks com replay: debug em produção sem logs manuais

Use o console de webhooks da ZAP API para inspecionar entregas, ver payloads completos, re-enviar eventos com falha e diagnosticar integrações sem acesso ao servidor.

Tutorial · 06 de jun. de 2026 · 10 min

Chatbot WhatsApp com IA: passo a passo com código (2026)

Integre ChatGPT ao WhatsApp via API REST: receba a mensagem no webhook, chame a OpenAI e devolva a resposta em segundos. Código Node.js funcional incluso. Atendimento automático 24h sem escrever resposta manualmente.

Tópicos:Chatbots com IAE-commerceAPI WhatsApp

Explore também

Casos de usoWhatsApp API por segmentoComparativoZAP API vs alternativasPreçosPlanos e o que está inclusoGlossárioTermos técnicos de WhatsApp API
ZAP-API

API REST para WhatsApp com webhooks assinados, Meta Pixel/CAPI e compliance LGPD. Sem aprovação da Meta.

Status operacional🇧🇷 Feito no Brasil

Produto

  • Preços
  • Casos de uso
  • Comparativo
  • Trial grátis
  • Dashboard

Recursos

  • Documentação
  • Blog
  • Glossário
  • RSS Feed

Empresa

  • Sobre
  • Imprensa
  • Termos de uso
  • Privacidade
  • Criar conta
  • Login

Contato

  • [email protected]
  • [email protected]
  • Resposta em até 24h úteis
© 2026 ZAP-API — Todos os direitos reservados·CNPJ 42.130.949/0001-56·Termos·Privacidade

Desenvolvido por PreviusIA