Skip to Content
Conceptos ClaveRieles de Pago

Rieles de Pago

rail es un campo opcional de las cuentas de destino que indica por qué esquema de pago local se alcanza ese destino. Existe porque hay un país que opera más de uno: en Colombia el mismo número de 10 dígitos puede ser una cuenta bancaria o la llave Bre-B basada en el documento de su titular, y son dos destinos distintos.

En el resto de los países el riel bancario es la única opción, así que el campo no aporta información y conviene omitirlo.

Se declara al crear el destino; k3 lo guarda en la cuenta y lo reenvía en cada pago, así el proveedor de liquidación no tiene que deducirlo por su cuenta. Nada más cambia: el riel es una declaración que hacés vos y que Koywe transmite. El dashboard de Koywe ya lo declara en todos los destinos colombianos creados desde ahí, así que lo que sigue es para quienes integran por API.

Opcional en todos los casos, y retrocompatible: el campo nunca es obligatorio. Las cuentas creadas antes de que existiera no tienen riel, y un destino bancario creado sin declararlo se comporta igual que antes. Donde sí importa es en una llave Bre-B colombiana, que necesita rail: "BREB" para quedar almacenada y liquidada como llave — ver Crear un destino Bre-B.


Valores

ValorSignificadoDónde
BREBaccountNumber contiene una llave Bre-B, no un número de cuenta bancaria.Solo Colombia
BANKaccountNumber contiene un número de cuenta bancaria.Cualquier país
(omitido)Sin declarar — no se almacena ningún riel. Ver Omitir el campo.Cualquier país

El campo se acepta en los dos endpoints de creación de destinos. En las respuestas de cuenta solo aparece cuando hay un riel declarado: si no lo hay, se omite del JSON en vez de venir en null.

POST /api/v1/organizations/{orgId}/merchants/{merchantId}/contacts/{contactId}/accounts POST /api/v1/organizations/{orgId}/merchants/{merchantId}/accounts

Omitir el campo

No declarar rail es el comportamiento por defecto, y es lo que tienen todas las cuentas creadas antes de que el campo existiera. Qué pasa en ese caso:

  • Al crear, accountNumber se valida como número de cuenta bancaria: el banco debe existir, debe soportar el type de la cuenta, y la longitud del número debe entrar en el rango de ese banco.
  • Al pagar, k3 no envía ningún riel y el proveedor lo resuelve a partir del destino — el comportamiento anterior a este campo. Un destino que contiene un @, un + o cualquier letra no puede ser un número de cuenta colombiano, así que se lee como llave Bre-B; uno compuesto solo por dígitos se lee como cuenta bancaria.

Para destinos bancarios, en cualquier país, eso es exactamente lo correcto y no hay nada que declarar.

El caso a mirar es una llave Bre-B compuesta solo por dígitos — un NIT, una cédula, un celular sin el prefijo +57. Ni k3 ni el proveedor pueden distinguirla de un número de cuenta, así que una llave así sin declarar queda guardada como cuenta bancaria y se liquida por el riel bancario. Las llaves que contienen un @, un + o una letra suelen rechazarse al crearlas (BAA00020 con type: "VIRTUAL", BAA00021 por longitud), y las reconoce el proveedor cuando llegan a pasar. Declarar rail: "BREB" es lo que hace que el resultado sea el mismo en todos los casos.


Crear un destino Bre-B

Declará el riel para una llave Bre-B. rail: "BREB" declara que accountNumber es una llave: k3 omite las validaciones del número contra los bancos colombianos, guarda el riel en la cuenta, y lo reenvía en cada pago para que el proveedor liquide por Bre-B. El campo sigue siendo opcional, pero sin él el destino se valida — y después se liquida — como número de cuenta bancaria.

La forma del número de cuenta no siempre permite distinguir una llave Bre-B de una cuenta bancaria: una llave que contiene un @, un + o una letra es reconocible, pero un NIT de 10 dígitos o un celular sin el prefijo +57 se ven exactamente igual que un número de cuenta, y adivinar mal manda plata a un desconocido. Declarar el riel es lo que elimina la adivinanza.

curl -X POST 'https://api-sandbox.koywe.com/api/v1/organizations/YOUR_ORG_ID/merchants/YOUR_MERCHANT_ID/contacts/cnt_abc123/accounts' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "name": "Bre-B Juan Pérez", "kind": "BANK", "isDefault": true, "countrySymbol": "CO", "currencySymbol": "COP", "accountNumber": "@juanperez", "rail": "BREB" }'
const brebDestination = await axios.post( `https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/contacts/${contactId}/accounts`, { name: 'Bre-B Juan Pérez', kind: 'BANK', isDefault: true, countrySymbol: 'CO', currencySymbol: 'COP', accountNumber: '@juanperez', // la llave Bre-B (acá un @alias), tal como la registró el beneficiario rail: 'BREB' // requerido para una llave Bre-B; exime de `entity` y `type` }, { headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' } } ); console.log(brebDestination.data.rail); // 'BREB' console.log(brebDestination.data.entity); // 'UNKNOWN_BANK' — una llave no tiene banco console.log(brebDestination.data.type); // 'VIRTUAL'

Con rail: "BREB", entity y type son opcionales. Una llave no tiene banco ni tipo de cuenta, así que no hace falta inventarlos. Si los omites, el destino queda con entity: "UNKNOWN_BANK" y type: "VIRTUAL" — así se ve en la respuesta de creación y en todo GET posterior. Si los envías, se guardan tal cual y no se validan contra el catálogo de bancos colombiano; ninguno de los dos se usa para enrutar un pago Bre-B. Sin rail: "BREB", Colombia los sigue requiriendo (BAA00040 / BAA00025).

Requisitos de la llave Bre-B

  • Longitud: entre 6 y 21 caracteres — el rango que aceptan todos los proveedores con los que liquidamos Colombia. La API no valida la longitud al crear el destino: una llave fuera de ese rango se guarda igual y el rechazo aparece recién en el primer pago, del lado del proveedor. Una llave más larga (típicamente un email largo) puede rechazarla la red según quién liquide el pago, así que conviene una forma corta y verificarla antes de operar.
  • Formas aceptadas: @alias (@juanperez), email (jperez@example.co), celular (+573001234567) o número de documento (1234567890). Los espacios se eliminan; una llave puramente numérica conserva solo sus dígitos.
  • La llave debe pertenecer al beneficiario. Al momento del pago la llave se resuelve contra la red y el documento de su titular se compara con el documentNumber del contacto (se tolera el dígito de verificación del NIT en cualquiera de los dos lados). Una llave registrada a nombre de otra persona se rechaza, no se redirige — así que crea el contacto con documentType y documentNumber completos.

Destinos bancarios colombianos

Para una cuenta bancaria real en Colombia, rail: "BANK" es opcional pero conviene enviarlo: declara explícitamente que accountNumber es un número de cuenta y no una llave. Las validaciones son las mismas en ambos casos — el banco debe existir, y el tipo y la longitud del número deben ser válidos para ese banco.

{ "name": "Bancolombia COP", "kind": "BANK", "countrySymbol": "CO", "currencySymbol": "COP", "accountNumber": "1234567890", "rail": "BANK", "entity": "BANCOLOMBIA", "type": "SAVINGS" }

Todos los demás países

Omite rail. BREB fuera de Colombia es una contradicción y se rechaza con BAA00045; BANK se acepta al crear pero no aporta nada, porque es el único riel que operan esos mercados.


Declarar el riel en una cuenta existente

Haz PUT sobre la cuenta con el riel que quieras declarar:

curl -X PUT 'https://api-sandbox.koywe.com/api/v1/organizations/YOUR_ORG_ID/merchants/YOUR_MERCHANT_ID/contacts/cnt_abc123/accounts/acc_def456' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "rail": "BREB" }'

En la actualización aplican cuatro reglas:

  • Solo Colombia. La actualización rechaza un riel declarado para un país que no ofrece elección de riel, con BAA00046 — ahí declarar el riel bancario sería enunciar el valor por defecto como si fuera una decisión.
  • No se puede borrar. Omitir rail deja el valor almacenado intacto, y null se rechaza. No hay camino de vuelta a un riel sin declarar.
  • Vuelve a correr la detección de duplicados. El riel es parte de la identidad de un destino, así que declararlo o cambiarlo puede chocar con una cuenta que ya tengas — BAA00012.
  • Mover el riel a BANK revalida el destino. Cuando el riel de una cuenta colombiana pasa a BANK —desde BREB o desde sin declarar— se vuelven a correr las validaciones bancarias contra el número ya guardado: el banco debe existir (BAA00019), soportar el tipo de la cuenta (BAA00020) y aceptar la longitud del número (BAA00021). Es lo que impide convertir una llave Bre-B en un destino bancario, que se liquidaría contra quien tenga ese número en ese banco. Cambiar entity sobre una cuenta colombiana que no es Bre-B dispara la misma revalidación, porque mueve el destino a otro banco.

Lo que no revalida: cambiar solo el nombre o el swiftCode, repetir el entity que ya estaba guardado, o mover el riel a BREB. En esos casos el destino no cambia, y una cuenta colombiana vieja cuyos datos hoy no pasarían la validación sigue pudiendo editarse.


Qué valida cada superficie

Crear y editar no validan lo mismo, porque no corren el mismo riesgo. La creación ve un destino entero por primera vez; la edición solo tiene que ocuparse de lo que el request cambia.

AcciónAl crear (POST)Al editar (PUT)
Declarar BREBOmite las validaciones bancarias del número, y entity y type dejan de ser requeridos.Se acepta en Colombia. No revalida el número: una llave la valida la red Bre-B, no nuestro catálogo.
Declarar BANKValida el número contra el banco y el tipo de cuenta.Revalida el número ya guardado (BAA00019 / BAA00020 / BAA00021), siempre que el riel efectivamente cambie. Reenviar el riel que ya estaba guardado no revalida nada.
Cambiar el banco (entity)Revalida el número contra el banco nuevo, salvo que el destino sea Bre-B.
Cambiar solo el nombre o el swiftCodeNo revalida nada: el destino no cambió.
Riel fuera del país que lo operaBAA00045BAA00045, y BAA00046 en países con un único riel.
Quitar el rielBasta con no declararlo.No se puede: null se rechaza y omitirlo deja el valor intacto.

No conviertas una llave Bre-B en un destino bancario. Ese cambio hace que el pago se liquide contra quien tenga ese número en ese banco. La revalidación frena el caso habitual — una llave que no es un número de cuenta válido ahí —, pero no puede frenarlos todos: un NIT cuya longitud encaja en el rango del banco pasa la validación, porque es indistinguible de una cuenta real. Si te equivocaste de riel al crear el destino, creá uno nuevo en vez de convertir el que ya existe.


Qué hace el riel al pagar

El riel declarado viaja con el pago, para que el proveedor de liquidación no tenga que inferirlo:

  • BREB — no se envía ni el código de banco ni el tipo de cuenta, y el número de cuenta viaja como llave. Una llave no tiene ninguno de los dos, y el proveedor valida el destino por la llave sola.
  • BANK — el código de banco se resuelve desde entity, como siempre.
  • Sin declarar — no se envía nada, y el proveedor resuelve el riel a partir del destino, igual que antes de que existiera el campo. Es el camino de las cuentas creadas antes del campo y de cualquier destino bancario que lo omita. Llega a Bre-B solo cuando la llave es visiblemente distinta de un número de cuenta (contiene un @, un + o una letra); una llave todo-dígitos se liquida por el riel bancario, que es justo la falla que este campo evita.

Un riel almacenado que no existe en el país del destino (una cuenta BREB que quedó en un país distinto de Colombia) rechaza el pago con BAA00045 en vez de liquidarlo adivinando.


Errores

CódigoEstadoCuándo
BAA00045400El riel declarado no existe en el país de la cuenta bancaria — p. ej. BREB fuera de Colombia. También rechaza un pago cuyo riel almacenado contradice el país del destino.
BAA00046400Declarar un riel no está soportado para este país. Solo lo devuelven los endpoints de actualización, para países con un único riel.
BAA00012409El riel declarado duplicaría un destino existente.
BAA00019404El banco no existe en el catálogo del país. Al crear un destino bancario, y al pasar una cuenta colombiana a rail: "BANK" o cambiarle el banco.
BAA00020400Tipo de cuenta no soportado por el banco — el síntoma habitual de una llave Bre-B enviada sin rail: "BREB". También al revalidar una actualización.
BAA00021400Longitud de número de cuenta inválida para el banco y el tipo de cuenta — misma causa que el anterior.
BAA00040400Falta entity. Requerido para Colombia salvo cuando declaras rail: "BREB".
BAA00025400Falta type. Requerido para Colombia salvo cuando declaras rail: "BREB".

Un 201 no prueba que la llave quedó guardada como llave. Una llave Bre-B sin declarar cuya longitud coincide con la de una cuenta real queda guardada como cuenta bancaria. Leé rail en la respuesta y, si viene ausente en un destino que querías Bre-B, declaralo con el PUT de arriba antes de crear una orden contra él.

Lista completa en Códigos de Error.


Próximos Pasos

Last updated on