Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.abacatepay.com/llms.txt

Use this file to discover all available pages before exploring further.

Pense nos webhooks como “mensagens enviadas pela AbacatePay para o seu sistema”, sem que você precise ficar consultando a API o tempo todo.

Por que usar webhooks?

Sem webhooks, sua aplicação teria que perguntar para a API a cada segundo:
“Esse pagamento já foi confirmado?”
Isso é lento e ineficiente. Com webhooks, a AbacatePay avisa você imediatamente:
“O pagamento foi confirmado. Aqui estão os dados.”
Assim você pode:
  • atualizar o status de um pedido
  • liberar acesso a um produto
  • enviar e-mails automáticos
  • registrar movimentações financeiras
Tudo isso sem precisar fazer nada manualmente, e sem fazer seu cliente esperar.

Como funciona na prática?

  1. Você cria um endpoint no seu sistema
    Ex.: https://meusite.com/webhooks/abacatepay
  2. Você cadastra esse endpoint no dashboard da AbacatePay
  3. Sempre que algo importante acontece, como um pagamento aprovado:
    • A AbacatePay envia um POST para a sua URL
    • O POST contém o evento (ex: checkout.completed, transparent.completed)
    • Seu sistema processa esse evento
É como receber uma notificação push — só que para servidores.

Ambientes (Dev mode vs Produção)

Ambientes da AbacatePay

  • Webhooks criados em Dev mode recebem eventos simulados
  • Webhooks criados em Produção recebem eventos reais
Dessa forma, você pode testar tudo antes de ir para produção.

Segurança dos webhooks

Webhooks precisam ser seguros — afinal, qualquer pessoa poderia tentar enviar requisições falsas para sua aplicação. Por isso, recomendamos duas camadas de proteção:

🔐 1. Secret na URL

Cada webhook tem um secret único, que vai na query string. Ex.: https://meusite.com/webhook/abacatepay?webhookSecret=SEU_SECRET Seu backend confere:
if (req.query.webhookSecret !== process.env.WEBHOOK_SECRET) {
  return res.status(401).json({ error: "Unauthorized" });
}

🛡️ 2. Assinatura HMAC (verificação do corpo)

Mesmo que alguém descubra sua URL e seu secret, ainda não consegue falsificar o evento. Por quê?
Porque cada webhook enviado pela AbacatePay inclui uma assinatura no header:
Essa assinatura é gerada usando HMAC-SHA256 e garante que:
  • o corpo da requisição não foi alterado
  • o evento realmente foi enviado pela AbacatePay
Seu backend deve recalcular a assinatura e comparar:
  • Se for igual → ✅ evento é legítimo
  • Se for diferente → ❌ evento rejeitado
Esse é o mesmo método usado por Stripe, PayPal, Shopify, GitHub, etc.

🔧 Exemplo de validação HMAC (Node.js)

Este exemplo mostra como validar a assinatura HMAC enviada no header
X-Webhook-Signature.
import crypto from "node:crypto";

// Public HMAC key
const ABACATEPAY_PUBLIC_KEY =
  "t9dXRhHHo3yDEj5pVDYz0frf7q6bMKyMRmxxCPIPp3RCplBfXRxqlC6ZpiWmOqj4L63qEaeUOtrCI8P0VMUgo6iIga2ri9ogaHFs0WIIywSMg0q7RmBfybe1E5XJcfC4IW3alNqym0tXoAKkzvfEjZxV6bE0oG2zJrNNYmUCKZyV0KZ3JS8Votf9EAWWYdiDkMkpbMdPggfh1EqHlVkMiTady6jOR3hyzGEHrIz2Ret0xHKMbiqkr9HS1JhNHDX9";

/**
 * Verifies if the webhook signature matches the expected HMAC.
 * @param rawBody Raw request body string.
 * @param signatureFromHeader The signature received from `X-Webhook-Signature`.
 * @returns true if the signature is valid, false otherwise.
 */
export function verifyAbacateSignature(rawBody: string, signatureFromHeader: string) {
  const bodyBuffer = Buffer.from(rawBody, "utf8")

  const expectedSig = crypto
    .createHmac("sha256", ABACATEPAY_PUBLIC_KEY)
    .update(bodyBuffer)
    .digest("base64");

  const A = Buffer.from(expectedSig);
  const B = Buffer.from(signatureFromHeader);

  return A.length === B.length && crypto.timingSafeEqual(A, B);
}

Criando um webhook no dashboard

1

Acesse a seção de Webhooks

Interface mostrando webhooks

Abra a área de Webhooks

É aqui que você cria e gerencia seus endpoints de notificação.
2

Clique em Criar

Configuração de webhook

Inicie a configuração

Informe o nome e a URL que receberá os eventos.
3

Configure os detalhes

O que você deve informar:

  • Nome: Ex.: “Pagamentos confirmados”
  • URL: Endpoint HTTPS que receberá os eventos
  • Secret: Chave usada para verificar a autenticidade

Eventos suportados

EventoQuando é disparado
checkout.completedPagamento de um checkout foi confirmado
checkout.refundedReembolso de um checkout foi concluído
checkout.disputedDisputa/chargeback aberta em um checkout
transparent.completedPagamento de um checkout transparente confirmado
transparent.refundedReembolso de um checkout transparente foi concluído
transparent.disputedDisputa/chargeback aberta em um pagamento transparente
subscription.completedAssinatura criada e ativada
subscription.cancelledAssinatura cancelada
subscription.renewedCobrança recorrente da assinatura foi paga
transfer.completedTransferência concluída com sucesso
transfer.failedTransferência falhou
payout.completedSaque concluído com sucesso
payout.failedSaque falhou
Todos os webhooks v2 compartilham o mesmo formato de payload:
{
  "id": "log_abc123xyz",
  "event": "checkout.completed",
  "apiVersion": 2,
  "devMode": false,
  "data": { ... }
}
Dados sensíveis: O campo taxId (CPF/CNPJ) é mascarado nos payloads (ex: 123.***.***-**). Para pagamentos com cartão, apenas os últimos 4 dígitos e a bandeira são enviados.
Os payloads detalhados de cada evento estão documentados individualmente na seção Eventos na barra lateral.

Estrutura dos payloads

Quando customer está vazio

Se não houver cliente vinculado ao checkout, pagamento ou assinatura, o objeto customer será null.

Boas práticas

Recomendações importantes

  • Use HTTPS em todos os webhooks
  • Valide o secret e a assinatura HMAC
  • Registre cada evento recebido — processe cada um uma única vez
  • Responda 200 OK somente após concluir o processamento
  • Implemente retentativas com idempotência
  • Não realize validação do payload inteiro dos webhooks (como com Zod), evitando que mudanças futuras não quebrem seu endpoint

Precisa de ajuda?

Nossa equipe pode te ajudar. Contate-nos: ajuda@abacatepay.com