Realiza cobros con Kushki One

La Payment API te permite procesar cobros presenciales con tarjeta desde tu sistema de caja hacia una terminal Kushki ONE en modo semi-integrado. La terminal gestiona toda la interacción con el tarjetahabiente y el chip EMV: tu sistema envía el monto y recibe el resultado.

Requisitos

Cómo funciona

Los payloads y los headers son idénticos entre topologías. Las rutas no — cambian cuatro cosas, y están listadas debajo de los base URL.

TopologíaBase URL
Red Local (LAN / Wi-Fi)http://{TERMINAL_IP}:6868/terminal/v1 o https://{TERMINAL_IP}:6869/terminal/v1
Nube (Internet) — UAThttps://uat-cloudt.kushkipagos.com/terminal/v1/{terminalSerial}
Nube (Internet) — Producciónhttps://cloudt.kushkipagos.com/terminal/v1/{terminalSerial}

Qué cambia entre Nube y red local, más allá del base URL:

DiferenciaRed LocalNube
Ruta de la consulta en línea/transaction_search_online/sync/transaction_search_online
Método de /abortGET, en ambos modosPOST, solo síncrono
Abort asíncronoDisponibleNo existe
Rutas de impresión/terminal/v1/print/{terminalSerial}/sync/print

Modos síncrono y asíncrono

Cada operación que requiere interacción con la terminal existe en dos variantes, bajo prefijos de ruta distintos.

ModoPrefijoComportamientoDónde llega el resultado
Síncrono/sync/Mantiene la conexión abierta hasta que el adquirente respondeEn la respuesta HTTP
Asíncrono/async/Responde de inmediato con un acuse TERMINAL_ACKNOWLEDGED. No bloqueaSolo por webhook

Operaciones disponibles

OperaciónRutaSíncronoAsíncronoQué hace
Venta/charge✅✅Cobro inmediato: autoriza y captura en un solo paso
Autorización/authorization✅✅Reserva fondos sin capturarlos
Captura/capture✅✅Cobra los fondos de una autorización aprobada
Re-autorización/re_authorization✅✅Extiende el monto o la vigencia de una autorización activa
Post propina/pos_tip✅✅Agrega propina a una transacción ya autorizada
Reversa/void✅✅Reversa una transacción: anulación dentro del día calendario, devolución pasado el corte
Cancelar/abort✅✅Cancela una operación en curso en la terminal
Consulta en línea/transaction_search_online✅—Consulta el historial en el adquirente
Consulta local/transaction_search_local✅—Consulta el historial almacenado en la terminal

Conceptos clave

client_transaction_id

Identificador UUID v4 que genera tu sistema de caja. Funciona como clave de idempotencia: si la terminal ya procesó ese identificador, detecta el duplicado y evita el doble cobro.

Genera uno nuevo por cada venta. Reutilízalo solo cuando estés reintentando exactamente la misma operación tras un fallo de red.

transaction_reference

Identificador que genera Kushki y devuelve en la respuesta de cada transacción aprobada, dentro de rawResponse. Es el vínculo entre operaciones del mismo ciclo de vida.

Estructura del monto

El objeto amount se envía en unidades mínimas de la moneda, como número entero. La cantidad de decimales depende del país.

Campos opcionales, por operación

Estos son los únicos campos opcionales, y cada uno pertenece a operaciones específicas. Se comportan igual en síncrono y asíncrono.

CampoTipoAplica aQué hace
amount.tipentero/charge y /authorizationAgrega propina. Se puede fijar desde la preautorización, no solo al cobrar
cashback_amountentero/chargeRetiro de efectivo adicional a la compra. Envía 0 si no aplica
deferred / query_deferredobjeto / booleano/chargeCuotas. El campo y su forma cambian por país — ver abajo
omit_cardbooleano/capture, /re_authorization y /voidCon true la operación se ejecuta sin pedir la tarjeta
metadataobjeto/charge, /authorization y /pos_tipTrazabilidad libre: reference, customer_email, device

En /pos_tip, amount.tip no es un campo opcional — es el monto de la operación.

omit_card es lo que hace funcionar el caso de hotelería: extender o capturar una preautorización cuando el cliente ya no está en el mostrador.

Las cuotas cambian por país

Los dos campos son mutuamente excluyentes y nunca viajan juntos:

PaísCampoFormaMáximo
Méxicoquery_deferredBooleano. La terminal ofrece Meses Sin Intereses al tarjetahabiente después de leer la tarjeta; tu POS no elige los meses—
Chiledeferredmonths, más credit_type: "03" para cuotas comercio — string, no número12 con credit_type, 48 sin él
ColombiadeferredSolo months. credit_type no aplica48
PerúdeferredSolo months. credit_type no aplica2–48, todas las redes

Si una capacidad no está habilitada para tu terminal, la terminal ignora el campo en vez de rechazar el request — así que un 200 no prueba que la propina se aplicó. Para habilitarla, escribe a soporte@kushkipagos.com.

Cómo leer el status HTTP

Flujos de pago

Venta directa

El flujo más común en retail. La terminal activa el lector al recibir el request y espera a que el tarjetahabiente complete la interacción.

POST /sync/charge → 200 OK (approved: true)

Pre-autorización y captura

Úsalo cuando el monto final no se conoce al momento de la interacción: hoteles, estaciones de servicio, restaurantes de cuenta abierta.

POST /sync/authorization → guarda transaction_reference
↓ (horas o días después)
POST /sync/capture → con el transaction_reference guardado

Puedes intercalar /re_authorization para ampliar el monto reservado o extender el plazo antes de capturar. Envía subtotal_iva0: 0 para extender solo la vigencia.

Vigencia de la autorización

Tipo de tarjetaVigencia desde la autorización
Débito (Visa / Mastercard)7 días
Crédito (Visa / Mastercard)28 días

La captura puede llegar hasta el 110% del total autorizado, sumando la autorización y todas las re-autorizaciones no canceladas. Se permite una sola captura por ciclo.

Propina posterior

Agrega una propina a una transacción ya autorizada. Úsalo cuando el tarjetahabiente decide el monto después del cobro inicial. Envía el valor en amount.tip junto al transaction_reference original.

Reversa

Hay un solo endpoint de reversa, /void, y el sistema decide en qué se convierte la operación según cuándo la llamas. El corte es a las 23:59 hora local en los cuatro países: dentro del mismo día calendario la reversa es una anulación; a partir de la medianoche entra al ciclo de devolución y tarda días hábiles.

Espera al menos 1 minuto después de la transacción original antes de reversarla, o falla sin motivo aparente.

El tipo que devuelve la búsqueda de transacciones dice qué terminó pasando:

TipoQué significa
VOIDLlamaste /void el mismo día calendario. Anulación — el tarjetahabiente no ve el cargo
REFUNDLlamaste /void después del corte. Entró al ciclo de devolución y tarda días hábiles
REVERSENo lo pediste. Lo genera la plataforma sola cuando falla la comunicación con la terminal

Autenticación

Kushki ONE usa un solo mecanismo — hash + cifrado — y es el mismo en Nube, red local y localhost: Authorization: Basic <SHA512>, timestamp en segundos, y el cuerpo como el sobre cifrado {"data":"<iv_hex>:<cipher_hex>"}.

Todos los payloads de esta página son el texto plano que se cifra, no lo que viaja por la red. El flujo completo, la cadena de derivación de claves y el árbol de diagnóstico están en Autenticación y cifrado de requests.

Ejemplo de venta directa

Cobro de 12000 unidades mínimas sin desglose de impuestos. Lo que representa depende de los decimales del país — revisa Formato de montos en Kushki ONE antes de tu primera integración.

  • Javascript
  • Python
const payload = {
amount: {
iva: 0, subtotal_iva: 0, subtotal_iva0: 12000,
extra_taxes: { airport_tax: 0, iac: 0, ice: 0, travel_agency: 0 },
},
client_transaction_id: crypto.randomUUID(),
};
const res = await fetch(`${BASE_URL}/sync/charge`, {
method: "POST",
headers: buildHeaders(payload),
body: JSON.stringify(payload),
});
const data = await res.json();
console.log(data.approved, data.rawResponse.transaction_reference);
import uuid, requests
payload = {
"amount": {
"iva": 0, "subtotal_iva": 0, "subtotal_iva0": 12000,
"extra_taxes": {"airport_tax": 0, "iac": 0, "ice": 0, "travel_agency": 0},
},
"client_transaction_id": str(uuid.uuid4()),
}
res = requests.post(f"{BASE_URL}/sync/charge",
headers=build_headers(payload), json=payload)
data = res.json()
print(data["approved"], data["rawResponse"]["transaction_reference"])

Buenas prácticas

  • Genera un client_transaction_id único por venta y reutilízalo solo en reintentos de la misma operación.
  • Persiste el transaction_reference en cuanto recibas la respuesta de autorización o cobro.
  • Verifica que los campos de amount sumen el total esperado antes de enviar el request.
  • Registra el client_transaction_id y el código HTTP de cada operación para facilitar la conciliación y el soporte.
  • Usa /abort solo mientras una transacción está activa en la terminal. Llamarlo después de que completó devuelve 409 Conflict.
  • Firma exactamente los mismos bytes que envías: serializa una vez, firma esa cadena y envía esa misma cadena.
Servicios asíncronos y webhooks

Integra el modo asíncrono: estados del ciclo de vida, estructura de los eventos y política de reintentos de entrega.

Catálogo de errores

Consulta los modelos de error, códigos por categoría y acciones correctivas para todos los endpoints.