Saltar al contenido principal

Modo servicio de Sentinel

Cómo controlar un terminal de pago Sentinel desde una caja registradora, un sistema ECR o una aplicación de terceros mediante HTTP local, un cable USB serie o intents de Android.

ConfiguraciónValor
AplicaciónSentinel 4.0.8
Paquetecom.paylands.posms.sentinel
Esquema de intentscom.paynopain.sentinelservice
Puerto local6889

1. Introducción​

Sentinel expone sus operaciones de pago a otras aplicaciones para que una caja registradora pueda cobrar con tarjeta sin que nadie tenga que interactuar con el terminal. Este documento define el contrato de integración: qué operaciones puedes invocar, qué debes enviar y qué recibirás como respuesta.

Los tres transportes permiten ejecutar las mismas operaciones y devuelven las mismas estructuras de datos. Elige el que se ajuste a la conexión entre tu caja y el terminal:

  • HTTP local — tu software se ejecuta en el propio terminal o en el mismo equipo y envía JSON a 127.0.0.1:6889.
  • USB serie — tu caja es un equipo independiente y detecta el terminal como un puerto COM.
  • Intents de Android — tu software es otra aplicación instalada en el mismo terminal Android.

La disponibilidad de cada operación varía según el transporte. Al principio de cada operación se indica si está disponible mediante cada uno de los tres transportes, para que puedas identificar qué admite tu integración.

note

Modo servicio. El terminal solo acepta operaciones externas cuando el modo servicio está habilitado en su configuración. Si está deshabilitado, las operaciones se rechazan con una respuesta JSON fija y no se realiza ningún cargo. La comprobación de estado es la única excepción: responde en ambos casos, lo que permite distinguir entre un terminal apagado y uno que simplemente no tiene activado el modo servicio.

2. Nombre del paquete y esquema de intents​

Sentinel Service se distribuía como una aplicación independiente con el paquete com.paynopain.sentinelservice. Ahora el modo servicio forma parte de la aplicación principal de Sentinel, por lo que también ha cambiado el nombre del paquete.

UsoValor
Nombre del paquetePaquete actual. Úsalo para comprobar la instalación con PackageManager y siempre que hagas referencia a la aplicación instalada: com.paylands.posms.sentinel
Esquema de intentsSe mantiene por compatibilidad con versiones anteriores. Sigue utilizándolo en todas las URI de intents: com.paynopain.sentinelservice://
danger

Actualiza la comprobación de instalación. Las URI de intents no necesitan cambios, pero cualquier comprobación previa que busque com.paynopain.sentinelservice como paquete instalado indicará que la aplicación no está instalada. Utiliza com.paylands.posms.sentinel. El nombre anterior se conserva únicamente como esquema de URI.

3. Transportes​

3.1 HTTP local​

Envía JSON mediante POST a la ruta de cada operación en el puerto 6889. Cada operación tiene su propia ruta.

POST http://127.0.0.1:6889/payment
Content-Type: application/json
Authorization: Bearer <token supplied by Paynopain>

{"amount":100,"currencyCode":978,"stan":"7f328336-f3fa-4e37-92d5-b7f1311c0f4d"}

El servidor responde con 200 OK y el resultado de la operación en el cuerpo, o con 404 Not Found si la ruta no existe. Las operaciones con tarjeta que finalizan devuelven el JSON de resultado de transacción descrito en §24; los fallos de validación devuelven un mensaje de texto plano (§4.4).

Rutas disponibles:

/payment          /preauthorization   /transaction
/refund /confirmation /transaction_by_stan
/referral /cancellation /list_transactions
/reversal /decrement /reports
/cardverify /cft /close_batch
/healthcheck /identify /reprint
/sync

3.2 HTTPS​

El mismo puerto utiliza TLS cuando se ha aprovisionado un certificado en el terminal. El certificado y la clave privada se reciben mediante la configuración del dispositivo como un almacén de claves PKCS#12 en base64. Mientras no exista, el servidor escucha mediante HTTP sin cifrar, de modo que las integraciones existentes siguen funcionando sin cambios. Consulta la pantalla de estado del servicio del terminal para comprobar cuál está activo.

3.3 USB serie​

El terminal se presenta como un dispositivo USB serie y la caja abre la conexión como un puerto COM. Esta función está disponible en terminales PAX; en otros modelos se indica que no hay enlace ECR y el servidor USB no se inicia.

ConfiguraciónValor
Línea115200 baudios, 8 bits de datos, sin paridad y 1 bit de parada
Formato de tramaCabecera de longitud de 4 bytes en big-endian, seguida de ese número de bytes de JSON en UTF-8
Solicitud{"id":"…","type":"payment","body":{ …same fields as HTTP… }}
Respuesta{"id":"…","type":"payment","result":"…"}

El id se devuelve en la respuesta para que puedas asociarla con su solicitud. type utiliza los mismos nombres que las rutas HTTP, sin la barra inicial. Solo se ejecuta una operación a la vez: si llega una segunda solicitud durante una operación, se responde inmediatamente con {"error":"busy: another operation is in progress"}. La comprobación de estado la atiende el hilo de lectura, por lo que sigue respondiendo mientras un pago espera la intervención del titular.

3.4 Intents de Android​

Lanza un intent de visualización y lee el resultado en onActivityResult. La autorización se gestiona con el equipo de Paynopain mediante la inclusión de tu aplicación en la lista de aplicaciones permitidas.

String uri = "com.paynopain.sentinelservice://payment?amount=100&currencyCode=978&stan=" + stan;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivityForResult(intent, PAYMENT_RESULT_CODE);

Los resultados se reciben en dos campos extra de tipo cadena: transactionResult contiene los datos de la operación y error_message explica una cancelación o un fallo. Consulta §26 para ver un ejemplo completo.

4. Convenciones​

4.1 Importes​

Todos los importes son números enteros expresados en la unidad mínima de la moneda: 100 equivale a un euro. La excepción es ISK, que no tiene unidad fraccionaria y se envía en coronas enteras.

4.2 STAN​

El stan es tu referencia de la operación y debes generarlo tú: un UUID único por solicitud. Se devuelve en el resultado y es la clave que permite recuperar una operación cuya respuesta no recibiste; consulta §16. Reutilizar un STAN hace que esa recuperación sea ambigua.

4.3 Moneda​

currencyCode es el código numérico ISO 4217: 978 para euros, 840 para dólares estadounidenses y 826 para libras esterlinas. Debe coincidir con la moneda configurada en el terminal; si no coincide, la operación se rechaza antes de acceder a la tarjeta.

4.4 Errores​

Los fallos de validación y de políticas devuelven una cadena de texto plano. Comprueba estos casos antes de interpretar el cuerpo de la respuesta como JSON:

RespuestaSignificado
Error: Missing required fields — …Los campos indicados no se han enviado o están vacíos. La lista aparece después del guion.
Error: No data received in the requestEl cuerpo de la solicitud está vacío.
Max Amount ExceededSe supera el límite configurado en el terminal. Si hay una propina fija, el límite se aplica a la suma del importe base y la propina.
Currency is not allowedcurrencyCode no coincide con la moneda del terminal.
Too much pending transactions. Please sync.La cola de operaciones sin sincronizar está llena. Ejecuta sync y vuelve a intentarlo.
Tokenization is not enabled for this merchantSe ha enviado tokenize: true para un comercio sin tokenización habilitada.
Operative not allowedLa operación no está disponible para el operador de este terminal.
Error: …Se ha producido un fallo inesperado; a continuación aparece el mensaje de la excepción.
danger

Estas cadenas dependen del idioma. Un terminal configurado en castellano devuelve Error: Campos requeridos faltantes en lugar del mensaje en inglés de la tabla anterior. Evita comparar el texto completo: utiliza un prefijo que controles o considera como fallo cualquier cuerpo que no sea JSON.

Hay dos respuestas que se devuelven como JSON. Modo servicio deshabilitado:

{"error":"Service mode disabled: terminal does not accept external operations"}

Y, solo en el transporte USB, una segunda operación concurrente:

{"error":"busy: another operation is in progress"}

4.5 Tiempos de espera​

Una operación que no produce ningún resultado, por ejemplo por un pago abandonado o una conexión interrumpida, se cancela a los 100 segundos y devuelve un error de tiempo de espera. La impresión tiene un límite de 30 segundos y, si se supera, se informa de que no se ha impreso. Configura el tiempo de espera de tu cliente por encima de 100 segundos para recibir la respuesta del terminal.


5. Pago​

Realiza un cargo en una tarjeta de débito o crédito. Además de una venta simple, esta operación admite propinas, pagos por QR y tokenización por venta.

Operación: payment

TransporteOperaciónDisponible
HTTP/paymentSí
USBpaymentSí
Intent//paymentSí

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
amountEnteroObligatorioUnidad mínima de la moneda. No incluye la propina fija, que se suma al importe.
currencyCodeEnteroObligatorioCódigo numérico ISO 4217. Debe coincidir con el del terminal.
stanCadenaObligatorioTu UUID para esta operación.
referenceCadenaOpcionalReferencia de texto libre que se guarda con la transacción y se muestra en el recibo.
customer_ext_idCadenaOpcionalTu identificador de cliente, que se devuelve en el resultado.
tipBooleano o enteroOpcionaltrue solicita una propina en la pantalla del terminal. Un entero indica una propina fija en la unidad mínima de la moneda, que se suma a amount sin mostrar una solicitud. Omite el campo si no hay propina.
channelCadenaOpcionalcard (por defecto) o qr.
qrMethodCadenaOpcionalCon channel: "qr", fija el método QR (por ejemplo, BIZUM) y omite el selector en pantalla. Omítelo para que el cajero elija.
tokenizeBooleanoOpcionalSustituye la configuración de tokenización del terminal solo para esta venta. Omítelo para seguir la configuración del terminal.

Respuesta​

Los datos del resultado de la transacción (§24), una vez finalizada la operación con tarjeta.

Ejemplo​

POST /payment
{"amount":100,"currencyCode":978,"stan":"7f328336-f3fa-4e37-92d5-b7f1311c0f4d"}
com.paynopain.sentinelservice://payment
?amount=100&currencyCode=978&stan=ebdd1b6a-02f4-4366-9a9e-d19758123746

5.1 Propinas​

tip admite dos tipos de valores porque cada modalidad de propina implica un comportamiento distinto para la integración:

  • "tip": true lleva Sentinel al primer plano y solicita una propina al titular en el terminal. La llamada espera a que termine todo el flujo y después devuelve el resultado habitual.
  • "tip": 150 añade una propina fija de 1,50 sin mostrar pantallas ni requerir interacción. El importe cobrado es amount + tip, y ese total debe mantenerse dentro del límite del terminal.

5.2 Pago por QR​

Con channel: "qr", el terminal muestra un código QR que el cliente puede tardar varios minutos en escanear. La llamada devuelve inmediatamente esta respuesta:

{"status":"QR_SHOWN","stan":"…","message":"QR mostrado en el terminal. Consulta el resultado con transaction_by_stan."}

Consulta periódicamente la transacción por STAN con el mismo stan para obtener el resultado.

5.3 Tokenización​

tokenize permite decidir por venta en lugar de seguir la configuración general del terminal. Ten en cuenta estas dos limitaciones:

  • La configuración de tokenización del comercio tiene prioridad. Si se solicita un token para un comercio sin tokenización habilitada, la operación se rechaza antes de realizar el cargo.
  • El control por venta solo se aplica a la ruta ECOPAYNET. En MONET, la aplicación de pago decide según la configuración del comercio, por lo que tokenize: false no impide recibir un token si el comercio está configurado para ello.

6. Preautorización​

Reserva un importe en una tarjeta sin capturarlo. Después puedes capturarlo mediante una confirmación, reducirlo mediante un decremento o liberarlo mediante una cancelación.

Operación: preauthorization

TransporteOperaciónDisponible
HTTP/preauthorizationSí
USBpreauthorizationSí
Intent//preauthorizationSí

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
amountEnteroObligatorioImporte que se va a reservar, en la unidad mínima de la moneda.
currencyCodeEnteroObligatorioCódigo numérico ISO 4217.
stanCadenaObligatorioTu UUID para esta operación.
referenceCadenaOpcionalReferencia de texto libre.
customer_ext_idCadenaOpcionalTu identificador de cliente.

Respuesta​

Resultado de transacción con operative igual a DEFERRED. Guarda transaction_id, auth_code y refund_id, ya que las operaciones posteriores los necesitan.

7. Confirmación​

Captura una preautorización por su importe completo o por un importe inferior al reservado.

Operación: confirmation

TransporteOperaciónDisponible
HTTP/confirmationSí
USBconfirmationSí
Intent//confirmationSí

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
amountEnteroObligatorioImporte que se va a capturar. Puede ser inferior al reservado.
currencyCodeEnteroObligatorioCódigo numérico ISO 4217.
parentIdentifierCadenaObligatoriotransaction_id de la preautorización.
stanCadenaObligatorioTu UUID para esta operación.
dateCadenaCondicionalObligatorio en ECOPAYNET. Fecha de la operación original.
authCodeCadenaCondicionalObligatorio en ECOPAYNET. Se obtiene del resultado de la preautorización.
refundIdCadenaCondicionalObligatorio en ECOPAYNET. Se obtiene del resultado de la preautorización.
customer_ext_idCadenaOpcionalTu identificador de cliente.

Respuesta​

Resultado de transacción con operative igual a CONFIRMATION.

note

Los campos condicionales dependen del operador del terminal. En ECOPAYNET, date, authCode y refundId son obligatorios y su ausencia genera un error de campos requeridos. En otros operadores se ignoran. Si no sabes qué operador utiliza un terminal, llama a identify, que devuelve el nombre del operador, o envía siempre los tres campos.

8. Cancelación​

Libera una preautorización sin capturarla.

Operación: cancellation

TransporteOperaciónDisponible
HTTP/cancellationSí
USBcancellationSí
Intent//cancellationSí

Disponibilidad: Modo servicio.

Solicitud​

Utiliza los mismos campos que la confirmación: amount, currencyCode, parentIdentifier y stan son obligatorios; date, authCode y refundId son obligatorios en ECOPAYNET; customer_ext_id es opcional.

Respuesta​

Resultado de transacción con operative igual a CANCELLATION.

9. Decremento​

Reduce el importe retenido por una preautorización y mantiene la reserva abierta. Puede utilizarse cuando la factura final es inferior a la estimación, pero la cuenta sigue abierta.

Operación: decrement

TransporteOperaciónDisponible
HTTP/decrementSí
USBdecrementSí
Intent//decrementSí

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
amountEnteroObligatorioImporte retenido actualmente por la preautorización.
decrementAmountEnteroObligatorioImporte que se va a liberar, en la unidad mínima de la moneda.
currencyCodeEnteroObligatorioCódigo numérico ISO 4217.
parentIdentifierCadenaObligatoriotransaction_id de la preautorización.
stanCadenaObligatorioTu UUID para esta operación.
authCodeCadenaOpcionalSe obtiene del resultado de la preautorización.
refundIdCadenaOpcionalSe obtiene del resultado de la preautorización.
dateCadenaOpcionalFecha de la operación original.
customer_ext_idCadenaOpcionalTu identificador de cliente.

Respuesta​

Resultado de transacción con operative igual a DECREMENT.

10. Devolución​

Devuelve dinero a la tarjeta utilizada en una venta anterior. Es necesario presentar la tarjeta.

Operación: refund

TransporteOperaciónDisponible
HTTP/refundSí
USBrefundSí
Intent//refundSí

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
amountEnteroObligatorioImporte que se va a devolver, en la unidad mínima de la moneda.
currencyCodeEnteroObligatorioCódigo numérico ISO 4217.
parentIdentifierCadenaObligatoriotransaction_id de la venta original.
refundIdCadenaObligatoriorefund_id del resultado de la venta original.
stanCadenaObligatorioTu UUID para esta operación.
dateCadenaCondicionalObligatorio en ECOPAYNET.
authCodeCadenaCondicionalObligatorio en ECOPAYNET.
customer_ext_idCadenaOpcionalTu identificador de cliente.

Ejemplo​

POST /refund
{"amount":100,"currencyCode":978,
"parentIdentifier":"9c76341c-fcbd-492d-8b7a-ed14d0fc6a8d",
"refundId":"1248529069100765184",
"stan":"79f5ae33-cad9-45f4-983e-d7a9a8fc1cc9"}

11. Devolución sin tarjeta​

Devuelve el importe de una venta anterior sin presentar la tarjeta, utilizando las credenciales de la transacción original.

Operación: referral

TransporteOperaciónDisponible
HTTP/referralSí
USBreferralSí
Intent//referralSí

Disponibilidad: Modo servicio.

Solicitud​

Utiliza los mismos campos que la devolución: amount, currencyCode, parentIdentifier, refundId y stan son obligatorios; date y authCode son obligatorios en ECOPAYNET; customer_ext_id es opcional.

Respuesta​

Resultado de transacción con operative igual a REFERRAL_REFUND.

Ejemplo​

com.paynopain.sentinelservice://referral
?amount=100&currencyCode=978
&parentIdentifier=1e7da5d3-4aec-4f97-9029-4dce55216964
&refundId=1334440644315197440
&stan=234ec44e-a377-4380-a4fb-bf15933301e0

12. Anulación​

Anula una venta el mismo día en que se realizó, antes de su liquidación. Es más económica y rápida que una devolución y no deja un abono por devolución en el extracto del titular.

Operación: reversal

TransporteOperaciónDisponible
HTTP/reversalSí
USBreversalSí
Intent//reversalSí

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
currencyCodeEnteroObligatorioCódigo numérico ISO 4217.
parentIdentifierCadenaObligatoriotransaction_id de la venta que se va a anular.
refundIdCadenaObligatoriorefund_id del resultado de la venta original.
stanCadenaObligatorioTu UUID para esta operación.
customer_ext_idCadenaOpcionalTu identificador de cliente.

No se envía amount: la anulación siempre afecta al importe original completo.

Respuesta​

Resultado de transacción con operative igual a REVERSAL. En los terminales ECOPAYNET esta operación no está disponible y devuelve Operative not allowed.

13. Verificación de tarjeta​

Lee y valida una tarjeta sin realizar ningún cargo y devuelve un token reutilizable.

Operación: cardverify

TransporteOperaciónDisponible
HTTP/cardverifySí
USBcardverifySí
Intent//cardverifySí

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
currencyCodeEnteroObligatorioCódigo numérico ISO 4217.
stanCadenaObligatorioTu UUID para esta operación.
dniCadenaOpcionalDocumento de identidad del titular.
referenceCadenaOpcionalReferencia de texto libre.
customer_ext_idCadenaOpcionalTu identificador de cliente.

Respuesta​

Resultado de transacción con operative igual a CARD_VERIFY, junto con los campos de token card_token, par y transaction_type. El importe es cero.

Ejemplo​

POST /cardverify
{"currencyCode":978,"stan":"5ad8fb83-9540-4a46-bfaa-d0b3f9bbc196"}

14. CFT — abono a tarjeta​

Abona dinero en la tarjeta de un beneficiario. El importe lo fija el backend a partir del token de la orden y el terminal lo confirma con la tarjeta.

Operación: cft

TransporteOperaciónDisponible
HTTP/cftSí
USBcftSí
Intent//cftSí

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
tokenCadenaObligatorioToken de la orden emitido por el backend. Determina el importe.
nameCadenaObligatorioNombre del beneficiario.
surnameCadenaObligatorioApellidos del beneficiario.
emailCadenaObligatorioCorreo electrónico del beneficiario.
stanCadenaObligatorioTu UUID para esta operación.

15. Consulta de transacción​

Consulta una transacción en el backend mediante su identificador.

Operación: transaction

TransporteOperaciónDisponible
HTTP/transactionSí
USBtransactionSí
Intent//transactionSí

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
transactionIdCadenaObligatorioIdentificador de la transacción.
stanCadenaObligatorioTu UUID para esta consulta.

Respuesta​

{
"id": "665d6dea126521c8926056ef",
"identifier": "919ff6d6-7727-4801-9035-9f57d2e8041a",
"merchant": "649c0329052f100dceea50e9",
"device": "64d1ef302ff0833b33ecffe6",
"operative": "AUTHORIZATION",
"status": "PAID",
"amount": 100,
"currency": "978",
"incoming": "DEVICE",
"integrator": "615d7d35be2246344cc49adf",
"integrator_external_id": "919FF6D6-7727-4801-9035-9F57D2E8041A",
"created_at": "2024-06-03T07:16:58.183Z",
"updated_at": "2024-06-03T07:16:58.384Z",
"historic": [{ "status": "PAID", "date": "2024-06-03T07:16:58.181Z" }]
}

16. Consulta de transacción por STAN​

Recupera una operación mediante el STAN que generaste. Permite resolver un pago cuya respuesta no recibiste y obtener el resultado de un pago por QR.

Operación: transaction_by_stan

TransporteOperaciónDisponible
HTTP/transaction_by_stanSí
USBtransaction_by_stanSí
Intent//transactionbystanSí

Disponibilidad: Modo servicio.

note

El host del intent es transactionbystan, sin guiones bajos. La ruta HTTP y el tipo USB son transaction_by_stan, con guiones bajos.

Solicitud​

CampoTipoRequisitoNotas
stanCadenaObligatorioEl STAN que enviaste con la operación original.

Respuesta mientras la operación sigue en curso​

Sentinel responde desde su cola local de operaciones pendientes, por lo que informa de las operaciones en curso en lugar de indicarlas como inexistentes:

{
"identifier": "4ad6624f-8ad4-4ef7-8557-d41616770f63",
"operative": "AUTHORIZATION",
"amount": 100,
"currency": "978",
"incoming": "DEVICE",
"response_status": "Pending",
"response_message": "In progress",
"stan": "2fdf5900-22ae-46b1-8398-8fcda2bcce04"
}

Respuesta cuando la operación ha finalizado​

El registro completo del backend, con el resultado de la operación con tarjeta dentro de result:

{
"id": "67a5f4e1d0a4c0353b3e04d6",
"identifier": "4ad6624f-8ad4-4ef7-8557-d41616770f63",
"merchant": "66e80b75a1a978f055c8fe07",
"device": "64d1ef302ff0833b33ecffe6",
"operative": "AUTHORIZATION",
"status": "PAID",
"amount": 100,
"currency": "978",
"incoming": "DEVICE",
"result": {
"aid": "A0000000031010",
"amount": 100,
"currency": "978",
"auth_code": "050107",
"brand": "VISA",
"pan": "476173******0119",
"reversal": false,
"date_terminal": "2025-02-07T11:56:17.836Z",
"date_server": "2025-02-07T11:56:17.836Z",
"response_status": "PAID",
"card_input": "CLESS",
"cardholder_method": ["[SIGNATURE]"],
"response_message": "OK: success",
"terminal_acquirer": "TPPESNA004",
"merchant_acquirer": "TPPESNA004",
"refund_id": "1337391474924330111",
"stan": "2fdf5900-22ae-46b1-8398-8fcda2bcce04"
},
"created_at": "2025-02-07T11:56:17.872Z",
"updated_at": "2025-02-07T11:56:18.452Z",
"historic": [{ "status": "PAID", "date": "2025-02-07T11:56:17.862Z" }]
}

17. Listado de transacciones​

Recupera transacciones recientes para conciliar una caja o recuperarse de una interrupción, por ejemplo cuando se ha perdido el propio STAN y no es posible utilizar las consultas individuales.

Operación: list_transactions

TransporteOperaciónDisponible
HTTP/list_transactionsSí
USBlist_transactionsSí
Intent—No

Disponibilidad: Modo servicio.

Solicitud​

Todos los campos son opcionales; un cuerpo vacío devuelve las 50 transacciones más recientes.

CampoTipoRequisitoNotas
limitEnteroOpcionalPor defecto, 50. Limitado a un máximo de 200.
dateFromCadenaOpcionalLímite inferior.
dateToCadenaOpcionalLímite superior.
statusCadenaOpcionalUn valor de TransactionStatus. Si no se reconoce el valor, se devuelve un error con la lista de valores admitidos.

Respuesta​

{
"status": "OK",
"count": 2,
"limit": 50,
"truncated": false,
"transactions": [
{
"identifier": "919ff6d6-7727-4801-9035-9f57d2e8041a",
"amount": 100,
"remaining_amount": null,
"currency": "978",
"operative": "AUTHORIZATION",
"status": "PAID",
"created_at": "2026-08-31T09:14:22Z",
"auth_code": "478893",
"refund_id": "1305910960162082816",
"parent_id": null,
"pan": "476173******0119",
"reference": null,
"aid": "A0000000031010",
"brand": "VISA",
"tip_amount": 0,
"is_qr": false,
"token": null,
"customer_ext_id": null
}
]
}

Las fechas utilizan ISO-8601 en UTC. No hay paginación: truncated es true cuando se han devuelto exactamente limit filas, lo que indica que puede haber más. Acota la consulta con dateFrom y dateTo.

18. Informes​

Totales del período que sigue abierto, equivalentes a un informe X. Esta operación es de solo lectura y no modifica datos.

Operación: reports

TransporteOperaciónDisponible
HTTP/reportsSí
USBreportsSí
Intent—No

Disponibilidad: Modo servicio.

Solicitud​

Sin cuerpo.

Respuesta​

{
"status": "OK",
"dateFrom": "2026-08-31 06:00:00",
"transactions": 42,
"totalAmount": 128400,
"authorizations": 38,
"totalAuthorizationsAmount": 131900,
"refunds": 2,
"totalRefundsAmount": 3500,
"deferred": 1,
"totalDeferredAmount": 5000,
"confirmations": 1,
"totalConfirmedAmount": 5000,
"cancelled": 0,
"totalCancelledAmount": 0
}

Todos los totales se expresan en la unidad mínima de la moneda y cubren las operaciones desde dateFrom, la fecha de corte establecida por el último cierre.

19. Cierre de lote​

Cierra el período de caja, equivalente a un informe Z. Imprime el informe y actualiza la fecha de corte para que el siguiente informe comience donde termina este.

Operación: close_batch

TransporteOperaciónDisponible
HTTP/close_batchSí
USBclose_batchSí
Intent—No

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
printBooleanoOpcionalPor defecto, true. Utiliza false para cerrar sin imprimir, por ejemplo si la caja imprime su propia copia.

Respuesta​

Los mismos totales que reports, con status igual a CLOSED y los campos adicionales cutoff y printed.

danger

Esta operación no liquida el lote con el adquirente. La liquidación con el adquirente la inicia el backend. El cierre de lote realiza lo mismo que el botón de la aplicación: imprime el informe y actualiza la fecha de corte local. Es una operación de caja.

20. Reimpresión de recibo​

Vuelve a imprimir un recibo o solicita al backend que lo emita como enlace. Puede utilizarse si se ha agotado el papel, el corte ha salido mal o el cliente vuelve más tarde a pedir una copia.

Operación: reprint

TransporteOperaciónDisponible
HTTP/reprintSí
USBreprintSí
Intent—No

Disponibilidad: Modo servicio.

Solicitud​

CampoTipoRequisitoNotas
transactionIdCadenaOpcionalOmítelo para reimprimir la transacción más reciente. La búsqueda se realiza entre las últimas 50.
copyCadenaOpcionalclient (por defecto) o merchant.
giftTicketBooleanoOpcionalPor defecto, false. Con true, esta impresión omite el subtotal, la propina y el total. No modifica la transacción ni las impresiones posteriores.
emailCadenaOpcionalEnvía el recibo por correo electrónico en lugar de imprimirlo y devuelve su URL.

Respuesta​

{"status":"PRINTED","identifier":"919ff6d6-…","copy":"client","giftTicket":false}
{"status":"SENT","identifier":"919ff6d6-…","email":"a@b.com","url":"https://…"}
{"status":"NOT_FOUND","message":"…"}
{"status":"ERROR","message":"El terminal no pudo imprimir (sin papel, sin impresora o error)"}

La impresora solo notifica cuando la impresión se completa correctamente. Si el terminal no tiene papel o impresora, devuelve ERROR al agotarse el tiempo de espera de impresión de 30 segundos.

Cada copia impresa incluye un código QR que contiene únicamente el UUID de la transacción. En la aplicación interactiva, el operador puede escanearlo desde la barra superior de Transacciones para recuperar y abrir esa transacción. El QR no contiene importes ni datos de tarjeta.


21. Comprobación de estado​

Comprueba si el terminal está encendido y accesible mediante el transporte elegido. Es la única operación que responde con independencia del modo servicio.

Operación: healthcheck

TransporteOperaciónDisponible
HTTP/healthcheckSí
USBhealthcheckSí
Intent//healthcheckSí

Disponibilidad: Siempre disponible.

Respuesta​

La cadena literal READY o NOT_READY, en texto plano.

Esta comprobación permite detectar la presencia del terminal. La caja necesita distinguir entre un terminal apagado o un cable desconectado y un terminal encendido sin el modo servicio activado. Para comprobar este último caso, solicita una operación y lee el error de modo servicio.

En USB, la comprobación de estado la atiende el hilo de lectura, por lo que sigue respondiendo mientras un pago espera la intervención del titular.

22. Identificación​

Consulta la identidad del terminal. Suele ser la primera llamada de una integración: necesitas el identificador para conciliar tus recibos con los del backend y el número de serie para tu inventario.

Operación: identify

TransporteOperaciónDisponible
HTTP/identifySí
USBidentifySí
Intent—No

Disponibilidad: Modo servicio.

Respuesta​

{
"status": "OK",
"identifier": "352966108076163",
"serialNumber": "1853237957",
"model": "A920Pro",
"manufacturer": "PAX",
"appVersion": "4.0.8",
"operator": "MONET"
}

Un terminal cuya configuración no ha finalizado devuelve {"status":"ERROR","message":"Terminal sin identificador: falta configuración"}. operator indica si se aplican los campos condicionales de ECOPAYNET.

23. Sincronización​

Envía las operaciones pendientes de la cola sin sincronizar. Si el terminal alcanza su límite de pendientes, rechaza todas las operaciones. En modo servicio puede no haber nadie delante del terminal para resolver esta situación manualmente.

Operación: sync

TransporteOperaciónDisponible
HTTP/syncSí
USBsyncSí
Intent//syncSí

Disponibilidad: Modo servicio.

Respuesta​

{"status":"NOTHING_TO_SYNC","pendingBefore":0,"pendingAfter":0}
{"status":"SYNCED","pendingBefore":7,"pendingAfter":0}
{"status":"IN_PROGRESS","pendingBefore":7,"pendingAfter":3,"message":"…"}
{"status":"ERROR","message":"…","pendingBefore":7}
note

La sincronización inicia el envío, pero no espera a que termine. El terminal no puede saber cuándo ha finalizado el backend, por lo que informa del número de pendientes antes y después de una breve espera y devuelve la respuesta. IN_PROGRESS indica que el trabajo continúa en segundo plano: vuelve a intentar la operación y llama de nuevo a sync si sigue siendo rechazada. SYNCED no garantiza que todas las transacciones en cola hayan llegado al backend.


24. Datos del resultado de transacción​

Datos que devuelve cada operación con tarjeta. Los nombres de los campos utilizan snake_case, con la única excepción de panExpiryDate.

CampoTipoRequisitoNotas
deviceCadenaSiempreIdentificador del terminal.
transaction_idCadenaSiempreIdentificador del backend. Utilízalo como parentIdentifier en operaciones posteriores.
stanCadenaSiempreEl STAN que enviaste.
operativeOperativeSiempreConsulta §25.
amountEnteroSiempreUnidad mínima de la moneda. Incluye la propina cuando la hay.
tip_amountEnteroOpcionalParte de amount correspondiente a la propina.
currencyCadenaSiempreCódigo numérico ISO 4217, como cadena.
response_statusTransactionStatusSiempreResultado de la operación. Consulta §25.
response_codeCadenaOpcionalCódigo de respuesta del adquirente.
response_messageCadenaSiempreResultado de la operación en un formato legible.
incomingIncomingSiempreDEVICE o API.
auth_codeCadenaOpcionalCódigo de autorización. Necesario para operaciones posteriores en ECOPAYNET.
refund_idCadenaOpcionalNecesario para devolver o anular esta transacción. Guárdalo.
parent_transaction_idCadenaOpcionalSe incluye en operaciones que hacen referencia a una anterior.
aidCadenaOpcionalIdentificador de la aplicación EMV.
brandCadenaOpcionalMarca de la tarjeta.
panCadenaOpcionalNúmero de tarjeta enmascarado.
panExpiryDateCadenaOpcionalFecha de caducidad enmascarada.
card_input_typeCardInputTypeOpcionalCómo se leyó la tarjeta. Consulta §25.
cvm_type_listCadenaOpcionalMétodo de verificación del titular.
reversalBooleanoOpcionalIndica si esta transacción se ha anulado.
date_terminalFechaOpcionalFecha y hora del terminal.
date_serverFechaOpcionalFecha y hora del backend. Utilízala de forma preferente si difiere de la del terminal.
emv_responseObjetoOpcionalDetalle EMV.
terminal_acquirerCadenaOpcionalIdentificador de terminal del adquirente.
merchant_acquirerCadenaOpcionalIdentificador de comercio del adquirente.
terminal_issuerCadenaOpcionalIdentificador de terminal del emisor.
merchant_issuerCadenaOpcionalIdentificador de comercio del emisor.
card_tokenCadenaOpcionalToken de tarjeta obtenido mediante una verificación de tarjeta.
additional_tokenCadenaOpcionalToken obtenido en una venta tokenizada, en cualquiera de las rutas de operador.
parCadenaOpcionalReferencia de cuenta de pago.
transaction_typeCadenaOpcionalTipo de transacción de la marca.
card_holder_messageCadenaOpcionalMensaje mostrado al titular.
invoice_numberCadenaOpcionalNúmero de factura del adquirente.
referenceCadenaOpcionalLa referencia que enviaste.
customer_ext_idCadenaOpcionalEl identificador de cliente que enviaste.

24.1 Ejemplo — un euro, aprobado​

{
"device": "352966108076163",
"transaction_id": "1876c5dd-3450-4f65-9ca4-872398aa61c6",
"stan": "cec60447-7467-4457-a542-40a791f11f02",
"operative": "AUTHORIZATION",
"amount": 100,
"currency": "978",
"response_status": "PAID",
"response_message": "success",
"incoming": "DEVICE",
"aid": "A0000000031010",
"auth_code": "478893",
"brand": "VISA",
"pan": "476173******0119",
"panExpiryDate": "****",
"card_input_type": "CLESS",
"cvm_type_list": "SIGNATURE",
"reversal": false,
"date_terminal": "Nov 12, 2024 04:03:44 PM",
"date_server": "Nov 12, 2024 04:03:48 PM",
"emv_response": { "smartCardScheme": 1, "authorisationResponseCode": "00" },
"terminal_acquirer": "TPPESNA004",
"merchant_acquirer": "TPPESNA004",
"refund_id": "1305910960162082816"
}

24.2 Ejemplo — un euro, rechazado​

Un rechazo es una respuesta normal: se recibe como un resultado válido con un estado distinto de PAID. Evalúa response_status para decidir cómo continuar.

{
"device": "352966108076163",
"transaction_id": "e1d7a4b1-2a8a-43e6-be62-001154f0d2f4",
"stan": "6162ab8a-92ab-4d7d-8393-26d3fd6b666c",
"operative": "AUTHORIZATION",
"amount": 100,
"currency": "978",
"response_status": "REFUSED",
"response_message": "KO - refused",
"incoming": "DEVICE",
"aid": "A0000000041010",
"auth_code": "327674",
"brand": "MASTERCARD",
"pan": "****************",
"card_input_type": "CLESS",
"cvm_type_list": "NO",
"reversal": false,
"terminal_acquirer": "M1TPNP0005",
"merchant_acquirer": "TPNP0005",
"refund_id": "128937286421796"
}

25. Enumeraciones​

Operative​

ValorSignificado
AUTHORIZATIONVenta.
DEFERREDPreautorización.
CONFIRMATIONCaptura de una preautorización.
CANCELLATIONLiberación de una preautorización.
DECREMENTLiberación parcial de una preautorización.
DEFERRED_UPDATEAjuste de una preautorización.
REFUNDDevolución con tarjeta presente.
REFERRAL_REFUNDDevolución sin tarjeta presente.
REVERSALAnulación en el mismo día.
CARD_VERIFYValidación de tarjeta sin cargo.
CFTAbono a una tarjeta.
PAYOUTDesembolso.
LIMITED_PAYMENTPago restringido.

TransactionStatus​

ValorSignificado
PAIDAprobado y liquidado localmente. Es el único valor que indica éxito.
REFUSEDRechazado por el emisor o el adquirente.
PENDINGEn curso; todavía no se conoce el resultado.
STARTEDIniciado en el terminal.
CANCELLEDCancelado antes de finalizar.
EXPIREDSe ha agotado el tiempo de espera antes de finalizar.
ERRORHa fallado por un motivo técnico.
DUPLICATEDRechazado por estar duplicado.
danger

CHIP_ERROR no es un estado de transacción. Aparecía en versiones anteriores de este documento, pero no es uno de los valores que puede devolver el SDK. Un fallo de chip se indica mediante ERROR y se detalla en response_message.

CardInputType​

ValoresSignificado
CONTACTChip insertado.
CLESSSin contacto.
CLESS_MAGSTRIPEPerfil de banda magnética sin contacto.
MAGNETICLectura de banda magnética.
MAGNETIC_FALLBACKLectura de banda magnética tras un fallo del chip.
CHIPChip.
MANUALIntroducida manualmente por el operador.
KEY_ENTRYEntrada manual.
NON_PRESENTIALTarjeta no presente.
UNKNOWNEl terminal no lo ha indicado.

Incoming​

DEVICE — iniciada en el terminal; incluye todas las operaciones de este documento. API — iniciada por el backend.

26. Integración mediante intents​

26.1 Lanzamiento de una operación​

const val PAYMENT_RESULT_CODE = 1001

val stan = UUID.randomUUID()
val uri = "com.paynopain.sentinelservice://payment" +
"?amount=100&currencyCode=978&stan=$stan"

startActivityForResult(Intent(Intent.ACTION_VIEW, Uri.parse(uri)), PAYMENT_RESULT_CODE)

26.2 Lectura del resultado​

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode != PAYMENT_RESULT_CODE) return

when (resultCode) {
RESULT_OK -> {
// Same payload as the HTTP and USB transports return.
val result = data?.getStringExtra("transactionResult")
}
RESULT_CANCELED -> {
val errorMessage = data?.getStringExtra("error_message")
}
}
}

26.3 Hosts de intents disponibles​

Todas las URI tienen el formato com.paynopain.sentinelservice://<host>?<query>. Los nombres de los parámetros de consulta coinciden con los campos JSON de la operación correspondiente.

payment           confirmation      transaction
preauthorization cancellation transactionbystan
refund decrement healthcheck
referral cardverify sync
reversal cft

Las operaciones que no aparecen en esta lista —listado de transacciones, informes, cierre de lote, reimpresión e identificación— solo están disponibles mediante HTTP y USB.

26.4 Comprobación previa de disponibilidad​

val installed = try {
packageManager.getPackageInfo("com.paylands.posms.sentinel", 0)
true
} catch (e: PackageManager.NameNotFoundException) {
false
}

Comprueba el nombre del paquete al verificar la instalación. El esquema de intents utiliza un nombre distinto; consulta §2.

La información contenida en este documento es propiedad de PAYNOPAIN SL y no puede copiarse, utilizarse ni divulgarse, total o parcialmente, salvo con el consentimiento previo por escrito de PAYNOPAIN SL.