Autenticación
Cada solicitud desde tu servidor usa autenticación HTTP Basic: el ID de tu proyecto como nombre de usuario y el secreto de tu proyecto como contraseña. Guarda el secreto en tu servidor; también firma tus webhooks.
https://payments.rubysoft.io/api
Authorization: Basic base64(PROJECT_ID:PROJECT_SECRET)Crear una factura
Usa una factura cuando el cliente paga un pedido concreto. Envía tu propio ID de pedido de 24 caracteres como payload, el precio en USD, cuánto puede faltar del monto (0 a 5%), la fecha de vencimiento y la URL que recibe los webhooks de esta factura.
payloadTu ID de pedido, 24 caracteres hexadecimales (sirve un ObjectId de MongoDB)meta[price]Precio en USDmeta[tolerancePercent]Faltante permitido, de 0 a 5meta[expiresAt]Vencimiento, ISO 8601, en el futurometa[webhookUrl]Adónde se envían los eventos de esta facturacurl -G https://payments.rubysoft.io/api/invoice/load \
-u "$PROJECT_ID:$PROJECT_SECRET" \
--data-urlencode "payload=65f2c1a9e4b0d3f7a2c91e04" \
--data-urlencode "meta[price]=120" \
--data-urlencode "meta[tolerancePercent]=1" \
--data-urlencode "meta[expiresAt]=2026-12-01T12:00:00Z" \
--data-urlencode "meta[webhookUrl]=https://shop.example/webhooks/rubynex"La respuesta incluye un objeto addresses con una clave por red. Muestra a tu cliente las redes que quieras ofrecer.
{
"id": "0b6f3c1e-8a52-4d7e-9c41-2f6a8d0e5b17",
"payload": "65f2c1a9e4b0d3f7a2c91e04",
"meta": {
"type": "invoice",
"status": "pending",
"price": "120",
"paid": "0",
"expiresAt": "2026-12-01T12:00:00.000Z"
},
"addresses": {
"tron": "T…",
"ethereum": "0x…",
"bsc": "0x…",
"bitcoin": "bc1q…"
}
}Direcciones de depósito fijas
Usa direcciones fijas para recargas: wallets, juegos, exchanges, suscripciones. Envía el ID de 24 caracteres de tu cliente como payload y obtén siempre las mismas direcciones.
curl -G https://payments.rubysoft.io/api/charge/load \
-u "$PROJECT_ID:$PROJECT_SECRET" \
--data-urlencode "payload=66a0b7d2c5e8f1a3b6d904c7"
# the same customer ID always returns the same addressesEstados de la factura
pendingEsperando el pagopaidLlegó el precio completounderpaidLlegó menos del preciooverpaidLlegó más de un 1% por encima del precioexpiredNingún pago antes del vencimientoWebhooks
Cada evento es un POST con cuerpo JSON y un encabezado X-Webhook-Signature: el HMAC-SHA256 del cuerpo sin procesar, con el secreto de tu proyecto decodificado de hex como clave, escrito en hex. Responde con cualquier estado 2xx. Cualquier otra respuesta se reintenta: los eventos de factura cada 15 segundos hasta entregarse, los eventos de pago cada 10 minutos, hasta 150 veces.
Eventos
invoice:<status>Una factura cambió de estadopending-paymentSe detectó un pago que espera confirmacionesconfirmed-paymentUn pago se confirmó y se acreditófailed-paymentUn pago no se pudo procesarPOST /webhooks/rubynex
Content-Type: application/json
X-Webhook-Signature: 9c1fd2…e07a
{
"id": "4e1a…c93f",
"message": {
"event": "invoice:paid",
"data": { "id": "0b6f3c1e-…", "payload": "65f2c1a9e4b0d3f7a2c91e04" }
},
"attempt": 0,
"timestamp": 1764590400
}Verificar la firma
import crypto from 'node:crypto';
import express from 'express';
const secret = Buffer.from(process.env.RUBYNEX_SECRET, 'hex');
// keep the raw body: the signature covers its exact bytes
app.post('/webhooks/rubynex', express.raw({ type: 'application/json' }), (req, res) => {
const expected = crypto.createHmac('sha256', secret).update(req.body).digest('hex');
const given = req.get('X-Webhook-Signature') ?? '';
if (given.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))) {
return res.sendStatus(401);
}
const { message } = JSON.parse(req.body);
if (message.event === 'invoice:paid') markOrderPaid(message.data.payload);
res.sendStatus(200);
});Confirmaciones por red
| Red | Monedas | Confirmaciones | Tiempo de acreditación |
|---|---|---|---|
| TRXUSDT | 1 | aprox. 3 s | |
| ETHUSDTUSDCDAI | 5 | aprox. 1 min | |
| BNBUSDTUSDCDAI | 10 | aprox. 8 s | |
| POLUSDTUSDCDAI | 20 | aprox. 40 s | |
| ETHUSDTUSDC | 10 | aprox. 20 s | |
| BTC | 1 | aprox. 10 min | |
| XRP | 1 | aprox. 4 s | |
| DOGE | 3 | aprox. 3 min |
Límites que conviene conocer
- Los pagos de $1 o menos se ignoran como polvo
- Tolerancia de faltante en facturas: hasta 5%
- Una factura se marca como pago en exceso cuando llega más de un 1% por encima de su precio
- El secreto de un proyecto se puede rotar una vez cada 5 minutos
¿Listo para tus claves?
Creamos tu proyecto y te enviamos su ID y secreto.