Integración
Conectá tu sistema con Lucky Cobros: API keys para crear depósitos esperados y pedir retiros, y un webhook firmado que te avisa al instante de cada cobro conciliado.
Tu servidor no está recibiendo un aviso
withdrawal.failed del retiro RT-000394 ($ 92.500,00) falló en los 5 intentos: tu servidor respondió 500 o no respondió en 10 s. El último intento automático es el 28/10/2026 15:43; si falla, lo podés reenviar a mano.
Estado de la conexión
https://api.luckycobros.com.ar/api/v1
API keys
Cada key identifica a tu sistema. Mostramos la clave completa una sola vez, cuando la creás.
IPs habilitadas por Lucky Cobros
Las administra nuestro equipo de soporte
-
203.0.113.24Servidor principal Habilitada -
203.0.113.25Servidor de respaldo Habilitada -
198.51.100.7Oficina CABA Inactivadesde el 20/10/2026
Toda llamada a la API tiene que salir de una de estas IPs, además de las que cargues en cada key. Para sumar una, escribinos a soporte.
Depósitos esperados
Los que tu sistema crea con la API
ttl_minutes. Pasado ese tiempo, un cobro de ese CUIT queda retenido para revisión.
ttl_minutes, vale ese.
| Nombre | Permisos | IPs permitidas | Creada | Último uso | Estado | Acciones |
|---|---|---|---|---|---|---|
| Producción · backoffice••••••••8f2a | Lectura y escrituraDepósitos, transacciones y retiros | 203.0.113.24203.0.113.25 | 02/09/2026por Joaquín Paz | hace 1 min | Activa | |
| Reportes (solo lectura)••••••••3b7e | LecturaTransacciones y retiros | — | 10/06/2026por Martina Ferreyra | 30/09/2026 23:58 | Revocadael 01/10/2026 | Sin acciones: la key está revocada |
Webhook
Te mandamos un aviso firmado a tu servidor cada vez que pasa algo con un cobro o un retiro.
Destino y firma
Configurado el 02/09/2026 por Joaquín Paz
No le estamos mandando avisos a tu sistema
Los cobros se siguen acreditando igual. Configurá una URL para enterarte al instante de cada cobro y cada retiro, sin tener que consultar la API.
Avisos pausados desde el 28/10/2026 14:05
No le mandamos nada a tu servidor ni a las URL de las sucursales. Cada aviso queda en el Registro de entregas como «Sin enviar · pausado» y lo podés reenviar desde ahí durante 30 días. Los cobros se siguen acreditando igual.
https://api.riogaming.com.ar/webhooks/cobros
whsec_••••••••••••Qm4t
X-Webhook-Signature de cada aviso. Nunca lo pongas en el código del sitio ni en la app.
Destinos por sucursal (opcional)
Si una sucursal tiene URL propia, sus avisos van ahí; si no, a la URL principal. Todos se firman con el mismo secreto.
| Sucursal | URL | Estado | Acciones |
|---|---|---|---|
| Casa central · CABARG-01 · Central 1 y Central 2 | Usa la URL principal | Principal | |
| Agencia RosarioRG-02 · Rosario | Usa la URL principal | Principal | |
| Agencia MendozaRG-03 · Mendoza | Usa la URL principal | Principal |
Cómo te llegan los avisos
- POSTUn JSON por evento a tu URL, con
eventydata. El nombre del evento también viaja enX-Webhook-Event. - Firmado con tu secreto en
X-Webhook-Signature. Si la firma no coincide, descartalo. - Respondé 2xx en menos de 10 s. Procesá el aviso después de responder.
- Si no responde 2xx, reintentamos hasta 6 veces en 24 h. Para no procesar dos veces el mismo aviso, usá el evento + el
iddel cobro o el evento + elcoelsa_iddel retiro. - ¿Vas a hacer un mantenimiento? Pausá los avisos: no se pierde ninguno y los reenviás desde el registro cuando vuelvas.
Documentación
Registro de entregas
Cada aviso que le mandamos a tu servidor y qué respondió. Tocá una fila para ver el cuerpo completo.
| Evento | Objeto | HTTP | Intentos | Demora | Estado | Detalle | |
|---|---|---|---|---|---|---|---|
| transaction.confirmedevt_7R4M2X9C | TX-0184529 | 28/10/2026 14:05:47 | — | 0 | — | Sin enviar · pausadoReenviable hasta el 27/11/2026 | |
| transaction.confirmedevt_7Q2K9M4P | TX-0184531 | 28/10/2026 14:03:11 | 200 | 1 | 182 ms | Entregado | |
| transaction.confirmedevt_7P1H3K8D | TX-0184530 | 28/10/2026 14:01:40 | 200 | 1 | 167 ms | Entregado | |
| transaction.confirmedevt_6Z8N2W5Q | TX-0184528 | 28/10/2026 13:58:22 | 200 | 1 | 201 ms | Entregado | |
| transaction.in_reviewevt_6X4L9B2S | TX-0184526 | 28/10/2026 13:54:07 | 200 | 1 | 196 ms | Entregado | |
| transaction.in_reviewevt_6W3J8N1R | TX-0184519 | 28/10/2026 13:47:03 | 200 | 1 | 214 ms | Entregado | |
| transaction.in_reviewevt_6T7F5C3M | TX-0184513 | 28/10/2026 13:37:41 | 200 | 2 | 188 ms | Entregado tras reintento | |
| withdrawal.completedevt_6V5D1R7K | RT-000398 | 28/10/2026 13:20:10 | 200 | 1 | 158 ms | Entregado | |
| withdrawal.completedevt_5Y2B8Q6N | RT-000397 | 28/10/2026 11:05:15 | 200 | 4 | 203 ms | Entregado tras reintentos | |
| withdrawal.completedevt_5X9K4D1H | RT-000396 | 28/10/2026 09:40:06 | 200 | 1 | 171 ms | Entregado | |
| withdrawal.failedevt_5T9H2C7V | RT-000394 | 27/10/2026 15:43:02 | 500 | 5 | 10.000 ms | ReintentandoPróximo: 28/10/2026 15:43 |
No hay entregas con este filtro
Probá con otro filtro o mirá todas las entregas.
Verificá la firma de cada aviso
Así sabés que el aviso lo mandamos nosotros y que nadie lo modificó en el camino. Rechazá cualquier aviso que no pase la verificación.
const crypto = require('node:crypto');
// true si X-Webhook-Signature corresponde a este cuerpo y a tu secreto.
// cuerpoCrudo: el cuerpo tal como llegó (Buffer). No lo parsees antes.
function firmaValida(secreto, cuerpoCrudo, encabezado) {
if (typeof encabezado !== 'string') return false;
const recibida = encabezado.trim().replace(/^sha256=/i, '').toLowerCase();
if (!/^[0-9a-f]{64}$/.test(recibida)) return false;
const esperada = crypto.createHmac('sha256', secreto).update(cuerpoCrudo).digest('hex');
return crypto.timingSafeEqual(Buffer.from(recibida, 'hex'), Buffer.from(esperada, 'hex'));
}
// Uso: si no es válida, respondé 401 y no hagas nada más.
if (!firmaValida(process.env.WEBHOOK_SECRET, cuerpoCrudo, req.headers['x-webhook-signature'])) {
res.writeHead(401).end();
}
<?php
// true si X-Webhook-Signature corresponde a este cuerpo y a tu secreto.
function firmaValida(string $secreto, string $cuerpoCrudo, string $encabezado): bool
{
$recibida = strtolower((string) preg_replace('/^sha256=/i', '', trim($encabezado)));
if (!preg_match('/^[0-9a-f]{64}$/', $recibida)) { return false; }
$esperada = hash_hmac('sha256', $cuerpoCrudo, $secreto);
return hash_equals($esperada, $recibida);
}
// El cuerpo crudo sale de php://input: no lo rearmes con json_encode.
$cuerpo = file_get_contents('php://input');
if (!firmaValida(getenv('WEBHOOK_SECRET'), $cuerpo, $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
import hashlib, hmac, re
def firma_valida(secreto: str, cuerpo_crudo: bytes, encabezado: str) -> bool:
"""True si X-Webhook-Signature corresponde a este cuerpo y a tu secreto."""
recibida = re.sub(r"^sha256=", "", (encabezado or "").strip(), flags=re.I).lower()
if not re.fullmatch(r"[0-9a-f]{64}", recibida):
return False
esperada = hmac.new(secreto.encode(), cuerpo_crudo, hashlib.sha256).hexdigest()
return hmac.compare_digest(esperada, recibida)
Paso a paso
- Leé el encabezadoLlega como
X-Webhook-Signature: sha256=…, con 64 caracteres hexadecimales. - Calculá el HMAC-SHA256Del cuerpo crudo, byte por byte, con tu secreto de firma. En hexadecimal.
- Compará en tiempo constanteSi no coincide, respondé 401 y descartá el aviso.
- Respondé 200 y procesá despuésSin repetir: un cobro por su
id, un retiro por sucoelsa_id.
Acreditá el saldo del jugador solo con avisos verificados. Ante la duda, consultá la transacción por la API.