Skip to main content
Webhooks permitem que sua aplicação receba notificações em tempo real sobre eventos importantes da AbacatePay.

Gerenciar webhooks

Gerencie seus webhooks diretamente em nossa plataforma. Você pode:
  • Listar todos os webhooks ativos
  • Criar novos webhooks
  • Remover webhooks existentes

Ambientes e Webhooks

Os webhooks são específicos para cada ambiente:
  • Webhooks criados em dev mode recebem notificações apenas do ambiente de testes
  • Webhooks criados em produção recebem notificações apenas de dados reais
Saiba mais sobre o ambiente de desenvolvimento aqui.

Criar webhooks

Segurança dos Webhooks

  • Configure um secret único para cada webhook
  • Valide o secret em todas as requisições recebidas
  • Use HTTPS para todas as URLs de webhook
  • Implemente retry logic para lidar com falhas temporárias

Como criar seu webhook

Siga estes passos no dashboard da AbacatePay:
1

Acesse a Seção de Webhooks

Interface da plataforma AbacatePay mostrando a seção de webhooks

Navegue até a seção Webhooks

Inicie o processo de configuração de um novo webhook
2

Inicie a Criação

Formulário de criação de webhook

Clique em 'Criar' e prepare-se para configurar

Você será direcionado ao formulário de configuração
3

Configure seu Webhook

Preencha os campos necessários:

  • Nome: Identificador único para seu webhook (ex: “Notificações de Pagamento”)
  • URL: Endpoint HTTPS que receberá as notificações
  • Secret: Chave secreta para validar as requisições

Segurança e verificação

As notificações podem (e devem) ser validadas em duas camadas complementares:

1) Secret na URL (autenticação simples)

Cada chamada de webhook inclui o secret configurado como parâmetro de query string. URL base do seu webhook:
https://meusite.com/webhook/abacatepay
URL com secret (como será chamado):
https://meusite.com/webhook/abacatepay?webhookSecret=seu_secret_aqui
Exemplo de validação (Express):
app.post('/webhook/abacatepay', (req, res) => {
  const webhookSecret = req.query.webhookSecret;
  if (webhookSecret !== process.env.WEBHOOK_SECRET) {
    return res.status(401).json({ error: 'Invalid webhook secret' });
  }

  const event = req.body;
  console.log('Received webhook:', event);
  res.status(200).json({ received: true });
});

2) Assinatura HMAC no cabeçalho (integridade do corpo)

Além do webhookSecret, valide a integridade da mensagem conferindo a assinatura enviada em X-Webhook-Signature. O exemplo abaixo mostra como validar a assinatura HMAC-SHA256 de forma segura.
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);
}
Importante: para que a verificação funcione, leia o corpo bruto da requisição (sem transformações) antes de qualquer middleware que faça parsing. Use exatamente os mesmos bytes recebidos ao calcular o HMAC.

Eventos Suportados

Atualmente, suportamos os seguintes eventos:

billing.paid

Este evento é disparado quando um pagamento é confirmado. O payload varia dependendo da origem do pagamento:
  • PIX QR Code
  • Cobrança
{
  "id": "log_12345abcdef",
  "data": {
    "payment": {
      "amount": 1000,
      "fee": 80,
      "method": "PIX"
    },
    "pixQrCode": {
      "amount": 1000,
      "id": "pix_char_mXTWdj6sABWnc4uL2Rh1r6tb",
      "kind": "PIX",
      "status": "PAID"
    }
  },
  "devMode": false,
  "event": "billing.paid"
}

withdraw.done

Este evento é disparado quando um saque é concluído com sucesso. O payload contém o objeto Transaction:
{
  "id": "log_12345abcdef",
  "data": {
    "transaction": {
      "id": "tran_123456",
      "status": "COMPLETE",
      "devMode": false,
      "receiptUrl": "https://abacatepay.com/receipt/tran_123456",
      "kind": "WITHDRAW",
      "amount": 5000,
      "platformFee": 80,
      "externalId": "withdraw-1234",
      "createdAt": "2025-03-24T21:50:20.772Z",
      "updatedAt": "2025-03-24T21:55:20.772Z"
    }
  },
  "devMode": false,
  "event": "withdraw.done"
}

withdraw.failed

Este evento é disparado quando um saque não é concluído. O payload contém o objeto Transaction:
{
  "id": "log_12345abcdef",
  "data": {
    "transaction": {
      "id": "tran_789012",
      "status": "CANCELLED",
      "devMode": false,
      "receiptUrl": "https://abacatepay.com/receipt/tran_789012",
      "kind": "WITHDRAW",
      "amount": 3000,
      "platformFee": 0,
      "externalId": "withdraw-5678",
      "createdAt": "2025-03-24T22:00:20.772Z",
      "updatedAt": "2025-03-24T22:05:20.772Z"
    }
  },
  "devMode": false,
  "event": "withdraw.failed"
}

Boas práticas e notas importantes

  • O campo devMode indica se o evento ocorreu no ambiente de desenvolvimento
  • Valores monetários são expressos em centavos
  • O campo fee representa a taxa cobrada pela AbacatePay
  • O campo event identifica o tipo de evento recebido
  • Implemente retries idempotentes e processe cada id de evento uma única vez
  • Registre falhas de verificação e responda com 4xx/5xx apropriadamente

Precisa de ajuda?

Nossa equipe está disponível para auxiliar na implementação de webhooks. Entre em contato pelo e-mail ajuda@abacatepay.com