Catálogo Unificado de Errores — Kushki ONE Connect
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.
1. Modelos de errores
Existen dos envolturas de error. Cuál recibes depende de si el fallo llega en una respuesta HTTP o en un evento asíncrono.
1.1 Respuestas HTTP: LinkFailure
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 | ✅ | Código único. Formato prefijo más número, por ejemplo PAR-001, TER-002, ACQ-13 |
param | texto | — | Campo o parámetro exacto que causó el error. Se usa sobre todo en errores PARAMETER |
message | texto | ✅ | Descripción legible del motivo del fallo |
object | objeto | — | Datos de trazabilidad: client_transaction_id, terminal_id y serial_number cuando corresponda |
El código de estado HTTP es coherente con el type del cuerpo. Para errores ACQUIRER se conserva el estado que devolvió originalmente Kushki.
{"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"}}
1.2 Eventos asíncronos: failure_reason
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."}}
2. Categorías de error
type | Origen | Descripción |
|---|---|---|
PARAMETER | Validación | Envío incorrecto de campos: requeridos vacíos, tipo incorrecto o formato inválido |
TERMINAL | Terminal | Estado de la terminal física: ocupada, fuera de línea, no vinculada, modo incompatible |
AUTHENTICATION | Seguridad | No es posible autenticar las credenciales o no alcanzan los permisos |
NOT_FOUND | Enrutamiento | Servicio o endpoint no encontrado. URL inválida |
ACQUIRER | Adquirente | Procesamiento o autorización de la transacción por parte del adquirente Kushki. Prefijo ACQ- |
INTERNAL | Aplicación | Errores inesperados: servicios caídos, fallos internos |
CONFIGURATION | Configuración DMS | La operación no está habilitada o supera los límites configurados para la terminal |
TERMINAL-PRINTER | Hardware | Errores de la impresora térmica integrada: sin papel, tapa abierta, atasco |
MANUFACTURER | SDK del fabricante | Errores del SDK de Sunmi o Landi. Prefijo MAN- |
3. Errores de validación — type: “PARAMETER”
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 2001 a 2037, además de dos códigos especiales de formato.
3.1 Códigos de sistema
code | Descripción |
|---|---|
BAD_FORMAT | Error de parseo JSON. El cuerpo del request no es un JSON válido o contiene un tipo de dato incorrecto |
BUSY | La terminal está procesando otra solicitud. Reintenta cuando quede disponible |
3.2 Validadores de monto y campos de pago
code | Campo | Mensaje | Aplica a |
|---|---|---|---|
2001 | amount.currency | Invalid currency: {valor}. Expected one of: [MXN, CLP, PEN, COP] | Ver nota |
2002 | amount.iva | amount.iva cannot be negative | Todos |
2003 | amount.subtotalIva | amount.subtotalIva cannot be negative | Todos |
2004 | amount.subtotalIva0 | amount.subtotalIva0 cannot be negative | Todos |
2005 | amount.tip | amount.tip cannot be negative | /charge y /pos_tip |
2006 | airportTax | airportTax cannot be negative | Todos |
2007 | iac | iac cannot be negative | Todos |
2008 | ice | ice cannot be negative | Todos |
2009 | travelAgency | travelAgency cannot be negative | Todos |
2012 | deferredMonths | deferredMonths must be > 0 when isDeferred is true | /charge |
2013 | cashbackAmount | cashbackAmount must be > 0 when isCashback is true | /charge |
3.3 Validadores de identificadores de transacción
code | Campo | Mensaje |
|---|---|---|
2010 | clientTransactionId | clientTransactionId must be a valid UUID format |
2011 | clientTransactionId | clientTransactionId is required |
2014 | transactionReference | transactionReference must be a valid UUID format |
2015 | transactionReference | transactionReference is required |
3.4 Validadores de paginación y fechas
code | Campo | Mensaje |
|---|---|---|
2016 | page | page must be greater than 0 |
2017 | size | size must be greater than 0 |
2018 | size | size must not exceed 500 |
2019 | start_date | start_date cannot be negative |
2020 | end_date | end_date cannot be negative |
2021 | start_date | start_date must be before end_date |
3.5 Validadores de configuración
code | Campo | Mensaje |
|---|---|---|
2022 | env | env is required |
2023 | privateCredentialId | privateCredentialId is required |
2024 | country | country is required |
2025 | pinTimeOut | pinTimeOut cannot be negative |
2026 | cardDetectTimeOut | cardDetectTimeOut cannot be negative |
2027 | pinKeyIndex | pinKeyIndex cannot be negative |
2028 | dataKeyIndex | dataKeyIndex cannot be negative |
2029 | timeoutSeconds | timeoutSeconds cannot be negative |
2030 | maxChipRetries | maxChipRetries cannot be negative |
2031 | countryCode | countryCode must be 3 uppercase letters or 3-4 digits (ISO 3166-1) |
2032 | currencyCode | currencyCode must be 3 uppercase letters or 3-4 digits (ISO 4217) |
2033 | merchantId | merchantId cannot be blank |
2034 | terminalId | terminalId cannot be blank |
2035 | terminalType | terminalType cannot exceed 2 characters |
2036 | CardInput | At least one card input method (ICC, NFC, MSR) must be enabled |
2037 | timeoutSeconds | timeoutSeconds cannot exceed 300 seconds (5 minutes) |
4. Errores de terminal — type: “TERMINAL”
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 | Terminal ocupada con una acción distinta a un pago | 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 |
TER-006 | Terminal no habilitada para ese tipo de operación | The terminal is not allowed to process {{type}} |
5. Errores de Autenticación — type: “AUTHENTICATION”
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": "AUTHENTICATION","code": "AUTH-001","message": "Invalid or expired credentials"}
6. Errores de enrutamiento e internos
type: “NOT_FOUND”
code | Descripción | Plantilla del mensaje |
|---|---|---|
NF-001 | Servicio o endpoint no encontrado | Service not found: {{url}} |
type: “INTERNAL”
code | Descripción | Mensaje |
|---|---|---|
INT-001 | Error inesperado del servidor o de la aplicación | Internal server error |
7. Errores del adquirente — type: “ACQUIRER”
Los errores del adquirente Kushki se encapsulan bajo type: "ACQUIRER" con esta regla de mapeo:
code: código Kushki original con el prefijoACQ-. El código13se convierte enACQ-13.message: idéntico al mensaje original de Kushki.object: incluyeclient_transaction_id,terminal_idyserial_numbercuando corresponda.- Estado HTTP: se conserva el que devolvió originalmente Kushki.
Error original de Kushki:
{"code": "13","message": "Either Invalid amount or Currency conversion field overflow"}
Error mapeado por Kushki ONE Connect, con el mismo 400 Bad Request:
{"type": "ACQUIRER","code": "ACQ-13","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: “MANUFACTURER”
Los errores del SDK del fabricante se encapsulan con el prefijo MAN- seguido del código original. El código -2001 de Sunmi se convierte en MAN--2001.
{"type": "MANUFACTURER","code": "MAN--2001","message": "Have no card","object": {"client_transaction_id": "c5a3f3be-9d6f-4d39-8af5-58dbb589af69","terminal_id": "172653","serial_number": "SN816265"}}
Códigos de Sunmi más frecuentes
code | Descripción | Acción recomendada |
|---|---|---|
MAN--2001 | Have no card | El cliente no presentó la tarjeta. Solicita un reintento |
MAN--2002 | Multiple cards | Hay más de una tarjeta en el campo NFC. Pide retirar las adicionales |
MAN--2581 | User canceled | El cliente canceló. Trátalo como cancelación esperada |
MAN--2582 | MSR or IC interrupted | Lectura interrumpida. Pide no retirar la tarjeta hasta que la terminal lo indique |
MAN--3023 | DUKPT overflow | Contador DUKPT agotado. Requiere reinyección de clave. Contacta a soporte |
MAN--4104 | Card is locked | Tarjeta bloqueada. El cliente debe contactar a su banco |
MAN--4111 | Card expired | Tarjeta vencida. Informa al cliente |
MAN--4120 | Amount exceeds contactless limit | El monto supera el límite NFC. Usa chip |
MAN--50020 | PIN entry cancel | El cliente canceló la entrada de PIN. Trátalo como cancelación |
MAN--60001 | Input PIN timeout | El cliente no ingresó el PIN a tiempo. Solicita un reintento |
9. Errores de configuración — type: “CONFIGURATION”
Se generan cuando la operación no está habilitada para esa terminal en el DMS, o cuando el monto supera los límites configurados. A diferencia de los errores PARAMETER, no se corrigen modificando el payload.
code | Causa | Acción recomendada |
|---|---|---|
-4001 | La propina no está habilitada en la terminal | Contacta a Operaciones Kushki para habilitarla en el DMS |
-4002 | El cashback no está habilitado en la terminal | Contacta a Operaciones Kushki para habilitarlo en el DMS |
-4003 | El monto de cashback supera el límite configurado | Informa al cliente el límite disponible. No reintentes con el mismo monto |
-4006 | El monto de la transacción supera el límite configurado | Informa al cliente. Contacta a Operaciones Kushki si el límite necesita ajuste |
{"type": "CONFIGURATION","code": "-4001","message": "Tip is not enabled","object": {"client_transaction_id": "c5a3f3be-9d6f-4d39-8af5-58dbb589af69","terminal_id": "172653","serial_number": "SN816265"}}
10. Errores de Impresora Kushki — type: “TERMINAL-PRINTER”
Errores del hardware de impresión. Están estandarizados sin importar el fabricante de la terminal.
code | Causa | Acción para el operador |
|---|---|---|
OUT_OF_PAPER | Sin rollo de papel | Inserta un rollo nuevo y reintenta |
COVER_OPEN | Tapa del compartimento abierta | Cierra firmemente la tapa |
COVER_INCOMPLETE | Tapa mal cerrada o rodillo sin presión | Abre y cierra asegurando el encaje del rodillo |
PAPER_JAM | Atasco de papel en el mecanismo | Retira el papel atascado e inserta un rollo nuevo |
BUSY | Cola de impresión ocupada con skipIfBusy: true | Reintenta en unos segundos |
PRINTER_HOT | Cabezal térmico sobrecalentado | Espera 2 o 3 minutos y reintenta |
MOTOR_HOT | Motor de arrastre sobrecalentado | Espera a que se enfríe |
CUTTER_ERROR | Guillotina de corte bloqueada | Requiere intervención de servicio técnico |
OFFLINE | El módulo no responde al sistema Android | Reinicia la terminal |
UNKNOWN_ERROR | Fallo no clasificado del hardware | Registra el caso y escala a soporte técnico |
11. Guía rápida de diagnóstico
Si el type es… | Y el code… | Entonces |
|---|---|---|
AUTHENTICATION | AUTH-001 | Verifica que firmas con el Business-Code y que la unidad del timestamp es la correcta |
AUTHENTICATION | 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 |
TERMINAL | TER-002 | La terminal está fuera de línea. Verifica la conectividad de red |
TERMINAL | TER-003 o TER-004 | La terminal está ocupada. Espera o usa abort |
TERMINAL | TER-006 | Funcionalidad no habilitada. Contacta a Operaciones Kushki |
TERMINAL-PRINTER | cualquiera | Condición física del hardware. Muestra el message al operador |
MANUFACTURER | empieza en MAN--200 | Problema de lectura de tarjeta. Solicita un reintento al cliente |
MANUFACTURER | MAN--50020 o MAN--60001 | El cliente canceló o no ingresó el PIN. Trátalo como cancelación esperada |
ACQUIRER | cualquiera | Rechazo del procesador. Muestra el message al cliente y registra el code |
CONFIGURATION | cualquiera | No reintentes con el mismo payload. Requiere ajuste en el DMS |
INTERNAL o NOT_FOUND | cualquiera | Registra el payload completo y escala a soporte técnico de Kushki |
Para depurar un fallo de firma, este es el patrón mínimo de registro:
- Javascript
- Python
try {const res = await fetch(url, { method: "POST", headers, body });const data = await res.json();if (!res.ok) {logger.error("kushki_one_error", {http: res.status,type: data.type,code: data.code,transaccion: data.object?.client_transaction_id,firma_presente: Boolean(headers.Authorization),});}} catch (e) {logger.error("kushki_one_red", { mensaje: e.message });}
try:res = requests.post(url, headers=headers, json=payload, timeout=30)data = res.json()if not res.ok:logger.error("kushki_one_error", extra={"http": res.status_code,"type": data.get("type"),"code": data.get("code"),"transaccion": data.get("object", {}).get("client_transaction_id"),"firma_presente": "Authorization" in headers,})except requests.RequestException as e:logger.error("kushki_one_red", extra={"mensaje": str(e)})
Autenticación de requests
Resuelve los errores AUTHENTICATION revisando los dos mecanismos de firma y sus diferencias.
Servicios asíncronos y webhooks
Interpreta el objeto failure_reason dentro del ciclo de vida de la transacción.
Chile
Ecuador
Mexico
Peru