Webhooks permitem que sua aplicação seja notificada automaticamente quando eventos ocorrem — como um pagamento confirmado ou uma transação expirada. Em vez de fazer polling, a Bob Payments avisa você.
Configurando um webhook
Acesse o Dashboard
Vá em Webhooks → Adicionar webhook no seu projeto.
Informe a URL
Insira a URL HTTPS da sua aplicação que receberá os eventos (ex: https://suaapi.com/webhooks/bob).
Copie o secret
Um secret é gerado automaticamente. Guarde-o para verificar a autenticidade das requisições.
Webhooks funcionam normalmente no sandbox. Use-os para testar o fluxo completo antes de ir a produção.
Eventos disponíveis
Disparado quando uma cobrança PIX é criada. Inclui pixCode e expirationDate. {
"event" : "transaction.created" ,
"type" : "transaction" ,
"title" : "Transação Criada" ,
"message" : "Nova transação de R$ 150,00 aguardando pagamento" ,
"data" : {
"transactionId" : "clx1abc123" ,
"externalId" : "pedido-001" ,
"amount" : 150.00 ,
"product" : "Plano Premium" ,
"customerName" : "João Silva" ,
"customer" : {
"name" : "João Silva" ,
"email" : "[email protected] " ,
"phone" : "11999990000" ,
"document" : "12345678901" ,
"documentType" : "CPF" ,
"address" : {
"street" : "Rua das Flores" ,
"streetNumber" : "123" ,
"neighborhood" : "Centro" ,
"complement" : "" ,
"zipCode" : "01310100" ,
"city" : "São Paulo" ,
"state" : "SP" ,
"country" : "BR"
}
},
"gateway" : "meu-gateway" ,
"pixCode" : "00020126580014br.gov.bcb.pix..." ,
"expirationDate" : "2026-03-10T15:30:00.000Z" ,
"createdAt" : "2026-03-10T14:30:00.000Z"
},
"timestamp" : "2026-03-10T14:30:00.000Z"
}
Disparado quando um pagamento PIX é confirmado. Use para liberar o produto ou serviço ao cliente. Inclui fee quando há taxa. {
"event" : "transaction.paid" ,
"type" : "transaction" ,
"title" : "Transação Paga" ,
"message" : "Transação de R$ 150,00 confirmada" ,
"data" : {
"transactionId" : "clx1abc123" ,
"externalId" : "pedido-001" ,
"amount" : 150.00 ,
"product" : "Plano Premium" ,
"customer" : {
"name" : "João Silva" ,
"email" : "[email protected] " ,
"phone" : "11999990000" ,
"document" : "12345678901" ,
"documentType" : "CPF" ,
"address" : {
"street" : "Rua das Flores" ,
"streetNumber" : "123" ,
"neighborhood" : "Centro" ,
"complement" : "" ,
"zipCode" : "01310100" ,
"city" : "São Paulo" ,
"state" : "SP" ,
"country" : "BR"
}
},
"gateway" : "meu-gateway" ,
"originDomain" : "meusite.com.br" ,
"isSandbox" : false ,
"fee" : { "amount" : 3.50 }
},
"timestamp" : "2026-03-10T14:35:00.000Z"
}
Disparado quando uma transação expira sem pagamento. Use para notificar o cliente ou criar nova cobrança. Não inclui gateway. {
"event" : "transaction.expired" ,
"type" : "transaction" ,
"title" : "Transação Expirada" ,
"message" : "Transação de R$ 150,00 expirou" ,
"data" : {
"transactionId" : "clx1abc123" ,
"externalId" : "pedido-001" ,
"amount" : 150.00 ,
"product" : "Plano Premium" ,
"customer" : {
"name" : "João Silva" ,
"email" : "[email protected] " ,
"phone" : "11999990000" ,
"document" : "12345678901" ,
"documentType" : "CPF" ,
"address" : { "..." : "..." }
},
"originDomain" : "meusite.com.br" ,
"isSandbox" : true
},
"timestamp" : "2026-03-11T03:00:00.000Z"
}
Disparado quando uma transação é estornada. {
"event" : "transaction.refunded" ,
"type" : "transaction" ,
"title" : "Transação Reembolsada" ,
"message" : "Transação de R$ 150,00 reembolsada" ,
"data" : {
"transactionId" : "clx1abc123" ,
"externalId" : "pedido-001" ,
"amount" : 150.00 ,
"product" : "Plano Premium" ,
"customer" : { "..." : "igual ao paid" },
"gateway" : "meu-gateway" ,
"originDomain" : "meusite.com.br" ,
"isSandbox" : false
},
"timestamp" : "2026-03-10T15:00:00.000Z"
}
Disparado quando uma transação é cancelada manualmente. {
"event" : "transaction.cancelled" ,
"type" : "transaction" ,
"title" : "Transação Cancelada" ,
"message" : "Transação de R$ 150,00 cancelada" ,
"data" : {
"transactionId" : "clx1abc123" ,
"externalId" : "pedido-001" ,
"amount" : 150.00 ,
"product" : "Plano Premium" ,
"customer" : { "..." : "igual ao paid" },
"gateway" : "meu-gateway" ,
"originDomain" : "meusite.com.br" ,
"isSandbox" : false
},
"timestamp" : "2026-03-10T14:40:00.000Z"
}
Disparado quando uma transação falha no processamento. {
"event" : "transaction.failed" ,
"type" : "transaction" ,
"title" : "transaction_failed" ,
"message" : "transaction_failed" ,
"data" : {
"transactionId" : "clx1abc123" ,
"externalId" : "pedido-001" ,
"amount" : 150.00 ,
"product" : "Plano Premium" ,
"customer" : { "..." : "igual ao paid" },
"gateway" : "meu-gateway" ,
"originDomain" : "meusite.com.br" ,
"isSandbox" : false
},
"timestamp" : "2026-03-10T14:33:00.000Z"
}
Verificando a assinatura
Cada requisição inclui dois headers de segurança:
Header Descrição X-Webhook-SignatureHMAC-SHA256 do payload em hex X-Webhook-TimestampISO 8601 do momento do envio
Verifique a assinatura sempre para garantir que a requisição veio da Bob Payments.
const crypto = require ( 'crypto' );
app . post ( '/webhooks/bob' , ( req , res ) => {
const sig = req . headers [ 'x-webhook-signature' ];
const secret = process . env . BOB_WEBHOOK_SECRET ;
const expected = crypto
. createHmac ( 'sha256' , secret )
. update ( JSON . stringify ( req . body ))
. digest ( 'hex' );
const sigBuffer = Buffer . from ( sig ?? '' , 'utf8' );
const expectedBuffer = Buffer . from ( expected , 'utf8' );
if (
sigBuffer . length !== expectedBuffer . length ||
! crypto . timingSafeEqual ( sigBuffer , expectedBuffer )
) {
return res . status ( 401 ). send ( 'Assinatura inválida' );
}
// Processe de forma assíncrona
processEvent ( req . body ). catch ( console . error );
// Responda 200 imediatamente
res . status ( 200 ). send ( 'ok' );
});
Retorne HTTP 200 imediatamente e processe o evento de forma assíncrona para evitar timeouts.