CollectPay Guía de integración · v1
Para plataformas que integran

Guía de integración

Desde dar de alta a tu primer cliente hasta consultar sus cobros. Todo lo que aparece acá está en producción.

Qué es y qué no

Collect Pay conecta tu plataforma con terminales de pago y procesadores. Tú le dices cuánto cobrar y a quién imputárselo; nosotros hacemos que la máquina cobre eso y te devolvemos el hecho.

El dinero no pasa por acá. Cada pago se acredita directo en la cuenta que tu cliente conectó con su propio procesador. Collect Pay no lo recibe, no lo retiene y no lo reparte.

Tampoco guardamos a tus clientes finales. La referencia de un cobro y la persona que lo hizo son cadenas opacas que tú mandas: acá no hay nombres, teléfonos ni direcciones.

Tus credenciales

Al crear tu cuenta recibes tres cosas, y se muestran una sola vez:

QuéPara qué
sk_live_…Operar en producción. Va en la cabecera X-API-Key.
sk_test_…Lo mismo, contra el ambiente de prueba. El prefijo decide el ambiente.
Secreto de avisosCon él firmamos lo que te mandamos. Sirve para verificar que somos nosotros.
Una key alcanza a todos tus clientes. Guárdala en tu backend, nunca en un navegador ni en una aplicación móvil.

O acótala: al emitirla desde tu panel puedes pasarle empresas: [3, 7] y esa key sólo podrá operar —y consultar— esas. Fuera de su alcance responde empresa_fuera_del_alcance_de_la_key y los listados vienen filtrados. Es lo que conviene si tienes una instalación por cliente y prefieres una key en cada una.

Si tu plataforma tiene muchos clientes

Hay dos formas de integrarse, y la diferencia no es de tamaño sino de dónde corre tu código.

Una sola instalación. Tu sistema corre en un lugar y desde ahí atiende a todos tus clientes. Te basta una cuenta: la key vive en tu backend y cada cliente es una empresa dentro de ella. Es lo que ya leíste arriba y no necesitas nada más.

Una instalación por cliente —cada uno con su dominio, su base y su API—. Acá una sola key es un problema: tendrías que desplegar la misma credencial en todas las instalaciones, y el día que una se filtre se filtran todos tus clientes con ella. Para eso existe la clave de partner.

Con ella abres una cuenta por cliente, en el momento en que ese cliente activa el cobro. Cada instalación guarda sólo sus propias credenciales. Si una se compromete, se compromete una.

POST/api/v1/partner/cuentas
curl -X POST https://collectpay.trackingtech.cl/api/v1/partner/cuentas \
  -H 'X-API-Key: pk_live_…' -H 'Content-Type: application/json' \
  -d '{"nombre":"Courier Austral","email":"ti@austral.cl",
       "empresa":{"nombre":"Courier Austral SpA","rut":"76.111.222-3"}}'

→ { "tenant_id": 12,
    "api_key": "sk_live_…", "api_key_test": "sk_test_…",
    "webhook_secret": "whs_…",
    "empresa": { "empresa_id": 31, … } }

Esas tres credenciales se muestran una sola vez. Guárdalas en la instalación de ese cliente y sigue desde ahí con los pasos 2 en adelante: los términos los acepta él, y la cuenta del procesador la conecta él.

La clave de partner no se despliega. Vive donde decides dar de alta a un cliente —tu panel, tu plano de control— y nunca en la instalación del cliente. Si la copias a cada instalación, vuelves exactamente al problema que esto evita: una credencial que abre cuentas, repartida en todas partes. Si sospechas que se filtró, se revoca y se emite otra; las cuentas que ya abrió siguen funcionando con sus propias keys.

La cuenta se cobra a quien la abrió. Cada cuenta recuerda con qué clave de partner nació, así que el consumo de tus clientes se consolida bajo tu nombre aunque sean veinte cuentas separadas. Cada una mantiene su propia tarifa, que puede no ser la misma para todos.

La clave de partner la emite quien opera Collect Pay, y se entrega una vez. No se solicita por API.

El modelo en una página

Esa última distinción es la que más conviene entender: un cobro puede tener varios intentos. El cliente intenta con una tarjeta, la rechazan, paga en efectivo. Un cobro, tres intentos, una deuda saldada.

PASO 1

Crear el courier

Lo haces tú con tu key, cuando tu cliente activa el servicio. Guarda el empresa_id junto a ese cliente en tu sistema, o manda tu propio id en ref_externa.

POST/api/v1/empresas
curl -X POST https://collectpay.trackingtech.cl/api/v1/empresas \
  -H 'X-API-Key: sk_live_…' -H 'Content-Type: application/json' \
  -d '{"nombre":"Courier Austral SpA","rut":"76.111.222-3","ref_externa":"cliente-482"}'

Nace sin poder cobrar. Faltan los dos pasos siguientes, y los hace el courier, no tú.

PASO 2

Que acepte los términos

Muéstrale el texto y registra quién acepta. Queda guardado el contenido exacto de esa versión: publicar una nueva no cambia lo que ya se firmó.

GET/api/v1/terminos/vigente
{ "version": 1, "titulo": "…",
  "tarifa": { "uf_por_transaccion": 0.0015, "definicion": "…" },
  "contenido_md": "# Términos…" }
POST/api/v1/empresas/{id}/terminos/aceptar
{ "version": 1, "nombre": "Nombre de quien firma", "cargo": "Gerente" }
PASO 3

Que conecte su procesador

Primero pregunta cómo. No todos los procesadores se conectan igual: con Mercado Pago el courier autoriza y vuelve; con SumUp puede autorizar o pegar una API key de su cuenta. En vez de que tu pantalla lo sepa de antemano, pídelo:

GET/api/v1/empresas/{id}/conexiones
{ "conectadas": [
    { "unidad_recaudadora_id": 4, "procesador": "mercado_pago", "estado": "habilitada",
      "cuenta": "ECOURIER", "maquinas": { "total": 3, "habilitadas": 3 } }
  ],
  "puede_cobrar_con": ["mercado_pago"],
  "opciones": [
    { "procesador": "sumup", "metodo": "autorizar", "recomendado": true,
      "titulo": "Conectar con SumUp",
      "ruta": "/api/v1/empresas/3/conexiones/sumup/autorizar",
      "campos": [], "pasos": ["Aprieta el botón: te llevamos…"],
      "costo": { "forma": "Un porcentaje de cada venta…", "advertencia": "Referencial…" } },
    { "procesador": "sumup", "metodo": "credenciales", …
      "campos": [{ "nombre": "api_key", "etiqueta": "API key de la cuenta SumUp" }] }
  ] }

Cada opción viene con su paso a paso redactado, la ruta que hay que llamar ya resuelta, y cuánto cuesta cobrar con ese procesador —como referencia, con su advertencia al lado: la tarifa la negocia el courier y la de verdad se la vamos a medir después, cobro a cobro—. Un procesador nuevo aparece en tu pantalla sin que toques una línea.

Una empresa puede tener varias cuentas conectadas a la vez. Conectar SumUp no toca la conexión de Mercado Pago: en conectadas aparecen las dos, con cuántas máquinas depende de cada una, y en opciones sólo las que faltan. Con eso tu pantalla muestra «Mercado Pago conectado · SumUp por conectar» sin saber de ninguno de los dos, y nadie tiene que crear una empresa aparte para probar un procesador nuevo. Para soltar una, DELETE /api/v1/empresas/{id}/conexiones/{procesador}: deja sin cobrar sólo a sus máquinas.

Después, con la opción elegida: pide la URL de autorización y manda ahí el navegador del courier. Autoriza en la pantalla del procesador, con sus propias credenciales, y vuelve a donde tú digas.

POST/api/v1/empresas/{id}/conexiones/mp
{ "retorno": "https://tu-sistema.cl/integraciones/collectpay" }

→ { "url_autorizacion": "https://auth.mercadopago.com/authorization?…",
    "expira_en": "2026-09-13T20:12:00Z" }
El retorno debe ser https y sin credenciales en la URL. Vuelve con ?conexion=ok si autorizó, y con ?conexion=error&motivo=… si canceló o el enlace venció —sin_autorizacion, enlace_vencido—. Siempre vuelve: tu pantalla no se queda esperando un retorno que no llega.

Una sola llamada para pintar tu pantalla

Si construyes tu propio panel de configuración, no compongas el estado desde cuatro endpoints. Éste responde lo único que esa pantalla pregunta: si la empresa ya puede cobrar y, si no, qué le falta. El falta viene redactado para mostrarlo tal cual.

GET/api/v1/empresas/{id}
{ "empresa_id": 3, "nombre": "Courier Austral SpA",
  "terminos": { "version":1, "por":"…", "aceptado_en":"…" },
  "conexion": { "estado":"habilitada", "cuenta":"…", "token_expira":"…" },
  "pods": { "total":2, "habilitados":1 }, "sesiones_abiertas": 1,
  "puede_cobrar": true, "falta": null }
PASO 4

Sucursales y terminales

Las dos cosas las crea tu plataforma con tu key, por API, y Collect Pay las espeja en el procesador: la sucursal se convierte en un local y cada POD en una caja. No hay que entrar al panel del procesador a crearlas a mano.

La dirección tiene que ser real —el local se registra con ella— y la región debe existir: se acepta el nombre común («Región Metropolitana», «Biobío») y se traduce al que el procesador exige.

POST/api/v1/empresas/{id}/sucursales
{ "nombre": "Bodega Central",
  "direccion": { "calle":"Av. Siempreviva", "numero":"1111",
                  "comuna":"Santiago", "region":"Región Metropolitana",
                  "lat":-33.4429, "lon":-70.6539 } }

Sobre esa sucursal se declara cada POD —una máquina, una caja— y la respuesta trae su pod_id, su estado y el QR de esa caja. El codigo es tuyo y es con el que vas a reconocer la máquina: letras, números, guión y guión bajo, entre 2 y 40, único dentro de la empresa. Se guarda en mayúsculas.

POST/api/v1/sucursales/{id}/pods
{ "codigo": "CAJA1", "nombre": "Caja mostrador", "procesador": "sumup" }

La cuenta la dice la máquina, no la sucursal. En la misma bodega puede haber una Point de Mercado Pago y un Solo de SumUp: procesador amarra el POD a esa cuenta y, de ahí en adelante, cada cobro de esa máquina sale por ella sin que nadie lo repita. Con una sola cuenta conectada se omite. Con dos o más, un intento que no venga de una máquina —un QR, un link— tiene que decir por cuál sale; si no, responde procesador_ambiguo en vez de adivinar, porque adivinar es cobrar por la cuenta equivocada.

Después, un paso físico que ninguna API puede hacer: encender el lector, vincularlo a esa caja desde la aplicación del procesador, y activar el POD con el número de serie de su etiqueta.

POST/api/v1/pods/{id}/activar
{ "serial": "N950NCD300246809" }

Queda en pendiente_reinicio. Reinicia la máquina y confirma con POST/api/v1/empresas/{id}/pods/refrescar. Cada POD trae además un siguiente_paso redactado: es lo que conviene mostrar en tu pantalla en vez de traducir los estados por tu cuenta.

El orden importa, pero no bloquea. El local y la caja se crean en el procesador con la conexión ya habilitada. Si declaras una sucursal antes de que el courier conecte su cuenta, se guarda igual —no se pierde el trabajo— pero todavía no existe del otro lado: se espeja sola al crear el primer POD, ya conectado. Lo que no se puede es cobrar con una máquina que nunca llegó al procesador.

Corregir una sucursal (PATCH) empuja el cambio al procesador: dos verdades para el mismo local es peor que no poder corregirlo, porque la de ellos es la que sale en los documentos. Y al dar de baja, el local o la caja se borran allá sólo si nunca cobraron; si cobraron se quedan, porque son parte de la historia de esos pagos.

PASO 5

Abrir la sesión

Alguien toma la máquina, por un turno de mostrador o una ruta. Sin esto, un cobro con tarjeta se rechaza: no habría a quién imputarle la plata.

POST/api/v1/empresas/{id}/sesiones
{ "pod_id": 2, "contexto": "ruta", "persona": { "ref": "driver-482" } }
Una sesión abierta por máquina. Abrir cierra la anterior: el acto de tomar el terminal es también el de soltárselo a quien lo tenía.
PASO 6

Crear el cobro

La deuda, sin método. No toca al procesador y la máquina no se entera de nada.

POST/api/v1/cobros
curl -X POST … /api/v1/cobros \
  -H 'X-Idempotency-Key: 7f3a9c21-…' \
  -d '{"empresa_id":3,"referencia":"TT-4471903","monto":23000,
       "descripcion":"Envío 1 bulto"}'

La referencia es única por empresa y es tu vínculo de vuelta: usa el identificador del envío o de la venta. Admite letras, números, guión y guión bajo, hasta 64 (^[A-Za-z0-9_-]{1,64}$): un id con barras o puntos se rechaza. Repetirla con otro monto es referencia_en_conflicto; repetirla con el mismo monto te devuelve el cobro que ya existe. La descripción se muestra en la pantalla del terminal, así que no puede llevar teléfonos, RUT ni correos: se valida y se rechaza.

La cabecera de idempotencia es obligatoria. Es lo que impide que un reintento de tu lado cobre dos veces.

PASO 7

Elegir el método

Acá, y sólo acá, entra el método. Sólo tarjeta enciende la máquina.

POST/api/v1/cobros/{id}/intentos
{ "metodo": "tarjeta", "punto": "ses_7Y2WYZTK", "expiracion": "PT3M" }

La expiración es ISO 8601 y su techo depende de por dónde se cobra: el monto en la pantalla de un lector admite de PT30S a PT3H —es una regla del aparato, no nuestra— y por defecto son 3 minutos. Lo que se cobra a distancia, QR y link, llega hasta PT24H, con 15 minutos y 24 horas por defecto. Pasarse es expiracion_fuera_de_rango.

MétodoQué pasa¿Se factura?
tarjetaLa máquina se enciende con el monto.Sí
qrDevuelve el QR de la caja. Exige punto, igual que la tarjeta: el QR es de una caja, y una caja la tiene alguien.Sí
linkDevuelve una URL. No notifica a nadie: el teléfono del cliente es tuyo.Sí
efectivoSe registra. Nace aprobado.No
transferenciaSe registra. Exige decir quién recibió.No
Un intento con el monto ya en la pantalla del lector se puede cancelar —POST/api/v1/cobros/{id}/intentos/{intento_id}/cancelar— y el procesador lo aplica cuando el lector sincroniza. Si aun así se niega, responde cancele_en_dispositivo: ahí lo cancela quien tiene la máquina, o se deja vencer. Muere el intento, nunca el cobro: el cliente puede pagar en efectivo y la deuda se salda igual.
PASO 8

Enterarse del pago

Tres caminos, y conviene usar los tres.

Te avisamos

Hacemos POST a tu URL de avisos cuando algo cambia. Firmado con tu secreto, con su evento_id para que deduplicues, y con reintentos de 1 minuto a 24 horas.

EventoCuándo
cobro.pagado · cobro.revertido · cobro.anulado La deuda cambió de estado. Trae el cobro completo.
pod.deshabilitado · pod.habilitado Una máquina salió del modo PDV —o volvió—. No tienes que preguntarlo: una máquina caída es alguien cobrando fuera del libro sin saberlo.
conexion.revocada El procesador rechazó renovar el acceso de ese courier. Hay que volver a conectar su cuenta.
lo que recibes
X-Collectpay-Event: cobro.pagado
X-Collectpay-Id: evt_9K2M…
X-Collectpay-Signature: ts=1789318216,v1=8f3c…

{ "tipo": "cobro.pagado",
  "cobro": { "id":"cob_HE7ME6YW", "referencia":"TT-4471903",
              "estado":"pagado", "monto":23000, "intentos": […] } }

La firma es HMAC-SHA256 sobre id:{evento_id};ts:{ts}; con tu secreto. Responde 200 y deduplica por evento_id.

Preguntas

Mientras la máquina está en pantalla, consulta el cobro cada dos segundos. Es lo que hace que la persona que está cobrando vea el resultado al instante.

Fuerzas

Si el aviso no llegó, pídenos la verdad al procesador. El resultado es el mismo que si el aviso hubiera llegado.

POST/api/v1/cobros/{id}/sincronizar
{ "estado": "pagado", "sincronizacion": { "intentos_actualizados": 1 } }

Consultar cobros e historial

ParaVerbo
Un cobro y sus intentosGET/api/v1/cobros/{id}
Buscar por tu referenciaGET/api/v1/cobros?referencia=TT-4471903
Ponerte al día tras una caídaGET/api/v1/cobros?actualizado_desde=…
Qué le pasó a un cobroGET/api/v1/cobros/{id}/historial
Conciliar el períodoGET/api/v1/intentos.csv?desde=…&hasta=…

El listado viene paginado: { "datos": […], "siguiente_cursor": 1487 }. Mientras ese cursor no sea null, queda más — pídelo con ?cursor=. Una sola página leída como si fuera todo es la forma silenciosa de perder cobros.

actualizado_desde es tu red de seguridad: si tu sistema estuvo caído, con eso recuperas todo lo que se movió sin perder nada.

El dinero se lee en el intento aprobado, no en el cobro: ahí están monto, fee y neto, junto con facturable y el pago (tipo, marca y cuotas). El cobro lleva el total y su estado. La comisión la calcula el procesador unos segundos después del pago, así que puede llegar vacía en el primer aviso y completarse enseguida.

Estados, y qué hacer con cada uno

Los estados son parte del contrato, no una convención interna: cada uno está declarado como lista cerrada en /docs, así que si mañana aparece uno nuevo aparece también ahí. Acá va lo que significan y —lo que de verdad importa— qué los mueve.

La máquina (POD)

Es el que más sorprende, porque la mitad de sus transiciones no las provoca tu código: las provoca alguien parado frente al aparato.

el camino completo de una máquina
POST /sucursales/{id}/pods
        │
        ▼
   registrado ─────────── la cuenta del procesador todavía no estaba conectada:
        │                    existe acá y no del otro lado. Conecta la cuenta y
        │                    vuelve a crear el POD.
        ▼
 pendiente_vinculacion ── ya tiene caja y QR. Falta el paso físico: encender
        │                    el lector y escanear ese QR con la app del procesador.
        │  POST /pods/{id}/activar  { "serial": "N950…" }
        ▼
  pendiente_reinicio ──── el lector quedó en modo PDV pero hay que reiniciarlo.
        │  reiniciar la máquina + POST /empresas/{id}/pods/refrescar
        ▼
   habilitado ─────────── cobra con tarjeta. siguiente_paso: null
        │
        │  alguien saca el lector de PDV · DELETE /pods/{id} ·
        │  se revoca la conexión de la empresa
        ▼
  deshabilitado ───────── vuelve con activar + refrescar
EstadoQué significa¿Cobra con tarjeta?
registradoExiste acá y no en el procesador. Con Mercado Pago pasa cuando se declara la máquina antes de conectar la cuenta; con un procesador que empareja —SumUp— es el estado normal hasta que alguien teclea el código que muestra el lector.No
pendiente_vinculacionTiene caja y QR. Espera que alguien escanee el QR en el lector y mande el serial.No
pendiente_reinicioQuedó en modo PDV; el lector tiene que reiniciarse para tomarlo.No
habilitadoEl lector reporta PDV y responde.Sí
deshabilitadoSalió de PDV, se dio de baja, o la empresa revocó su conexión.No
Lo que se teclea al activar depende del procesador. En SumUp el código sale del propio lector, y hay un paso que no está en ningún menú obvio: la opción API sólo aparece con la sesión cerrada. Primero menú de arriba › Ajustes › Acerca de › Cerrar sesión; después, en el mismo menú, Conexiones › conectar al Wi-Fi › API › Conectar. El código dura 5 minutos. Un Solo atado al Cloud API vive deslogueado: deja de cobrar por su cuenta y cobra sólo lo que le manda el sistema, que es justamente la promesa. Con Mercado Pago es el serial de la etiqueta, y la máquina queda en pendiente_reinicio hasta que se reinicia. Con SumUp es el código de emparejamiento que la propia máquina muestra en pantalla —y que se vence—, y queda habilitada de inmediato. El verbo y el campo son los mismos (serial); lo que cambia lo dice siguiente_paso.
No traduzcas los estados por tu cuenta. Cada POD trae siguiente_paso ya redactado para mostrarlo tal cual —dice qué falta y en qué pantalla del lector—, y es null exactamente cuando la máquina puede cobrar. Si prefieres tu propio texto, la lista de arriba es la que tienes que cubrir entera.

Dos campos más que la pantalla agradece: modo_operacion es lo que reporta el lector (PDV o STANDALONE; en standalone el monto se teclea en el aparato y el cobro queda fuera del libro), y ultimo_visto_en es la última vez que contestó. Los dos se refrescan con POST/api/v1/empresas/{id}/pods/refrescar, que además deshabilita solo al que volvió a standalone.

Los dos QR, que no son el mismo

Vale la pena separarlos porque se llaman igual y viven en campos distintos:

CuálDónde vienePara qué
El QR de la cajapod.proveedor.qr_imagen al crear el POD Identifica a esa caja para siempre. Se imprime y se pega en la máquina. Es también el que se escanea desde la app del procesador para vincular el lector.
El cobro con QRintento.qr.datos al crear un intento con metodo: "qr" No crea otro QR: le carga el monto a esa misma caja. El cliente escanea y paga lo que corresponde.

Por eso un intento con QR exige punto, igual que la tarjeta: el QR es de una caja, y una caja la tiene alguien.

El cobro y el intento

CobroQué significa
solicitadoLa deuda está viva. Admite intentos.
pagadoUn intento la saldó. No admite otro intento.
revertidoSe devolvió el total, por /reverso o por un reembolso del procesador.
anuladoSe cerró sin pagarse.
IntentoQué significaQué lo saca de ahí
creadoLa order salió, el lector todavía no la tomó.El lector, o cancelar.
en_dispositivoEl monto está en la pantalla del lector.El cliente paga, alguien cancela, o expira.
esperando_pagoQR o link entregado, esperando al cliente.El pago, la cancelación o la expiración.
aprobadoPagado. Acá vive el dinero: monto, fee y neto.Nada: es final.
rechazadoEl medio de pago no pasó. detalle dice por qué.Nada: se intenta con otro método.
canceladoLo cancelaste tú o el lector.Nada.
expiradoSe venció la ventana.Nada.
requiere_accionEl procesador dice que ese estado ya no cambia y hay que mirar la máquina.Una persona. Queda como pendiente en la rendición.

Un cobro puede tener varios intentos y sólo uno aprobado. Los movimientos de plata que se suman para una liquidación son los intentos aprobados, nunca los cobros.

La sesión y la conexión

La sesión no tiene estado: o tiene cerrada_en o está abierta. Cerrarla congela la rendición. Cada conexión de la empresa con un procesador sí lo tiene: pendiente (nunca se autorizó, o se empezó y no se terminó), habilitada (puede cobrar) y revocada (se cortó desde acá o desde la cuenta del procesador; sus PODs quedan deshabilitados con ella, y los de las otras cuentas siguen cobrando).

El token no lo tienes que vigilar tú. Dure lo que dure —180 días en Mercado Pago, una hora en SumUp— el servicio lo renueva antes de que venza; si esa ventana se pierde —porque estuvimos abajo esa semana, por ejemplo— lo detecta al ir a usarlo y lo renueva ahí mismo. Lo único que no se arregla solo es que el courier revoque el acceso desde su cuenta de Mercado Pago: ahí la conexión pasa a revocada, puede_cobrar se apaga y cobrar responde conexion_no_habilitada con el motivo. Esa sí hay que volver a conectarla.

Qué devuelve cada verbo

La forma exacta de cada respuesta —campos, tipos, qué puede venir null y qué valores admite cada estado— está en /docs, verbo por verbo y con un ejemplo real al lado. Lo que conviene saber antes de leerlo:

Errores

Todos vienen con una clave estable. Programa contra la clave, no contra el mensaje.

ClaveQué pasó
terminos_no_aceptadosLa empresa no firmó todavía.
conexion_no_habilitadaNo conectó su procesador, o revocó el acceso.
punto_no_resolubleNo hay sesión abierta, o el POD no está habilitado.
intento_en_cursoEsa máquina ya tiene un cobro en pantalla.
cancele_en_dispositivoYa está en el lector: se cancela ahí.
cobro_cerradoPagado, anulado o revertido: no admite otro intento.
idempotencia_en_conflictoMisma cabecera, otro cuerpo.
expiracion_fuera_de_rangoMás de 3 horas en un lector, o más de 24 a distancia.
procesador_no_soportaEl procesador de esa empresa no hace eso. No todos empujan el monto a un lector: ofrece otro método en vez de un error técnico.
procesador_ambiguoLa empresa tiene más de una cuenta conectada y lo que pediste no dice por cuál sale. Manda procesador, o cobra desde una máquina —que ya sabe cuál es la suya.
terminal_ya_registradaEse serial o código de emparejamiento ya está en otra máquina de la empresa. La respuesta dice en cuál.
referencia_en_conflictoEsa referencia ya existe en la empresa, con otro monto.
descripcion_con_datos_personalesLa descripción lleva un teléfono, un RUT o un correo.
empresa_no_pertenece_al_tenantEsa empresa no es de tu cuenta.

Prueba y producción

El prefijo de la key decide el ambiente. Con sk_test_ puedes forzar el resultado de un intento sin mover dinero, usando el terminal virtual SBX0000001.

El ambiente de prueba no convierte la cuenta del courier en una de prueba. Si conectó su cuenta real, cobrar con una máquina física cobra de verdad, en los dos ambientes. El terminal virtual sólo funciona con una cuenta de prueba del procesador.

El contrato completo, verbo por verbo, está en /docs.