Android
Integra el módulo Kotlin o llama directamente a HTTPS. Obtén la serie con la API autorizada del fabricante; solicita permiso de red y ejecuta las peticiones fuera del hilo de interfaz.
GUÍA DE INTEGRACIÓN · SEPTIEMBRE 2026
Conecta tu aplicación de terminal a ControlPOS por HTTPS. Emite el comprobante después de confirmar la operación y entrega al cliente un enlace, un QR o un PDF.
01 / CONEXIÓN
Solicita a un administrador un comercio y terminal de pruebas. En Terminales → Códigos de alta, el administrador genera el código. La documentación no crea credenciales ni proporciona un sandbox público; usa una instancia de pruebas acordada con el administrador.
La serie debe ser estable y única, con un máximo de 64 caracteres. El código determina el comercio; no envíes un comercio distinto. La etiqueta ayuda a identificar fabricante, modelo y sucursal.
curl --request POST "$BASE_URL/api/terminals/enroll" \
--header 'Content-Type: application/json' \
--data '{"enrollmentCode":"CPE-REEMPLAZAR","serial":"MARCA-MODELO-0001","tokenLabel":"Modelo · Sucursal de pruebas"}'Define BASE_URL con el origen de tu instancia de pruebas. El origen del servicio publicado es https://ticket.control-pos.com. No ejecutes pruebas de emisión allí sin un comercio destinado a pruebas.
{
"terminal": { "id": "…", "serial": "MARCA-MODELO-0001" },
"token_id": "…",
"token": "cpt_…",
"token_expires_at": null
}Respuesta abreviada. Guarda el token en almacenamiento protegido por el dispositivo. Solo se muestra una vez: no lo incluyas en el APK, repositorios, capturas ni logs. Si se pierde o se expone, el administrador debe revocarlo y emitir uno nuevo. No vuelvas a canjear automáticamente un código si perdiste la respuesta: primero revisa el alta en el panel.
Este ejemplo es un ticket en efectivo. Para tarjeta agrega el bloque card descrito abajo. Crea una clave por operación y persiste el cuerpo y la clave antes de enviar.
curl --request POST "$BASE_URL/api/tickets" \
--header 'Content-Type: application/json' \
--header "X-Terminal-Token: $TERMINAL_TOKEN" \
--header "Idempotency-Key: $OPERATION_KEY" \
--data @ticket-example.json{
"terminalSerial": "MARCA-MODELO-0001",
"currency": "MXN",
"items": [{ "name": "Consumo", "qty": 1, "price": 100.00 }],
"tip": 10.00,
"transactionType": "venta",
"capture": { "orderReference": "ORDEN-0001", "paymentMethod": "efectivo" }
}La primera emisión devuelve 201. Un reintento resuelto con la misma clave y cuerpo devuelve 200 y el mismo ticket. La respuesta incluye id, folio, amount, receipt_svg, created_at y expires_at. Los importes de respuesta son cadenas: en este ejemplo, amount: "110.00".
Con el id recibido, construye BASE_URL + "/t/" + id para el enlace o contenido del QR. El PDF está en /t/{id}/pdf. Estas rutas son públicas: comparte el enlace únicamente con su destinatario. Respeta expires_at; el recibo puede dejar de estar disponible después de su vencimiento.
02 / CONTRATO HTTP
Solicitudes en JSON con nombres camelCase; respuestas del ticket en snake_case. Envía credenciales solo al origen HTTPS configurado. El token de terminal permite emitir tickets; no permite navegar el panel ni consultar los endpoints administrativos.
| Método y ruta | Autenticación | Resultado |
|---|---|---|
| POST /api/terminals/enroll | Código en el cuerpo; sin token | Terminal y credencial |
| POST /api/tickets | X-Terminal-Token o Authorization: Bearer | 201 nuevo / 200 reintento |
| GET /t/{id} | Enlace público; sin token | Vista del comprobante |
| GET /t/{id}/pdf | Enlace público; sin token |
| Campo | Regla |
|---|---|
| terminalSerial * | Serie registrada, 1–64 caracteres; debe corresponder al token. |
| items * | Entre 1 y 200 conceptos. name: 1–120 caracteres; qty: positivo, hasta 3 decimales y 6 enteros; price: no negativo, hasta 2 decimales y 10 enteros. |
| currency | Tres letras mayúsculas; por defecto MXN. No convierte monedas. |
| tip | No negativa, hasta 2 decimales y 10 enteros; por defecto 0. Total = suma de conceptos + propina. |
| transactionType | venta (por defecto), devolucion, cancelacion, check_in, checkout. Describe el comprobante; no ejecuta la operación financiera. |
| card | Opcional. brand: visa, mastercard, amex, card; type: credito, debito; last4: exactamente 4 dígitos; entryMode: chip (por defecto), contactless, swipe, manual. |
| capture | Opcional. orderReference (64), cashier (80), operationNumber (32), batchNumber (32), affiliation (32 caracteres). installments: entero 2–48; paymentMethod: efectivo, tarjeta, transferencia, otro; capturedAt: fecha y hora ISO 8601 UTC. transaccionId (UUID) y rrn (12): autorización que ya dio el switch; obligatorios en ventas con tarjeta, si faltan o no coinciden con RRN, terminal e importe el servidor responde 409 AUTHORIZATION_NOT_FOUND (reintentable, no crea ticket). |
| receiptTemplate | Código opcional, hasta 64 caracteres. Una plantilla inexistente rechaza la emisión. |
* Obligatorio. No envíes PAN completo, CVV, PIN ni datos de banda. No añadas impuestos o descuentos como campos nuevos: el contrato actual no los calcula.
"card": { "brand": "visa", "type": "debito", "last4": "1234", "entryMode": "contactless" },
"capture": {
"operationNumber": "000123", "batchNumber": "001",
"affiliation": "AFILIACION", "paymentMethod": "tarjeta",
"capturedAt": "2026-09-04T18:00:00Z"
}Fragmento para una operación de prueba con tarjeta. Captura los valores reales de la transacción desde la aplicación de pagos; no inventes datos faltantes.
voucher-venta, voucher-devolucion, voucher-cancelacion, estancia-check-in, estancia-checkout, consumo-restaurante y detalle-retail. La disponibilidad final depende de la configuración del comercio.
03 / ADAPTADORES
La API no depende de una marca. La aplicación anfitriona adapta el resultado del pago, la identidad del dispositivo y la entrega del comprobante. Cada modelo requiere validar sistema operativo, permisos, distribución de aplicaciones y acceso al SDK del fabricante.
Integra el módulo Kotlin o llama directamente a HTTPS. Obtén la serie con la API autorizada del fabricante; solicita permiso de red y ejecuta las peticiones fuera del hilo de interfaz.
Usa un cliente HTTPS/JSON nativo o un servicio intermediario autorizado. Si el equipo no permite aplicaciones externas, acuerda con su proveedor una integración desde el sistema de caja.
Implementa un adaptador para el SDK de impresora del modelo. Renderiza texto o imagen al ancho soportado; un SVG no es un comando de impresora. Si no hay impresora, entrega QR o enlace.
PAX, Ingenico, Newland, SUNMI y otros fabricantes: este flujo es una guía de adaptación, no una declaración de compatibilidad certificada. Se requiere probar cada modelo y versión con su SDK y restricciones de distribución. Los SDK de pagos e impresión de terceros no se incluyen.
04 / OPERACIÓN CONFIABLE
Usa Idempotency-Key de hasta 120 caracteres, única por operación dentro de la terminal. Guarda esa clave y el JSON en una cola durable antes del primer intento. Tras timeout, corte de red o respuesta 5xx, reintenta con la misma clave y cuerpo, espera creciente y variación aleatoria. El SDK no implementa la cola ni los reintentos por ti.
| Respuesta | Acción del integrador |
|---|---|
| 400 · datos inválidos | Revisar code, error y details cuando estén presentes. Corregir datos; no reintentar en bucle. |
| 401 / 403 | Revisar token, vigencia y serie. Para el alta, revisar código con el administrador. Detener reintentos automáticos. |
| 404 | Revisar recurso, id y vencimiento del ticket. |
| 409 · idempotencia_en_proceso | Esperar y repetir el mismo cuerpo y clave. |
| 409 · idempotencia_cuerpo_distinto | Detener y conciliar la operación; no generar otra clave automáticamente para el mismo cobro. |
| 409 · idempotencia_ticket_purgado | Revisión operativa: el ticket ya no está disponible; evitar una emisión nueva automática. |
| 429 | Respetar Retry-After, en segundos. Los límites son configurables por instancia. |
| 5xx / timeout / sin red | Conservar pendiente y reintentar la emisión con límites y backoff; nunca repetir el cobro por un fallo del ticket. |
Para soporte, conserva X-Request-Id o traceId, fecha, serie, versión de app y código de error. Omite tokens y datos sensibles. Un fallo al imprimir se resuelve reimprimiendo el ticket guardado, sin volver a emitir ni cobrar.
05 / HERRAMIENTAS
Esquemas de alta, emisión y entrega pública. Impórtalo en tu cliente de API.
Descargar JSON ↓Variables vacías para tu instancia, código y token. La emisión crea datos reales en el entorno que configures.
Descargar colección ↓Cuerpo de referencia para la solicitud de inicio rápido. Sustituye la serie por la del equipo.
Descargar ejemplo ↓Módulo Kotlin y aplicación de ejemplo. Requiere compilar y validar con tu modelo; no es un AAR certificado.
Descargar SDK y ejemplo ↓ControlPOSDigitalReceiptsSDK.init(
baseUrl = "https://ticket.control-pos.com",
terminalToken = tokenGuardado
)El ZIP incluye el README, el módulo digital-receipts-sdk y app-sample. El SDK HTTP es independiente del fabricante y no reemplaza su SDK de pagos o impresora. Revisa los modelos disponibles antes de usar campos ampliados de la API; para el contrato completo puedes integrar HTTPS directamente.
06 / ACEPTACIÓN
Ejecuta estas pruebas en el entorno acordado y registra modelo, firmware, versión de app, fecha y evidencia. Esta lista no equivale a una certificación bancaria.