RAYO
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

EventoDescrição
transaction.paidPagamento PIX confirmado
transaction.expiredQR Code PIX expirado
transaction.cancelledTransaçã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

ParametroTipoDescricao
Content-Type
stringapplication/json
X-Webhook-Signature
stringAssinatura HMAC-SHA256 do payload
X-Webhook-Timestamp
stringTimestamp da requisição (Unix epoch)
X-Webhook-Id
stringID ú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 endpoint
app.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:

TentativaIntervalo
1ª tentativaImediato
2ª tentativa5 minutos
3ª tentativa30 minutos
4ª tentativa2 horas
5ª tentativa24 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.