Skip to main content
Verificar um webhook é confirmar, antes de processar, que a requisição veio da AbacatePay e que o corpo chegou intacto. Sem isso, qualquer pessoa que descubra a URL do seu webhook pode enviar eventos falsos, como um pagamento que nunca aconteceu.

Como funciona a verificação

Cada entrega traz duas provas. Confira as duas. Uma resposta 401 não gera nova tentativa. As regras de entrega estão em Webhooks.

Como conferir o secret

O secret é o valor de 32 caracteres ou mais que você definiu ao criar o webhook. Ele chega em cada entrega em dois lugares, com o mesmo valor:
Leia de um dos dois. O header tem a vantagem de não aparecer nos logs de URL do seu servidor. Compare sempre em tempo constante: uma comparação comum (===, ==, !==) responde mais rápido quando os primeiros caracteres não batem, e isso ajuda quem tenta adivinhar o valor.

Como validar a assinatura HMAC

O header X-Webhook-Signature traz a assinatura do corpo, em base64:
Ela é calculada com HMAC-SHA256 sobre o corpo bruto da requisição, usando a chave pública da AbacatePay que aparece nos exemplos abaixo. A chave é a mesma para todas as contas e não tem relação com o secret do seu webhook nem com a chave pública pk_ do abacatepay.js. Como ela é pública, a assinatura prova que o corpo está intacto, e quem prova a origem é o secret. Calcule a assinatura sobre o corpo exatamente como chegou, antes de qualquer parse de JSON. Um JSON lido e serializado de novo muda espaços e ordem, e a assinatura deixa de bater. No Express, use express.raw({ type: "application/json" }) na rota do webhook.

Checklist de segurança

  • A URL do webhook usa HTTPS. Uma URL http:// é recusada em qualquer ambiente.
  • O secret é aleatório, tem 32 caracteres ou mais e fica numa variável de ambiente, nunca no código.
  • O seu endpoint confere o secret (header ou URL) em tempo constante.
  • O seu endpoint valida a assinatura HMAC sobre o corpo bruto.
  • Quando algo não confere, o endpoint responde 401 e não processa nada.
  • O endpoint descarta eventos repetidos. Veja como evitar processar duas vezes.
  • O endpoint não valida o payload inteiro com um schema rígido (como Zod), porque campos novos podem ser adicionados.
  • Se o secret vazar, crie um webhook novo com outro secret e exclua o antigo.

Perguntas frequentes

Quase sempre é o corpo: o seu framework leu o JSON e você está assinando o objeto serializado de novo. Calcule o HMAC sobre os bytes exatos que chegaram, antes do parse.
Sim. O secret prova que a requisição veio da AbacatePay, e a assinatura prova que o corpo não foi alterado. Uma não substitui a outra.
Não. A assinatura X-Webhook-Signature usa a chave pública da AbacatePay mostrada nos exemplos. O secret só é comparado com o valor que você guardou.