Ficha

Conecta tu juego a Ficha

Una API HTTP con JSON. Si tu juego puede hacer una petición web, puede cobrar entradas y pagar premios con la ficha que tus jugadores usan en todos los demás juegos.

Conectar mi juego

Las cuatro ideas

Montos en céntimos
Siempre enteros: 150 es S/ 1.50. Una ficha vale un sol.
La banca de tu juego
Cada juego tiene su propia cuenta. Un cobro pasa fichas del jugador a la banca; un pago, de la banca al jugador. Tu juego nunca crea fichas: solo puede pagar lo que hay en su banca. Tú la llenas desde tu saldo y te llevas sus ganancias desde el panel.
El jugador da permiso
Para cobrarle, el jugador tiene que conectar su cuenta con tu juego y elegir un límite diario (lo cobrado en 24 horas). Puede cambiarlo o desconectarte cuando quiera.
Referencia: reintentar es seguro
Cada cobro y pago lleva una referencia tuya y única (por ejemplo partida-8812-entrada). Si se corta la conexión, repite la misma petición: Ficha devuelve la operación original con "repetida": true y no cobra dos veces.

Conectar a un jugador

Hay dos formas. La primera sirve para cualquier juego; la segunda es más cómoda en juegos web.

Con un código (escritorio, celular, consola, bots)

Tu juego pide un código, lo enseña en pantalla y el jugador lo escribe en ficha.bezenti.com/vincular. Esta ruta no usa el secreto, así que puedes llamarla desde el propio juego.

curl -X POST https://ficha.bezenti.com/api/v1/vinculaciones \
  -H "Content-Type: application/json" \
  -d '{"juego": "mi-juego", "limite_diario": 2000}'
// Respuesta (201)
{
  "codigo": "BCDF-GH23",
  "codigo_dispositivo": "fdc_…",
  "url": "https://ficha.bezenti.com/vincular",
  "url_directa": "https://ficha.bezenti.com/vincular?codigo=BCDF-GH23",
  "expira_en": 600,
  "intervalo": 3
}

Enseña el código (o un QR de url_directa) y consulta GET /api/v1/vinculaciones/{codigo_dispositivo} cada intervalo segundos. El estado pasa de pendiente a aprobada, rechazada o vencida (a los 10 minutos). Cuando se aprueba, trae al jugador:

{ "estado": "aprobada", "juego": "mi-juego", "jugador": { "id": 12, "usuario": "mateo_99", "nombre": "Mateo" } }

Guarda el id: es lo que mandas en cada cobro y pago. No hace falta volver a conectar en cada partida.

Si el código lo pide el cliente del juego, tu servidor no debe fiarse del id que le mande el cliente: un cliente modificado puede mandar el de otra persona. Haz que el cliente le pase el codigo_dispositivo y que tu servidor consulte él mismo esa ruta, comprobando que estado es aprobada y que juego es tu id público. Nadie puede adivinar un codigo_dispositivo.

Con redirección (juegos web)

Registra en el panel la dirección de regreso de tu juego. Luego manda al jugador a:

https://ficha.bezenti.com/autorizar?juego=mi-juego
  &redireccion=https://mijuego.com/ficha/callback
  &estado=<valor aleatorio que guardas en su sesión>
  &limite=2000

Al aprobar, vuelve a tu dirección con ?codigo=fac_…&estado=… (o ?error=rechazado). Comprueba que estado es el que guardaste y canjea el código desde tu servidor, antes de 5 minutos:

curl -X POST https://ficha.bezenti.com/api/v1/token \
  -H "Authorization: Bearer $FICHA_SECRETO" \
  -H "Content-Type: application/json" \
  -d '{"codigo": "fac_…", "redireccion": "https://mijuego.com/ficha/callback"}'

Cobrar y pagar

Desde tu servidor, con Authorization: Bearer <secreto>. Los dos aceptan el mismo cuerpo:

curl -X POST https://ficha.bezenti.com/api/v1/cobros \
  -H "Authorization: Bearer $FICHA_SECRETO" \
  -H "Content-Type: application/json" \
  -d '{"jugador": 12, "monto": 50, "concepto": "Entrada a la partida", "referencia": "partida-8812-entrada"}'
// Respuesta (201 si es nueva, 200 si es un reintento)
{
  "id": 481,
  "tipo": "cobro",
  "jugador": 12,
  "monto": 50,
  "concepto": "Entrada a la partida",
  "referencia": "partida-8812-entrada",
  "saldo_jugador": 1450,
  "banca": 3050,
  "creado": "2026-11-04T19:20:11.000Z",
  "repetida": false
}

Para pagar un premio, lo mismo en POST /api/v1/pagos. Puedes pagarle a un jugador aunque te haya desconectado (lo que ya ganó es suyo); cobrarle, no.

Antes de cobrar puedes mirar GET /api/v1/jugadores/{id}: trae su saldo y su disponible_hoy, para avisarle antes de que empiece la partida.

Errores

Siempre con la misma forma. Compara el código, no el mensaje:

{ "error": { "codigo": "saldo_insuficiente", "mensaje": "Saldo insuficiente: tienes S/ 0.20 y necesitas S/ 0.50.", "saldo": 20, "falta": 30 } }
CódigoHTTPQué pasó
sin_secreto / secreto_invalido401Falta la cabecera Authorization o el secreto no es de ningún juego (¿lo regeneraste?).
juego_suspendido403El cajero suspendió tu juego. Nada se cobra ni se paga.
jugador_no_vinculado403Ese jugador nunca conectó su cuenta con tu juego. Pídele que lo haga.
autorizacion_revocada403El jugador desconectó tu juego: ya no puedes cobrarle (pagarle sí).
limite_excedido403Pasa el límite diario del jugador. Trae limite_diario y disponible_hoy.
saldo_insuficiente402Al jugador no le alcanza. Trae saldo y falta. Sugiérele recargar.
banca_insuficiente402Tu banca no alcanza para el premio. Pon fondos desde tu panel.
referencia_repetida409Esa referencia ya se usó para otra operación distinta (otro monto, jugador o tipo).
monto_invalido · concepto_invalido · referencia_invalida · jugador_invalido · json_invalido400Datos mal formados: lee el mensaje.
error_interno500Algo falló en Ficha. Reintenta con la misma referencia: nunca se cobra dos veces.

Todas las rutas

RutaSecretoPara qué
POST /api/v1/vinculacionesNoPide un código para que el jugador conecte su cuenta.
GET /api/v1/vinculaciones/{codigo_dispositivo}NoEstado del código; al aprobarse trae al jugador.
POST /api/v1/tokenSíCanjea el código de la vinculación web por el jugador.
GET /api/v1/jugadores/{id}SíSaldo del jugador y cuánto le puedes cobrar hoy.
POST /api/v1/cobrosSíJugador → banca del juego.
POST /api/v1/pagosSíBanca del juego → jugador.
GET /api/v1/operaciones/{referencia}SíBusca un cobro o pago por tu referencia.
GET /api/v1/bancaSíSaldo de la banca y lo cobrado y pagado.
GET /api/v1/movimientos?limite=&antes=SíHistorial de la banca, paginado.

La especificación completa está en openapi.json: sirve para generar un cliente en cualquier lenguaje o para importarla en Postman o Insomnia.

Librerías

Pequeñas y sin dependencias. Generan la referencia si no la das y reintentan solas ante cortes de red, sin cobrar dos veces.

Seguridad

  • El secreto va solo en tu servidor. Nunca dentro del juego que descarga el jugador (un .exe, un .apk o el JavaScript de una web se pueden abrir y leer). Quien tenga el secreto puede vaciar tu banca.
  • Decide en el servidor. Quién ganó y cuánto se paga lo calcula tu servidor, no el cliente: si el cliente dice «gané», cualquiera puede mentir.
  • ¿Tu juego no tiene servidor? Puede conectar jugadores con un código sin secreto, pero para cobrar y pagar necesita uno. Un servidor mínimo como el del juego de ejemplo cabe en un archivo.
  • Pon en la banca solo lo que necesitas para los premios del día. Si algo sale mal, el daño se limita a eso.
  • Si el secreto se filtró, crea uno nuevo en el panel: el anterior deja de funcionar al momento.