🔔 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.
✨ 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://https://upay-sistema-api.onrender.com//api/webhooks/subscriptions" \
-H "Authorization: Bearer SUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://meusite.com.br/webhooks/upay",
"events": ["payment.completed", "payment.failed"],
"description": "Webhook para notificações de pagamento"
}'
Resposta
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://meusite.com.br/webhooks/upay",
"events": ["payment.completed", "payment.failed"],
"description": "Webhook para notificações de pagamento",
"status": "ACTIVE",
"secret": "whsec_abc123...",
"createdAt": "2025-12-30T00:00:00.000Z"
}
}
Guarde o secret em local seguro. Ele será usado para validar as requisições do webhook.
📋 Eventos Disponíveis
Eventos de Pagamento
payment.completed - Pagamento confirmado
payment.failed - Pagamento falhou
payment.pending - Pagamento pendente
payment.refunded - Pagamento reembolsado
payment.cancelled - Pagamento cancelado
Eventos de Link de Pagamento
payment_link.created - Link de pagamento criado
payment_link.updated - Link de pagamento atualizado
payment_link.deleted - Link de pagamento deletado
Eventos de Produto
product.created - Produto criado
product.updated - Produto atualizado
product.deleted - Produto deletado
Eventos de Cupom
coupon.created - Cupom criado
coupon.used - Cupom utilizado
coupon.expired - Cupom expirado
📖 Exemplo Completo
const response = await fetch('https://https://upay-sistema-api.onrender.com//api/webhooks/subscriptions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://meusite.com.br/webhooks/upay',
events: [
'payment.completed',
'payment.failed',
'payment.refunded'
],
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://https://upay-sistema-api.onrender.com//api/webhooks/subscriptions" \
-H "Authorization: Bearer SUA_API_KEY"
Listar Eventos Enviados
curl -X GET "https://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://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": ["payment.completed", "payment.failed", "payment.refunded"],
"status": "ACTIVE"
}'
🗑️ Deletando uma Assinatura
curl -X DELETE "https://https://upay-sistema-api.onrender.com//api/webhooks/subscriptions/{id}" \
-H "Authorization: Bearer SUA_API_KEY"
🔐 Validando Webhooks
Assinatura HMAC
Todas as requisições de webhook incluem um header X-Upay-Signature com uma assinatura HMAC-SHA256. Use o secret da assinatura para validar que a requisição veio da UPay.
Exemplo de Validação (Node.js)
const crypto = require('crypto');
function validateWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(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-upay-signature'];
const secret = process.env.UPAY_WEBHOOK_SECRET;
if (!validateWebhookSignature(req.body, signature, secret)) {
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-Upay-Signature')
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: payment.completed
{
"id": "evt_abc123",
"type": "payment.completed",
"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": "pix",
"status": "COMPLETED",
"client": {
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "João Silva",
"email": "[email protected]"
}
}
}
Exemplo: payment.failed
{
"id": "evt_def456",
"type": "payment.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-Upay-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