REST API · v1.0

Api Juegos.
Game API

API REST para integrar el sistema de lotería electrónica Melate Digital en tus juegos. Controla partidas, genera folios, evalúa premios y procesa pagos con doble barrera anti-fraude.

Laravel 11 Sanctum tokens RBAC · Spatie SHA-256 sealed JSON:API
base url https://game-sala.degestec.mx/api/v1
Todos los endpoints devuelven Content-Type: application/json. Incluye siempre el header Accept: application/json para recibir errores en JSON en lugar de redirecciones HTML.

Autenticación

Melate usa Laravel Sanctum con tokens Bearer. Haz login para obtener tu token y pásalo en el header Authorization de cada request. Los tokens expiran en 8 horas (un turno de trabajo).

Authorization: Bearer 1|abc123...
roles del sistema
Rol Descripción Acceso
admin Administrador del sistema Game API + Admin API
cajero Operador de caja Cashier API
sistema Integración máquina-a-máquina Read only

Flujo del juego

Cada partida sigue un ciclo estricto de 4 estados. No hay transiciones hacia atrás. El folio ganador se sella con SHA-256 al inicio y se revela solo al finalizar.

pending
creada
active
folios abiertos
closed
evaluando
finished
resultados
Solo puede existir una partida activa por sala. Intentar crear una segunda devuelve 409 Conflict. La evaluación de folios ocurre en un job de cola — el estado pasa a finished de forma asíncrona.

Códigos de error
HTTP error Descripción
401 UNAUTHENTICATED Token ausente, inválido o expirado
403 INSUFFICIENT_PERMISSIONS El rol no tiene acceso al endpoint
404 NOT_FOUND Recurso no encontrado
409 GAME_START_FAILED Ya existe una partida activa en la sala
409 PAYMENT_FAILED El folio ya fue cobrado (doble pago prevenido)
422 VALIDATION_ERROR Parámetros inválidos o faltantes
estructura de error
{
  "success": false,
  "message": "Room 'Sala Principal' already has an active game (#4).",
  "error":   "GAME_START_FAILED"
}

Auth
POST /auth/login Obtener token de acceso público
body params
Campo Tipo Req Descripción
email string required Email del usuario
password string required Contraseña (mín. 8 chars)
device_name string optional Nombre del dispositivo para el token
request
curl -X POST https://game-sala.degestec.mx/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "email": "cajero1@melate.test",
    "password": "Cajero1234!",
    "device_name": "terminal-01"
  }'
response 200
{
  "success":  true,
  "message":  "Login successful.",
  "data": {
    "token":      "1|abc123xyz...",
    "token_type": "Bearer",
    "expires_in": 28800,
    "user": {
      "id":          2,
      "name":        "Cajero Sala Principal",
      "email":       "cajero1@melate.test",
      "role":        "cajero",
      "room":        { "id": 1, "name": "Sala Principal", "slug": "sala-principal" },
      "permissions": ["folio.generate", "folio.view", "folio.pay"]
    }
  }
}
POST /auth/logout Revocar token actual token
request
curl -X POST https://game-sala.degestec.mx/api/v1/auth/logout \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
response 200
{ "success": true, "message": "Logged out successfully." }
GET /auth/me Perfil del usuario autenticado token
request
curl https://game-sala.degestec.mx/api/v1/auth/me \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Game API

Controla el ciclo de vida de las partidas. Requiere rol admin para start/close.

POST /game/start Iniciar nueva partida admin
body params
Campo Tipo Req Descripción
room_id integer required ID de la sala donde se jugará
prize_table_id integer required ID de la tabla de premios a usar
currency_id integer required ID de la moneda (MXN=1, USD=2, EUR=3)
request
curl -X POST https://game-sala.degestec.mx/api/v1/game/start \
  -H "Authorization: Bearer {admin_token}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"room_id": 1, "prize_table_id": 1, "currency_id": 1}'
response 201
{
  "success": true,
  "data": {
    "id":             5,
    "status":         "active",
    "win_folio_hash": "b4e81573ba3da2...",  // SHA-256 público — prueba de integridad
    "started_at":     "2026-04-10T00:00:00+00:00",
    "room":           { "id": 1, "name": "Sala Principal" },
    "currency":       { "id": 1, "code": "MXN" },
    "prize_table":    { "id": 1, "name": "Tabla Estándar" }
  }
}
GET /game/active?room_id={id} Partida activa de una sala token
query params
Campo Tipo Req Descripción
room_id integer required ID de la sala a consultar
request
curl "https://game-sala.degestec.mx/api/v1/game/active?room_id=1" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
POST /game/{id}/close Cerrar partida y evaluar folios admin
notas
El cierre es asíncrono. El estado pasa a closed inmediatamente, pero la evaluación ocurre en cola. Consulta /game/{id}/results hasta que el estado sea finished.
request
curl -X POST https://game-sala.degestec.mx/api/v1/game/5/close \
  -H "Authorization: Bearer {admin_token}" \
  -H "Accept: application/json"
response 200
{
  "success": true,
  "message": "Game closed successfully. Evaluation has been dispatched.",
  "data": { "id": 5, "status": "closed", "closed_at": "2026-04-10T..." }
}
GET /game/{id}/results Resultados de una partida finalizada público
response 200 (finished)
{
  "success": true,
  "data": {
    "winning_numbers": {
      "balls":   [8, 11, 12, 29, 32],
      "stars":   [6, 9],
      "diamond": 1
    },
    "hash_verified": true,   // SHA-256 verificado
    "statistics": {
      "total_folios":       24,
      "total_winners":      3,
      "total_bet_amount":   "2400.00",
      "total_prize_amount": "750.00"
    }
  }
}

Cashier API

Operaciones de caja: generación de folios y cobro de premios. Requiere rol cajero.

POST /cashier/folios/generate Generar folios para la partida activa cajero
body params
Campo Tipo Req Descripción
bet_amount numeric required Monto por folio (1–10000)
quantity integer optional Cantidad de folios (1–10, default 1)
request
curl -X POST https://game-sala.degestec.mx/api/v1/cashier/folios/generate \
  -H "Authorization: Bearer {cajero_token}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"bet_amount": 100, "quantity": 2}'
response 201
{
  "success": true,
  "data": {
    "game_id": 5,
    "folios": [
      {
        "folio_code": "f6d46708-473a-4029-bf57-8baeae8ff348",  // UUID imprimible en ticket
        "balls":      [3, 17, 22, 38, 49],
        "stars":      [4, 9],
        "diamond":    2,
        "bet_amount": "100.00",
        "status":     "activo"
      }
    ]
  }
}
GET /cashier/folios/{code} Obtener detalle de un folio cajero
request
curl "https://game-sala.degestec.mx/api/v1/cashier/folios/f6d46708-473a-4029-bf57-8baeae8ff348" \
  -H "Authorization: Bearer {cajero_token}" \
  -H "Accept: application/json"
GET /cashier/folios/{code}/validate Validar si un folio es ganador cajero
response 200 (ganador)
{
  "success":      true,
  "data": {
    "folio_code":  "f6d46708-...",
    "status":      "evaluado",
    "is_winner":   true,
    "prize_amount": "500.00",
    "prize_label":  "Tres + dos estrellas",
    "is_paid":     false,
    "can_collect":  true
  }
}
POST /cashier/folios/{code}/pay Cobrar premio de un folio ganador cajero
doble barrera anti-fraude
Barrera 1SELECT FOR UPDATE bloquea lecturas concurrentes del mismo folio.
Barrera 2UNIQUE(folio_id) en tabla payments: solo un INSERT puede tener éxito. Intentar pagar dos veces devuelve 409.
body params
Campo Tipo Req Descripción
notes string optional Notas del cajero (verificación de ID, etc.)
request
curl -X POST "https://game-sala.degestec.mx/api/v1/cashier/folios/f6d46708-.../pay" \
  -H "Authorization: Bearer {cajero_token}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"notes": "INE verificado"}'
response 200
{
  "success":     true,
  "message":     "Prize paid successfully.",
  "data": {
    "payment_id":  12,
    "folio_code":  "f6d46708-...",
    "amount_paid": "500.00",
    "currency":    "MXN",
    "paid_at":     "2026-04-10T14:32:00+00:00",
    "cajero":      "Cajero Sala Principal"
  }
}
GET /cashier/sales Reporte de ventas del cajero cajero
query params
Campo Tipo Req Descripción
game_id integer optional Filtrar por partida. Default: partida activa
per_page integer optional Resultados por página (10–100, default 20)

Admin API

Reportes, configuración y auditoría. Requiere rol admin.

GET /admin/games Listar todas las partidas admin
query params
Campo Tipo Descripción
status string pending | active | closed | finished
room_id integer Filtrar por sala
per_page integer Resultados por página (5–100)
GET /admin/games/{id}/stats Estadísticas detalladas de una partida admin
response 200
{
  "data": {
    "stats": {
      "total_folios":    48,
      "total_winners":   5,
      "total_bet":       4800.00,
      "total_prizes":    1250.00,
      "prize_breakdown": [ ... ]
    }
  }
}
POST /admin/prize-tables Crear tabla de premios admin
body example
{
  "name":      "Tabla Navidad 2026",
  "is_active": true,
  "rules": [
    { "balls_match": 5, "stars_match": 2, "diamond_match": 1, "multiplier": 2000, "label": "Jackpot navideño" },
    { "balls_match": 0, "stars_match": 0, "diamond_match": 0, "multiplier": 0,    "label": "Sin premio" }
  ]
}
GET /admin/audit-logs Registro de auditoría inmutable admin
query params
Campo Descripción
action game.start | folio.pay | user.login | ...
entity_type Game | Folio | Payment | User
entity_id ID del recurso afectado
from / to Rango de fechas (YYYY-MM-DD)
POST /admin/rooms/{id}/lock Bloquear o desbloquear una sala admin
body params
Campo Tipo Req Descripción
lock boolean required true = bloquear · false = desbloquear
GET /admin/reports/revenue Reporte de ingresos por sala y fecha admin
query params
Campo Descripción
from Fecha inicio (YYYY-MM-DD)
to Fecha fin (YYYY-MM-DD)
room_id Filtrar por sala
response 200
{
  "data": {
    "summary": {
      "total_games":        12,
      "total_bet_amount":   48000.00,
      "total_prize_amount": 12500.00,
      "net_revenue":        35500.00,
      "margin_percentage":  73.96
    },
    "by_room": [ ... ]
  }
}
Melate Digital API v1.0 — 2026  ·  Panel Cajero