Skip to main content
Sem validação, qualquer pessoa que descobrir sua URL de webhook pode forjar eventos e acionar lógica de negócio (ex: liberar acesso sem pagar). Os dois mecanismos abaixo — secret e HMAC — garantem que o evento veio da AbacatePay e que o corpo não foi alterado. Use ambos. Todo webhook enviado pela AbacatePay inclui dois mecanismos de segurança: um secret na URL e uma assinatura HMAC no header. Use os dois juntos.

1. Secret na URL

Ao criar o webhook, você define um secret. A AbacatePay inclui esse valor como query parameter em cada requisição:
Seu backend valida antes de qualquer processamento:

2. Assinatura HMAC

Mesmo que alguém descubra sua URL e seu secret, a assinatura HMAC garante que o corpo da requisição não foi alterado e que o evento realmente veio da AbacatePay. O header enviado é:
A assinatura é calculada com HMAC-SHA256 sobre o corpo raw da requisição usando a chave pública da AbacatePay.

Validação em Node.js

Validação em Python

Validação em Go

Use sempre timingSafeEqual (ou equivalente) ao comparar assinaturas — nunca ==. Comparações diretas são vulneráveis a timing attacks.

Retentativas

Se seu endpoint não retornar 2xx dentro do timeout, a AbacatePay tenta reenviar o evento automaticamente com backoff progressivo. O que pode causar retentativa:
  • Timeout na conexão
  • Resposta com status 5xx
  • Resposta com status 4xx (exceto 200)
Boas práticas para lidar com retentativas:

Idempotência é obrigatória

Armazene o campo id de cada evento recebido. Antes de processar, verifique se esse ID já foi tratado anteriormente. Eventos duplicados são raros mas acontecem.

Checklist de segurança

  • Use HTTPS — nunca HTTP em produção
  • Valide o secret na query string
  • Valide a assinatura HMAC do header
  • Responda 200 OK somente após concluir o processamento
  • Implemente idempotência usando o id do evento
  • Não valide o payload inteiro com schemas rígidos (como Zod) — campos novos podem ser adicionados futuramente