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
Evento Descrição payment_completedPagamento foi confirmado com sucesso payment_expiredPagamento expirou sem confirmação refund_completedReembolso foi processado withdrawal_completedSaque foi processado com sucesso withdrawal_failedSaque foi rejeitado ou falhou withdrawal_reversedSaque foi estornado pelo PSP balance_block_createdBloqueio de saldo criado (MED/judicial/administrativo) balance_block_approvedBloqueio aprovado — valor devolvido ao pagador balance_block_rejectedBloqueio rejeitado — valor retorna ao lojista
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
}
}
Campo Tipo Descrição eventstring Tipo do evento eventIdstring ID único do evento (geralmente o ID da transação) timestampstring Data/hora do evento em formato ISO 8601 dataobject Dados específicos do evento
Cada requisição de webhook inclui os seguintes headers:
Header Descrição Content-Typeapplication/jsonX-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:
Calcule a signing key : SHA256(seu_webhook_secret) em hex
Calcule o HMAC-SHA256 do body da requisição usando a signing key
Compare o resultado com o header X-Webhook-Signature usando comparação em tempo constante
SDK (@pague-dev/sdk-node)
Node.js (crypto)
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" ,
"e2eId" : "E18189547202603160145ZYFfVx3jP8D" ,
"counterpartName" : "Maria Silva" ,
"counterpartDocument" : "12345678900" ,
"metadata" : {
"orderId" : "ORDER-12345" ,
"customerId" : "CUST-67890"
}
}
}
Campo Tipo Descrição transactionIdstring ID único da transação environmentstring Ambiente (production ou sandbox) amountnumber Valor total do pagamento feeAmountnumber Taxa cobrada netAmountnumber Valor líquido (amount - feeAmount) currencystring Moeda (BRL) paymentMethodstring Método de pagamento (pix) statusstring Status do pagamento (completed) completedAtstring Data/hora da conclusão em ISO 8601 externalReferencestring Sua referência externa (opcional) e2eIdstring ID fim-a-fim da rede PIX (opcional, presente quando disponível) counterpartNamestring Nome do pagador conforme retornado pelo PSP (opcional) counterpartDocumentstring CPF/CNPJ do pagador conforme retornado pelo PSP (opcional, sem máscara) metadataobject Metadados customizados enviados na criação do pagamento (opcional)
payment_expired
Enviado quando um pagamento PIX expira sem confirmação.
{
"event" : "payment_expired" ,
"eventId" : "payment_expired_d5e6f7a8-1234-5678-9abc-def012345678" ,
"timestamp" : "2026-01-11T19:30:00.000Z" ,
"data" : {
"transactionId" : "d5e6f7a8-1234-5678-9abc-def012345678" ,
"environment" : "sandbox" ,
"amount" : 75.50 ,
"feeAmount" : 0 ,
"netAmount" : 0 ,
"currency" : "BRL" ,
"paymentMethod" : "pix" ,
"status" : "expired" ,
"expiredAt" : "2026-01-11T19:30:00.000Z" ,
"externalReference" : "pedido-12345" ,
"metadata" : {
"orderId" : "ORDER-12345" ,
"customerId" : "CUST-67890"
}
}
}
Campo Tipo Descrição transactionIdstring ID único da transação environmentstring Ambiente (production ou sandbox) amountnumber Valor do pagamento feeAmountnumber Taxa cobrada (sempre 0 para pagamentos expirados) netAmountnumber Valor líquido (sempre 0 para pagamentos expirados) currencystring Moeda (BRL) paymentMethodstring Método de pagamento (pix) statusstring Status do pagamento (expired) expiredAtstring Data/hora da expiração em ISO 8601 externalReferencestring Sua referência externa (opcional) metadataobject Metadados 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" : 50.00 ,
"currency" : "BRL" ,
"paymentMethod" : "pix" ,
"status" : "completed" ,
"refundedAt" : "2026-01-11T19:22:15.400Z" ,
"externalReference" : "pedido-12345" ,
"metadata" : {
"orderId" : "ORDER-12345" ,
"customerId" : "CUST-67890"
}
}
}
Convenção do netAmount em refund : representa o que o destinatário do evento (o cliente final) efetivamente recebe — ou seja, o valor cheio do reembolso. A taxa de reembolso é debitada separadamente do saldo do lojista. O custo total do refund para o lojista é amount + feeAmount.
Campo Tipo Descrição refundTransactionIdstring ID único da transação de reembolso originalTransactionIdstring ID da transação original que foi reembolsada environmentstring Ambiente (production ou sandbox) amountnumber Valor do reembolso feeAmountnumber Taxa do reembolso cobrada do lojista netAmountnumber Valor líquido recebido pelo cliente final (igual a amount) currencystring Moeda (BRL) paymentMethodstring Método de pagamento da transação original statusstring Status do reembolso (completed) refundedAtstring Data/hora do reembolso em ISO 8601 externalReferencestring Sua referência externa do pagamento original (opcional) metadataobject Metadados 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" ,
"externalReference" : "saque-empresa-001" ,
"e2eId" : "E18189547202603160145ZYFfVx3jP8D" ,
"counterpartName" : "João da Silva" ,
"counterpartDocument" : "12345678900" ,
"metadata" : {
"batchId" : "BATCH-001"
}
}
}
Campo Tipo Descrição withdrawalIdstring ID único do saque environmentstring Ambiente (production ou sandbox) amountnumber Valor do saque feeAmountnumber Taxa do saque netAmountnumber Valor líquido transferido currencystring Moeda (BRL) statusstring Status do saque (completed) completedAtstring Data/hora da conclusão em ISO 8601 externalReferencestring Sua referência externa enviada na criação do saque (opcional) e2eIdstring ID fim-a-fim da rede PIX (opcional, presente após confirmação do PSP) counterpartNamestring Nome do destinatário no banco de destino (opcional) counterpartDocumentstring CPF/CNPJ do destinatário (opcional, sem máscara) metadataobject Metadados 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" ,
"externalReference" : "saque-empresa-001" ,
"e2eId" : "E18189547202603160145ZYFfVx3jP8D" ,
"counterpartName" : "João da Silva" ,
"counterpartDocument" : "12345678900" ,
"metadata" : {
"batchId" : "BATCH-001"
}
}
}
Campo Tipo Descrição withdrawalIdstring ID único do saque environmentstring Ambiente (production ou sandbox) amountnumber Valor do saque feeAmountnumber Taxa do saque netAmountnumber Valor líquido que seria transferido currencystring Moeda (BRL) statusstring Status do saque (failed) failedAtstring Data/hora da falha em ISO 8601 failureReasonstring Motivo da falha (insufficient_funds, invalid_account, etc.) externalReferencestring Sua referência externa enviada na criação do saque (opcional) e2eIdstring ID fim-a-fim da rede PIX (opcional, presente apenas se o saque chegou a ser processado pelo PSP) counterpartNamestring Nome do destinatário no banco de destino (opcional) counterpartDocumentstring CPF/CNPJ do destinatário (opcional, sem máscara) metadataobject Metadados customizados do saque (opcional)
withdrawal_reversed
Enviado quando um saque é estornado pelo PSP.
{
"event" : "withdrawal_reversed" ,
"eventId" : "f12a34b5-6c78-9d01-ef23-456789abcdef" ,
"timestamp" : "2026-01-11T20:00:00.000Z" ,
"data" : {
"reversalTransactionId" : "f12a34b5-6c78-9d01-ef23-456789abcdef" ,
"originalTransactionId" : "e73775b5-70ee-4bad-be4c-4acff9890e27" ,
"environment" : "sandbox" ,
"amount" : 500.00 ,
"feeAmount" : 0 ,
"netAmount" : 500.00 ,
"currency" : "BRL" ,
"paymentMethod" : "pix" ,
"status" : "completed" ,
"reversedAt" : "2026-01-11T20:00:00.000Z" ,
"metadata" : {
"batchId" : "BATCH-001"
}
}
}
Campo Tipo Descrição reversalTransactionIdstring ID único da transação de estorno originalTransactionIdstring ID do saque original que foi estornado environmentstring Ambiente (production ou sandbox) amountnumber Valor do estorno feeAmountnumber Taxa do estorno netAmountnumber Valor líquido do estorno currencystring Moeda (BRL) paymentMethodstring Método de pagamento (pix) statusstring Status do estorno (completed) reversedAtstring Data/hora do estorno em ISO 8601 externalReferencestring Sua referência externa do saque original (opcional) metadataobject Metadados customizados do saque original (opcional)
balance_block_created
Enviado quando um bloqueio de saldo é criado (MED, judicial ou administrativo).
{
"event" : "balance_block_created" ,
"eventId" : "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef" ,
"timestamp" : "2026-01-11T19:30:00.000Z" ,
"data" : {
"blockId" : "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef" ,
"transactionId" : "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812" ,
"environment" : "production" ,
"amount" : 1500.00 ,
"currency" : "BRL" ,
"blockType" : "med" ,
"referenceNumber" : "MED-2026-001234" ,
"reason" : "Notificação de infração Pix recebida" ,
"status" : "awaiting_response" ,
"createdAt" : "2026-01-11T19:30:00.000Z" ,
"externalReference" : "pedido-12345" ,
"e2eId" : "E18189547202603160145ZYFfVx3jP8D"
}
}
Campo Tipo Descrição blockIdstring ID único do bloqueio transactionIdstring ID da transação original bloqueada environmentstring Ambiente (production ou sandbox) amountnumber Valor bloqueado em reais currencystring Moeda (BRL) blockTypestring Tipo do bloqueio (med, judicial ou administrative) referenceNumberstring Número de referência do bloqueio reasonstring Motivo do bloqueio statusstring Status inicial (awaiting_response) createdAtstring Data/hora da criação em ISO 8601 externalReferencestring Referência externa da transação original (opcional) e2eIdstring ID fim-a-fim da rede PIX da transação original (opcional)
balance_block_approved
Enviado quando um bloqueio de saldo é aprovado e o valor é devolvido ao pagador original.
{
"event" : "balance_block_approved" ,
"eventId" : "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef" ,
"timestamp" : "2026-01-12T14:00:00.000Z" ,
"data" : {
"blockId" : "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef" ,
"transactionId" : "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812" ,
"environment" : "production" ,
"amount" : 1500.00 ,
"currency" : "BRL" ,
"blockType" : "med" ,
"referenceNumber" : "MED-2026-001234" ,
"reason" : "Notificação de infração Pix recebida" ,
"resolutionReason" : "Devolução confirmada pelo BACEN" ,
"status" : "approved" ,
"createdAt" : "2026-01-11T19:30:00.000Z" ,
"resolvedAt" : "2026-01-12T14:00:00.000Z" ,
"externalReference" : "pedido-12345" ,
"e2eId" : "E18189547202603160145ZYFfVx3jP8D"
}
}
Campo Tipo Descrição blockIdstring ID único do bloqueio transactionIdstring ID da transação original bloqueada environmentstring Ambiente (production ou sandbox) amountnumber Valor bloqueado em reais currencystring Moeda (BRL) blockTypestring Tipo do bloqueio (med, judicial ou administrative) referenceNumberstring Número de referência do bloqueio reasonstring Motivo original do bloqueio resolutionReasonstring Motivo da resolução (opcional) statusstring Status do bloqueio (approved) createdAtstring Data/hora da criação em ISO 8601 resolvedAtstring Data/hora da resolução em ISO 8601 externalReferencestring Referência externa da transação original (opcional) e2eIdstring ID fim-a-fim da rede PIX da transação original (opcional)
balance_block_rejected
Enviado quando um bloqueio de saldo é rejeitado e o valor retorna ao saldo disponível do lojista.
{
"event" : "balance_block_rejected" ,
"eventId" : "e5f6a7b8-9c0d-1e2f-3a4b-567890abcdef" ,
"timestamp" : "2026-01-12T14:00:00.000Z" ,
"data" : {
"blockId" : "e5f6a7b8-9c0d-1e2f-3a4b-567890abcdef" ,
"transactionId" : "b1c89f20-d8e5-5f6a-99ee-4f47eafeb923" ,
"environment" : "production" ,
"amount" : 250.00 ,
"currency" : "BRL" ,
"blockType" : "med" ,
"referenceNumber" : "MED-2026-005678" ,
"reason" : "Notificação de infração Pix recebida" ,
"resolutionReason" : "Defesa aceita - transação legítima comprovada" ,
"status" : "rejected" ,
"createdAt" : "2026-01-11T19:30:00.000Z" ,
"resolvedAt" : "2026-01-12T14:00:00.000Z" ,
"externalReference" : "pedido-67890" ,
"e2eId" : "E4071059520260316020613919677838"
}
}
Campo Tipo Descrição blockIdstring ID único do bloqueio transactionIdstring ID da transação original bloqueada environmentstring Ambiente (production ou sandbox) amountnumber Valor bloqueado em reais currencystring Moeda (BRL) blockTypestring Tipo do bloqueio (med, judicial ou administrative) referenceNumberstring Número de referência do bloqueio reasonstring Motivo original do bloqueio resolutionReasonstring Motivo da resolução (opcional) statusstring Status do bloqueio (rejected) createdAtstring Data/hora da criação em ISO 8601 resolvedAtstring Data/hora da resolução em ISO 8601 externalReferencestring Referência externa da transação original (opcional) e2eIdstring ID fim-a-fim da rede PIX da transação original (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.