Webhook
Webhook PixIn (CashIn)
Receba notificações sobre transações de entrada (Pix). O webhook é enviado automaticamente quando uma transação PIX é confirmada, expirada ou cancelada.
Visão Geral
Quando uma transação PIX muda de status, a Rayo envia uma requisição HTTP POST para a URL configurada no campo postbackUrl ao criar a transação.
Eventos
| Evento | Descrição |
|---|---|
transaction.paid | Pagamento PIX confirmado |
transaction.expired | QR Code PIX expirado |
transaction.cancelled | Transação cancelada |
Payload do Webhook
webhook-pixin-payload.json
json
{ "event": "transaction.paid", "timestamp": "2025-01-15T15:10:00Z", "data": { "id": "f2d96218-6635-4839-81d7-9f2d5aaf4f14", "status": "PAID", "paymentMethod": "PIX", "amount": 500, "externalId": "pedido-123", "customer": { "name": "João Silva", "email": "joao@email.com", "document": "12345678900" }, "pix": { "paidAt": "2025-01-15T15:10:00Z", "endToEndId": "E12345678202501151510ABCDEF" } }}Headers da Requisição
| Parametro | Tipo | Descricao |
|---|---|---|
Content-Type | string | application/json |
X-Webhook-Signature | string | Assinatura HMAC-SHA256 do payload |
X-Webhook-Timestamp | string | Timestamp da requisição (Unix epoch) |
X-Webhook-Id | string | ID único da notificação (para idempotência) |
Validação de Assinatura
Sempre valide a assinatura do webhook para garantir que a requisição veio da Rayo:
webhook-handler.js
javascript
import crypto from 'crypto'; function validateWebhookSignature(payload, signature, timestamp, secret) { const signaturePayload = `${timestamp}.${JSON.stringify(payload)}`; const expectedSignature = crypto .createHmac('sha256', secret) .update(signaturePayload) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) );} // No seu endpointapp.post('/webhook/rayo', (req, res) => { const signature = req.headers['x-webhook-signature']; const timestamp = req.headers['x-webhook-timestamp']; if (!validateWebhookSignature(req.body, signature, timestamp, process.env.WEBHOOK_SECRET)) { return res.status(401).json({ error: 'Invalid signature' }); } const { event, data } = req.body; switch (event) { case 'transaction.paid': console.log('Pagamento confirmado:', data.id); // Liberar produto/serviço break; case 'transaction.expired': console.log('QR Code expirado:', data.id); break; } // Sempre retornar 200 para confirmar recebimento res.status(200).json({ received: true });});Retentativas
Se seu endpoint retornar um código de erro ou não responder:
| Tentativa | Intervalo |
|---|---|
| 1ª tentativa | Imediato |
| 2ª tentativa | 5 minutos |
| 3ª tentativa | 30 minutos |
| 4ª tentativa | 2 horas |
| 5ª tentativa | 24 horas |
Boas Práticas
Responda rapidamente
Retorne status 200 imediatamente e processe o webhook de forma assíncrona. Webhooks que demoram mais de 30 segundos serão considerados falhos.
Implemente idempotência
Use o header X-Webhook-Id para evitar processar o mesmo evento duas vezes.
Use HTTPS
Seu endpoint deve usar HTTPS. Requisições para endpoints HTTP serão rejeitadas.