API
API utilizada por la aplicación de PC para operar con el dispositivo POS a través de SDConn.
Base URL: http://localhost:8484
Todas las respuestas son JSON con Content-Type: application/json.
Operaciones
POST /api/v1/read
Operación completa de lectura de tarjeta. Este es el endpoint principal que la aplicación de PC usa para procesar un pago.
Flujo estándar (sin intentToken):
- Obtiene información del dispositivo (serial number, modelo, etc.)
- Obtiene la ubicación GPS del dispositivo
- Crea una operación en la API de Mobbex (/p/pos/operation)
- Envía el token de lectura al dispositivo para que lea la tarjeta
- Devuelve los datos de la tarjeta leída junto con el intentToken generado
Flujo con token externo (con intentToken):
Si se envía un intentToken en el cuerpo, se omite la llamada a la API de Mobbex y se usa ese token directamente para la lectura. En este caso la respuesta incluye además la geolocation del dispositivo.
Cuerpo:
Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
total | number | Sí | Monto total como float (ej: 15.00) |
otherAmount | number | No | Monto adicional (propina, etc.) |
intent | string | No | Tipo de intento (por defecto: "payment.v2") |
currency | string | No | Código de moneda (por defecto: "ARS") |
hideAmount | boolean | No | Ocultar monto en la pantalla del dispositivo |
test | boolean | No | Enviar operación en modo test a Mobbex |
intentToken | string | No | Token externo. Si se envía, omite la llamada a la API de Mobbex |
source | string | No | Fuente de pago (ej: "arg.qr"). Si se envía, activa el flujo QR en lugar de lectura de tarjeta |
description | string | No | Descripción de la operación (se envía a la API de Mobbex) |
reference | string | No | Referencia externa de la operación |
async | boolean | No | Si es true, la lectura se ejecuta en segundo plano y se devuelve inmediatamente el intentToken. El resultado se consulta con GET /api/v1/read/:token |
Respuesta exitosa — flujo tarjeta (estándar):
Respuesta exitosa — flujo tarjeta (con token externo):
Respuesta exitosa — flujo QR (con source):
Cuando se envía source, SDConn:
- Crea el intent token (o usa el intentToken externo).
- Llama al endpoint de operación (/p/operations/{token}) con la fuente.
- Descarga la imagen QR del resultado y la codifica en base64.
- Envía la imagen al dispositivo POS para que la muestre en pantalla.
- Retorna los datos de la operación (el pago queda pendiente hasta que el usuario escanee el QR).
Nota: En el flujo QR, la respuesta no contiene sourceData ya que no se lee una tarjeta. El campo operationId identifica la operación para consultar su estado. El campo status indica el estado actual de la operación (generalmente pendiente hasta que se escanee el QR).
Respuesta — modo asíncrono (async: true):
Cuando se envía async: true, SDConn ejecuta los pasos 1-3 (obtener info del dispositivo, ubicación y token) de forma síncrona y luego lanza la lectura de tarjeta o flujo QR en segundo plano. Responde inmediatamente con el intentToken para que el cliente pueda consultar el resultado cuando esté listo.
El resultado se consulta con GET /api/v1/read/:token (ver sección siguiente).
Error:
Posibles errores:
Error | Descripción |
|---|---|
total is required and must be > 0 | Falta el monto o es inválido |
credentials not configured | No se configuraron credenciales (solo si no se envía intentToken). Cuando se usa un token externo, las credenciales no son necesarias |
credentials required for source operations | Se envió source pero no hay credenciales (el flujo QR siempre requiere credenciales para llamar al endpoint de operación) |
no device connected | No hay dispositivo conectado |
device info not available | No se pudo obtener info del dispositivo |
Card read failed | El dispositivo no pudo leer la tarjeta |
TIMEOUT | Se agotó el tiempo de lectura (120s) |
CANCELLED | La lectura fue cancelada |
NOT_IN_PINPAD_MODE | El dispositivo no está en modo pinpad |
Operate response did not contain a QR barcode | La respuesta del endpoint de operación no contiene el código QR esperado |
GET /api/v1/read/:token
Consulta el resultado de una operación de lectura asíncrona iniciada con async: true.
Parámetro de ruta:
Parámetro | Tipo | Descripción |
|---|---|---|
token | string | El intentToken devuelto por POST /api/v1/read |
Respuesta — pendiente (la lectura aún está en progreso):
Respuesta — completada (la lectura finalizó exitosamente):
La respuesta contiene todos los campos que devolvería una lectura síncrona (sourceData, geolocation, etc.). El resultado se elimina del almacenamiento interno una vez consumido.
Respuesta — error (la lectura falló):
El resultado de error también se elimina una vez consumido.
Token no encontrado:
DELETE /api/v1/read
Cancela una lectura de tarjeta en progreso (tanto síncrona como asíncrona). Envía la señal de cancelación al dispositivo para que deje de esperar la tarjeta.
Respuesta:
Pantalla del dispositivo
Mostrar resultado — POST /api/v1/display
Muestra una pantalla de resultado con animación en el dispositivo POS. Es fire-and-forget: SDConn responde inmediatamente tras enviar el comando.
Cuerpo:
Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
status | string o number | No | Estado del resultado (ver tablas abajo) |
title | string | No | Título que se muestra en pantalla |
subtitle | string | No | Subtítulo debajo del título |
total | number | No | Monto como float (ej: 15.00) |
currency | string | No | Código de moneda (ej: "ARS") |
text | string | No | Texto adicional debajo del monto |
timeout | number | No | Segundos antes de volver a pantalla de espera (defecto: 10). Usar 0 para desactivar. |
Valores de status por nombre:
Valor | Animación |
|---|---|
"success" | Círculo verde con check |
"error" | Círculo rojo con X |
"neutral" | Círculo naranja con reloj |
"none" | Sin animación, fondo blanco |
Valores de status por código numérico:
Se pueden enviar códigos numéricos directamente (por ejemplo, el status.code del procesador) y el dispositivo resuelve la animación automáticamente:
Códigos | Se resuelve a |
|---|---|
3, 4, 200, 300-302, 605, 800 | success |
400-417, 500, 603, 604 | error |
1, 2, 100, 210, 600-602, 610 | neutral |
Otros | none |
Respuesta:
Mostrar carga — POST /api/v1/display
Muestra una pantalla de carga con spinner en el dispositivo POS. Es fire-and-forget. Se usa para indicar que se está procesando una operación.
Cuerpo:
Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
view | string | Sí | Debe ser "loading" |
title | string | No | Título que se muestra en pantalla |
subtitle | string | No | Subtítulo debajo del título |
timeout | number | No | Segundos antes de volver a pantalla de espera (defecto: 10). Usar 0 para desactivar. |
Respuesta:
Para quitar la pantalla de carga, enviar un DELETE /api/v1/display o mostrar otra vista.
Mostrar selección — POST /api/v1/display
Muestra una pantalla con opciones seleccionables en el dispositivo POS. Es bloqueante: la petición HTTP queda en espera hasta que el usuario selecciona una opción o se agota el timeout.
Cuerpo:
Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
view | string | Sí | Debe ser "choose" |
title | string | No | Título de la pantalla |
subtitle | string | No | Subtítulo |
values | array | Sí | Lista de opciones. Cada opción tiene label (texto visible) y value (valor de retorno) |
timeout | number | No | Segundos de espera antes de timeout (defecto: 60) |
Respuesta exitosa (usuario seleccionó una opción):
Respuesta — timeout:
Ocultar pantalla — DELETE /api/v1/display
Oculta la pantalla del dispositivo antes de que expire el timeout. El dispositivo vuelve a la pantalla de espera de pinpad.
Respuesta:
Información de tarjeta
POST /api/v1/card/info
Analiza los datos de track de una tarjeta y extrae el código de servicio para determinar si la tarjeta tiene chip EMV o capacidad contactless (NFC). No requiere conexión con un dispositivo — es un utilitario de parsing local.
Cuerpo:
Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
track1 | string | No | Datos de track 1 (actualmente no se parsea, reservado para uso futuro) |
track2 | string | Sí | Datos de track 2 (formato ISO 7813) |
Formato de Track 2:
El separador puede ser = (texto) o D (hex).
Respuesta exitosa:
Campo | Tipo | Descripción |
|---|---|---|
pan | string | PAN enmascarado (primeros 8 dígitos del BIN + últimos 4 dígitos) |
expiry | string | Vencimiento en formato AAMM |
serviceCode.code | string | Código de servicio de 3 dígitos |
serviceCode.hasChip | boolean | La tarjeta tiene chip EMV (IC) |
serviceCode.chipRequired | boolean | El chip es obligatorio (no se permite fallback a banda magnética) |
serviceCode.contactless | boolean | La tarjeta soporta contactless (NFC/tap) |
serviceCode.international | boolean | La tarjeta es de intercambio internacional |
serviceCode.pinRequired | boolean | Se requiere PIN para la transacción |
serviceCode.cashAllowed | boolean | Se permite retiro de efectivo |
Referencia del primer dígito del código de servicio:
Dígito | Significado | hasChip | chipRequired | contactless |
|---|---|---|---|---|
1 | Internacional, chip obligatorio | ✓ | ✓ | |
2 | Internacional, chip + contactless | ✓ | | ✓ |
5 | Nacional, chip obligatorio | ✓ | ✓ | |
6 | Nacional, chip + contactless | ✓ | | ✓ |
7 | Privado, chip obligatorio | ✓ | ✓ | |
0 | Solo banda magnética | | | |
Error:
Proxy de procesamiento
POST /api/v1/p/operations/:token
Proxy directo a la API de Mobbex (POST {mobbexAPIBase}/p/operations/{token}). Reenvía el cuerpo tal cual, sin parsing ni validación. Útil cuando el intent token se genera externamente y se quiere procesar la operación sin pasar por el flujo de lectura.
Las credenciales de Mobbex (si están configuradas) se agregan automáticamente como headers x-api-key y x-access-token.
Parámetro de ruta:
Parámetro | Tipo | Descripción |
|---|---|---|
token | string | Intent token a operar |
Cuerpo: Se envía directamente a la API de Mobbex sin modificaciones.
Respuesta: Se reenvía directamente la respuesta de la API de Mobbex sin modificaciones.
Conexión al dispositivo por API
POST /api/v1/connect
Inicia una conexión al dispositivo de forma programática (alternativa al panel de administración).
Conexión serial:
Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
mode | string | Sí | Debe ser "serial" |
port | string | Sí | Nombre del puerto serial (ej: "COM3", "/dev/cu.usbmodem1421") |
Respuesta exitosa (serial):
La conexión serial se establece inmediatamente (handshake + modo pinpad). No requiere verificación adicional.
Conexión HTTP:
Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
mode | string | Sí | Debe ser "http" |
ip | string | Sí | IP del dispositivo |
port | string | No | Puerto del dispositivo (defecto: 5000) |
Respuesta exitosa (HTTP):
El dispositivo mostrará un PIN en pantalla. Se debe verificar con POST /api/v1/connect/verify.
POST /api/v1/connect/verify
Verifica el PIN mostrado en el dispositivo para completar la conexión HTTP.
Cuerpo:
Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
ip | string | Sí | IP del dispositivo |
port | number | No | Puerto del dispositivo (defecto: 5000) |
pin | string | Sí | PIN mostrado en el dispositivo |
Respuesta exitosa:
Error (PIN inválido):
Reconexión
POST /api/v1/reconnect
Intenta reconectarse al último dispositivo guardado usando el token de confianza. No requiere PIN.
Respuesta exitosa:
Error:
Dispositivo
GET /api/v1/device/info
Obtiene información del hardware y software del dispositivo conectado.
Respuesta:
La información se cachea en memoria por 24 horas y se limpia al cambiar de modo de conexión o dispositivo.
GET /api/v1/device/location
Obtiene la ubicación GPS del dispositivo. Se cachea por 5 minutos. La consulta al dispositivo tiene un timeout de 1 segundo — si no responde a tiempo, se omite la ubicación (no se envía en la operación). Si no hay ubicación disponible (ni en caché ni del dispositivo), la operación continúa sin geolocalización.
Respuesta — ubicación disponible:
Respuesta — ubicación no disponible:
GET /api/v1/devices
Lista los dispositivos conectados actualmente.
Respuesta:
Si no hay dispositivo conectado, devices es un array vacío.
DELETE /api/v1/devices/:id
Elimina un dispositivo de la lista de dispositivos activos.
Respuesta:
PATCH /api/v1/devices/:id/mode
Cambia el modo de operación del dispositivo.
Cuerpo:
Modo | Descripción |
|---|---|
normal | Modo POS estándar con pantalla de ingreso de monto |
slave | Modo cola. Recibe trabajos de pago desde una cola |
transit | Lectura continua de tarjetas para peajes/transporte |
pinpad | Modo pinpad. Espera comandos de lectura del controlador |
POST /api/v1/pinpad-config
Personaliza la pantalla de espera del modo pinpad. Permite configurar título, subtítulo e imagen de fondo.
Todos los campos son opcionales — solo se envían al dispositivo los campos proporcionados. Los campos omitidos no se modifican.
Si background_image es una URL (http:// o https://), SDConn descarga la imagen, la redimensiona y optimiza automáticamente antes de enviarla al dispositivo:
- Imágenes estáticas (PNG, JPEG): se redimensionan a máximo 480px de ancho (manteniendo proporción) y se re-codifican como JPEG calidad 80.
- GIF animados: se redimensionan a máximo 480px de ancho, se limitan a 90 frames (eliminando frames de forma uniforme y acumulando los delays para mantener la velocidad de animación), y se re-codifican como GIF con dithering Floyd-Steinberg y paleta de 256 colores.
Nota: background_image solo está disponible en modo HTTP. Si se envía en modo serial, se retorna un error.
Cuerpo:
Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
title | string | No | Título mostrado en la pantalla de espera |
subtitle | string | No | Subtítulo mostrado debajo del título |
background_image | string | No | URL de la imagen de fondo (PNG, JPEG o GIF) o string base64. Si es URL, se descarga, optimiza y convierte a base64 automáticamente. Solo disponible en modo HTTP. |
Comportamiento según modo de conexión:
- Serial: Solo title y subtitle. Se envía como campo waiting dentro del mensaje SET_MODE ({ mode: "pinpad", waiting: { title, subtitle } }). Si se envía background_image, se retorna error.
- HTTP: Se envía via POST /device/pinpad-config al dispositivo. Soporta los 3 campos.
Respuesta exitosa:
Errores: