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" ,
"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) 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" : 49.75 ,
"currency" : "BRL" ,
"paymentMethod" : "pix" ,
"status" : "completed" ,
"refundedAt" : "2026-01-11T19:22:15.400Z" ,
"externalReference" : "pedido-12345" ,
"metadata" : {
"orderId" : "ORDER-12345" ,
"customerId" : "CUST-67890"
}
}
}
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 netAmountnumber Valor líquido do reembolso 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" ,
"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 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" ,
"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.) 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"
}
}
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
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"
}
}
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
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"
}
}
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
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.