Pular para o conteúdo principal

Visão Geral

Webhooks permitem que você receba notificações HTTP automáticas quando eventos importantes acontecem na sua conta, como pagamentos confirmados, reembolsos processados ou saques concluídos.

Eventos Disponíveis

EventoDescrição
payment_completedPagamento foi confirmado com sucesso
refund_completedReembolso foi processado
withdrawal_completedSaque foi processado com sucesso
withdrawal_failedSaque foi rejeitado ou falhou

Estrutura do Payload

Todos os webhooks seguem a mesma estrutura base:
{
  "event": "payment_completed",
  "eventId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
  "timestamp": "2026-01-11T19:03:28.280Z",
  "data": {
    // Dados específicos do evento
  }
}
CampoTipoDescrição
eventstringTipo do evento
eventIdstringID único do evento (geralmente o ID da transação)
timestampstringData/hora do evento em formato ISO 8601
dataobjectDados específicos do evento

Headers Enviados

Cada requisição de webhook inclui os seguintes headers:
HeaderDescrição
Content-Typeapplication/json
X-Webhook-SignatureAssinatura HMAC-SHA256 do payload
X-Webhook-TimestampTimestamp em milliseconds

Validando a Assinatura

Cada webhook é assinado com HMAC-SHA256 para garantir autenticidade. Siga estes passos para validar:
  1. Calcule a signing key: SHA256(seu_webhook_secret) em hex
  2. Calcule o HMAC-SHA256 do body da requisição usando a signing key
  3. Compare o resultado com o header X-Webhook-Signature usando comparação em tempo constante
import { verifyWebhookSignature, parseWebhook } from '@pague-dev/sdk-node';

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'] as string;
  const rawBody = req.body; // raw string body

  if (!verifyWebhookSignature(rawBody, signature, 'seu_webhook_secret')) {
    return res.status(401).send('Assinatura inválida');
  }

  const event = parseWebhook(rawBody);
  if (!event) {
    return res.status(400).send('Payload inválido');
  }

  // Processar o evento...
  res.status(200).send('OK');
});
Sempre use comparação em tempo constante (timingSafeEqual) para evitar ataques de timing. Nunca compare assinaturas com ===.

Exemplos de Payload

payment_completed

Enviado quando um pagamento PIX é confirmado.
{
  "event": "payment_completed",
  "eventId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
  "timestamp": "2026-01-11T19:03:28.280Z",
  "data": {
    "transactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
    "environment": "sandbox",
    "amount": 100.21,
    "feeAmount": 0.5,
    "netAmount": 99.71,
    "currency": "BRL",
    "paymentMethod": "pix",
    "status": "completed",
    "completedAt": "2026-01-11T19:03:28.277Z",
    "externalReference": "pedido-12345",
    "metadata": {
      "orderId": "ORDER-12345",
      "customerId": "CUST-67890"
    }
  }
}
CampoTipoDescrição
transactionIdstringID único da transação
environmentstringAmbiente (production ou sandbox)
amountnumberValor total do pagamento
feeAmountnumberTaxa cobrada
netAmountnumberValor líquido (amount - feeAmount)
currencystringMoeda (BRL)
paymentMethodstringMétodo de pagamento (pix)
statusstringStatus do pagamento (completed)
completedAtstringData/hora da conclusão em ISO 8601
externalReferencestringSua referência externa (opcional)
metadataobjectMetadados customizados enviados na criação do pagamento (opcional)

refund_completed

Enviado quando um reembolso é processado.
{
  "event": "refund_completed",
  "eventId": "c92d45e6-8b33-4f12-a789-2e56f8901def",
  "timestamp": "2026-01-11T19:22:15.456Z",
  "data": {
    "refundTransactionId": "c92d45e6-8b33-4f12-a789-2e56f8901def",
    "originalTransactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812",
    "environment": "sandbox",
    "amount": 50.00,
    "feeAmount": 0.25,
    "netAmount": 49.75,
    "currency": "BRL",
    "status": "completed",
    "completedAt": "2026-01-11T19:22:15.400Z",
    "metadata": {
      "orderId": "ORDER-12345",
      "customerId": "CUST-67890"
    }
  }
}
CampoTipoDescrição
refundTransactionIdstringID único da transação de reembolso
originalTransactionIdstringID da transação original que foi reembolsada
environmentstringAmbiente (production ou sandbox)
amountnumberValor do reembolso
feeAmountnumberTaxa do reembolso
netAmountnumberValor líquido do reembolso
currencystringMoeda (BRL)
statusstringStatus do reembolso (completed)
completedAtstringData/hora da conclusão em ISO 8601
metadataobjectMetadados customizados do pagamento original (opcional)

withdrawal_completed

Enviado quando um saque é processado com sucesso.
{
  "event": "withdrawal_completed",
  "eventId": "e73775b5-70ee-4bad-be4c-4acff9890e27",
  "timestamp": "2026-01-11T19:08:21.953Z",
  "data": {
    "withdrawalId": "e73775b5-70ee-4bad-be4c-4acff9890e27",
    "environment": "sandbox",
    "amount": 500.00,
    "feeAmount": 2.50,
    "netAmount": 497.50,
    "currency": "BRL",
    "status": "completed",
    "completedAt": "2026-01-11T19:08:21.939Z",
    "metadata": {
      "batchId": "BATCH-001"
    }
  }
}
CampoTipoDescrição
withdrawalIdstringID único do saque
environmentstringAmbiente (production ou sandbox)
amountnumberValor do saque
feeAmountnumberTaxa do saque
netAmountnumberValor líquido transferido
currencystringMoeda (BRL)
statusstringStatus do saque (completed)
completedAtstringData/hora da conclusão em ISO 8601
metadataobjectMetadados customizados do saque (opcional)

withdrawal_failed

Enviado quando um saque é rejeitado ou falha.
{
  "event": "withdrawal_failed",
  "eventId": "b84f12c3-9a21-4e67-bc88-1d45f6789abc",
  "timestamp": "2026-01-11T19:15:42.123Z",
  "data": {
    "withdrawalId": "b84f12c3-9a21-4e67-bc88-1d45f6789abc",
    "environment": "sandbox",
    "amount": 1000.00,
    "feeAmount": 5.00,
    "netAmount": 995.00,
    "currency": "BRL",
    "status": "failed",
    "failedAt": "2026-01-11T19:15:42.100Z",
    "failureReason": "insufficient_funds",
    "metadata": {
      "batchId": "BATCH-001"
    }
  }
}
CampoTipoDescrição
withdrawalIdstringID único do saque
environmentstringAmbiente (production ou sandbox)
amountnumberValor do saque
feeAmountnumberTaxa do saque
netAmountnumberValor líquido que seria transferido
currencystringMoeda (BRL)
statusstringStatus do saque (failed)
failedAtstringData/hora da falha em ISO 8601
failureReasonstringMotivo da falha (insufficient_funds, invalid_account, etc.)
metadataobjectMetadados customizados do saque (opcional)

Boas Práticas

Retorne um status 200 OK o mais rápido possível. Processe o webhook de forma assíncrona se necessário.
Use o eventId para evitar processar o mesmo evento duas vezes. Webhooks podem ser reenviados em caso de falha.
Configure seu endpoint apenas com HTTPS para garantir a segurança dos dados.

Retentativas

Se o seu endpoint não responder com status 2xx, tentaremos reenviar o webhook:
  • 5 tentativas com backoff exponencial
  • Intervalo inicial: 2 segundos
  • Intervalo máximo: ~30 segundos entre tentativas
Após 5 tentativas sem sucesso, o webhook é marcado como falho.