API
53 min
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 { "total" 15 00, "otheramount" 0, "intent" "token de intento", "currency" "ars", "hideamount" false, "test" false, "intenttoken" "", "source" "", "description" "", "reference" "", "async" false } 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) { "result" true, "intenttoken" "token generado por mobbex", "sourcedata" { "pin" " ", "emvdata" " ", "cryptogram" " ", "ksn" " ", "track2" " " } } respuesta exitosa — flujo tarjeta (con token externo) { "result" true, "intenttoken" "token externo enviado", "geolocation" \[ 31 4201, 64 1888], "sourcedata" { "pin" " ", "emvdata" " ", "cryptogram" " ", "ksn" " ", "track2" " " } } respuesta exitosa — flujo qr (con source) { "result" true, "intenttoken" "token generado por mobbex", "operationid" "ks6d18und", "source" "arg qr", "status" { "code" "100", "text" "pendiente" }, "geolocation" \[ 31 4201, 64 1888] } 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 { "result" true, "intenttoken" "token generado o externo", "async" true, "status" "pending" } el resultado se consulta con get /api/v1/read/\ token (ver sección siguiente) error { "result" false, "intenttoken" "token si fue generado", "error" "descripción del 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) { "result" false, "intenttoken" "token", "status" "pending" } respuesta — completada (la lectura finalizó exitosamente) { "result" true, "intenttoken" "token", "status" "completed", "sourcedata" { "pin" " ", "emvdata" " ", "cryptogram" " ", "ksn" " ", "track2" " " } } 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ó) { "result" false, "intenttoken" "token", "status" "error", "error" "timeout" } el resultado de error también se elimina una vez consumido token no encontrado { "result" false, "error" "no async operation found for this token" } 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 { "result" true } 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 { "status" "success", "title" "pago aprobado", "subtitle" "visa 1234", "total" 15 00, "currency" "ars", "text" "id 123456", "timeout" 10 } 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 { "result" true } 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 { "view" "loading", "title" "procesando pago ", "subtitle" "no retire la tarjeta", "timeout" 30 } 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 { "result" true } 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 { "view" "choose", "title" "seleccione cuotas", "subtitle" "visa 1234", "values" \[ { "label" "1 pago $15 00", "value" "1" }, { "label" "3 cuotas $5 75 c/u", "value" "3" }, { "label" "6 cuotas $3 08 c/u", "value" "6" } ], "timeout" 60 } 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) { "result" true, "selected" { "label" "3 cuotas $5 75 c/u", "value" "3" } } respuesta — timeout { "result" false, "error" "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 { "result" true } 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 { "track1" "%b4111111111111111^doe/john^2512101000000000?", "track2" ";4111111111111111=2512101000000000?" } 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 ;pan=yymmsssddddddddd? │ │ │ └─ datos discrecionales │ │ └─── código de servicio (3 dígitos) │ └────── vencimiento (aamm) └─────────── número de tarjeta (pan) el separador puede ser = (texto) o d (hex) respuesta exitosa { "result" true, "pan" "41111111 1111", "expiry" "2512", "servicecode" { "code" "101", "haschip" true, "chiprequired" true, "contactless" false, "international" true, "pinrequired" false, "cashallowed" true } } 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 { "result" false, "error" "invalid track2 no separator found (expected '=' or 'd')" } 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 { "mode" "serial", "port" "com3" } 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) { "result" true, "mode" "serial", "port" "com3", "connected" true } la conexión serial se establece inmediatamente (handshake + modo pinpad) no requiere verificación adicional conexión http { "mode" "http", "ip" "192 168 1 50", "port" "5000" } 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) { "result" true, "mode" "http", "ip" "192 168 1 50", "port" 5000, "verificationneeded" true, "message" "enter the pin displayed on the device using post /api/v1/connect/verify" } 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 { "ip" "192 168 1 50", "port" 5000, "pin" "123456" } 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 { "result" true, "mode" "http", "device" { "ip" "192 168 1 50", "port" 5000, "name" "pos n62" }, "connected" true } error (pin inválido) { "result" false, "error" "invalid pin" } reconexión post /api/v1/reconnect intenta reconectarse al último dispositivo guardado usando el token de confianza no requiere pin respuesta exitosa { "result" true, "device" { "ip" "192 168 1 50", "port" 5000, "name" "pos n62" } } error { "result" false, "error" "no saved device or device not reachable" } dispositivo get /api/v1/device/info obtiene información del hardware y software del dispositivo conectado respuesta { "type" "pos", "serialnumber" "sn12345", "deviceextras" { "os" "android", "osversion" "11", "manufacturer" "nexgo", "model" "n62", "serialnumber" "sn12345", "bundleid" "com sugaway pos", "buildnumber" 42, "appversion" "1 2 3", "romversion" "n62 20230101", "kernelversion" "4 14 116" } } 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 { "latitude" 31 4201, "longitude" 64 1888, "accuracy" 12 5, "provider" "gps", "timestamp" 1741564800000 } respuesta — ubicación no disponible { "error" "location not available" } get /api/v1/devices lista los dispositivos conectados actualmente respuesta { "result" true, "devices" \[ { "ip" "192 168 1 50", "port" 5000, "name" "pos n62" } ] } 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 { "result" true } patch /api/v1/devices/\ id/mode cambia el modo de operación del dispositivo cuerpo { "mode" "pinpad" } 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 { "title" "mi negocio", "subtitle" "acerque o inserte su tarjeta", "background image" "https //example com/background png" } 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 { "result" true } errores { "result" false, "error" "no device connected" } { "result" false, "error" "background image is only available in http mode" } flujo típico de uso sin token externo (flujo estándar) app pc sdconn dispositivo pos │ │ │ │ post /api/v1/read │ │ │ { total 15 00 } │ │ │ ─────────────────────────────>│ │ │ │ (obtiene info del dispositivo)│ │ │ ──────────────────────────────>│ │ │<──────────────────────────────│ │ │ │ │ │ (crea operación en mobbex) │ │ │ ──────────> mobbex api │ │ │<────────── { token } │ │ │ │ │ │ (lectura de tarjeta) │ │ │ ──────────────────────────────>│ │ │ (usuario pasa tarjeta)│ │ │<────────── { sourcedata } │ │ │ │ │ { result true, │ │ │ intenttoken " ", │ │ │ sourcedata { } } │ │ │<─────────────────────────────│ │ │ │ │ │ post /api/v1/display │ │ │ { status "success" } │ │ │ ─────────────────────────────>│ │ │ │ ──────────────────────────────>│ │ │ (pantalla de resultado)│ con token externo app pc sdconn dispositivo pos │ │ │ │ post /api/v1/read │ │ │ { total 15 00, │ │ │ intenttoken "ext token" } │ │ │ ─────────────────────────────>│ │ │ │ (obtiene info del dispositivo)│ │ │ ──────────────────────────────>│ │ │<──────────────────────────────│ │ │ │ │ │ (omite llamada a mobbex api) │ │ │ │ │ │ (lectura de tarjeta) │ │ │ ──────────────────────────────>│ │ │ (usuario pasa tarjeta)│ │ │<────────── { sourcedata } │ │ │ │ │ { result true, │ │ │ intenttoken "ext token", │ │ │ geolocation \[lat, lng], │ │ │ sourcedata { } } │ │ │<─────────────────────────────│ │ flujo qr (con source) app pc sdconn dispositivo pos │ │ │ │ post /api/v1/read │ │ │ { total 15 00, │ │ │ source "arg qr" } │ │ │ ─────────────────────────────>│ │ │ │ (obtiene info del dispositivo)│ │ │ ──────────────────────────────>│ │ │<──────────────────────────────│ │ │ │ │ │ (crea operación en mobbex) │ │ │ ──────────> mobbex api │ │ │<────────── { token } │ │ │ │ │ │ (obtiene qr de mobbex) │ │ │ ──────────> mobbex api │ │ │<────────── { barcode } │ │ │ │ │ │ (muestra qr en dispositivo) │ │ │ ──────────────────────────────>│ │ │ (qr visible en pantalla)│ │ │ │ │ { result true, │ │ │ intenttoken " ", │ │ │ operationid " ", │ │ │ source "arg qr", │ │ │ status { code, text }, │ │ │ geolocation \[lat, lng] } │ │ │<─────────────────────────────│ │ │ │ │ │ (espera a que el usuario │ │ │ escanee el qr — consultar │ │ │ estado externamente) │ │ │ │ │ │ delete /api/v1/read │ │ │ (cuando quiera cancelar) │ │ │ ─────────────────────────────>│ ──────────────────────────────>│ │ │ (quita qr) │ flujo asíncrono app pc sdconn dispositivo pos │ │ │ │ post /api/v1/read │ │ │ { total 15 00, │ │ │ async true } │ │ │ ─────────────────────────────>│ │ │ │ (obtiene info del dispositivo)│ │ │ ──────────────────────────────>│ │ │<──────────────────────────────│ │ │ │ │ │ (crea operación en mobbex) │ │ │ ──────────> mobbex api │ │ │<────────── { token } │ │ │ │ │ { result true, │ (lanza lectura en background) │ │ intenttoken " ", │ ──────────────────────────────>│ │ async true, │ │ │ status "pending" } │ │ │<─────────────────────────────│ │ │ │ │ │ (polling) │ │ │ get /api/v1/read/\ token │ │ │ ─────────────────────────────>│ │ │ { status "pending" } │ │ │<─────────────────────────────│ │ │ │ (usuario pasa tarjeta)│ │ │<────────── { sourcedata } │ │ │ │ │ get /api/v1/read/\ token │ │ │ ─────────────────────────────>│ │ │ { result true, │ │ │ status "completed", │ │ │ intenttoken " ", │ │ │ sourcedata { } } │ │ │<─────────────────────────────│ │ flujo con vista choose (cuotas) app pc sdconn dispositivo pos │ │ │ │ post /api/v1/display │ │ │ { view "choose", │ │ │ title "cuotas", │ │ │ values \[ ] } │ │ │ ─────────────────────────────>│ │ │ │ ──────────────────────────────>│ │ │ (usuario toca una opción)│ │ │<────────────────────────────── │ │ │ │ │ { result true, │ │ │ selected { │ │ │ label "3 cuotas", │ │ │ value "3" } } │ │ │<─────────────────────────────│ │