Catálogo Unificado de Errores — Kushki ONE Connect
🚧 Early Release — Beta
Esta documentación está en acceso temprano. Los parámetros, estructuras de respuesta y comportamientos pueden cambiar sin previo aviso. No uses esta versión en producción sin coordinarlo previamente con el equipo de integraciones de Kushki.
Kushki ONE Connect devuelve un payload JSON estructurado ante cualquier fallo, sin importar si el problema se originó en la terminal, en una validación, en la autenticación o en el adquirente. Eso te permite construir integraciones robustas, automatizar flujos de recuperación y dejar de depender exclusivamente de los códigos de estado HTTP.Este manual es tu herramienta de diagnóstico: la estructura del modelo de datos, los catálogos por categoría, cómo mapeamos los rechazos de terceros y una guía rápida para resolver los casos frecuentes.
Toda respuesta de error comparte esta estructura. Evalúa primero el campo type para clasificar la fuente del fallo y luego consulta el code correspondiente.
Campo
Tipo
Siempre presente
Descripción
type
texto
✅
Categoría del error. Identifica la fuente del fallo. Ver Sección 2
code
texto
✅
Prefijo más número para las familias propias de Kushki ONE (PAR-003, TER-004, AUTH-001, NF-001, CONF-4007, MAN-30005). Los códigos del adquirente son los suyos, sin prefijo
param
texto
—
Campo exacto del request que causó el error. Aparece solo cuando la falla es atribuible a un campo — ver abajo
message
texto
✅
Descripción legible del motivo del fallo
object
objeto
—
Datos de trazabilidad: client_transaction_id, terminal_id y serial_number cuando corresponda
En los endpoints de pago el status HTTP es siempre 200, pase lo que pase: confirma que la terminal procesó tu petición, no que la operación haya salido bien. Evalúa siempre el cuerpo. Los endpoints de impresión son la excepción y devuelven códigos reales — 404 si el job no existe, 409 mientras la cola está ocupada.Los cinco campos de arriba están en la raíz del cuerpo. Las dos envolturas que devolvían las versiones viejas, {"success": false, "data": {…}} y {"failure": {…}}, ya no existen. Y object.terminal_id puede llegar vacío en TER-003 — no dependas de él.
{"type":"PARAMETER","code":"PAR-003","param":"amount","message":"Amount must be a value greater than 0","object":{"client_transaction_id":"1018282","terminal_id":"172653","serial_number":"PJ715652"}}
Cuando integras por el modo asíncrono, los fallos no llegan en una respuesta HTTP sino dentro del evento del webhook, en el objeto failure_reason.
Campo
Tipo
Descripción
type
texto
Categoría del error, con los mismos valores de la Sección 2
code
texto
Código único del error
message
texto
Descripción legible del motivo
{"status":"TERMINAL_REJECTED","previous_status":"CARD_PRESENTED","client_transaction_id":"c5a3f3be-9d6f-4d39-8af5-58dbb589af79","failure_reason":{"type":"TERMINAL","code":"TER-172","message":"The maximum operation time was exceeded."}}
failure_reason solo aparece en dos estados
El objeto viene únicamente en los eventos TERMINAL_REJECTED y DECLINED. En el resto de los estados del ciclo de vida no está presente. Revisa Servicios asíncronos y webhooks para el detalle de la máquina de estados.
Diferencias con LinkFailure
failure_reason no incluye param ni object. La trazabilidad la aportan los campos del propio evento: client_transaction_id, terminal.serial_number y merchant_id.
Cuándo viene param y cuándo no
param no es un campo opcional que a veces falta. Se omite deliberadamente cuando el error no lo causó un campo de tu request. La regla en una línea: param aparece solo cuando el error es atribuible a un campo del request.
Sí trae param
Por qué
PAR-003, TER-003, AUTH-001
Errores de validación de datos — hay un campo culpable
NF-001
Trae el identificador que no se encontró
No trae param
Por qué
TER-004
Impresora ocupada, o cancelación del tarjetahabiente. El request era válido; falló el hardware o la persona
MAN-30005
Timeout de tarjeta o PIN. Misma razón
ACQUIRER
La transacción fue válida y el banco la rechazó
CONF-4007
Aprovisionamiento de la terminal, no la llamada
PAR-002 con JSON ilegible
El parser falla antes de deserializar, así que no hay campo que señalar
Sin esta regla un integrador lee el catálogo, ve param entre los campos y programa asumiendo que siempre llega.
Se generan cuando el request contiene campos con formato incorrecto, valores fuera de rango o campos requeridos ausentes. El campo param identifica el campo específico. Todos son prevenibles validando el payload en tu sistema de caja antes de llamar a la API.
code
Descripción
Plantilla del mensaje
Ejemplo
PAR-001
Campo requerido no enviado
Field {{field}} is required
Field amount.subtotal_iva0 is required
PAR-002
Campo de tipo incorrecto
Field {{field}} must be a/an {{type}}
Field amount.subtotal_iva must be an integer
PAR-003
Formato incorrecto o valor no válido
Field {{field}} must satisfy: {{condition}}
Field amount.iva must satisfy: value >= 0
Cuando el type es PARAMETER, el code también puede ser un código numérico del rango 2002 a 2021, además del código de formato BAD_FORMAT.
Error de parseo JSON. El cuerpo del request no es un JSON válido o contiene un tipo de dato incorrecto
No existe el código BUSY
Una terminal ocupada es TER-003 cuando está ejecutando una transacción y TER-004 cuando está imprimiendo — las dos con type: TERMINAL. Por HTTP, una cola de impresión ocupada llega como un 409.
/charge y /authorization, más /pos_tip donde la propina es el monto
2006
amount.extra_taxes.airport_tax
amount.extra_taxes.airport_tax cannot be negative
Todos
2007
amount.extra_taxes.iac
amount.extra_taxes.iac cannot be negative
Todos
2008
amount.extra_taxes.ice
amount.extra_taxes.ice cannot be negative
Todos
2009
amount.extra_taxes.travel_agency
amount.extra_taxes.travel_agency cannot be negative
Todos
La moneda no viaja en el request
El objeto amount no incluye un campo de moneda: la terminal resuelve la moneda desde su propia configuración. No hay validador para eso — los códigos que revisaban amount.currency, isDeferred e isCashback se retiraron porque ninguno de esos campos se envía nunca.
Los montos son enteros
Los errores 2002 a 2009 se disparan con frecuencia por enviar montos con decimales en lugar de enteros en la unidad mínima de la moneda. Revisa Formato de montos en Kushki ONE antes de depurar el payload.
Las cuotas viajan en el objeto deferred en todos los mercados salvo México, que usa el booleano query_deferred. Los dos son mutuamente excluyentes y nunca viajan juntos. Estas validaciones todavía no tienen código numérico asignado:
Condición
Resultado
deferred.months fuera del rango del país
Error PARAMETER en deferred.months
deferred.credit_type enviado fuera de Chile
Error PARAMETER — credit_type solo existe en Chile
deferred y query_deferred juntos
Error PARAMETER — son mutuamente excluyentes
query_deferred enviado fuera de México
Error PARAMETER — el campo es solo de México
El techo depende del mercado: México envía query_deferred como booleano, Chile admite hasta 12 meses con credit_type: "03" o hasta 48 sin él, Colombia hasta 48, y Perú de 2 a 48 para todas las redes. El contrato completo, país por país, está en Acepta pagos con Kushki One.
3.4 Validadores de identificadores de transacción#
Se generan cuando la terminal física no puede aceptar la operación. A diferencia de los errores de hardware, indican un problema de estado o conectividad, no un fallo de componente.
code
Descripción
Plantilla del mensaje
TER-001
Terminal no vinculada al comercio
Terminal {{serial_number}} does not exist, or is not linked to your account
TER-002
Terminal no responde: fuera de línea o fuera de red
Terminal {{serial_number}} is not responding. It may be offline or not connected to the local network
TER-003
Terminal ocupada procesando una transacción
Terminal {{serial_number}} is busy processing transaction (client_transaction_id: {{id}})
TER-004
Impresora ocupada, o cancelación del tarjetahabiente. Ver la sección de este código más abajo
Terminal {{serial_number}} is busy executing action {{action}}
TER-005
Terminal en un modo incompatible con la operación
The terminal is in {{mode}} mode and does not allow the requested action
Se generan cuando las credenciales son inválidas o no alcanzan los permisos para la acción solicitada.
code
Descripción
Mensaje
AUTH-001
No es posible autenticar las credenciales
Invalid or expired credentials
AUTH-002
Credenciales válidas pero sin permiso para el recurso
Your credentials are valid but do not grant access to this resource
{"type":"AUTH","code":"AUTH-001","message":"Invalid or expired credentials"}
AUTH-001 solo en producción, en Red Local o Localhost
Si la integración pasó la certificación en UAT y falla en producción con AUTH-001, verifica que envías el header encrypted_http_communication: true en cada request, también en UAT. Detalle en Autenticación y cifrado de requests.
Nunca registres la firma completa
No escribas el valor del header Authorization en tus registros de producción. Registra solo su presencia o ausencia para diagnóstico.
Los errores del adquirente Kushki se encapsulan bajo type: "ACQUIRER" con esta regla de mapeo:code: el código nativo del adquirente, sin cambios y sin prefijo. E020 se devuelve como E020. Los códigos de autorización son nativos de la red procesadora y se dejan intactos para mantener la trazabilidad ISO 8583 que exigen las franquicias — no esperes un prefijo ACQ-, nunca llega. message: idéntico al mensaje original de Kushki. object: incluye client_transaction_id, terminal_id y serial_number cuando corresponda. Estado HTTP: se conserva el que devolvió originalmente Kushki.Error original de Kushki:
{"code":"E020","message":"Either Invalid amount or Currency conversion field overflow"}
Error mapeado por Kushki ONE Connect, con el mismo 400 Bad Request:
{"type":"ACQUIRER","code":"E020","param":"","message":"Either Invalid amount or Currency conversion field overflow","object":{"client_transaction_id":"1018282","terminal_id":"172653","serial_number":"PJ715652"}}
8. Errores del fabricante — type: "TERMINAL-SUNMI"#
Los errores del SDK del fabricante se encapsulan con el prefijo MAN- — un solo guión — seguido del número. El código confirmado en respuestas reales es MAN-30005: se venció el tiempo de lectura de la tarjeta o de ingreso del PIN, y se trata como una cancelación esperada, no como una falla. Para el catálogo Sunmi completo por rango funcional, pídelo al equipo de integraciones de Kushki.
9. Errores de configuración — type: "CONFIGURATION"#
Se generan cuando la operación no está habilitada para esa terminal, o cuando el monto supera los límites configurados. A diferencia de los errores PARAMETER, no se corrigen modificando el payload.
{"type":"CONFIGURATION","code":"CONF-4001","message":"Tip is not enabled","object":{"client_transaction_id":"c5a3f3be-9d6f-4d39-8af5-58dbb589af69","terminal_id":"172653","serial_number":"SN816265"}}
Estos errores no se resuelven en el código
Un error CONFIGURATION indica que la funcionalidad existe pero no está activa para esa terminal. La terminal ignora los campos de funcionalidades deshabilitadas, así que este error aparece cuando la funcionalidad está parcialmente configurada o cuando se exceden sus límites. Para cambiar una funcionalidad o un límite, escribe a soporte@kushkipagos.com.
10. Errores de Impresora Kushki — type: "TERMINAL-PRINTER"#
Errores del hardware de impresión. Están estandarizados sin importar el fabricante de la terminal.
Verifica que firmas con el Business-Code y que la unidad del timestamp es la correcta. En Red Local y Localhost, verifica también que envías el header encrypted_http_communication: true
AUTH
AUTH-002
Las credenciales son válidas pero faltan permisos. Contacta a integraciones
PARAMETER
cualquiera
Revisa el campo indicado en param. Agrega validación en tu caja antes de llamar a la API
PARAMETER
2002 a 2009
Muy probablemente enviaste montos con decimales en lugar de enteros
INTERNAL
MQTT_REQUEST_FAILED
El relay de Nube no pudo llegar a la terminal. Verifica que esté en línea y reintenta. Solo en Nube
TERMINAL
TER-002
La terminal está fuera de línea. Verifica la conectividad de red
TERMINAL
TER-003
La terminal está ocupada con una transacción. Espera o usa abort
TERMINAL
TER-004
En un endpoint de impresión la impresora está ocupada: reintenta. En un endpoint de pago el tarjetahabiente canceló: no reintentes
Registra el payload completo y escala a soporte técnico de Kushki
Qué registrar siempre
Guarda type, code, message, object.client_transaction_id y la fecha y hora en tu sistema de registro. Sin esos cinco datos, un diagnóstico que toma minutos puede tomar días.
Para depurar un fallo de firma, este es el patrón mínimo de registro: