Visão geral
Webhooks são notificações HTTP enviadas pela Upay Gateway API para sua aplicação quando eventos importantes ocorrem. Isso permite que você reaja em tempo real a mudanças de status, pagamentos confirmados e outros eventos sem precisar fazer polling constante.
Pré-requisitos
Antes de começar, você precisa:
Uma conta ativa na Upay
Sua API Key configurada (veja Autenticação )
Um endpoint HTTPS público para receber webhooks
Funcionalidades
Eventos em tempo real : Receba notificações instantâneas
Múltiplos eventos : Configure webhooks para diferentes tipos de eventos
Retry automático : Tentativas automáticas em caso de falha
Segurança : Assinatura HMAC para validar requisições
Histórico : Visualize todos os eventos enviados
Múltiplas URLs : Configure diferentes endpoints para diferentes eventos
Criando uma assinatura de webhook
Requisição Básica
curl -X POST "https://upay-sistema-api.onrender.com/api/v1/webhooks/subscriptions" \
-H "Authorization: Bearer SUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://meusite.com.br/webhooks/upay",
"events": ["transaction.completed", "transaction.failed"],
"description": "Webhook para notificações de transação"
}'
Resposta
{
"success" : true ,
"data" : {
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"url" : "https://meusite.com.br/webhooks/upay" ,
"events" : [ "transaction.completed" , "transaction.failed" ],
"description" : "Webhook para notificações de transação" ,
"status" : "ACTIVE" ,
"secret" : "whsec_abc123..." ,
"createdAt" : "2025-12-30T00:00:00.000Z"
}
}
Guarde o secret em local seguro. Ele é necessário para validar a autenticidade dos webhooks recebidos e não será exibido novamente.
O Gateway envia webhooks usando o método POST para a URL configurada. Cada envio inclui o cabeçalho X-Webhook-Signature para validação de integridade.
Cabeçalhos HTTP
Cabeçalho Descrição Content-TypeSempre application/json X-Webhook-SignatureAssinatura HMAC-SHA256 (formato: sha256=ASSINATURA) X-Webhook-EventTipo do evento disparado X-Webhook-DeliveryID único da entrega (UUID) User-AgentUPAY-Webhook/1.0
Eventos Suportados
Evento Descrição transaction.createdUma nova transação foi gerada transaction.updatedUma transação teve seus dados atualizados transaction.completedPagamento confirmado com sucesso transaction.failedPagamento falhou ou foi recusado payment_link.createdUm link de pagamento foi criado payment_link.updatedUm link de pagamento foi editado balance.updatedO saldo da conta foi alterado
Eventos de Transação (Transaction)
transaction.created - Transação criada
transaction.updated - Status da transação atualizado
transaction.completed - Pagamento confirmado/concluído
transaction.failed - Pagamento falhou
Eventos de Link de Pagamento
payment_link.created - Link de pagamento criado
payment_link.updated - Link de pagamento atualizado
Exemplo completo
const response = await fetch ( 'https://upay-sistema-api.onrender.com/api/v1/webhooks/subscriptions' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
url: 'https://meusite.com.br/webhooks/upay' ,
events: [
'transaction.completed' ,
'transaction.failed'
],
description: 'Webhook para processar notificações de pagamento'
})
});
const { data } = await response . json ();
console . log ( 'Webhook Secret:' , data . secret );
Listando assinaturas
Listar todas as assinaturas
curl -X GET "https://upay-sistema-api.onrender.com/api/webhooks/subscriptions" \
-H "Authorization: Bearer SUA_API_KEY"
Listar eventos enviados
curl -X GET "https://upay-sistema-api.onrender.com/api/webhooks/events?page=1&limit=20" \
-H "Authorization: Bearer SUA_API_KEY"
Atualizando uma assinatura
curl -X PUT "https://upay-sistema-api.onrender.com/api/webhooks/subscriptions/{id}" \
-H "Authorization: Bearer SUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://meusite.com.br/webhooks/upay-v2",
"events": ["transaction.completed", "transaction.failed"],
"isActive": true
}'
Deletando uma assinatura
curl -X DELETE "https://upay-sistema-api.onrender.com/api/webhooks/subscriptions/{id}" \
-H "Authorization: Bearer SUA_API_KEY"
Validando a Assinatura
Para garantir que o webhook foi enviado pela UPAY, você deve validar o header X-Webhook-Signature.
Obtenha o corpo bruto (raw body) da requisição.
Gere um HMAC-SHA256 usando o corpo bruto e o seu WEBHOOK_SECRET.
Compare o resultado (em hexadecimal) com o valor recebido no header (removendo o prefixo sha256=).
Exemplo em Node.js:
const crypto = require ( 'crypto' );
function verifySignature ( payload , signatureHeader , secret ) {
const [ algorithm , signature ] = signatureHeader . split ( '=' );
if ( algorithm !== 'sha256' ) return false ;
const expectedSignature = crypto
. createHmac ( 'sha256' , secret )
. update ( payload )
. digest ( 'hex' );
return crypto . timingSafeEqual (
Buffer . from ( signature ),
Buffer . from ( expectedSignature )
);
}
// No seu endpoint de webhook
app . post ( '/webhooks/upay' , express . json (), ( req , res ) => {
const signature = req . headers [ 'x-webhook-signature' ];
const secret = process . env . UPAY_WEBHOOK_SECRET ;
if ( ! verifySignature ( req . rawBody , signature , secret )) { // req.rawBody é necessário para a validação
return res . status ( 401 ). json ({ error: 'Invalid signature' });
}
// Processar webhook
const event = req . body ;
console . log ( 'Evento recebido:' , event . type );
res . status ( 200 ). json ({ received: true });
});
Exemplo de Validação (Python)
import hmac
import hashlib
import json
def validate_webhook_signature ( payload , signature , secret ):
expected_signature = hmac.new(
secret.encode( 'utf-8' ),
json.dumps(payload).encode( 'utf-8' ),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_signature)
# No seu endpoint de webhook
@app.route ( '/webhooks/upay' , methods = [ 'POST' ])
def webhook ():
signature = request.headers.get( 'X-Webhook-Signature' , '' ).replace( 'sha256=' , '' )
secret = os.getenv( 'UPAY_WEBHOOK_SECRET' )
if not validate_webhook_signature(request.json, signature, secret):
return jsonify({ 'error' : 'Invalid signature' }), 401
# Processar webhook
event = request.json
print ( f "Evento recebido: { event[ 'type' ] } " )
return jsonify({ 'received' : True }), 200
Estrutura do payload
Exemplo: transaction.completed
{
"id" : "evt_5f9d7a2b-1234-5678-90ab-cdef12345678" ,
"type" : "transaction.completed" ,
"timestamp" : "2024-03-15T10:30:00.000Z" ,
"data" : {
"id" : "tx_240315_a7b2c9" ,
"userId" : "usr_987654321" ,
"value" : 150.00 ,
"amountCents" : 15000 ,
"status" : "PAID" ,
"paymentMethod" : "PIX" ,
"paymentDate" : "2024-03-15T10:29:55.000Z" ,
"completedAt" : "2024-03-15T10:30:00.000Z"
},
"subscription" : {
"id" : "sub_12345678" ,
"url" : "https://suaapiv1.com/webhooks"
}
}
Exemplo: transaction.failed
{
"id" : "evt_def456" ,
"type" : "transaction.failed" ,
"createdAt" : "2025-12-30T00:00:00.000Z" ,
"data" : {
"transactionId" : "550e8400-e29b-41d4-a716-446655440000" ,
"paymentLinkId" : "550e8400-e29b-41d4-a716-446655440001" ,
"amount" : 199.00 ,
"amountCents" : 19900 ,
"currency" : "BRL" ,
"paymentMethod" : "credit_card" ,
"status" : "FAILED" ,
"error" : "Cartão recusado" ,
"errorCode" : "CARD_DECLINED"
}
}
🔄 Retry e Confiabilidade
A UPay tenta entregar webhooks automaticamente:
Primeira tentativa : Imediata
Retry 1 : Após 1 minuto
Retry 2 : Após 5 minutos
Retry 3 : Após 15 minutos
Retry 4 : Após 1 hora
Seu endpoint deve responder com status HTTP 200-299 para confirmar o recebimento. Respostas com erro ou timeout resultarão em retry.
Boas práticas
Responda rapidamente : Processe webhooks de forma assíncrona quando possível
Valide a assinatura : Sempre valide o X-Webhook-Signature
Idempotência : Processe eventos de forma idempotente usando o id do evento
Logs : Mantenha logs de todos os webhooks recebidos
Testes : Use webhooks de teste para validar sua implementação
Testando webhooks
Usando ngrok (Desenvolvimento Local)
# Instale o ngrok
npm install -g ngrok
# Exponha sua aplicação local
ngrok http 3000
# Use a URL do ngrok na assinatura do webhook
# Ex: https://abc123.ngrok.io/webhooks/upay
Endpoint de Teste
app . post ( '/webhooks/upay' , express . json (), ( req , res ) => {
console . log ( 'Webhook recebido:' , JSON . stringify ( req . body , null , 2 ));
res . status ( 200 ). json ({ received: true });
});
Próximos passos
Referência da API Veja todos os endpoints disponíveis
Links de Pagamento Configure webhooks para links de pagamento