# Listado de errores
Source: https://transfiya.me/1-85/directorio-federado/acerca-de/untitled-page
| **HTTP** | **Código** | **Descripción** |
| -------- | ---------- | ---------------------------------------------------------------------------------- |
| 400 | 1013 | El contenido enviado no es válido o está mal cifrado |
| 400 | 1013 | No se puede actualizar el estado de un QR expirado |
| 400 | 1013 | No se puede actualizar el estado de un QR pagado |
| 400 | 1013 | No se puede actualizar el estado de un QR cancelado |
| 400 | 1013 | No se puede actualizar el estado de un QR inhabilitado |
| 400 | 1013 | No se puede actualizar el estado de un QR estático, solo se puede inhabilitar |
| 400 | 1013 | No se puede actualizar el estado de un QR dinámico, solo se puede cancelar o pagar |
| 400 | 1013 | El hash de seguridad no coincide |
| 400 | 1013 | El QR se encuentra expirado |
| 400 | 1013 | El QR se encuentra pagado |
| 400 | 1013 | El QR se encuentra inhabilitado |
| 400 | 1013 | El QR se encuentra cancelado |
| 401 | 1013 | Token inválido o expirado |
| 403 | 1013 | El cliente no tiene permisos para acceder a este recurso |
| 500 | 1005 | Error inesperado en el servidor |
| 502 | 1005 | Problema de comunicación entre servidores. Intente nuevamente más tarde |
| 503 | 1005 | El servicio no está disponible temporalmente. Intente nuevamente más tarde |
# Cómo actualizar el estado de un QR
Source: https://transfiya.me/1-85/directorio-federado/tecnologia-de-acceso-qr/como-actualizar-el-estado-de-un-qr
### Especificaciones para actualización de estado del QR
Las Entidades Participantes pueden actualizar el estado del QR una vez haya sido usado y se requiera dar de baja.
```json theme={null}
Dominio: https://bank.apihub.crt.achcolombia.com.co
```
```json theme={null}
PATCH /ach/bk/v1/money-movement/qr/{id}
```
NOTA: Enviar el ID del QR (el que se entregó en la generación del mismo) en el path
### Estados soportados
| **Estado** | **Tipo de QR** | **Descripción** |
| ---------- | ------------------- | ----------------------------------------------------------------------------------------- |
| ACTIVE | Estático / Dinámico | Todo QR inicia en este estado. Indica que está disponible para pago. |
| INACTIVE | Solo Estático | Estado final. El QR ya no está disponible para recibir pagos. |
| CANCELED | Solo Dinámico | Estado final. El comercio lo canceló antes de cualquier transacción. |
| PAID | Solo Dinámico | Estado final. Se recibió la notificación de pago exitosa. El QR no puede volverse a usar. |
| EXPIRED | Solo Dinámico | Estado final. Se superó el tiempo de vigencia del QR. No puede utilizarse. |
### Transiciones Permitidas — QR Estático
| **Estado Actual** | **Evento / Causa** | **Estado Siguiente** |
| ----------------- | --------------------------- | -------------------- |
| ACTIVE | Solicitud de inhabilitación | INACTIVE |
### Transiciones Permitidas — QR Dinámico
| **Estado Actual** | **Evento / Causa** | **Estado Siguiente** |
| ----------------- | ---------------------------- | -------------------- |
| ACTIVE | Comercio cancela | CANCELED |
| ACTIVE | Notificación exitosa de pago | PAID |
| ACTIVE | Expira vigencia | EXPIRED |
### Máquina de Estados QR Estáticos
```mermaid theme={null}
stateDiagram-v2
[*] --> ACTIVE
ACTIVE --> INACTIVE: inhabilitar()
state "Estado final No disponible para pagos" as FINAL
INACTIVE --> FINAL
FINAL --> [*]
```
```mermaid theme={null}
stateDiagram-v2
direction TB
[*] --> ACTIVE
ACTIVE --> CANCELED : cancelar()
ACTIVE --> PAID : pagoExitoso()
ACTIVE --> EXPIRED : expira() (automático)
%% Notas descriptivas de estados finales
note right of CANCELED
Estado final
Comercio canceló antes de transaccionar
end note
note right of PAID
Estado final
Pago exitoso confirmado; no reutilizable
end note
note right of EXPIRED
Estado final
Se superó el tiempo de vigencia
end note
```
### Campos de Entrada
| **Campo** | **Tipo** | **Descripción** | **Formato** | **Obligatorio** |
| ------------ | ---------- | ----------------------------------------------------------------------- | ------------------------------------ | --------------- |
| **meta** | **object** | | | **SI** |
| requestId | uuid | Código generado por la entidad participante para identificar el paquete | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | SI |
| timestamp | datetime | Fecha y hora de la solicitud de generación del código QR | 2025-12-23T18:16:35.099Z | SI |
| version | string | Versión del esquema, enviar el valor "1.0" | 1.0 | SI |
| **data** | **object** | | | **SI** |
| movementType | enum | Tipo de operación a realizar. \[QR, QRVALIDATE, QRPARSER] | QR | SI |
| status | enum | Estado de código QR. \[INACTIVE, CANCELED, PAID] | PAID | SI |
```json Request theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-16T01:48:22.252Z",
"version": "1.0"
},
"data": {
"movementType": "QR",
"status": "INACTIVE"
}
}
```
### Campos de Salida:
| **Campo** | **Tipo** | **Descripción** | **Formato** |
| -------------------- | ---------- | ----------------------------------------------------------------------- | ------------------------------------ |
| **meta** | **object** | | |
| requestId | uuid | Código generado por la entidad participante para identificar el paquete | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| timestamp | datetime | Fecha y hora de la respuesta a la solicitud de generación del código QR | 2025-12-23T18:16:35.099Z |
| status | enum | Estado de la respuesta. SUCCESS, ERROR | SUCCESS |
| statusCode | string | Código HTTP de la respuesta | 200 |
| statusDesc | string | Descripción del código HTTP | OK |
| **data** | **object** | | |
| id | string | Identificador único del QR en el sistema | 123e4567-e89b-12d3-a456-426614174000 |
| qrStatus | string | Estado actual del QR | ACTIVE |
| lastModifiedDateTime | datetime | Fecha y hora en la que se modificación el estado del QR | 2026-01-16T01:51:46.706Z |
| **error** | **object** | | |
| code | integer | Código de error generado (cero si no hay errores) | 1005 |
| message | string | Mensaje de error (vacío si no hay errores) | Fallas técnicas |
```json Response Exitoso theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-16T01:51:46.706Z",
"status": "SUCCESS",
"statusCode": "200",
"statusDesc": "string"
},
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"qrStatus": "INACTIVE",
"lastModifiedDateTime": "2026-01-16T01:51:46.706Z"
}
}
```
```json Response Error 400 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "400",
"statusDesc": "Bad Request"
},
"error": {
"code": "1013",
"message": "El contenido enviado no es válido o está mal cifrado"
}
}
```
```json Response Error 500 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "500",
"statusDesc": "Internal Server Error"
},
"error": {
"code": "1005",
"message": "Fallas Técnicas"
}
}
```
# Como consultar un QR
Source: https://transfiya.me/1-85/directorio-federado/tecnologia-de-acceso-qr/como-consultar-un-qr
### Especificaciones para actualización de estado del QR
Las Entidades Participantes pueden consultar un QR.
```json theme={null}
Dominio: https://bank.apihub.crt.achcolombia.com.co
```
```json theme={null}
GET /ach/bk/v1/money-movement/qr/{id}
```
NOTA: Enviar el ID del QR (el que se entregó en la generación del mismo) en el path
### Campos de Salida
| **Campo** | **Tipo** | **Descripción** | **Formato** |
| -------------------- | ---------- | ----------------------------------------------------------------------- | ------------------------------------ |
| **meta** | **object** | | |
| requestId | uuid | Código generado por la entidad participante para identificar el paquete | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| timestamp | datetime | Fecha y hora de la respuesta a la solicitud de generación del código QR | 2025-12-23T18:16:35.099Z |
| status | enum | Estado de la respuesta. SUCCESS, ERROR | SUCCESS |
| statusCode | string | Código HTTP de la respuesta | 200 |
| statusDesc | string | Descripción del código HTTP | OK |
| **data** | **object** | | |
| id | string | Identificador único del QR en el sistema | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| qrCode | string | Cadena de texto que contiene el código QR generado en formato EMVCO | Cadena TLV |
| creationDateTime | datetime | Fecha y hora en la que se generó el QR | 2025-12-23T18:16:35.099Z |
| qrStatus | string | Estado actual del QR | PAGADO |
| duration | integer | Vigencia del QR. Tiempo durante el cual el QR es válido | 60 |
| expirationDateTime | datetime | Fecha y hora de expiración del QR (ISO 8601, UTC-0 con “Z”) | 2025-12-23T18:16:35.099Z |
| lastModifiedDateTime | datetime | Fecha y hora en la que se modificó el estado del QR | 2025-12-23T18:16:35.099Z |
| imageB64 | string | Imagen del QR en Base 64 | Binario del QR en Base 64 |
| **error** | **object** | | |
| code | integer | Código de error generado (cero si no hay errores) | 1005 |
| message | string | Mensaje de error (vacío si no hay errores) | Fallas técnicas |
### Campos de Salida:
```json Response Exitoso theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-16T01:51:46.706Z",
"status": "SUCCESS",
"statusCode": "string",
"statusDesc": "string"
},
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"qrCode": "00020101021126320014CO.COM.ACH.LLA0510000169664749250014CO.COM.ACH.RED0103ACH5303170540410005802CO5913Julián Suarez6006Bogota610611405662110701008020080270016CO.COM.ACH.CANAL0103POS81250015CO.COM.ACH.CIVA01020382230014CO.COM.ACH.IVA0101083240015CO.COM.ACH.BASE0101084250015CO.COM.ACH.CINC01020385230014CO.COM.ACH.INC0101090590016CO.COM.ACH.TRXID0135CO.COM.ACH.RED34E81961EB12640F5B2D191860014CO.COM.ACH.SEC01648f66c1e3a2e6b0ee5358cd566f935eec8d30efb218f33aa17b316542fe2ab1b06304ACEA",
"creationDateTime": "2026-01-16T01:51:46.706Z",
"qrStatus": "ACTIVE",
"duration": 60,
"expirationDateTime": "2026-01-16T01:51:46.706Z",
"imageB64": "iVBORw0KGgoAAAANSUhEUgAAAUQAAAFECAYAAABf6kfGAAAAAklEQVR4AewaftIAABl5SURBVO3BQW7A1pLAQFLw/a/MCbTq1QMEyU7+oKvsH6y11uJirbXW7WKttdbtYq211u1irbXW7WKttdbtYq211u1irbXW7WKttdbtYq211u1irbXW7WKttdbtYq211u1irbXW7WKttdbtYq211u2Hl1T+UsWk8kTFpDJVPKHyRMWk8kTFpDJVT"
}
}
```
```json Response Error 400 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "400",
"statusDesc": "Bad Request"
},
"error": {
"code": "1013",
"message": "El contenido enviado no es válido o está mal cifrado"
}
}
```
```json Response Error 500 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "500",
"statusDesc": "Internal Server Error"
},
"error": {
"code": "1005",
"message": "Fallas Técnicas"
}
}
```
# Como iniciar una transferencia Bre-b con QR
Source: https://transfiya.me/1-85/directorio-federado/tecnologia-de-acceso-qr/como-crear-una-transaccion-bre-b-con-qr
El presente documento tiene como proposito orientar a las Entidades Participantes en el proceso necesario para iniciar una transaccion **Bre-b** a partir de la lectura de un **codigo QR**. Aqui se describen los pasos, requisitos tecnicos, consideraciones operativas y mejores practicas que garantizan una experiencia de pago eficiente, segura y estandarizada.
Esta guia busca asegurar que todas las Entidades involucradas comprendan plenamente el flujo de la transaccion, los elementos obligatorios contenidos en el QR y las validaciones que deben realizarse para completar exitosamente la operacion. Al seguir estas indicaciones, las Entidades Participantes podrán integrar y ejecutar el proceso Bre-b de forma consistente, manteniendo altos niveles de calidad en el servicio ofrecido a sus usuarios.
### Flujo general del proceso
### Paso a paso
1. **Escanear el QR:** La Entidad Participante origen, a través de la UX deberá presentar la opción para escanear códigos QR a sus usuarios.
2. **Lectura de QR:** Una vez realizado el escaneo, la Entidad participante obtiene la cadena TLV y debe enviar esta cadena al servicio expuesto por Transfiya para obtener un objeto JSON estructurado y legible con los datos del QR. El detalle de este proceso podrá ser consultado en el apartado [Cómo leer un QR - Transfiya Guide](https://transfiya.me/1-85/directorio-federado/tecnologia-de-acceso-qr/como-leer-un-qr).
3. **Resolución de llave:** Con los datos obtenidos en la respuesta al servicio de lectura, la Entidad Participante origen debe identificar el valor de la llave y efectuar el proceso de resolución a través del servicio expuesto por Transfiya, como se detalla en [Cómo resolver llaves - Transfiya Guide](https://transfiya.me/es/v1.104/directory/guides/how-to-resolve-keys).
A continuación se muestra el dato que la entidad debe extraer del JSON para obtener la llave.
```json theme={null}
{
"26": {
"id": "26",
"name": "Merchant Account Information",
"len": 30,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.LLA",
"rawData": "CO.COM.ACH.LLA"
},
"02": {
"id": "02",
"name": "Merchant ID",
"len": 16,
"data": "0099545147", // Dato correspondiente al valor de llave
"rawData": "0099545147"
}
},
```
El JSON es un fragmento de la respuesta enviada por Transfiya al consumo del servicio de lectura.
Dentro del campo "26", se podrá encontrar entre otros:\
Objeto 2 -> "name" (Tipo de llave)\
"data" (Valor de llave). Este es el que se deberá mapear para posteriormente procesar la resolución.
4. **Mapear datos adicionales del QR:** El JSON con los datos del QR, contienen información necesaria para poder iniciar la transferencia en Transfiya. En el siguiente cuadro se detallan los campos obligatorios para crear la transacción en Bre-b.
| **Tag (JSON)** | **Nombre** | **Descripción** |
| -------------- | --------------------------- | -------------------------------------------------------------------------------------- |
| 54 | Transaction Amount | El cual contiene el monto del QR (si su valor es > a 0.00) |
| 90 | Unreserved Templates (IdQR) | Contiene el ID de QR generado por el SPBVI o la Entidad Participante que generó el QR. |
```json theme={null}
},
"54": {
"id": "54",
"name": "Transaction Amount",
"len": 4,
"data": "1000.00", // Valor a mapear
"rawData": "1000.00"
},
"90": {
"id": "90",
"name": "Unreserved Templates",
"len": 43,
"data": {
"00": {
"id": "00",
"name": "Globally Unique Identifier",
"len": 16,
"data": "CO.COM.ACH.TRXID", //Valor a Mapear y concatenar con "data" del subtag 01
"rawData": "CO.COM.ACH.TRXID"
},
"01": {
"id": "01",
"name": "Payment System specific",
"len": 19,
"data": "6A1AB61E0E8ADAB4BB9", //Valor a Mapear y concatenar con "data" del subtag 01
"rawData": "6A1AB61E0E8ADAB4BB9"
}
},
```
Los demás datos contenidos en el JSON, podrán ser usados por las Entidades Participantes para los fines que consideren pertinentes.
El JSON es un fragmento de la respuesta enviada por Transfiya al consumo del servicio de lectura.
A futuro Bre-b podrá solicitar la inclusión de más campos en la mensajería para el procesamiento transaccional.
6. **Iniciar la transacción:** Con los datos obtenidos de la resolución de la llave (signer handle), Transaction Amount y el IdQR. La Entidad Participante está lista para iniciar la transacción, para esto deberá invocar el servicio expuesto por Transfiya. Se relaciona una tabla con la homologación de los campos y un ejemplo que sirve como guia.
| **Transfer** | **QR Tag (JSON)** | **Descripción** |
| ----------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| source | N/A | Signer handle del usuario originador de la transacción. |
| target | N/A | Signer handle obtenido de la resolución de la llave destino. |
| symbol | N/A | Valor por defecto |
| amount | 54 | Valor de la transación. Si en el QR, el tag 54 (amount) tiene un valor diferente a 0.00. Debe enviarse el valor de dicho campo. De lo contrario, se debe enviar el valor que ingresa el usuario dentro de la UX durante la iniciación de la transacción. |
| labels | N/A | Objeto |
| description | N/A | Descripción de la transacción |
| domain | N/A | Dominio de Transfiya. |
| type | N/A | Describe al tipo de transacción a procesar. Para este caso es SENDMOL |
| sourceChannel | N/A | Corresponde al canal que se usa para generar a transferencia |
| tx\_id | N/A | Corresponde al tx\_id asignado por la Entidad origen, debe ser generado y enviado según las especificaciones de Bre-b |
| idQr | 90 | Corresponde al id QR asignado por la Entidad que generó el QR. La construcción de este campo debe ser la concatenación del valor del campo "data" (subtag 00) y el valor del campo "data" (subtag 01). Ejemplo: CO.COM.ACH.TRXID6A1AB61E0E8ADAB4BB9 |
| received | N/A | Marca de tiempo regulatoria |
| dispatched | N/A | Marca de tiempo regulatoria |
| deviceFingerPrint | N/A | Objeto con la información del dispositivo que genera la tx. Este objeto debe ser capturado con la respectiva librearía o en su defecto, como la Entidad lo haga. |
### Request creación de transferencia
```json theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"symbol": "$tin",
"amount": "100.00",
"labels": {
"description": "Payment for lunch",
"domain": "tin",
"type": "SENDMOL",
"sourceChannel": "APP",
"tx_id": "20250114890915944TFY123456789012345",
"idQr":"CO.COM.ACH.TRXID6A1AB61E0E8ADAB4BB9",
"received": "2025-01-14T20:40:57.322-05:00",
"dispatched": "2025-01-14T20:40:58.322-05:00",
"deviceFingerPrint": {
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"country": "Colombia",
"city": "Bogotá",
"mobileDevice": "990000862471854",
"SIMCardId": "8991101200003204510",
"model": "Huawei Mate 20 Pro",
"operator": "Bharti Airtel Limited"
}
}
}' "/v1/transfer"
```
7. **Confirmación de la creación de transacción y procesamiento:** Una vez la Entidad Participante origen solicite la inciación de transferencia en Transfiya. El sistema ejecuta el procesamiento de manera habitual y que las Entidades ya conocen. El detalle podrá ser consultado y revisado en [Como enviar a Bre-B - Transfiya Guide](https://transfiya.me/es/v1.104/transfers-mol/guides/how-to-send-mol).
8. **Acreditación al usuario receptor:** La Entidad Participante receptora una vez reciba la instrucción de crédito desde Transfiya, deberá ejecutar el proceso habitual para acreditación en el usuario receptor. El flujo se detalla en [Como acreditar al beneficiario - Transfiya Guide](https://transfiya.me/es/v1.104/transfers-mol/guides/how-to-credit-receiver).
# Cómo generar un QR
Source: https://transfiya.me/1-85/directorio-federado/tecnologia-de-acceso-qr/como-generar-un-qr
### Especificaciones para generación de QR
Las Entidades Participantes pueden habilitar la generación de códigos QR a través de Transfiya. Para su implementación, deberán tener en cuenta los siguientes campos, cumpliendo con el estándar EMVCo y los lineamientos del Banco de la República.
Es posible generar códigos QR estáticos o dinámicos, tanto para personas naturales como para empresas, utilizando los siguientes campos de entrada.
```json theme={null}
Dominio: https://bank.apihub.crt.achcolombia.com.co
```
```json theme={null}
POST /ach/bk/v1/money-movement/qr
```
### Campos de Entrada:
| **Campo** | **Tipo** | **Descripción** | **Formato** | **Obligatorio** |
| ---------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------ | --------------- |
| **meta** | **object** | | | **SI** |
| requestId | uuid | Código generado por la entidad participante para identificar la solicitud | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | SI |
| timestamp | time | Fecha y hora de la solicitud de generación del código QR | 2025-12-23T18:16:35.099Z | SI |
| version | string | Versión del esquema. Enviar siempre el valor **"1.0"** | 1.0 | SI |
| **data** | **object** | | | **SI** |
| movementType | enum | Tipo de operación. Valores válidos: **QR(Generación, Atualización de estado), QRVALIDATE(Validación), QRPARSER(Lectura)** | QR | SI |
| **amountInformation** | **object** | | | **SI** |
| amount | decimal | Valor de la transacción con dos decimales, Este campo es opcional al generar el QR **ESTATICO**. Si no se envía, el usuario podrá ingresar el valor a pagar. Si se envía, debe ser mayor a 0 y el QR será de tipo **HÍBRIDO**. | 100.00 / 100.85 / 100.05 / 200.50 | SI |
| currency | string | Código de moneda. Enviar siempre **"COP"** | COP | SI |
| **target** | **object** | | | **SI** |
| personType | enum | Tipo de persona destino. Valores válidos: **NATURAL, LEGAL** | NATURAL | SI |
| merchantCode | string | Código del comercio destino. Para persona jurídica según estándar ISO 18245
Si aliasValue y aliasType están vacios, este campo es obligatorio. | Min 1 - Máx 20 | NO |
| fullName | string | Nombre completo del destino cuando es persona natural | Min 1 - Máx 25 | NO |
| businnesName | string | Nombre del comercio o razón social cuando personType = "LEGAL" | Min 1 - Máx 25 | NO |
| **location** | **object** | | | **SI** |
| city | string | Código de ciudad asociada a la persona, comercio o negocio (Código Divipola - DANE) | Min 1 - Máx 20 | SI |
| postalCode | string | Código postal de la persona, comercio o negocio | Min 1 - Máx 10 | SI |
| **alias** | **object** | | | **SI** |
| aliasType | enum | Tipo de llave del destino. Valores válidos: **PHONE, ALPHANUM, EMAIL, NRIC, MERCHANTCODE** | PHONE | NO |
| aliasValue | string | Valor de la llave de identificación. Según el formato regulado Bre-b | Min 1 - Máx 92 | NO |
| **purposeInformation** | **object** | | | **SI** |
| transactionPurpose | enum | Motivo de la transacción. Valores válidos: **COMPRAS, ANULACIONES, TRANSFERENCIAS, RETIRO, RECAUDO, RECARGAS, DEPOSITO** | TRANSFERENCIAS | SI |
| **useCaseInformation** | **object** | | | **SI** |
| qrType | enum | Tipo de QR. Valores válidos: **STATIC, DYNAMIC** | DYNAMIC | SI |
| categoryCode | string | Categoría del comercio destino
Si el campo personType = "LEGAL", el valor de este campo debe ser diferente de 0000 y va de acuerdo al estándar ISO 18245. | Min 1 - Máx 4 | SI |
| terminal | string | Terminal asociada al comercio destino | Min 1 - Máx 25 | SI |
| vat | decimal | Valor del IVA con dos decimales | Min 1 - Máx 13 | SI |
| vatBase | decimal | Base del IVA con dos decimales | Min 1 - Máx 13 | SI |
| tax | decimal | Valor del impuesto INC con dos decimales | Min 1 - Máx 13 | SI |
| channel | enum | Canal de origen. Valores válidos: **IM, POS, APP, ECOMM, MPOS, ATM, CB, OFC** | POS | SI |
### Tabla de canales:
| Código | Descripción |
| ------ | --------------------- |
| IM | POS Manual |
| POS | POS / PINPAD |
| APP | Banca Móvil |
| ECOMM | Internet |
| MPOS | POS / PINPAD |
| ATM | Cajero Automático |
| CB | Corresponsal Bancario |
| OFC | Oficina |
### Reglas para los valores de tipo decimal
**Ejemplos de valores permitidos:**
A: 1000.00
B: 1000.85
C: 1000.05
**Reglas para el dato:**
* Valor con dos (2) cifras decimales unicamente
* Separador decimal el carácter punto (.)
* Valores mayores o igual a cero
* No puede ser NULL
```json Request Persona natural theme={null}
{
"meta": {
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-12-23T18:16:35.099Z",
"version": "1.0"
},
"data": {
"movementType": "QR",
"amountInformation": {
"amount": "0.00",
"currency": "COP"
},
"target": {
"personType": "NATURAL",
"fullName": "Carlos Alberto Valderrama",
"location": {
"city": "11001",
"postalCode": "110221"
},
"alias": {
"aliasType": "PHONE",
"aliasValue": "3002627700"
}
},
"purposeInformation": {
"transactionPurpose": "COMPRAS"
},
"useCaseInformation": {
"qrType": "STATIC",
"categoryCode": "0000",
"terminal": "TERM-001",
"vat": "0.00",
"vatBase": "0.00",
"tax": "0.00",
"channel": "POS"
}
}
}
```
```json Request Persona jurídica theme={null}
{
"meta": {
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-12-23T18:16:35.099Z",
"version": "1.0"
},
"data": {
"movementType": "QR",
"amountInformation": {
"amount": "0.00",
"currency": "COP"
},
"target": {
"personType": "LEGAL",
"businessName": "Papelería Mis Papeles",
"location": {
"city": "11001",
"postalCode": "110221"
},
"alias": {
"aliasType": "MERCHANTCODE",
"aliasValue": "22445577"
}
},
"purposeInformation": {
"transactionPurpose": "TRANSFERENCIAS"
},
"useCaseInformation": {
"qrType": "STATIC",
"categoryCode": "0000",
"terminal": "TERM-001",
"vat": "0.00",
"vatBase": "0.00",
"tax": "0.00",
"channel": "POS"
}
}
}
```
### Campos de Salida
| **Campo** | **Tipo** | **Descripción** | **Formato** |
| ------------------ | ---------- | ------------------------------------------------------------------------------- | ------------------------------------ |
| **meta** | **object** | | |
| requestId | uuid | Código generado por la entidad participante para identificar el paquete | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| timestamp | datetime | Fecha y hora de la respuesta a la solicitud de generación del código QR | 2025-12-23T18:16:35.099Z |
| status | enum | Estado de la respuesta. Valores: **SUCCESS, ERROR** | SUCCESS |
| statusCode | string | Código HTTP de la respuesta | 200 |
| statusDesc | string | Descripción del código HTTP | OK |
| **data** | **object** | | |
| id | uuid | Identificador único del QR en el sistema | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| qrCode | string | Cadena de texto en formato EMVCo (TLV) que contiene el código QR generado | Cadena TLV |
| creationDateTime | datetime | Fecha y hora en la que se generó el QR | 2025-12-23T18:16:35.099Z |
| qrStatus | enum | Estado actual del QR: **HABILITADO, INHABILITADO, CANCELADO, PAGADO, EXPIRADO** | HABILITADO |
| movementType | enum | Tipo de operación. Valores: **QR, QRVALIDATE, QRPARSER** | QR |
| duration | integer | Vigencia del QR. Indica el tiempo durante el cual el QR es válido | 5 |
| expirationDateTime | datetime | Fecha y hora de expiración del QR (ISO 8601, UTC-0 con “Z”) | 2025-12-23T18:16:35.099Z |
| imageB64 | string | Imagen del QR en base 64 | Binario de la imagen |
| **error** | | | |
| code | integer | Código del error (cero si no hay errores) | 1005 |
| message | string | Mensaje de error (vacío si no hay errores) | Fallas técnicas |
```json Response Exitoso theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "SUCCESS",
"statusCode": "200",
"statusDesc": "OK"
},
"data": {
"id": "fcc765f9-8e2b-4251-86e0-5fead7f3f0fe",
"qrCode": "00020101021126320014CO.COM.ACH.LLA0510000169664749250014CO.COM.ACH.RED0103ACH5303170540410005802CO5913Julián Suarez6006Bogota610611405662110701008020080270016CO.COM.ACH.CANAL0103POS81250015CO.COM.ACH.CIVA01020382230014CO.COM.ACH.IVA0101083240015CO.COM.ACH.BASE0101084250015CO.COM.ACH.CINC01020385230014CO.COM.ACH.INC0101090590016CO.COM.ACH.TRXID0135CO.COM.ACH.RED34E81961EB12640F5B2D191860014CO.COM.ACH.SEC01648f66c1e3a2e6b0ee5358cd566f935eec8d30efb218f33aa17b316542fe2ab1b06304ACEA",
"creationDate": "2026-01-16T20:05:18.494Z",
"qrStatus": "ACTIVE",
"movementType": "QR",
"duration": "0",
"expirationDate": "2026-01-16T20:05:18.494Z",
"imageB64": "iVBORw0KGgoAAAANSUhEUgAAAUQAAAFECAYAAABf6kfGAAAAAklEQVR4AewaftIAABl5SURBVO3BQW7A1pLAQFLw/a/MCbTq1QMEyU7+oKvsH6y11uJirbXW7WKttdbtYq211u1irbXW7WKttdbtYq211u1irbXW7WKttdbtYq211u1irbXW7WKttdbtYq211u1irbXW7WKttdbtYq211u2Hl1T+UsWk8kTFpDJVPKHyRMWk8kTFpDJVTCpTxaRyUjGpTBWTylQxqUwVk8pUMamcVEwqU8WkclLxm1SmiknljYpJZaqYVE4qJpWpYlL5SxVvXKy11rpdrLXWul2stda6/fCxii+pfEnlCZWp4qRiUnmi4omKJ1S+pHKiMlWcVEwqU8WJylTxRMWJyhMVJxWTylRxojJVTCpPVEwqJxVPVHxJ5UsXa621bhdrrbVuF2uttW4//DKVJyqeqJhUTiomlZOKSWWqmFSmiknlDZWTijcqTipOVE5Unqh4Q+Wk4kRlqphU3lCZKk5UpoonKiaVk4rfpPJExW+6WGutdbtYa611u1hrrXX74X+cyknFScUbKlPFpPKEylRxUnFSMalMFZPKVHGi8kTFEypfqnii4qRiUplUpoqpYlKZKqaK31QxqZxU/H9ysdZa63ax1lrrdrHWWuv2w/+4ihOVqeJEZar4UsWkMlU8ofKGyhsVJyonKlPFScWXVL5UMalMKlPFVHGiMlWcVJxUnFRMKpPKVPG/7GKttdbtYq211u1irbXW7YdfVvGXVKaKN1SmihOVE5XfVPGEylTxhMobFZPKVPGXKp5QmVSeUJkqTipOVKaKSWWqOFGZKr5U8V9ysdZa63ax1lrrdrHWWuv2w8dU/pLKVDGpTBWTylQxqZyoTBWTylQxqZyoTBWTyonKVPGEylRxUjGpnKhMFZPKVDGpTBWTylTxhMpUcVIxqUwVk8qJylQxqUwVk8pUMalMFU+oTBUnKv9lF2uttW4Xa621bhdrrbVu9g/+h6m8UfEllaliUnmiYlI5qXhC5aRiUjmpOFGZKiaVL1WcqEwVT6hMFZPKVDGpTBVvqEwVJypvVPx/crHWWut2sdZa63ax1lrr9sNLKlPFpHJSMak8UTGpTBWTyhMqU8VfUnlC5Y2KN1ROKiaVJyomlaniDZX/EpWTiqliUjmpmFSeUJkqJpWp4kRlqphUTireuFhrrXW7WGutdbtYa611++GlikllqphUJpWp4ksqX1L5UsWJyhMVT6icqJxUPKHypYoTlZOKSWWq+JLKVDGpTBWTyonKlyomlanipGJSmSqeqPhNF2uttW4Xa621bhdrrbVu9g9eUHmi4gmVNyomlZOKE5Wp4g2VqeJEZao4UTmpmFSmikllqjhRmSomlaniROWJihOVqeIJlZOKJ1TeqHhCZao4UTmpeEJlqjhROal442KttdbtYq211u1irbXW7YeXKiaVqeJE5aRiUpkqJpVJZar4kspJxZcqJpWp4ksqU8WJyhMVf0llqnijYlKZVKaKSeXfVDGpTBVTxaRyojJVPKFyUvGli7XWWreLtdZat4u11lq3H/6YylRxojJVnFR8SWWqeEPlCZWpYqqYVKaKE5WpYlKZVKaKqWJSeUPlpOKJiknlpOKJihOVqeJE5aRiUjmp+FLFl1SmihOVqeKNi7XWWreLtdZat4u11lq3H/5YxaRyUjGpTBVPqLyhMlWcqEwVJypfUpkqpopJ5aRiUpkqpooTlaliqphUJpWpYlKZKk4qvqTyhMpJxRMVk8pU8YTKVDGpnKi8ofKbLtZaa90u1lpr3S7WWmvd7B/8IpW/VDGpTBWTyknFGyonFScqJxWTylQxqZxUTCpPVEwqU8Wk8kTFGypTxYnKScWkMlVMKlPFGypTxaTyRsWkMlWcqJxUPKEyVXzpYq211u1irbXW7WKttdbth4+pfKliUpkqvlQxqUwVk8oTFZPKScWkMqn8l6hMFZPKScWkcqIyVUwqb1ScqLyh8kbFpHJSMamcqPwmlZOKqWJSmSreuFhrrXW7WGutdbtYa611s3/wIZWTiknliYpJZao4UXmi4kRlqjhRmSpOVH5TxRMqT1S8oTJVnKhMFZPKVDGpTBVPqJxUTCpPVEwqU8Wk8kTFpDJVnKhMFZPKScWkclLxpYu11lq3i7XWWreLtdZatx9eUpkqJpUnKk5U3qiYVKaKSeUNlROVL1WcqEwqU8UbFZPKScWkcqIyVUwVX1KZKk4qTlSmiknlRGWqeKPiCZWTit9U8Zsu1lpr3S7WWmvdLtZaa93sH7ygclIxqXypYlKZKn6TyknFGyonFU+ovFHxJZWpYlKZKk5UpoovqUwVk8oTFScqJxWTylQxqZxUTCpTxRMqU8WJylTxly7WWmvdLtZaa90u1lpr3X74ZSpTxRsqb6i8UfGGyhsVk8obFW+onFRMKlPFScUbKlPFpDJVTCpPVJyoTCpTxUnFpPKbKt6oeKLiRGWq+NLFWmut28Vaa63bxVprrdsPH6uYVE5UpopJZao4qZhUpoonVJ6omFSmikllqphUJpWpYlI5qZhUnqg4qZhUTlTeqJgqTlSmiknlCZWpYlJ5o+KJikllqjhRmSpOVL5UMalMFb/pYq211u1irbXW7WKttdbthz+mMlVMKlPFpPJExaTyRMWXVKaKSeU3qUwVk8qXKn6TyhMVJxVPqEwqJxWTyqQyVZxUnFScqDyhMlVMKn9JZap442KttdbtYq211u1irbXW7Yf/mIpJ5aRiUplUnqiYVE4qJpWTiicqnqg4UXlDZao4UZkqJpWpYlI5qThRmVR+U8UTFZPKpPJExRMVJypTxRsVJypTxUnFly7WWmvdLtZaa90u1lpr3X54qWJSOamYVE4qTlS+pPKEylQxqUwqU8UTKicVJxV/qeIJlZOKJyomlZOKE5WpYlL5UsUTKlPFEypTxRsVk8pU8V9ysdZa63ax1lrrdrHWWutm/+BDKlPFpPKXKk5UpopJ5aTiCZWp4gmV31QxqUwVJypTxaRyUjGpTBVPqEwVk8qXKk5UpooTlaniDZWp4g2VL1VMKlPFpDJVvHGx1lrrdrHWWut2sdZa6/bDSyonKlPFpDJVPKFyojJV/CaVqWKqmFROKqaKSWWqeEJlUnmj4omKSeUJlZOKJyqeUDlR+U0qU8VJxRsqJxVPqEwqJypTxZcu1lpr3S7WWmvdLtZaa91++FjFl1SmipOKN1ROKiaVJ1SeUJkqnlCZKp6oeELlCZWpYlKZVE4qTlSeUJkqnqj4L1M5qZgqJpUTlanijYpJZap442KttdbtYq211u1irbXW7YeXKiaVk4onKp5QOan4TRVPVPymiicqJpWp4t9UMamcqEwVk8pJxW9SmSqeqHhC5QmVNyp+U8WXLtZaa90u1lpr3S7WWmvdfnhJ5aTiCZU3Kt6oeKLiiYpJZap4Q+U3qZxUnKhMFZPKVDGpTBWTylQxqZyofEllqjhRmSomlZOKSeWk4g2VSeWNiidUpoo3LtZaa90u1lpr3S7WWmvd7B98SOWk4ksqU8WJylRxovKlihOVqeJE5aRiUjmpmFROKp5QOan4N6mcVJyoTBWTylRxonJSMalMFU+oPFExqTxRcaLyRMUbF2uttW4Xa621bhdrrbVu9g9eUJkqJpWTihOVk4o3VL5U8SWVqeIJlScqvqQyVZyovFFxovJExaRyUjGpTBUnKlPFpDJVTCpTxYnKScVfUpkq/tLFWmut28Vaa63bxVprrdsPL1V8SWWqOFH5UsWkMlU8oXJScVIxqUwVk8pUMalMFW+oTBUnKicVk8pUcaJyUjGpPFHxhspUcaJyovKEyknFicpvqvg3Xay11rpdrLXWul2stda62T/4kMpU8YbKVPFvUpkqJpWpYlL5UsUTKlPFpDJVTCpPVJyoTBWTylQxqbxR8YbKVHGiclLxb1J5ouIJlS9VfOlirbXW7WKttdbtYq211s3+wYdUpopJZaqYVKaKSWWqeEPliYpJ5Y2KSWWq+EsqU8WXVKaKSWWq+EsqU8Wk8pcqJpWTijdUpopJ5aRiUjmpmFSmihOVqeKNi7XWWreLtdZat4u11lq3H/5lKicqU8UTKlPFExVvVEwqk8oTKlPFpPJGxaTyRMWkMlWcVEwqU8Wk8kbFVDGpvFExqUwVk8pJxaRyojJVnFS8ofJGxRMVX7pYa611u1hrrXW7WGutdfvhYxWTyhsVk8pUMamcqEwVk8qJylRxojJVnKhMKlPFpDJVfKliUpkq3lCZKqaKk4q/VDGpvKHyhMqJylQxqUwVv6liUnlC5aTiSxdrrbVuF2uttW4Xa621bvYPXlCZKp5QmSomlaliUnmi4g2VJyqeUDmpeELliYpJZao4UXmi4kRlqnhCZao4UZkqTlSeqPhNKicVk8pUMak8UTGpTBVfUpkq3rhYa611u1hrrXW7WGutdbN/8CGVNypOVE4qJpWTiknljYpJ5YmKE5WpYlKZKp5QmSomlScqJpWp4i+pfKliUnmj4g2VqWJS+VLFpDJVnKicVEwqU8WXLtZaa90u1lpr3S7WWmvd7B98SOWkYlJ5omJSOak4UZkqJpV/U8WJyknFb1I5qfiSylTxhMpJxaQyVXxJ5aTiROVLFScqJxVPqLxR8aWLtdZat4u11lq3i7XWWrcfPlYxqZxUPKEyVZyoTBVTxW+qmFSmiidU3lCZKk5UpoqTihOVNypOVE4qTlTeUJkqTipOVE4qJpWp4jdVnKhMFVPFpHJS8Zsu1lpr3S7WWmvdLtZaa91++I9ROamYVKaKqeJEZap4ouINlZOKk4onKp6omFSmiknliYr/kooTlaliqvhNFU+onFRMKlPFVHGiMlX8L7lYa611u1hrrXW7WGutdfvhJZWpYqqYVKaKk4qTikllqphUTlROKiaVqeKJihOVqWJSOamYVKaKSeWk4r9EZap4QmWqmFSmihOVqWJSOamYKp6omFSmiknlCZUnVKaK/7KLtdZat4u11lq3i7XWWrcfXqo4UXmiYlI5qThReaJiUplUpopJ5aTiRGWqmFSmihOVL6mcVEwqT6g8UfFGxUnFicoTFW+onFRMFX+pYlJ5o+IvXay11rpdrLXWul2stda62T94QWWqeELlpGJS+U0Vk8pUcaIyVXxJ5aTiROWk4kTlN1W8oTJVnKhMFZPKVPGEylTxhsoTFZPKGxUnKicVk8pUcaIyVXzpYq211u1irbXW7WKttdbth4+pTBWTyhMqT1RMKlPFicpU8SWVqWJSeUPlL1VMKlPFpHKiMlU8UfGGyonKScUTKicVU8WkcqIyVZyoTBUnKk+oPKEyVfymi7XWWreLtdZat4u11lq3H16q+FLFEyonFScqU8WkMlVMKlPFlypOVKaKJ1TeUJkqTiqeUHmjYlI5qXhC5Y2KJ1SeqHii4kTlpOIJlZOKSeWk4o2LtdZat4u11lq3i7XWWrcf/ljFpHKiMlWcqDxRMalMFU+oTBUnKlPFpDJVPKEyVZyoTBVPqJxUTCpPVEwqT1RMKicqU8WJylRxonJSMVWcqEwqJxUnKm+oTBUnKv+mi7XWWreLtdZat4u11lq3H15SeaLiiYonKiaVJypOVJ5QeaNiUnmi4g2VqeJEZaqYVKaKE5VJ5QmVqeKJiicqTlSmihOVk4qp4g2VL1W8UfGXLtZaa90u1lpr3S7WWmvdfvhYxaTyhMobKlPFEypTxW+qmFSmiidU3qiYVCaVqeINlaliqnhD5QmVN1ROKr6kMlWcqEwVU8WJyonK/7KLtdZat4u11lq3i7XWWrcfPqZyonJS8YbKpDJVfKliUjmp+E0Vk8pUMam8oTJVTConFU+oTBVvVJyonFRMKk+onFRMKicq/6aKJ1SeUJkqvnSx1lrrdrHWWut2sdZa6/bDSxVPqEwVJypPVEwqJypTxUnFpDJVnKhMFScqU8WJylQxqTxRcaLyRMWk8psqTlSmiqnijYpJZaqYVJ6oeEPlpGKqmFQmlanipGJSOan4TRdrrbVuF2uttW4Xa621bj98TGWqmCpOVKaKE5UnVN5QmSomlSdUTiomlaliqnhDZar4SxWTylTxhMpUMVVMKlPFicpU8UbFpDJVPKEyVUwVk8qk8kTFEyr/JRdrrbVuF2uttW4Xa621bvYP/kNUnqh4Q2WqmFSmiknliYpJZao4UZkqvqRyUvGEyknFicobFScqU8WJylTxhsoTFZPKVPGEyhsVJypTxaQyVZyoTBVfulhrrXW7WGutdbtYa611++EllaniRGWqmCqeUDmpmFSmiknlROWkYlJ5Q+VEZao4UZkq3lA5qZhUTlROKp5QmSqmihOVJ1SmipOKSeVE5QmVqWKqOFF5o+INlaniN12stda6Xay11rpdrLXWuv3wUsWkclIxqbxRMalMKlPFScWk8psqJpWpYlI5UTmpmFSmiknlSxWTylQxqZyoTBVvqEwVJypTxW+q+C9TOamYKiaVqeJEZap442KttdbtYq211u1irbXWzf7BH1J5omJSmSpOVH5TxaRyUjGpvFExqZxUTCpfqphUTipOVE4qJpU3Kk5UTiomlaniDZWTihOVqeIJlS9VTCpPVHzpYq211u1irbXW7WKttdbN/sELKicVT6j8popJ5YmKSWWqmFROKk5UpoovqUwVJypTxaRyUnGiMlWcqEwVJypTxaQyVZyonFRMKlPFicpJxYnKVDGpnFRMKk9UTCpTxYnKScWXLtZaa90u1lpr3S7WWmvdfvhYxaTyRMWJyl+qmFROVE4qJpWpYqqYVN6oeELliYpJ5URlqphUpooTlaliqjipOFE5qXhC5Q2VqeKJiicqJpWp4gmVqWKqOFGZKt64WGutdbtYa611u1hrrXX74WMqJxVPqJxUTCpTxaQyVbxRcaLyhMoTFU+onKhMFScqJxWTylRxUjGpTBWTyhMqU8WkclJxojJVnKhMFU+oTBUnKlPFpDJVTBUnKlPFpDKpTBWTylTxpYu11lq3i7XWWreLtdZatx9eqnhCZaqYVKaKSWVSeUPlDZWp4omKE5U3VKaKJ1TeUJkqJpWTiqniDZWpYlKZKp5QmSreUHmiYlKZKqaKN1ROKt5QmSomlanijYu11lq3i7XWWreLtdZatx9eUpkqJpU3VKaKSWWqeKNiUpkqJpVJZaqYVKaKL6m8oTJVTCpTxaQyVZxUPKEyVZyoTBVvqJxUnKhMFScVk8pUMalMFScqU8WJylRxovJGxaQyVXzpYq211u1irbXW7WKttdbth5cqTireqJhUpooTlSdUpopJZao4UTlROamYVN5QeaPiCZWTikllqjhRmSomlScqnqg4UZkqJpWpYlKZKiaVJ1SmikllqphU3qiYVE5UporfdLHWWut2sdZa63ax1lrr9sNLKicVk8pUcaIyVTxRMak8oXKiMlVMFZPKScVfqphU/pLKicoTKlPFpDJVnKhMFZPKScWXVKaKE5Wp4qTiSxWTylRxojKpTBVfulhrrXW7WGutdbtYa611++GlijdUpooTlaliUpkqnqiYVL5UMalMKicVk8pUMalMFZPKVHGiMlVMFScqT1S8oTJVnKhMFf9lKlPFVPGEyhMqU8WkMlVMKicVk8qkMlW8cbHWWut2sdZa63ax1lrr9sNLKlPFScWkcqIyVUwqU8VJxYnKVHGi8psqJpUTlROVL6k8UTGpTBWTylTxRMWJyonKExWTylRxojJVTCpvqEwVT1RMKpPKicpJxb/pYq211u1irbXW7WKttdbN/sH/MJWp4kRlqphUpoovqZxUnKicVDyhMlWcqJxUnKhMFU+o/KaKJ1ROKk5UpoonVJ6omFS+VPGEyknFX7pYa611u1hrrXW7WGutdfvhJZW/VPGbKv5SxaQyVbyhMlWcqHxJ5UsVJypTxaTyhMpUcVJxojJVnKhMFVPFEypvVEwqJypTxRsqJxVvXKy11rpdrLXWul2stda6/fCxii+pPKEyVUwVb6hMFU9UTConKlPFpHJS8UTFpDJVPFExqUwqJxUnKk9UTConFW+oTBWTyknFEyonFZPKVPGlit9U8aWLtdZat4u11lq3i7XWWrcffpnKExVPVJyoTBWTylQxqUwVJyr/JpUvVUwqU8UTFScqk8oTFScqJypfqphUTireqJhUJpWpYlKZKiaVE5W/pDJVvHGx1lrrdrHWWut2sdZa6/bD/ziVk4qTikllqphUvlRxonJS8YTKVDGpvKEyVUwqU8UbFScqJxWTylTxhMpU8YbKGxWTyhMqJxUnKlPFpPJExaTypYu11lq3i7XWWreLtdZatx/+n1OZKk4qJpUnKn6TylRxovJGxaRyUjGp/CWVqWJSmVSmijcqJpWTiknlpGJS+VLFpDJVnKhMFU9UnKhMFV+6WGutdbtYa611u1hrrXX74ZdV/KaKSeUNlTdUpopJ5aRiqphUJpU3VKaKk4oTlZOKSeWk4ksVk8qXVJ5QeULlpOIJlZOKSeWk4kRlqjhR+UsXa621bhdrrbVuF2uttW4/fEzlL6lMFU+oTBWTyhsqU8UbFZPKGxWTyhMVJxVPVPylihOVqeKNijdUpooTlaliUjlReUPljYoTlanijYu11lq3i7XWWreLtdZaN/sHa621uFhrrXW7WGutdbtYa611u1hrrXW7WGutdbtYa611u1hrrXW7WGutdbtYa611u1hrrXW7WGutdbtYa611u1hrrXW7WGutdbtYa611+z96XlMp3xigvAAAAABJRU5ErkJggg=="
}
}
```
```json Response Error 400 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "400",
"statusDesc": "Bad Request"
},
"error": {
"code": "1013",
"message": "El contenido enviado no es válido o está mal cifrado"
}
}
```
```json Response Error 500 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "500",
"statusDesc": "Internal Server Error"
},
"error": {
"code": "1005",
"message": "Fallas Técnicas"
}
}
```
# Cómo leer un QR
Source: https://transfiya.me/1-85/directorio-federado/tecnologia-de-acceso-qr/como-leer-un-qr
### Especificaciones para lectura de QR
Las Entidades Participantes pueden habilitar la lectura de código QR a través de Transfiya, por lo cual deberán implementar las siguientes especificaciones:
```json theme={null}
Dominio: https://bank.apihub.crt.achcolombia.com.co
```
```json theme={null}
POST /ach/bk/v1/money-movement/qr
```
### Campos de Entrada
| **Campo** | **Tipo** | **Descripción** | **Formato** | **Obligatorio** |
| ---------------------- | ---------- | ----------------------------------------------------------------------- | ------------------------------------ | --------------- |
| **meta** | **object** | | | **SI** |
| requestId | uuid | Código generado por la entidad participante para identificar el paquete | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | SI |
| timestamp | datetime | Fecha y hora de la solictud de generación del código QR | 2025-12-23T18:16:35.099Z | SI |
| version | string | Versión del esquema, enviar el valor "1.0" | 1.0 | SI |
| **data** | **object** | | | **SI** |
| movementType | enum | Tipo de operación realizada. \[QR, QRVALIDATE, QRPARSER] | QRPARSER | SI |
| **useCaseInformation** | **object** | | | **SI** |
| qrCode | string | Cadena de texto que contiene el código QR generado en formato EMVCO | Cadena TLV | SI |
| | | | | |
```json Request theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:07:31.512Z",
"version": "1.0"
},
"data": {
"movementType": "QRPARSER",
"useCaseInformation": {
"qrCode": "00020101021126580014br.gov.bcb.pix0136d2905f4-4f6e-4e2e-8c7a-5a7c6c3e8f9f520400005303986540615.005802BR5925Fulano de Tal6037Sao Paulo61080540900062070503***63041D3D"
}
}
}
```
### Campos de Salida:
El sistema Transfiya retornará un JSON con los campos contenidos en la cadena TLV. Esta información es necesaria para que la Entidad Participante Origen ejecute el proceso de resolución de llave y la creación de la transacción.
### Campos de Respuesta
| **Campo** | **Tipo** | **Descripción** | **Formato** |
| ------------- | ---------- | ----------------------------------------------------------------------- | ------------------------------------ |
| **meta** | **object** | | |
| requestId | uuid | Código generado por la entidad participante para identificar el paquete | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| timestamp | datetime | Fecha y hora de la respuesta a la solicitud de generación del código QR | 2025-12-23T18:16:35.099Z |
| status | enum | Estado de la respuesta. SUCCESS, ERROR | SUCCESS |
| statusCode | string | Código HTTP de la respuesta | 200 |
| statusDesc | string | Descripción del código HTTP | OK |
| **data** | **object** | | |
| movementType | enum | Tipo de operación a realizar. \[QR, QRVALIDATE, QRPARSER] | QRPARSER |
| Tag number | object | Número del tag EMVCO | 26 |
| id | string | Número del tag EMVCO | 26 |
| name | string | Nombre del campo | Merchant Account Information |
| len | string | Tamaño del campo | 32 |
| data | object | Contenido del tag | - |
| SubTag Number | object | Número del subTag EMVCO | 26 |
| id | string | Número del subTag EMVCO | 01 |
| name | string | Nombre del campo | Global Unique Identifier |
| len | string | Tamaño del campo | 14 |
| data | string | Contenido del tag | CO.COM.ACH.LLA |
| rawdata | string | Fragmento del TLV para este TAG | CO.COM.ACH.LLA |
| rawdata | string | Fragmento del TLV para este TAG | 0014CO.COM.ACH.LLA02103152466845 |
| **error** | **object** | | |
| code | integer | Código de error generado (cero si no hay errores) | 1005 |
| message | string | Mensaje de error (vacío si no hay errores) | Fallas técnicas |
```json Response Exitoso theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "SUCCESS",
"statusCode": "200",
"statusDesc": "OK"
},
"data": {
"movementType": "QRPARSER",
"26": {
"id": "26",
"name": "Merchant Account Information",
"len": 32,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.LLA",
"rawData": "CO.COM.ACH.LLA"
},
"02": {
"id": "02",
"name": "Celular",
"len": 10,
"data": "3152466845",
"rawData": "3152466845"
}
},
"rawData": "0014CO.COM.ACH.LLA02103152466845"
},
"49": {
"id": "49",
"name": "Merchant Account Information",
"len": 25,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.RED",
"rawData": "CO.COM.ACH.RED"
},
"01": {
"id": "01",
"name": "Merchat PAN",
"len": 3,
"data": "ACH",
"rawData": "ACH"
}
},
"rawData": "0014CO.COM.ACH.RED0103ACH"
},
"53": {
"id": "53",
"name": "Transaction Currency",
"len": 3,
"data": "170",
"rawData": "170"
},
"54": {
"id": "54",
"name": "Transaction Amount",
"len": 4,
"data": "8900",
"rawData": "8900"
},
"58": {
"id": "58",
"name": "Country Code",
"len": 2,
"data": "CO (Colombia)",
"rawData": "CO"
},
"59": {
"id": "59",
"name": "Merchant Name",
"len": 13,
"data": "Julián Suarez",
"rawData": "Julián Suarez"
},
"60": {
"id": "60",
"name": "Merchant City",
"len": 6,
"data": "Bogota",
"rawData": "Bogota"
},
"61": {
"id": "61",
"name": "Postal Code",
"len": 6,
"data": "114056",
"rawData": "114056"
},
"62": {
"id": "62",
"name": "Additional Data Field Template",
"len": 11,
"data": "07010080200",
"rawData": "07010080200"
},
"63": {
"id": "63",
"name": "CRC",
"len": 4,
"data": "2F1E",
"rawData": "2F1E"
},
"80": {
"id": "80",
"name": "Unreserved Templates",
"len": 27,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 16,
"data": "CO.COM.ACH.CANAL",
"rawData": "CO.COM.ACH.CANAL"
},
"01": {
"id": "01",
"len": 3,
"data": "POS",
"rawData": "POS"
}
},
"rawData": "0016CO.COM.ACH.CANAL0103POS"
},
"81": {
"id": "81",
"name": "Unreserved Templates",
"len": 25,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 15,
"data": "CO.COM.ACH.CIVA",
"rawData": "CO.COM.ACH.CIVA"
},
"01": {
"id": "01",
"len": 2,
"data": "03",
"rawData": "03"
}
},
"rawData": "0015CO.COM.ACH.CIVA010203"
},
"82": {
"id": "82",
"name": "Unreserved Templates",
"len": 23,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.IVA",
"rawData": "CO.COM.ACH.IVA"
},
"01": {
"id": "01",
"len": 1,
"data": "0",
"rawData": "0"
}
},
"rawData": "0014CO.COM.ACH.IVA01010"
},
"83": {
"id": "83",
"name": "Unreserved Templates",
"len": 24,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 15,
"data": "CO.COM.ACH.BASE",
"rawData": "CO.COM.ACH.BASE"
},
"01": {
"id": "01",
"len": 1,
"data": "0",
"rawData": "0"
}
},
"rawData": "0015CO.COM.ACH.BASE01010"
},
"84": {
"id": "84",
"name": "Unreserved Templates",
"len": 25,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 15,
"data": "CO.COM.ACH.CINC",
"rawData": "CO.COM.ACH.CINC"
},
"01": {
"id": "01",
"len": 2,
"data": "03",
"rawData": "03"
}
},
"rawData": "0015CO.COM.ACH.CINC010203"
},
"85": {
"id": "85",
"name": "Unreserved Templates",
"len": 23,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.INC",
"rawData": "CO.COM.ACH.INC"
},
"01": {
"id": "01",
"len": 1,
"data": "0",
"rawData": "0"
}
},
"rawData": "0014CO.COM.ACH.INC01010"
},
"90": {
"id": "90",
"name": "Unreserved Templates",
"len": 43,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 16,
"data": "CO.COM.ACH.TRXID",
"rawData": "CO.COM.ACH.TRXID"
},
"01": {
"id": "01",
"len": 19,
"data": "62FB70176DC0B870F58",
"rawData": "62FB70176DC0B870F58"
}
},
"rawData": "0016CO.COM.ACH.TRXID011962FB70176DC0B870F58"
},
"91": {
"id": "91",
"name": "Unreserved Templates",
"len": 86,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.SEC",
"rawData": "CO.COM.ACH.SEC"
},
"01": {
"id": "01",
"len": 64,
"data": "ac77cb8cc46f1e0aee1b8e3212bc9f27bcb8ec16aaf38d2ce42194a92bfc4d12",
"rawData": "ac77cb8cc46f1e0aee1b8e3212bc9f27bcb8ec16aaf38d2ce42194a92bfc4d12"
}
},
"rawData": "0014CO.COM.ACH.SEC0164ac77cb8cc46f1e0aee1b8e3212bc9f27bcb8ec16aaf38d2ce42194a92bfc4d12"
},
"00": {
"id": "00",
"name": "Payload Format Indicator",
"len": 2,
"data": "01",
"rawData": "01"
},
"01": {
"id": "01",
"name": "Point of Initiation Method",
"len": 2,
"data": "11",
"rawData": "11"
}
}
}
```
```json Response Error 400 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "400",
"statusDesc": "Bad Request"
},
"error": {
"code": "1013",
"message": "El contenido enviado no es válido o está mal cifrado"
}
}
```
```json Response Error 500 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "500",
"statusDesc": "Internal Server Error"
},
"error": {
"code": "1005",
"message": "Fallas Técnicas"
}
}
```
# Cómo validar un QR
Source: https://transfiya.me/1-85/directorio-federado/tecnologia-de-acceso-qr/como-validar-un-qr
### Especificaciones para validación de QR
ACH cuenta con la capacidad de validar la veracidad del código QR antes de realizar la acreditación del dinero en la entidad participante destino. Sin embargo, las entidades que lo requieran podrán implementar el método de validación según lo establecido en esta documentación.
El servicio de validación aplica unicamente para los códigos QR generados por Transfiya.
```json theme={null}
Dominio: https://bank.apihub.crt.achcolombia.com.co
```
```json theme={null}
POST /ach/bk/v1/money-movement/qr
```
### Campos de Entrada
| **Campo** | **Tipo** | **Descripción** | **Formato** | **Obligatorio** |
| ---------------------- | ---------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------- | --------------- |
| **meta** | **object** | | | **SI** |
| requestId | uuid | Código generado por la entidad participante para identificar el paquete | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | SI |
| timestamp | datetime | Fecha y hora de la solicitud de generación del código QR | 2025-12-23T18:16:35.099Z | SI |
| version | string | Versión del esquema, enviar el valor "1.0" | 1.0 | SI |
| **data** | **object** | | | **SI** |
| movementType | enum | Tipo de operación a realizar. \[QR, QRVALIDATE, QRPARSER] | QRVALIDATE | SI |
| **useCaseInformation** | **object** | | | **SI** |
| idQr | string | Campo para la identificación de la transacción. (Tag 90) | CO.COM.ACH.RED3748349738748374 | SI |
| crc | string | Código de redundancia cíclica del QR (Tag 63) | 3A5F | NO |
| hash | string | Cadena de caracteres de seguridad del QR (Tag 91) | 7f9c2ba4e88f827d616045507605853ed73b4761f1d1f6c5e9f7f0f4b7a4f1f0 | NO |
```json Request theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T17:18:15.761Z",
"version": "1.0"
},
"data": {
"movementType": "QRVALIDATE",
"useCaseInformation": {
"idQr": "CO.COM.ACH.RED3748349738748374",
"crc": "3A5F",
"hash": "7f9c2ba4e88f827d616045507605853ed73b4761f1d1f6c5e9f7f0f4b7a4f1f0"
}
}
}
```
### Campos de Salida:
| **Campo** | **Tipo** | **Descripción** | **Formato** |
| ------------- | ---------- | ----------------------------------------------------------------------- | ------------------------------------ |
| **meta** | **object** | - | - |
| requestId | uuid | Código generado por la entidad participante para identificar el paquete | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| timestamp | datetime | Fecha y hora de la respuesta a la solicitud de generación del código QR | 2025-12-23T18:16:35.099Z |
| status | enum | Estado de la respuesta. SUCCESS, ERROR | SUCCESS |
| statusCode | string | Código HTTP de la respuesta | 200 |
| statusDesc | string | Descripción del código HTTP | OK |
| **data** | **object** | | |
| movementType | enum | Tipo de operación a realizar. \[QR, QRVALIDATE, QRPARSER] | QRVALIDATE |
| qr | object | - | - |
| Tag number | object | Número del tag EMVCO | 26 |
| id | string | Número del tag EMVCO | 26 |
| name | string | Nombre del campo | Merchant Account Information |
| len | string | Tamaño del campo | 32 |
| data | object | Contenido del tag | - |
| SubTag Number | object | Número del subTag EMVCO | 26 |
| id | string | Número del subTag EMVCO | 01 |
| name | string | Nombre del campo | Global Unique Identifier |
| len | string | Tamaño del campo | 14 |
| data | string | Contenido del tag | CO.COM.ACH.LLA |
| rawdata | string | Fragmento del TLV para este TAG | CO.COM.ACH.LLA |
| rawdata | string | Fragmento del TLV para este TAG | 0014CO.COM.ACH.LLA02103152466845 |
| **error** | **object** | | |
| code | integer | Código de error generado (cero si no hay errores) | 1005 |
| message | string | Mensaje de error (vacío si no hay errores) | Fallas técnicas |
### Campos de Respuesta
```json Response Exitoso theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "SUCCESS",
"statusCode": "200",
"statusDesc": "OK"
},
"data": {
"movementType": "QRPARSER",
"26": {
"id": "26",
"name": "Merchant Account Information",
"len": 32,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.LLA",
"rawData": "CO.COM.ACH.LLA"
},
"02": {
"id": "02",
"name": "Merchant ID",
"len": 10,
"data": "3152466845",
"rawData": "3152466845"
}
},
"rawData": "0014CO.COM.ACH.LLA02103152466845"
},
"49": {
"id": "49",
"name": "Merchant Account Information",
"len": 25,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.RED",
"rawData": "CO.COM.ACH.RED"
},
"01": {
"id": "01",
"name": "Merchat PAN",
"len": 3,
"data": "ACH",
"rawData": "ACH"
}
},
"rawData": "0014CO.COM.ACH.RED0103ACH"
},
"53": {
"id": "53",
"name": "Transaction Currency",
"len": 3,
"data": "170",
"rawData": "170"
},
"54": {
"id": "54",
"name": "Transaction Amount",
"len": 4,
"data": "8900",
"rawData": "8900"
},
"58": {
"id": "58",
"name": "Country Code",
"len": 2,
"data": "CO (Colombia)",
"rawData": "CO"
},
"59": {
"id": "59",
"name": "Merchant Name",
"len": 13,
"data": "Julián Suarez",
"rawData": "Julián Suarez"
},
"60": {
"id": "60",
"name": "Merchant City",
"len": 6,
"data": "Bogota",
"rawData": "Bogota"
},
"61": {
"id": "61",
"name": "Postal Code",
"len": 6,
"data": "114056",
"rawData": "114056"
},
"62": {
"id": "62",
"name": "Additional Data Field Template",
"len": 11,
"data": "07010080200",
"rawData": "07010080200"
},
"63": {
"id": "63",
"name": "CRC",
"len": 4,
"data": "2F1E",
"rawData": "2F1E"
},
"80": {
"id": "80",
"name": "Unreserved Templates",
"len": 27,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 16,
"data": "CO.COM.ACH.CANAL",
"rawData": "CO.COM.ACH.CANAL"
},
"01": {
"id": "01",
"len": 3,
"data": "POS",
"rawData": "POS"
}
},
"rawData": "0016CO.COM.ACH.CANAL0103POS"
},
"81": {
"id": "81",
"name": "Unreserved Templates",
"len": 25,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 15,
"data": "CO.COM.ACH.CIVA",
"rawData": "CO.COM.ACH.CIVA"
},
"01": {
"id": "01",
"len": 2,
"data": "03",
"rawData": "03"
}
},
"rawData": "0015CO.COM.ACH.CIVA010203"
},
"82": {
"id": "82",
"name": "Unreserved Templates",
"len": 23,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.IVA",
"rawData": "CO.COM.ACH.IVA"
},
"01": {
"id": "01",
"len": 1,
"data": "0",
"rawData": "0"
}
},
"rawData": "0014CO.COM.ACH.IVA01010"
},
"83": {
"id": "83",
"name": "Unreserved Templates",
"len": 24,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 15,
"data": "CO.COM.ACH.BASE",
"rawData": "CO.COM.ACH.BASE"
},
"01": {
"id": "01",
"len": 1,
"data": "0",
"rawData": "0"
}
},
"rawData": "0015CO.COM.ACH.BASE01010"
},
"84": {
"id": "84",
"name": "Unreserved Templates",
"len": 25,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 15,
"data": "CO.COM.ACH.CINC",
"rawData": "CO.COM.ACH.CINC"
},
"01": {
"id": "01",
"len": 2,
"data": "03",
"rawData": "03"
}
},
"rawData": "0015CO.COM.ACH.CINC010203"
},
"85": {
"id": "85",
"name": "Unreserved Templates",
"len": 23,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.INC",
"rawData": "CO.COM.ACH.INC"
},
"01": {
"id": "01",
"len": 1,
"data": "0",
"rawData": "0"
}
},
"rawData": "0014CO.COM.ACH.INC01010"
},
"90": {
"id": "90",
"name": "Unreserved Templates",
"len": 43,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 16,
"data": "CO.COM.ACH.TRXID",
"rawData": "CO.COM.ACH.TRXID"
},
"01": {
"id": "01",
"len": 19,
"data": "62FB70176DC0B870F58",
"rawData": "62FB70176DC0B870F58"
}
},
"rawData": "0016CO.COM.ACH.TRXID011962FB70176DC0B870F58"
},
"91": {
"id": "91",
"name": "Unreserved Templates",
"len": 86,
"data": {
"00": {
"id": "00",
"name": "Global Unique Identifier",
"len": 14,
"data": "CO.COM.ACH.SEC",
"rawData": "CO.COM.ACH.SEC"
},
"01": {
"id": "01",
"len": 64,
"data": "ac77cb8cc46f1e0aee1b8e3212bc9f27bcb8ec16aaf38d2ce42194a92bfc4d12",
"rawData": "ac77cb8cc46f1e0aee1b8e3212bc9f27bcb8ec16aaf38d2ce42194a92bfc4d12"
}
},
"rawData": "0014CO.COM.ACH.SEC0164ac77cb8cc46f1e0aee1b8e3212bc9f27bcb8ec16aaf38d2ce42194a92bfc4d12"
},
"00": {
"id": "00",
"name": "Payload Format Indicator",
"len": 2,
"data": "01",
"rawData": "01"
},
"01": {
"id": "01",
"name": "Point of Initiation Method",
"len": 2,
"data": "11",
"rawData": "11"
}
}
}
```
```json Response Error 400 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "400",
"statusDesc": "Bad Request"
},
"error": {
"code": "1013",
"message": "El contenido enviado no es válido o está mal cifrado"
}
}
```
```json Response Error 500 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "500",
"statusDesc": "Internal Server Error"
},
"error": {
"code": "1005",
"message": "Fallas Técnicas"
}
}
```
# Tecnologia de acceso QR
Source: https://transfiya.me/1-85/directorio-federado/tecnologia-de-acceso-qr/tecnologia-de-acceso-qr
### Definición de producto
El código QR (Quick Response) es una herramienta visual bidimensional con estructura cuadrada, diseñada para almacenar información codificada de forma eficiente. Su lectura es rápida y su capacidad supera la de los códigos de barras tradicionales. Puede ser estático, con contenido fijo, o dinámico, adaptándose a cada transacción mediante generación en tiempo real.
En Colombia, esta tecnología se habilita como parte del sistema Bre-B de pagos inmediatos, en cumplimiento del artículo 104 de la Ley 2294 de 2023 y bajo la regulación del Banco de la República para transfrencias y/o pagos inmediatos a personas y comercios. El objetivo es facilitar pagos digitales mediante billeteras electrónicas y acceso móvil, utilizando el estándar internacional EMVCo. Esto permite que los usuarios realicen pagos sin contacto físico con la tarjeta, mejorando la seguridad y ampliando los puntos de aceptación en todo el país.
### Tipos de QR:
**Estático**
Es un código de respuesta rápida que contiene información fija, como los datos del comercio o una llave destino (comercio o persona). Se genera una sola vez y no se actualiza con cada transacción. Por lo general, se imprime o se exhibe en un lugar visible (como una vitrina o factura), y el usuario debe ingresar manualmente el monto a pagar.\
Para las Entidades Participantes, este tipo de QR representa una solución sencilla y de bajo costo para habilitar pagos, aunque con menor automatización y control sobre la transacción.
**Dinámico**
Este código se genera en tiempo real y contiene información específica de cada transacción, como el valor exacto, la llave destino (comercio o persona), la referencia de pago, entre otros. Al escanearlo, el usuario no necesita digitar ningún dato adicional: el pago se procesa automáticamente.\
Desde el punto de vista de las Entidades Participantes, el QR dinámico permite una experiencia de pago más segura, rápida y trazable, ideal para integraciones con sistemas de facturación, puntos de venta y billeteras digitales.
### Capacidades a ofrecer
* **Exposición de API:** Transfiya ofrecerá una API para facilitar la integración de generación y lectura de QR.
* Disponer canal para **garantizar** una comunicación **segura** y **eficiente**.
* Transfiya entrega la cadena de datos para la **generación** de QR conforme al estándar **EMVco**.
* Dentro del proceso de lectura, se ofrecerá la decodificación de imagen para **interpretar** el contenido del QR, obteniendo entre otros **la llave**, el **ID de QR**, **tipo de QR** y el **hash de seguridad**. El cual será entregado por Transfiya en formato JSON. para que la Entidad Participante origen orqueste el flujo transaccional.
Transfiya dispone a las Entidades Participantes, el siguiente contrato swagger para facilitar la integración a la tecnología de acceso QR. [Archivo descargable](https://www.achcolombia.com.co/documents/d/guest/qr_documentacion_swagger)
# Token de autenticación
Source: https://transfiya.me/1-85/directorio-federado/tecnologia-de-acceso-qr/token-de-autenticacion
### Especificaciones para solicitud de token
Las Entidades Participantes deberán implementar la autenticación de token para poder usar los servicios asociados a la tecnología de acceso QR.
```json theme={null}
Dominio: https://bank.apihub.crt.achcolombia.com.co
```
```json theme={null}
POST /ach/bk/apihub-bank/oauth2/token
```
### Campos de Entrada (headers):
| **Campo** | **Tipo** | **Descripción** | **Obligatorio** |
| -------------- | ---------- | ------------------------------------------------------------------------------------- | --------------- |
| **client\_id** | **string** | Client id generado a través del Developer Portal | **SI** |
| client\_secret | string | Client secret generado a través del Developer Portal | SI |
| scope | string | Para métodos POST (MoneyMovementsQR) y para método PATCH (MoneyMovementsQR\_UpdState) | SI |
| grant\_type | string | Tipo de token: client\_credentials | SI |
### Solicitud ejemplo:
```json Request theme={null}
curl --location 'https://bank.apihub.crt.achcolombia.com.co/ach/bk/apihub-bank/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: incap_ses_890_3286497=0uIPUYfyzQxs6s9A2epZDHYdk2kAAAAAk9ZeeTyNHEV58iRw9N3l8A==; nlbi_3286497=mihMNSZn4kHPFoZU7C6EMgAAAADxTfoP6vcW/M90RfjWPszY; visid_incap_3286497=fOkez2awRsiYw88W1QKmTHYdk2kAAAAAQUIPAAAAAAB2uyYNGL6rD0eQYTOzyDnC' \
--data-urlencode 'client_id=xxxxxxxxx' \
--data-urlencode 'client_secret=xxxxxxxxx' \
--data-urlencode 'scope=MoneyMovementsQR' \
--data-urlencode 'grant_type=client_credentials'
```
### Campos de Salida
| **Campo** | **Tipo** | **Descripción** |
| --------------- | ---------- | ---------------------------------------------------------- |
| **token\_type** | **string** | Tipo de token: Bearer |
| access\_token | string | Token generado por ACH Colombia |
| scope | string | Permiso de la API: MoneyMovementsQR |
| expires\_in | string | Tiempo vigencia del token. Actualmente en 1 hora (3600 ms) |
| consented\_on | string | Indicador asignado por ACH Colombia |
```json Response Exitoso theme={null}
{
"token_type": "Bearer",
"access_token": "AAIgNWQ3OTdjZjFhZjliZmE2NjY0MGMzMGRiOWNkNDFkNzcHa5k0p8TwxJWpRtHIY7wV1GKkMgUdAbTljy0G9XCLjhGuoCJC_mYbeklz3CTPMQDBdIm9rcRG1rSp4EAwo5yLLvEewI_V8ynMLDVO2m1pMShXyVTLMSdsEo90Nzb3S8yu2a1nvvnv3tWYW2_LvSQe",
"scope": "MoneyMovementsQR",
"expires_in": 3600,
"consented_on": 1771249253
}
```
```json Response Error 400 theme={null}
{
"httpCode": "400",
"httpMessage": "Bad Request",
"moreInformation": "One or more required API parameters are missing in the API request."
}
```
```json Response Error 500 theme={null}
{
"meta": {
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2026-01-15T00:03:39.558Z",
"status": "ERROR",
"statusCode": "500",
"statusDesc": "Internal Server Error"
},
"error": {
"code": "1005",
"message": "Fallas Técnicas"
}
}
```
# Como reintentar créditos
Source: https://transfiya.me/1-85/transferencias-bre-b/guias-de-uso/como-reintentar-creditos
## **Punto de No Retorno en el Proceso de Liquidación – Servicio Bre‑B**
De acuerdo con la normativa aplicable a los procesos de transferencia Bre‑B y los lineamientos operativos del Banco de la República para la compensación y liquidación de transacciones interbancarias, se establece lo siguiente respecto al ciclo operativo y al punto de no retorno:
Una transacción Bre‑B alcanza la fase de **liquidación definitiva** cuando se cumplen de manera secuencial los siguientes hitos operativos:
1. **Confirmación de débito por parte de la entidad de origen:**\
La entidad financiera que inicia la transacción confirma que los fondos han sido debitados exitosamente de la cuenta del ordenante.
2. **Confirmación de disponibilidad por parte de la entidad de destino:**\
La entidad receptora valida que se encuentra en la capacidad operativa y contable de **acreditar los recursos** correspondientes al beneficiario.
3. **Liquidación por parte del Banco de la República:**\
Una vez las dos confirmaciones anteriores han sido registradas, el Banco de la República procede con la **liquidación de la operación**, generando la respectiva confirmación de liquidación a las entidades participantes.
### **Punto de No Retorno**
Con la confirmación de liquidación emitida por el Banco de la República, la transacción alcanza el denominado **punto de no retorno**, entendido como el momento a partir del cual:
* La entidad de destino **tiene la obligación de acreditar** los recursos al beneficiario final.
* **No es procedente ni permitido** generar un rechazo de la transacción.
* Se considera que la operación ha sido irrevocablemente liquidada en el sistema de pagos administrado por el Banco de la República.
Este comportamiento operativo busca garantizar la integridad del proceso de pagos, la irreversibilidad posterior a la liquidación y la trazabilidad regulatoria de las transferencias interbancarias, evitando excepciones que puedan comprometer la correcta ejecución del servicio Bre‑B.
## **Manejo de Intermitencias y Capacidad de Retomar Transacciones – Funcionalidad de Reintento**
Dentro de las operaciones del servicio Bre‑B, se ha identificado que algunos participantes pueden experimentar **dificultades técnicas intermitentes** en ciertas capas de su infraestructura tecnológica. Estas intermitencias, aunque breves, pueden impedir que una transacción culmine exitosamente aun cuando ya haya sido completado el proceso de liquidación ante el Banco de la República.
Con el propósito de fortalecer la continuidad operativa y asegurar la correcta finalización del flujo transaccional, **Transfiya implementó una capacidad adicional que permite retomar la operación desde el último punto alcanzado**, lanzando un reintento controlado para completar la transacción sin afectar la integridad del proceso.
### **Responsabilidad de las Entidades Participantes**
Es importante resaltar que, aunque Transfiya asegura la ejecución técnica del reintento, **la correcta administración contable y operativa recae en cada entidad financiera**, en particular:
* La entidad debe garantizar que su core bancario **controle y evite dobles (o múltiples) abonos**, especialmente en escenarios donde la operación se reactive tras un evento de intermitencia.
* La entidad debe asegurarse de identificar y registrar cualquier operación que haya sido **objeto de ajuste manual** durante la reconexión o reintento del proceso.
* La responsabilidad de conciliar y validar que los abonos se realicen una sola vez en el core es exclusiva de la entidad participante.
El propósito central de esta capacidad es **mantener la armonía transaccional** entre los tres niveles involucrados:
1. Lo **liquidado en el MOL** (Banco de la República).
2. Lo **registrado y operado en Transfiya**.
3. Lo **ejecutado en el core** de cada entidad financiera.
Esta sincronización es clave para preservar la integridad del ecosistema de pagos y asegurar que el estado final de cada transacción refleje de manera coherente lo liquidado oficialmente.
## **Reintento Operativo mediante Interfaz Estándar**
La reactivación del proceso se realizará de forma estandarizada mediante un **botón de reintento**. Los pasos para reintentar son los siguientes:
* Se ubica la transacción que se quiere completar y vemos los detalles.
* Nos ubicamos en el apartado de \*\*Eventos de la transacción \*\*donde encontraremos el error por el cual no se completó el pago, lo analizamos y presionamos el botón "**OPEN**"
* Luego de esto obtendremos mas detalles del fallo y aparecerá el botón "**Reintentar**"
* A continuación obtendremos el resultado del proceso, si es exitoso se producirán los llamados necesarios para completar la transacción y pasará de aceptada a aprobada.
Esto solo se producirá si el Banco de la República confirma a Transfiya mediante el flujo de la transacción que la liquidación procesó forma exitosa, en caso contrario no se podrá visualizar esta opción.
En este esquema operativo:
* El **action principal SENDMOL** sigue siendo responsabilidad exclusiva de la **entidad de origen** de la transacción.
* El **action de crédito DOWNLOAD** permanece a cargo de la **entidad receptora**.
El mecanismo de reintento tiene como finalidad principal llevar las transacciones al estado **Aprobado**, siempre y cuando exista confirmación oficial del Banco de la República de que la transacción fue liquidada.
# Actualizar an accion
Source: https://transfiya.me/b2b-2/action/actualizar-an-accion
/public/tinapiv8.yaml put /v1/action/{action_id}
# Crear una accion
Source: https://transfiya.me/b2b-2/action/crear-una-accion
/public/tinapiv8.yaml post /v1/action
# Enviar una accion
Source: https://transfiya.me/b2b-2/action/enviar-una-accion
/public/tinapiv8.yaml post /v1/action/{action_id}/sendit
# Obtener accion por ID
Source: https://transfiya.me/b2b-2/action/obtener-accion-por-id
/public/tinapiv8.yaml get /v1/action/{action_id}
# Create credentials
Source: https://transfiya.me/b2b-2/credentials/create-credentials
/public/tinapiv8.yaml post /oauth
Endpoint used for creating of credentials
# Get api key
Source: https://transfiya.me/b2b-2/credentials/get-api-key
/public/tinapiv8.yaml get /oauth/key/{handle}
Endpoint used to get api key
# Get credentials
Source: https://transfiya.me/b2b-2/credentials/get-credentials
/public/tinapiv8.yaml get /oauth/client/{handle}
Endpoint used to get credentials
# Regenerate secrets
Source: https://transfiya.me/b2b-2/credentials/regenerate-secrets
/public/tinapiv8.yaml put /oauth/{handle}
Endpoint used to regenerate secrets
# Update credentials
Source: https://transfiya.me/b2b-2/credentials/update-credentials
/public/tinapiv8.yaml put /oauth/credentials/{handle}
Endpoint used for updating of credentials
# Aceptar una transferencia
Source: https://transfiya.me/b2b-2/transfer/aceptar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/accept
# Actualizar una transferencia
Source: https://transfiya.me/b2b-2/transfer/actualizar-una-transferencia
/public/tinapiv8.yaml put /v1/transfer/{transfer_id}
# Continuar una transferencia
Source: https://transfiya.me/b2b-2/transfer/continuar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/continue
# Crear una transferencia
Source: https://transfiya.me/b2b-2/transfer/crear-una-transferencia
/public/tinapiv8.yaml post /v1/transfer
# Inicializar una transferencia
Source: https://transfiya.me/b2b-2/transfer/inicializar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{transferId}/initiate
# Rechazar una transferencia
Source: https://transfiya.me/b2b-2/transfer/rechazar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/reject
# Actualiza la transferencia.
Source: https://transfiya.me/b2b/action/actualiza-la-transferencia
/public/spi-banksv3.yaml post /v1/action
TIN Cloud will call this endpoint when bank needs to sign the pending action. Depending on the key handling strategy it can use keys stored in the TIN Cloud or keys stored on local Key management system.
# Acreditar al destino.
Source: https://transfiya.me/b2b/credit/acreditar-al-destino
/public/spi-banksv3.yaml post /v1/credit
Executes download on TIN Cloud side and credit on banking core side.
# Debitar al origen.
Source: https://transfiya.me/b2b/debit/debitar-al-origen
/public/spi-banksv3.yaml post /v1/debit
Executes upload on TIN Cloud side and debit on banking core side.
# Notificacion de la transferencia.
Source: https://transfiya.me/b2b/status/notificacion-de-la-transferencia
/public/spi-banksv3.yaml post /v1/status
Notification channel. It receives action object as a confirmation of transfer acceptance or reject action.
# This is the endpoint to get a temporal token to set in the oauth2 header
Source: https://transfiya.me/b2b/token/this-is-the-endpoint-to-get-a-temporal-token-to-set-in-the-oauth2-header
/public/spi-banksv3.yaml post /oauth/token
# Create a new signer
Source: https://transfiya.me/directory/signer/create-a-new-signer
/public/spi-v3.yaml post /v1/signer
Endpoint to create a signer with necessary details.
# Get a signer with signer handle.
Source: https://transfiya.me/directory/signer/get-a-signer-with-signer-handle
/public/spi-v3.yaml get /v1/signer/{signerAddress}
Endpoint to get a signer.
# Resolves SPI signer
Source: https://transfiya.me/directory/signer/resolves-spi-signer
/public/spi-v3.yaml post /v1/signer/lookup.dice
Endpoint to resolve signer in DICE
# Retrieve signers
Source: https://transfiya.me/directory/signer/retrieve-signers
/public/spi-v3.yaml get /v1/signer
Get signers with support for filtering.
# Update a signer
Source: https://transfiya.me/directory/signer/update-a-signer
/public/spi-v3.yaml put /v1/signer/{signerAddress}
Endpoint to update a signer.
# Como buscar una cuenta
Source: https://transfiya.me/es/v1.104/b2b/guides/How-to-lookup-a-signer
Aprende cómo obtener el firmante asociado a un alias utilizando la API de Transfiya.
# Cómo consultar una cuenta - Versión 1
Esta guía está destinada para que las Entidades Participantes que desean validar si un usuario receptor se encuentra creado en de Transfiya (signer).
Un Signer es una representación de una credencial de pago en Transfiya, dentro de cada creación de Signer se almacena la información del usuario y la información de la cuenta, y debido a esto, las Entidades pueden hacer una búsqueda con la información del usuario y del banco para obtener el signer registrado.
## Filtros disponibles para obtener un signer por datos del beneficiario:
Puedes usar los siguientes filtros en el endpoint `POST [baseUrl]/v1/signer/lookup`:
* `labels.proprietary`
* `labels.identification`
* `labels.bankAccountNumber`
* `labels.routerReference`
### Campos de entrada:
| **Etiqueta** | **Descripción** | **Tipo** | **Longitud** | **Obligatoriedad** |
| :--------------- | :------------------------------------------------------------ | :------- | :----------------------------------------------------------- | :----------------- |
| proprietary | Tipo de documento, admite: CC,CE,PA,TI,NUIP,NIT,OTR,PPT y PEP | Texto | 1-4 | Si |
| identification | Número de documento | Texto | 1-18 carácteres | Si |
| bankAccounNumber | Número de cuenta | Texto | 1-Máximo 34 dígitos | Si |
| routerReference | Identificador de billetera del banco en Transfiya. | Texto | 1- Máximo 34 caracteres alfanuméricos, debe comenzar con `$` | Si |
### Ejemplo de solicitud
```json theme={null}
curl --location 'https://ach-minka-stg.transferenciasinmediatas.com/v1/signer/lookup' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ****' \
--data '{
"labels": {
"proprietary": "NIT",
"identification": "804153241",
"bankAccountNumber": "335278945",
"routerReference": "$bancoamarillo"
}
}'
```
```json theme={null}
{
"pagination": {
"pageNum": 0,
"pageSize": 50
},
"error": {
"code": 0,
"message": "Success"
},
"entities": [
{
"handle": "wL62NznU8SPZavTRsy2G3bQ7E2qFL8jpcM",
"wallets": []
}
]
}
```
# Cómo consultar una cuenta - Versión 2
Esta versión del Signer Lookup está destinada para que las Entidades Participantes que desean validar si un usuario receptor se encuentra creado en de Transfiya (signer). Usando como datos de entrada el tipo de identificación y número de identificación del beneficiario.
Transfiya permite a las Entidades, relacionar el caso de uso para ejecutar la respectiva resolución de la información de manera eficiente.
A continuación, se relaciona los valores que permite recibir el campo *useCase:*
| Valor | Descripción |
| -------- | ------------------------------------------------------------- |
| b2p-send | Corresponde a una transacción tipo SEND de empresa a persona. |
| b2b-send | Corresponde a una transacción tipo SEND de empresa a empresa. |
### Campos de entrada:
| **Etiqueta** | **Descripción** | **Tipo** | **Longitud** | **Obligatoriedad** |
| :------------- | :------------------------------------------------------------ | :------- | :-------------- | :----------------- |
| useCase | Caso de uso. Admite: b2p-send y b2b-send | Texto | 1-8 | Si |
| proprietary | Tipo de documento, admite: CC,CE,PA,TI,NUIP,NIT,OTR,PPT y PEP | Texto | 1-4 | Si |
| identification | Número de documento | Texto | 1-18 carácteres | Si |
### Ejemplo de solicitud
```json theme={null}
curl --location 'https://ach-minka-stg.transferenciasinmediatas.com/v2/signer/lookup' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ****' \
--data '{
"useCase": "b2b-send",
"labels": {
"proprietary": "NIT",
"identification": "804153241"
}
}
```
Response
```json theme={null}
{
"entities": [
{
"handle": "wWZd85BW1kCj5RgeNET6EC55sG5uGDqpWB",
"bankName": "Banco Amarillo",
"bankBicfi": "3854",
"proprietary": "NIT",
"identification": "804153241",
"routerReference": "$bancoamarillo",
"bankAccountNumber": "335278944"
},
{
"handle": "wL62NznU8SPZavTRsy2G3bQ7E2qFL8jpcM",
"bankName": "Banco Amarillo",
"bankBicfi": "3854",
"proprietary": "NIT",
"identification": "804153241",
"routerReference": "$bancoamarillo",
"bankAccountNumber": "335278945"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Lista de códigos de error
A continuación se listan los códigos de error asociados a esta operación:
| **Código de error** | **Descripción** | **HTTP Status** |
| :------------------ | :-------------------------------------------- | :-------------- |
| 99 | Error inesperado del servidor | 400 |
| 100 | No tienes permisos para acceder a este método | 403 |
| 102 | Etiquetas inválidas | 400 |
| 118 | Error de validación del esquema del recurso | 400 |
# Como dispersar a llaves
Source: https://transfiya.me/es/v1.104/b2b/guides/How-to-send-key
Description of your new file.
# Como dispersar a llaves
La habilitación de **dispersión a llaves** representa un avance significativo en la forma en que las empresas gestionan sus pagos, permitiéndoles realizar transferencias de manera más ágil, segura y personalizada.
Esta funcionalidad permite dispersar fondos directamente a cuentas asociadas a llaves digitales (como número de celular, correo electrónico o documento de identidad), eliminando la necesidad de conocer el número de cuenta del beneficiario. Esto no solo simplifica el proceso de pago, sino que también mejora la experiencia del usuario final, reduce errores operativos y fortalece la trazabilidad de las transacciones.
Con la dispersión a llaves, las empresas podrán optimizar procesos como el pago de nómina, proveedores, incentivos y devoluciones, todo con mayor flexibilidad y control.
Es importante tener en cuenta que, la dispersión a llaves se podrá habilitar de 2 maneras:\
**1. Habilitación de Bre-b:** A través de esta capacidad, la Entidad Origen podrá enviar transferencias inmediatas a llaves registradas en Bre-b y su respectiva liquidación en el MOL de Banco de la Republica, teniendo en cuenta los requerimientos de vinculación, controles y topes transaccionales establecidos por el banco central.\
**2. Ecosistema Transfiya:** Las Entidades participantes podrán procesar el envío de transferencias inmediantes a llaves registradas en Bre-b y que estas llaves estén asociadas a Entidades Participantes con una conexión activa en Transfiya. Bajo este esquema, el proceso de compensación y liquidación se hace en Transfiya (Prefondeo y Reintegro) y los topes transaccionales serán configurados y administrados por la Entidad Participante origen.
### Flujo dispersión a llaves:
### Definiciones de la integración:
Para la habilitación del flujo de resolución de llave y procesamiento transaccional, las Entidades Participantes deben:
1. **Creación de Signer tipo Business**
Las Entidades Participantes podrán identificar a cada Empresa originadora en Transfiya a través del proceso de creación de Signer tipo Business. El detalle de este proceso, se encuentra en [Como crear llaves de negocio - Transfiya Guide](https://transfiya.me/es/v1.85/b2b/guides/how-to-create-signer-business).
2. **Crear signer tipo generico**
En caso de que lo deseen las Entidades Participantes podrán habilitar la dispersion de dinero hacía llaves usando un signer genérico sin la necesidad de identificar a cada originador en Transfiya. El detalle de este proceso, se encuentra en [Cómo registrar signer genérico - Transfiya Guide](https://transfiya.me/es/v1.85/b2b/guides/how-to-create-generic-signer).
3. **Configurar reglas de negocio**
Cada signer tipo que actuará como originador ya sea tipo Business o Generico, debe tener reglas de negocio configuradas y parametrizadas en Transfiya, para esto las Entidades Participantes deberán asignar el monto máximo por transacción, la cantidad máxima diaria de transacciones y el monto acomulado diario a través de los mecánismos especificados en [¿Cómo actualizar reglas de negocio para una empresa? - Transfiya Guide](https://transfiya.me/es/v1.85/b2b/guides/how-to-setup-business-rules).
4. **Resolver la llave del beneficiario**
Si el identificador del beneficiario es una llave, las Entidades Participantes deberán implementar y habilitar el flujo de resolución de llaves. Razón por la cual, deben integrar las características y propiedades de la resolución de llaves en Transfiya, teniendo como base [Cómo resolver llaves - Transfiya Guide](https://transfiya.me/es/v1.85/directory/guides/how-to-resolve-keys).
5. **Procesamiento transaccional**
Una vez realizada la resolución de la llave del beneficiario, se puede proceder con el procesamiento transaccional en Transfiya a través de las capacidades actuales que las Entidades Participantes conocen. El detalle se encuentra en [Como enviar cuenta a cuenta - Transfiya Guide](https://transfiya.me/es/v1.85/b2b/guides/how-to-create-transfer).
# Cómo recibir pagos
Source: https://transfiya.me/es/v1.104/b2b/guides/how-to-collect-payments-Request
Aprende cómo solicitar dinero en tiempo real usando Transfiya como método de pago.
# Cómo recibir pagos
Solicitar dinero usando una transferencia de dinero en tiempo real.
Esta guía está dirigida a empresas que desean agregar **Transfiya** como un método de pago en tiempo real para recibir dinero de sus clientes.
Cada movimiento de dinero o pago se inicia mediante un flujo de transferencia.
Una **transferencia** representa un conjunto de acciones necesarias para mover fondos desde una fuente (como una cuenta bancaria, billetera o saldo de empresa) hacia un destino.
## Endpoint para crear una transferencia
Para iniciar un pago, es necesario crear un objeto de transferencia utilizando una llamada simple a la API REST:
```http theme={null}
POST https://[baseURL]/v1/transfer
```
El objeto de transferencia utiliza una estructura de mensajería simple que forma la base del protocolo de Minka. Incluye los siguientes campos:
* `source:` la fuente de los fondos
* `target:` el destino de los fondos
* `symbol:` el activo o moneda a transferir
* `amount:` el monto a transferir
Puedes encontrar más detalles sobre la estructura de la solicitud y la respuesta en la referencia de la API de Transferencias.
La diferencia entre un envío (send o payout) y una solicitud (request o payin) es simplemente el orden de los campos `source` y `target` en las etiquetas (`labels`).
### Ejemplo de cuerpo de solicitud
```json theme={null}
{
"source": "$573051000001",
"target": "wdF75EWdSfXmEkDDwUv6N6FSUi1is92XnD",
"symbol": "$tin",
"amount": "2000",
"labels": {
"type": "REQUEST",
"description": "Prueba",
"domain": "tin",
"transactionPurpose": "TRANSFER",
"numberOfTransactions": "1",
"sourceChannel": "POS",
"tx_id": "{{$randomBitcoin}}",
"invoiceId": "11111",
"invoiceDetail": "999999"
}
}
```
## Identificar una transferencia de tipo "REQUEST"
Para identificar una transferencia de envío de dinero, es necesario configurar `labels.type` como `REQUEST`.
Actualmente soportamos dos formatos posibles para los campos `source` y `target`:
* **Wallets**: siempre comienzan con `"$57"` seguido de un número de teléfono de 10 dígitos, por ejemplo: `"$57350424242"`.
* **Firmantes (Signers)**: son alfanuméricos, como `"wS1EU4AtgzD6VDtsrJyGKXmkQdvkWt9Qeq"`, y **no** comienzan con `"$"`.
Las transferencias con `labels.type` configurado como `REQUEST` se cancelan automáticamente después de 12 horas si el usuario fuente no las acepta.
## Flujo simplificado de solicitud de transferencia
El proceso simple de crear solicitudes de transferencia puede integrarse directamente en tu experiencia de usuario (UX) o ser llamado desde tu middleware para desembolsar fondos. Para más información, consulta la sección Solicitud de Transferencia.
La transferencia permanecerá en estado **PENDING** hasta que el usuario acepte la solicitud en su aplicación bancaria.
El flujo simplificado de solicitud de transferencia hacia una wallet (que representa el número de teléfono de una persona) puede visualizarse en el siguiente diagrama:
# Como crear una llave de tipo cuenta
Source: https://transfiya.me/es/v1.104/b2b/guides/how-to-create-account-keys
Cómo registrar llaves en Transfiya
Para la creación de llaves, se utilizará la interfaz de aplicación destinada a la creación de signers.
La plataforma Transfiya utiliza tipos de datos y [esquemas dinámicos](../about/about-validations) para garantizar la integridad y consistencia de los datos en toda la plataforma. Esto incluye reglas de validación para diversos campos dentro del sistema.
**Tipos de Validaciones:**
| Tipo signer | Schema aplicada | Descripción |
| ----------- | --------------- | ------------------------------------------ |
| `BUSINESS` | BUSINESS | Representa una empresa o persona jurídica. |
## Sintaxis de Referencia para el campo *aliasValue*
* **bankAccountType**: tipo de cuenta (en minúsculas), basado en los valores estándar de Transfiya.
* **bankAccountNumber**: número de cuenta bancaria
* **routerReference**: código de compensación o Bicfi válido del banco.
Este formato unificado garantiza consistencia y compatibilidad con los mecanismos de enrutamiento de Transfiya, facilitando la interoperabilidad entre participantes.
## 🏦 Tipos de Cuenta Soportados
A continuación se listan los tipos de cuenta reconocidos en Transfiya:
| Nombre | Valor |
| :---------------------------- | :----- |
| Cuenta de ahorros | `svgs` |
| Cuenta corriente | `cacc` |
| Depósito de bajo monto | `dbmo` |
| Depósito ordinario | `dord` |
| Depósito inclusivo bajo monto | `dbmi` |
Estos valores deben utilizarse exclusivamente en minúsculas y reflejan el tipo de cuenta real registrada por el firmante en el sistema financiero.
## 🌐 Referencia Bancaria
El identificador del banco (`bankReference`) debe ser el código de compensación o Bicfi válido, que permita una resolución clara y única del participante receptor.
## ✅ Ejemplo de referencia válida
**svgs:44255107106500\@7095**
### Ejemplo llave persona
A continuación se presenta un ejemplo de creación de una llave tipo 'BUSINESS' donde el tipo de Alias es "ACCOUNT":
```json theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"aliasType": "ACCOUNT",
"aliasValue": "svgs:1234@7095",
"type": "BUSINESS",
"name": "Jorge SAS",
"proprietary": "NIT",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "10010010001",
"routerReference": "$bancorojo"
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
```json theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "ACCOUNT",
"aliasValue": "svgs:1234@b7095,
"type": "BUSINESS",
"name": "Jorge SAS",
"proprietary": "NIT",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "10010010001",
"routerReference": "$bancorojo"
"created": "2024-10-11T11:59:24.241-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Campos de entrada:
| **Etiqueta** | **Descripción** | **Tipo** | **Longitud** | **Obligatoriedad** |
| :---------------- | :------------------------------------------------------------ | :------- | :----------------------------------------------------------- | :----------------- |
| aliasType | Tipo de llave: ACCOUNT | Texto | N/A | Si |
| aliasValue | Valor de la llave. Ej: svgs:44255107106500\@1001 | Texto | 1-Máximo 34 carácteres | Si |
| type | Tipo de signer: BUSINESS | Texto | N/A | Si |
| name | Nombre para identificación | Texto | 1-140 carácteres | Si |
| proprietary | Tipo de documento, admite: CC,CE,PA,TI,NUIP,NIT,OTR,PPT y PEP | Texto | 1-4 | Si |
| identification | Número de identificación | Texto | 1-18 carácteres | Si |
| bankAccountType | Número de cuenta, admite: SVGS, TRAS,CACC,DBMO,DORD, DBMI | Texto | 1-4 | Si |
| bankAccountNumber | Número de la cuenta | Texto | 1-Máximo 34 dígitos | Si |
| routerReference | Identificador de billetera del banco en Transfiya. | Texto | 1- Máximo 34 caracteres alfanuméricos, debe comenzar con `$` | Si |
# Cómo registrar signer genérico
Source: https://transfiya.me/es/v1.104/b2b/guides/how-to-create-generic-signer
Cómo registrar signer genérico en Transfiya
## Introducción
Ahora, el Directorio Federado de Transfiya permite la creación de **signer genérico**, las cuales se utilizan en el flujo de transferencias de **cuenta a cuenta** cuando la entidad receptora **no ha implementado el proceso de onboarding automático**.
Estos signers permiten ejecutar transferencias sin necesidad de que el signer del receptor sea creado en tiempo real.
**La entidad receptora debe registrar este signer genérico una única vez** y quedará disponible para su uso en futuras operaciones.
## Ejemplo de creación de Signer
Para la creación de llaves, se utilizará la interfaz de aplicación destinada a la creación de signers.
La plataforma Transfiya utiliza tipos de signers y [esquemas dinámicos](../about/about-validations) para garantizar la integridad y consistencia de los datos en toda la plataforma. Esto incluye reglas de validación para diversos campos dentro del sistema.
| Tipo signer | Schema aplicada | Descripción |
| ----------- | --------------- | ---------------------------------------------------------- |
| `GENERIC` | GENERIC | Representa una signer genérico de una Entidad Participante |
### Ejemplo de creación: Signer Genérico
A continuación se presenta un ejemplo de creación de una llave tipo 'GENERIC':
```json theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"type": "GENERIC",
"name": "Signer generico 1",
"bankName": "Banco Rojo",
"routerReference": "$bancorojo",
"bankBicfi": "7095",
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
```json theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"type": "GENERIC",
"name": "Generico",
"proprietary": "NIT",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"routerReference": "$bancorojo",
"createdBy": "$minka"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Campos de entrada:
| **Etiqueta** | **Descripción** | **Tipo** | **Longitud** | **Obligatoriedad** |
| --------------- | -------------------------------------------------- | -------- | ------------------------------------------------------------ | ------------------ |
| type | Tipo de signer: GENERIC | Texto | N/A | Si |
| name | Nombre para identificación | Texto | 1-140 carácteres | Si |
| bankName | Nombre del banco | Texto | 1-140 carácteres | Si |
| routerReference | Identificador de billetera del banco en Transfiya. | Texto | 1- Máximo 34 caracteres alfanuméricos, debe comenzar con `$` | Si |
| bankBicfi | Representa el código de compensación del banco. | Texto | 1-Máximo 4 caracteres numéricos | Si |
Con base en lo anterior, para la creación de un *signer* de tipo **GENERIC**, donde el banco origen corresponde a **Source** y el banco destino a **Target**, se deberán crear dos *signers* independientes entre sí. Una vez creados, ambos deberán asociarse al *wallet* **\$Banco**, aplicando de manera estricta la configuración estándar definida para este tipo de integración.
## Request:
```text theme={null}
PUT https://ach-minka-stg.transferenciasinmediatas.com/v1/wallet/{{walletUser}}
```
## Body:
```text theme={null}
{
"labels": {
"bankDomain" :"{{bankBicfi}}",
"targetGenericSigner": "{{targetGenericSigner}}",
"sourceGenericSigner": "{{sourceGenericSigner}}"
}
}
```
# Como crear llaves de negocio
Source: https://transfiya.me/es/v1.104/b2b/guides/how-to-create-signer-business
En esta guía encontraremos un ejemplo de cómo crear un signer tipo business
### Ejemplo de creación llave de negocio
A continuación se presenta un ejemplo de creación de una llave tipo 'BUSINESS' y un análisis comparativo con la implementación actual en Transfiya:
```json theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"type": "BUSINESS",
"name": "Cognito Inc",
"proprietary": "NIT",
"identification": "900123456",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"routerReference": "$bancorojo"
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
```json theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"type": "BUSINESS",
"name": "Cognito Inc",
"proprietary": "NIT",
"identification": "900123456",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"routerReference": "$bancorojo"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Campos de entrada:
| **Etiqueta** | **Descripción** | **Tipo** | **Longitud** | **Obligatoriedad** |
| :---------------- | :------------------------------------------------------------ | :------- | :----------------------------------------------------------- | :----------------- |
| type | Tipo de signer: BUSINESS | Texto | N/A | Si |
| name | Nombre para identificación | Texto | 1-140 carácteres | Si |
| proprietary | Tipo de documento, admite: CC,CE,PA,TI,NUIP,NIT,OTR,PPT y PEP | Texto | 1-4 | Si |
| identification | Número de identificación | Texto | 1-18 carácteres | Si |
| bankAccountType | Número de cuenta, admite: SVGS, TRAS,CACC,DBMO,DORD, DBMI | Texto | 1-4 | Si |
| bankAccountNumber | Número de la cuenta | Texto | 1-Máximo 34 dígitos | Si |
| routerReference | Identificador de billetera del banco en Transfiya. | Texto | 1- Máximo 34 caracteres alfanuméricos, debe comenzar con `$` | Si |
# Como enviar cuenta a cuenta
Source: https://transfiya.me/es/v1.104/b2b/guides/how-to-create-transfer
Guia sobre transferencias cuenta a cuenta usando Transfiya
Para soportar los modelos de transferencia en Transfiya para Empresas, es necesario permitir la referencia directa a cuentas bancarias en los campos `source` y `target` de cada transacción. La estructura de estas referencias debe contener información sobre el tipo de cuenta, el número de cuenta y el banco al cual pertenece.
## 📌 Sintaxis de Referencia
* **bankAccountType**: tipo de cuenta (en minúsculas), basado en los valores estándar de Transfiya.
* **bankAccountNumber**: número de cuenta bancaria (coincide con `labels.bankAccountNumber` del signer).
* **routerReference**: código de compensación o Bicfi válido del banco receptor.
Este formato unificado garantiza consistencia y compatibilidad con los mecanismos de enrutamiento de Transfiya, facilitando la interoperabilidad entre participantes.
## 🏦 Tipos de Cuenta Soportados
A continuación se listan los tipos de cuenta reconocidos en Transfiya:
| Nombre | Valor |
| ----------------------------- | ------ |
| Cuenta de ahorros | `svgs` |
| Cuenta corriente | `cacc` |
| Depósito de bajo monto | `dbmo` |
| Depósito ordinario | `dord` |
| Depósito inclusivo bajo monto | `dbmi` |
Estos valores deben utilizarse exclusivamente en minúsculas y reflejan el tipo de cuenta real registrada por el firmante en el sistema financiero.
## 🌐 Referencia Bancaria
El identificador del banco (`bankReference`) debe ser el código de compensación o Bicfi válido, que permita una resolución clara y única del participante receptor.
## ✅ Ejemplo de referencia válida
**svgs:44255107106500\@1001**
Transferencias cuenta a cuenta con y sin signer de tipo cuenta
Cuando el usuario receptor ya está registrado en Transfiya, la transferencia se acepta automáticamente tras la validación de reglas y ejecución del débito. Sin embargo, si el usuario aún no está registrado, el flujo requiere una etapa adicional de onboarding:
Transfiya notifica al banco destino que existe una transferencia pendiente.
El banco destino debe validar los datos y crear el firmante (usuario).
Una vez completado el onboarding, el banco acepta la transferencia manualmente.
Esta diferencia impacta directamente en los tiempos de procesamiento y en la lógica de integración de los participantes, ya que se introduce una validación activa del banco destino antes de continuar con las siguientes fases (acción, crédito y estado).
```mermaid theme={null}
sequenceDiagram
autonumber
participant sb as Banco Origen
participant ty as Transfiya
participant tb as Banco Destino
sb ->>+ ty: Crear transferencia
ty ->> ty: Validar reglas de negocio
ty -->>- sb: Transferencia creada
alt Débito (asíncrono)
ty ->>+ sb: Llamar a débito
sb ->> sb: Procesar débito
sb ->> -ty: Continuar transferencia
end
ty ->> ty: Resolver firmante destino
ty ->> ty: Aceptar transferencia
alt Acción (síncrona)
ty ->>+ sb: Llamar a acción
sb ->> sb: Procesar acción
sb -->>- ty: Respuesta de acción
end
alt Crédito (asíncrono)
ty ->>+ tb: Llamar a crédito
tb ->> tb: Procesar crédito
tb ->> tb: Firma con Signer Registrado
tb ->> -ty: Continuar transferencia
end
ty ->>+ sb: Consultar estado
sb -->>- ty: Respuesta de estado
ty ->>+ tb: Consultar estado
tb -->>- ty: Respuesta de estado
```
```mermaid theme={null}
sequenceDiagram
autonumber
participant sb as Banco Origen
participant ty as Transfiya
participant tb as Banco Destino
sb ->>+ ty: Crear transferencia
ty ->> ty: Validar reglas de negocio
ty -->>- sb: Transferencia creada
alt Débito (asíncrono)
ty ->>+ sb: Llamar a débito
sb ->> sb: Procesar débito
sb ->> -ty: Continuar transferencia
end
ty ->> ty: Resolver firmante destino
alt Onboarding (asíncrono)
ty ->>+ tb: Consultar estado (PENDING)
tb -->> ty: Confirmar recepción
tb ->> tb: Validar cuenta
tb ->>+ ty: Crear firmante
ty -->>- tb: Respuesta de creación
tb ->> -ty: Aceptar transferencia
end
alt Acción (síncrona)
ty ->>+ sb: Llamar a acción
sb ->> sb: Procesar acción
sb -->>- ty: Respuesta de acción
end
alt Crédito (asíncrono)
ty ->>+ tb: Llamar a crédito
tb ->> tb: Procesar crédito
tb ->> -ty: Continuar transferencia
end
ty ->>+ sb: Consultar estado
sb -->>- ty: Respuesta de estado
ty ->>+ tb: Consultar estado
tb -->>- ty: Respuesta de estado
```
```mermaid theme={null}
sequenceDiagram
autonumber
participant sb as Banco Origen
participant ty as Transfiya
participant tb as Banco Destino
sb ->>+ ty: Crear transferencia
ty ->> ty: Validar reglas de negocio
ty -->>- sb: Transferencia creada
alt Débito (asíncrono)
ty ->>+ sb: Llamar a débito
sb ->> sb: Procesar débito
sb ->> -ty: Continuar transferencia
end
ty ->> ty: Resolver signer genérico
ty ->> ty: Aceptar transferencia
alt Acción (síncrona)
ty ->>+ sb: Llamar a acción
sb ->> sb: Procesar acción
sb -->>- ty: Respuesta de acción
end
alt Crédito (asíncrono)
ty ->>+ tb: Llamar a crédito
tb ->> tb: Procesar crédito
tb ->> tb: Firma con Signer Genérico
tb ->> -ty: Continuar transferencia
end
ty ->>+ sb: Consultar estado
sb -->>- ty: Respuesta de estado
ty ->>+ tb: Consultar estado
tb -->>- ty: Respuesta de estado
```
Crear una transferencia hacia una cuenta bancaria se realiza de la misma forma que cualquier otra transferencia en Transfiya. La única diferencia es que, en el campo `target`, no se utiliza un **alias**, sino una **referencia directa a la cuenta bancaria**.
Este tipo de transferencia es útil cuando se conoce directamente el número de cuenta, tipo de cuenta y banco destino, sin necesidad de pasar por el directorio de alias.
Se agregan los atributos de nombre, tipo de identificación e identificación al tipo de transferencia de cuenta a cuenta. Estos serán utilizados por la entidad receptora en caso de que decida usar su signer genérico.
## Campos de entrada - Transfer cuenta a cuenta
| Nombre | Tipo | Descripción | Longitud | Obligatorio | Condiciones adicionales y reglas |
| ------------------ | ------ | ----------------------------------------- | -------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| source | string | Handle del signer origen | Min 1 -
Max 50 | SI
| N/A |
| target | string | Datos del receptor | Min 1 - Max 80 | SI | La estructura debe ser:
tipo de cuenta:número de cuenta\@código compensación del banco receptor
Ej: svgs:88745145\@1007
Los valores : y @ son fijos
El número de cuenta no deberá superar los 34 caracteres de longitud y en caso de que aplique, contemplar los 0 (ceros) a la izquierda. |
| amount | number | Monto de la transacción | Min 1 - Max 13 | SI | Separador del decimal es punto (.)
Soporta 2 decimales |
| symbol | string | Simbolo del sistema | Min 1 - Max 4 | SI | Valor estático "\$tin" |
| labels | Object | | | SI | Objeto que contiene información |
| type | string | Tipo de transacción | Min 1 - Max 4 | SI | Valo fijo "SEND" |
| domain | string | Dominio de la transacción | Min 1 - Max 3 | SI | Valor fijo "tin" |
| description | string | Descripción | Min 1 - Max 80 | NO | N/A |
| sourceChannel | string | Canal origen de la transacción | Min 1 - Max 3 | SI | Soporta: IM, POS, APP, WEB, ECOMM, ATM, PSE |
| tx\_id | string | Identificación de la transferencia | Min 1 - Max 36 | NO | Identificador asignado por la Entidad Originadora |
| transactionPurpose | string | Propósito de la transferencia | Min 1 - Max 13 | SI | Valor fijo "TRANSFER" |
| source | Object | | | SI | Objeto que contiene información |
| name | string | Nombre del originador | Min 1 Max 160 | SI | Nombre o razón social |
| proprietary | string | Tipo de documento del originador | Min 1 - Max 4 | SI | Soporta: CC,CE,PA,TI,NUIP,NIT,OTR,PPT,PEP
En mayúscula |
| identification | string | Número de identificación del originador | Min 1 Max 34 | SI | Cuando el tipo de documento es NIT, el valor es sin
digito de verificación y sin guion (9 caracteres máximo). |
| target | Object | | | SI | Objeto que contiene información |
| name | string | Nombre del beneficiario | Min 1 Max 160 | SI | Nombre o razón social |
| proprietary | string | Tipo de documento del beneficiario | Min 1 - Max 4 | SI | Soporta: CC,CE,PA,TI,NUIP,NIT,OTR,PPT,PEP
En mayúscula |
| identification | string | Número de identificación del beneficiario | Min 1 Max 34 | SI | Cuando el tipo de documento es NIT, el valor es sin
digito de verificación y sin guion (9 caracteres máximo).. |
| deviceFingerPrint | string | | | NO | Objeto que contiene información del dispositivo origen
Se envia el objeto y el campo si se logra capturar información del
dispostivo origen |
```json theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"source": "widwXWf5JLoU5NsaxLM3Sjs9gRRauC3R4H", // Handle Signer Business, Generic o Person
"target": "svgs:44255107106500@1001",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"type": "SEND",
"domain": "tin",
"description": "Salary for March",
"sourceChannel": "APP",
"tx_id": "20250114890915944TFY123456789012345",
"transactionPurpose": "TRANSFER",
"numberOfTransactions": "1",
"source":{
"name": "Johnny Wayney",
"proprietary": "cc",
"identification": "35111223456"
},
"target":{
"name": "John Wicky Wayne",
"proprietary": "cc",
"identification": "35111223455"
},
"deviceFingerPrint": {
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"country": "Colombia",
"city": "Bogotá",
"mobileDevice": "990000862471854",
"SIMCardId": "8991101200003204510",
"model": "Huawei Mate 20 Pro",
"operator": "Bharti Airtel Limited"
}
}
}' "/v1/transfer"
```
```json theme={null}
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wfvmRir8XxRtoEuUBDkv3BP4T7BQezwm1f",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "SEND",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "PENDING",
"tx_ref": "Lf13jsK83omPv3bOt",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:40:57.322-05:00",
"description": "DEV - SEND trx 01",
"sourceChannel": "APP",
"transactionPurpose": "TRANSFER",
"numberOfTransactions": "1",
"name": "John Wicky Wayne",
"proprietary": "cc",
"identification": "35111223455",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
}
},
},
"target": {
"signer": {
"handle": "wfvmRir8XxRtoEuUBDkv3BP4T7BQezwm1f",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
## 🧩 ¿Qué hacer si la cuenta destino no está registrada?
En los flujos de transferencia **cuenta a cuenta**, es posible que la cuenta destino no tenga un *signer* activo en el sistema. En ese caso, **`Transfiya invoca automáticamente el endpoint /credit de la entidad receptora`**, utilizando un *signer genérico*. Este mecanismo permite acreditar fondos incluso cuando el usuario aún no ha sido registrado formalmente.
Para que esta funcionalidad funcione correctamente, la entidad receptora debe haber creado previamente un signer genérico . Puedes revisar cómo hacerlo en la sección de
.
### 🏦 ¿Cómo se acredita la cuenta?
Transfiya envía al endpoint `/credit` toda la información necesaria que la entidad receptora necesita para realizar la acreditación de fondos. Esta información viene dentro del campo `target.signer.labels` e incluye:
* `name`: Nombre del titular
* `proprietary`: Tipo de documento (ej. CC, NIT)
* `identification`: Número de identificación
* `bankAccountType`: Tipo de cuenta (`svgs`, `cacc`, etc.)
* `bankAccountNumber`: Número de cuenta
* `bankId`: Identificador del banco (BICFI)
Solo deben implementar este proceso aquellas entidades que no hayan implementado el onboarding automático para transferencias cuenta a cuenta y hayan configurado previamente un signer genérico.
### 🧪 Ejemplo del endpoint `/credit`
```bash theme={null}
POST https://ban.co/transfiya/credit
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "82de7c0b8b34c7ca6c52547161b2629b1c1e6bdef402999ad60266e6760e4d24",
"type": "SEND",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "COMPLETED",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:41:00.841-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
✅ ¿Qué hace la entidad receptora?
La entidad receptora debe procesar la acreditación utilizando únicamente los datos recibidos en target.signer.labels. Esto le permite evitar procesos de onboarding y acreditar directamente a la cuenta bancaria especificada por la entidad originadora.
Este flujo permite interoperabilidad con cuentas no registradas, mejorando la experiencia del usuario sin sacrificar seguridad ni trazabilidad.
## 🕵️ ¿Qué hacer si no tengo la información de la cuenta del receptor?
En algunos casos, la entidad originadora puede no tener acceso directo al tipo y número de cuenta del cliente receptor. Para estos escenarios, Transfiya permite realizar una búsqueda utilizando alias registrados, ya sea para personas o empresas, mediante el **Directorio Federado**.
Para ello, existen dos servicios disponibles:
* `lookup.dice`: para búsquedas reguladas bajo el modelo SPI.
* `signer.lookup`: para búsquedas no reguladas.
Estos métodos permiten al participante origen consultar el alias y recuperar toda la información necesaria del firmante receptor para poder inicializar correctamente una transacción de tipo cuenta a cuenta.
### 🔍 Ejemplo de uso de `lookup.dice`
```bash theme={null}
curl --location '{{url}}/v1/signer/lookup.dice' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data-raw '{
"aliasValue": "@testing",
"received": "2025-04-10T15:49:15.015-05:00",
"dispatched": "2025-04-10T15:49:15.015-05:00"
}'
```
📦 ¿Qué devuelve la consulta?
La respuesta del directorio incluye datos esenciales como: • Nombre completo del titular • Tipo de cuenta (svgs, cacc, etc.) • Número de cuenta • Tipo y número de documento • Banco asociado
Con esta información, la entidad originadora puede construir la referencia de cuenta y ejecutar la transferencia como si ya conociera esos datos desde el inicio.
Esta funcionalidad es especialmente útil en transferencias empresariales o institucionales donde las relaciones entre participantes están basadas en alias conocidos públicamente.
# ¿Cómo actualizar reglas de negocio para una empresa?
Source: https://transfiya.me/es/v1.104/b2b/guides/how-to-setup-business-rules
Se pueden configurar reglas de negocio para signers (originadores) que sean de tipo BUSINESS o GENERIC. Las reglas que se pueden parametrizar son las siguientes:
| Regla | Campo en el objeto `signer` | Tipo | Longitud / Validación |
| ------------------------------------ | --------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------- |
| Monto máximo de transferencia | `labels.maxAmountOfTransfer` | Number | Habilitado para recibir el valor máximo para el tipo de dato. Este valor contiene dos decimales al final. |
| Cantidad de transferencias en el día | `labels.dailyCountOfTransfersLimit` | Number | Habilitado para recibir el valor máximo para el tipo de dato |
| Monto acumulado en el día | `labels.dailySumAmountOfTransfersLimit` | Number | Habilitado para recibir el valor máximo para el tipo de dato. Este valor contiene dos decimales al final. |
```json theme={null}
Request:
curl -X PUT \
-H "x-api-key: API_KEY" \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"labels": {
"maxAmountOfTransfer": 10000000,
"dailyCountOfTransfersLimit": 100,
"dailySumAmountOfTransfersLimit": 100000000
}
}' "URL/v1/signer/SIGNER_HANDLE"
```
```json theme={null}
Response:
{
"id": "11259be1-e38a-4970-bfc8-c7824e29ae76",
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2", "labels": {
"type": "PERSON",
"createdBy": "tcYV0MRoklTXUwSFFkkQ",
"created": "2022-04-12T16:17:49-05:00",
"routerReference": "$bancorojo",
"name": "",
"maxAmountOfTransfer": 10000000,
"dailyCountOfTransfersLimit": 100,
"dailySumAmountOfTransfersLimit": 100000000
},
"signer_id": "11259be1-e38a-4970-bfc8-c7824e29ae76",
"keeper": [
{
"public": "04513ecd39384a91181df50fa995e63995c9d2e683f8a607bd43b939f607dc269958653eef349e864
8af85a5f369a0c19432c2c60a9bc483eac45c43811ef96fc7",
"scheme": "ecdsa-ed25519",
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
## Lista de códigos de error
A continuación se listan los códigos de error asociados a esta operación:
| Código de error | Descripción | HTTP Status |
| --------------- | --------------------------------------------- | ----------- |
| 99 | Error inesperado del servidor | 400 |
| 100 | No tienes permisos para acceder a este método | 403 |
| 102 | Etiquetas inválidas | 400 |
| 118 | Error de validación del esquema del recurso | 400 |
| 121 | Firmante no encontrado en la base de datos | 400 |
# Empresas
Source: https://transfiya.me/es/v1.104/b2b/intro/intro-b2b
Introducción a la sección de empresas de Transfiya
# 💼 Introducción – Transfiya para Empresas
**Transfiya para Empresas** permite a los bancos extender los servicios de pagos en tiempo real a sus clientes empresariales, aprovechando la infraestructura ya consolidada de Transfiya. Esta expansión habilita el envío y recepción de fondos hacia y desde números de cuenta de forma instantánea, desbloqueando nuevos flujos transaccionales como **B2P, P2B, P2M y B2B**.
Al integrar estos nuevos flujos, los bancos pueden ofrecer a las empresas los mismos beneficios que ya disfrutan más de 12 millones de usuarios individuales, como mayor liquidez, eficiencia operativa y una inclusión financiera más amplia.
## 🏦 ¿Cómo agrega valor a los bancos?
Los pagos en tiempo real han dejado de ser una novedad para convertirse en una necesidad. Al integrar Transfiya para Empresas, los bancos logran:
* Mayor adopción de pagos digitales por parte de clientes empresariales.
* Liquidez instantánea en las cuentas de las empresas.
* Menor dependencia de compensaciones en lote (batch).
* Eficiencia operativa gracias al monitoreo en tiempo real, reduciendo reclamos y disputas.
* Nuevas oportunidades de ingresos mediante tarifas transaccionales y servicios de valor agregado.
* Mejor experiencia para los clientes empresariales al ofrecer pagos instantáneos y conciliaciones sin fricción.
La capacidad de monitorear cada transacción en tiempo real mejora significativamente la trazabilidad y reduce disputas operativas.
## 🧾 ¿Cómo agrega valor a las empresas?
Independientemente del sector o del tamaño, las empresas se benefician especialmente en dos aspectos clave: **liquidez inmediata** y **eficiencia operativa**. Algunos ejemplos incluyen:
* **Desembolsos en tiempo real**: pagos inmediatos a empleados o contratistas.
* **Reembolsos y conciliaciones más rápidas**: mejora en el manejo del flujo de caja.
* **Mejor experiencia al cliente**: devoluciones, pagos y abonos instantáneos.
* **Nuevas formas de pago**: facturación en tiempo real, pagos con QR, débitos directos, etc.
Estas funcionalidades permiten a las empresas competir con mejores condiciones financieras y operativas, sin depender de infraestructura tradicional de pagos.
## 🌐 ¿Cómo potencia el ecosistema P2P existente?
Transfiya ya procesa más de **40 millones de transacciones P2P mensuales**, con un SLA de **99.99%** de disponibilidad. Al extender este ecosistema robusto al ámbito empresarial, se capitaliza:
* Infraestructura segura y escalable.
* Base de usuarios activos (+12 millones).
* Interoperabilidad entre múltiples instituciones financieras.
La interoperabilidad existente entre participantes permite una adopción inmediata sin desarrollos complejos de integración.
# Casos de Uso
Source: https://transfiya.me/es/v1.104/b2b/intro/use-cases
Casos de Uso para Empresas
Transfiya para Empresas habilita múltiples flujos transaccionales que impactan positivamente distintos tipos de operaciones y relaciones financieras. A continuación, se detallan los principales escenarios de uso disponibles a través de la solución:
***
## 🔄 B2P – De Empresa a Persona
Las empresas pueden realizar pagos instantáneos a individuos, optimizando procesos como:
* **Pagos bajo demanda**: Envíos inmediatos desde portales empresariales o apps móviles.
* **Nómina y pagos a proveedores en lote**: Procesamiento masivo con trazabilidad completa de cada transacción.
* **Integración vía APIs (BaaS)**: Automatización de pagos para plataformas, fintechs o ERPs.
* **Pagos gubernamentales (G2P)**: Desembolsos individuales o masivos por parte de entidades estatales.
El canal B2P permite mejorar la experiencia del receptor final, reduciendo tiempos de espera y eliminando intermediarios tradicionales.
***
## 💳 P2B – De Persona a Empresa
Los usuarios pueden realizar pagos directos a empresas de forma sencilla y segura:
* **Solicitudes de pago en tiempo real**: Enviadas desde Transfiya, facilitando la recolección inmediata.
* **Solicitudes masivas**: Generadas desde portales corporativos, ideales para cobros sistemáticos o facturación periódica.
* **Pagos recurrentes**: Aplicables a modelos de suscripción como servicios digitales, membresías o SaaS.
* **Botón de pago Transfiya**: Alternativa en tiempo real a medios tradicionales como PSE o tarjetas.
Esta modalidad reduce el fricción del usuario en procesos de pago y aumenta la conversión en canales digitales.
***
## 🛒 P2M – De Persona a Comercio
Transfiya también habilita pagos ágiles en el punto de venta, tanto físico como digital:
* **Pagos con código QR**: Escaneo y confirmación inmediata desde el móvil del usuario.
* **Pagos con NFC**: A través de apps bancarias, sin necesidad de datáfono o terminal físico.
Con estas opciones, los comercios pueden reducir costos operativos asociados a pasarelas de pago tradicionales.
***
## 🏢 B2B – De Empresa a Empresa
Flujos optimizados entre actores empresariales, facilitando la gestión financiera y operativa:
* **Pagos a proveedores**: Liquidación de facturas en tiempo real.
* **Transferencias interempresariales**: Movimientos entre cuentas de una misma empresa o grupo corporativo.
* **Pagos integrados vía API**: Automatización dentro de plataformas de gestión empresarial.
* **Pagos de comercio o liquidaciones**: Procesamiento inmediato para reducir riesgos y mejorar la transparencia financiera.
Todas estas operaciones pueden ejecutarse mediante archivos planos desde portales empresariales, integración por API o conectores dentro de sistemas financieros ya existentes.
# Modelo de datos
Source: https://transfiya.me/es/v1.104/directory/about/about-data-model
Descripción detallada sobre el modelo de datos en Transfiya
## Modelo de data
La mayoría de los campos establecidos en la regulación ya están siendo registrados en Transfiya. El modelo de datos detallado con las diferencias se puede encontrar a continuación:
| Nombre | Transfiya | Requerido | Condición | Tipo | Validación | Comentario |
| ---------------------------------------- | ------------------------- | ----------------------- | ------------------------------------ | ----- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Tipo de llave | labels.aliasType | Requerido | | Texto | Ver tabla `labels.aliasType` | Nuevo valor requerido por regulación. |
| Valor de llave | labels.aliasValue | Requerido | | Texto | Ver tabla `labels.aliasValue` | No distingue entre mayúsculas y minúsculas, se almacena en mayúsculas. |
| Estado de llave | labels.status | Opcional con condición | No permitido en llamada de creación. | Texto | Ver tabla `labels.status` | ACTIVE por defecto. |
| Identificador | handle | Opcional | | Texto | 26-35 caracteres alfanuméricos con estructura base58 | |
| Tipo de identificación | labels.proprietary | Requerido | | Texto | Ver tabla `labels.proprietary` | |
| Descripción | labels.description | Opcional | | Texto | Máximo 255 caracteres. | |
| Número de identificación | labels.identification | Requerido | | Texto | Máximo 18 caracteres alfanuméricos, caracteres especiales no permitidos. | |
| Tipo de cliente | labels.type | Requerido | | Texto | Uno de los valores: PERSON, BUSINESS, TROUPE | Solo PERSON y BUSINESS son usados para transferencias reguladas. |
| Nombre de entidad legal del cliente | labels.name | Requerido con condición | labels.type = 'BUSINESS' | Texto | 1-140 caracteres | |
| Primer nombre del cliente | labels.firstName | Requerido con condición | labels.type = 'PERSON' | Texto | 1-40 caracteres | |
| Segundo nombre del cliente | labels.secondName | Opcional con condición | labels.type = 'PERSON' | Texto | 1-40 caracteres | Nuevo valor requerido por regulación. |
| Primer apellido del cliente | labels.lastName | Opcional con condición | labels.type = 'PERSON' | Texto | 1-40 caracteres | Cambiado a obligatorio para coincidir con la regulación. |
| Segundo apellido del cliente | labels.secondLastName | Opcional con condición | labels.type = 'PERSON' | Texto | 1-40 caracteres | Nuevo valor requerido por regulación. |
| País de residencia | labels.countryOfResidence | Opcional | | Texto | Código ISO de país de 2 caracteres. [https://www.iso.org/obp/ui](https://www.iso.org/obp/ui/#search) | |
| Identificación de entidad emisora | labels.createdBy | Generado por Transfiya | | Texto | Referencia de participante Transfiya | Identificador de billetera del banco en Transfiya. |
| Tipo de método de pago | labels.bankAccountType | Requerido | | Texto | Uno de los valores:SVGS, CACC, DBMO, DORD, DBMI | |
| Número de método de pago | labels.bankAccountNumber | Requerido | | Texto | Máximo 34 dígitos | |
| Código nacional del banco | labels.bankBicfi | Opcional | | Texto | 4 dígitos | |
| Nombre del banco | labels.bankName | Opcional | | Texto | Máximo 64 caracteres | |
| Número de identificación del banco | labels.bankId | Opcional | | Texto | Máximo 9 caracteres numéricos | Representa un número NIT del banco sin dígito de verificación o un código asignado por BanRep. |
| Referencia del router del banco | labels.routerReference | Requerido | | Texto | Máximo 34 caracteres alfanuméricos, debe comenzar con `$` | Identificador de billetera del banco en Transfiya. |
| Fecha/hora de creación del registro | labels.created | Generado por Transfiya | | Texto | Fecha y hora en formato ISO 8601 | |
| Fecha/hora de modificación del registro | labels.updated | Generado por Transfiya | | Texto | Fecha y hora en formato ISO 8601 | |
| Código SPBVI objetivo | labels.targetSpbviCode | Opcional | | Texto | Ver tabla `labels.targetSpbviCode` | TFY por defecto. |
| Fecha/hora de consentimiento del usuario | labels.consented | Opcional | | Texto | Fecha y hora en formato ISO 8601, será establecido por Transfiya si no se proporciona. | Nuevo campo para registrar el momento en que el usuario dio consentimiento para registrar datos. |
| Keeper | keeper | Requerido | | Array | Ver tabla `keeper` | Llave pública del firmante. |
### Tipos de llaves
Para hacer que los signers sean compatibles con la regulación, se han añadido nuevas etiquetas que definen claramente el tipo y valor de cada alias (llave). Estas etiquetas permiten una integración fluida entre el sistema Transfiya y los requisitos regulatorios establecidos.
Signer label (`labels.aliasType`):
| Name | Transfiya | Regulation |
| --------------- | --------- | ---------- |
| Phone number | PHONE | M |
| Alphanumeric | ALPHANUM | O |
| Email | EMAIL | E |
| Document number | NRIC | NRIC |
| Merchent Id | MERCHANT | B |
Ejemplo y validaciones de alias label (`labels.aliasValue`):
| Tipo de alias | Ejemplo | Validación | Comentario |
| ------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| Número de teléfono | `3012344567` | Debe comenzar con `3` y tener 9 dígitos después de este prefijo. | |
| Alfanumérico | `@JORGE35` | Comienza con el símbolo `@`. Máximo 20 caracteres alfanuméricos y mínimo 5 caracteres alfanuméricos (No puede incluir espacios, tildes ni el caracter ñ) después del símbolo `@`. | El símbolo `@` está reservado para IDs alfanuméricos, nombres de usuario, etc. |
| Correo electrónico | `TEST@COMPANY.IO` | Máximo 92 caracteres. Debe tener un único carácter `@`. Máximo 30 caracteres antes del `@` y 61 después. | |
| Número de documento | `PR5002499` | Mínimo 3 y máximo 18 caracteres alfanuméricos, no se permiten caracteres especiales. | El número de identificación del documento debe ser único en el sistema, incluso si se repite en Colombia. |
| ID de comerciante | `0012345678` | Comienza con `00` y tiene 10 dígitos en total. | |
### Status de signers (llaves regulatorias)
Signers van a incluir el estado de las llaves regulatorias asociadas a cada signer.
Los estados se manejan usando el label staus an nivel de signer (`labels.status`):
| Name | Transfiya | Regulation |
| ---------------------- | -------------------------- | ---------- |
| Active | ACTIVE | ACTV |
| Blocked by client | SUSPENDED\_BY\_CLIENT | SUSP |
| Blocked by participant | SUSPENDED\_BY\_PARTICIPANT | SUSB |
| Inactive (cancelled) | INACTIVE | ICTV |
### Tipo de documento
Document type enum (`labels.proprietary`):
| Name | Transfiya | Regulation | Comment |
| ------------------------------------- | --------- | ---------- | -------------------------------- |
| Citizenship Card | CC | CC | |
| Foreign ID Card | CE | CE | |
| Passport Number | PA | PAS | |
| Identity Card | TI | TDI | |
| Unique Personal Identification Number | NUIP | NUIP | |
| Tax Identification Number | NIT | NIT | |
| Other | OTR | - | Not supported by regulation |
| Temporary Protection Permit | PPT | PPT | New value required by regulation |
| Special Stay Permit | PEP | PEP | New value required by regulation |
### Tipo de cuenta
Tipo de cuenta (`labels.bankAccountType`):
| Name | Transfiya | Regulation | Comment |
| ----------------------------- | --------- | ---------- | -------------------------------- |
| Savings accounts | SVGS | CAHO | |
| Cash trading account | TRAS | - | Not supported by regulation |
| Current account | CACC | CCTE | |
| Other | OTHR | - | Not supported by regulation |
| Low-amount deposits | DBMO | DBMO | New value required by regulation |
| Ordinary deposits | DORD | DORD | New value required by regulation |
| Inclusive low-amount deposits | DBMI | DBMI | New value required by regulation |
### Codigos de participantes SPBVI
SPBVI codes (`labels.targetSpbviCode`):
| Name | Code |
| ------------- | ---- |
| Transfiya | TFY |
| Entre cuentas | ENT |
| Credibanco | CRB |
| Visionamos | VIS |
| Servibanca | SRV |
### Keeper (firmas digitales)
El objeto Keeper contiene información de la llave almacenada en el lado del banco que se utiliza para asegurar este firmante y autorizar los pagos relacionados con él.
Los campos del keeper se definen a continuación y siguen en el modelo actual:
| Nombre | Campo | Tipo | Requerido | Validación |
| ------------- | ------ | ----- | --------- | --------------------------------------- |
| Tipo de llave | scheme | Texto | Requerido | Uno de:`ecdsa-ed25519`, `eddsa-ed25519` |
| Llave pública | public | Texto | Requerido | 64-130 caracteres |
### Logica campo "amount" para la generación de un QR.
El campo amount en la generación de códigos QR de tipo **ESTATICO**.
* Este campo no debe ser enviado en la generación del QR, permitiendo que el usuario ingrese el valor a pagar.
* En caso de ser enviado, deberá tener un valor mayor a cero (0) y el QR se considerará como **QR de tipo HÍBRIDO**.
Los **campos de IVA** serán obligatorios, en la generación de QR tanto persona **Natural** como **Jurídica**.
* Sus valores podrán ser **iguales o mayores a cero**, soportando **dos (2) decimales separados por punto** (Base 100).
* Los campos deberán enviarse de la siguiente forma:
```json theme={null}
"vat": 0.00,
"vatBase": 0.00,
"tax": 0.00
```
### Logica Tag 50 QR.
Con el objetivo de asegurar la correcta construcción de la llave tipo *merchant*, se establece el siguiente ajuste en la lógica de lectura:
**Validación de longitud de la etiqueta (len)**
**Caso 1: Longitud mayor a 30**
Cuando el valor de “**len” sea mayor a 30**, se deberá aplicar la siguiente lógica:
* Omitir los primeros **4 caracteres** del campo data.
* Tomar los siguientes **10 caracteres**, los cuales conformarán la estructura de la llave tipo *merchant*.
**Ejemplo:**
TAG: "50"
len: 31
data: "[011000911500130013CO.COM.RBM.CU](http://011000911500130013CO.COM.RBM.CU)"
**Resultado esperado (llave merchant):**
0091150013
**Caso 2: Longitud igual a 30**
Cuando el valor de “**len” sea igual a 30**, se deberá aplicar el siguiente tratamiento:
* Omitir los primeros **4 caracteres** (correspondientes a la red adquiriente).
* El siguiente carácter será siempre **"9"**, el cual deberá ser reemplazado por **"00"**.
* Los siguientes **8 caracteres** completarán la estructura de la llave tipo *merchant*.
**Ejemplo:**
TAG: "50"
len: 30
data: “[01099389706120013CO.COM.RBM.CU](http://01099389706120013CO.COM.RBM.CU)”
**Resultado esperado (llave merchant):**
0038970612
# Errores de DICE
Source: https://transfiya.me/es/v1.104/directory/about/about-errors
Guía completa sobre el manejo de errores en el sistema DICE
## Resumen
Transfiya implementa un sistema de gestión de errores fundamentado en el estándar HTTP, proporcionando una estructura clara y coherente para el manejo de excepciones.
Aunque los sistemas externos emplean códigos de error particulares, Transfiya ha desarrollado un mecanismo de mapeo que convierte automáticamente estos códigos a su propia arquitectura estandarizada de errores HTTP.
Esta avanzada capacidad de normalización optimiza significativamente el proceso de integración para los participantes del ecosistema, minimizando o incluso eliminando por completo la necesidad de desarrollar lógicas personalizadas para el tratamiento de errores específicos.
Los errores de MOL y DICE se incluyen aquí solo con fines de referencia. El participante no necesita mapear errores de DICE directamente.
### Mensajes de error Transfiya
Cuando se produce un error durante una transferencia o en el sistema de directorio, la plataforma responde con códigos de estado HTTP específicos y un objeto de error estructurado que proporciona información detallada sobre la incidencia.
El sistema implementa una clasificación estratégica de códigos de error organizados en rangos específicos, facilitando una categorización clara, identificación rápida y resolución eficiente de incidencias.
La estructura de errores está distribuida estratégicamente según el tipo de participante afectado:
* `1xx` - Errores de sistema TransfiYa
* `3xx` - Errores de participantes
El sistema Transfiya implementa un protocolo de respuesta estandarizado. Todas las solicitudes procesadas exitosamente hacia la plataforma retornan invariablemente un código de estado HTTP `200`.
Cuando ocurre algún error durante el procesamiento, el sistema devuelve un objeto de error estructurado que contiene un código numérico específico y una descripción clara del problema, facilitando su identificación y resolución.
```json theme={null}
{
"error": {
"code": ,
"message": ""
}
}
```
```jsx theme={null}
{
"error": {
"code": 123,
"message": "DICE error: Key already registered with same account number"
}
}
```
En el caso de respuestas exitosas, un objeto de error con código `0` se añade a la respuesta original.
### Estrategia de mapeo integral
TransfiYa implementa validaciones exhaustivas de todos los campos y esquemas según los requisitos regulatorios, lo que mitiga significativamente la posibilidad de que ocurran errores de DICE.
No obstante, documentamos estos mapeos de errores como medida preventiva para garantizar una respuesta adecuada ante situaciones excepcionales o imprevistas que pudieran presentarse.
La estrategia general de mapeo es la siguiente:
| Categoria | Descripcion |
| ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `118 - ResourceValidationError` | Los errores de validación de campos. |
| `118 - DICE error: The participant cannot be determined` | El participante que está intentando realizar la operación no existe en el directorio centralizado. |
| `120 - DICE error: Request timeout` | No se recibe respuesta del DICE dentro de los tiempos regulatorios. |
| `121 - DICE error: Keys not found or inactive` | La llave no existe en el directorio federado ni en el centralizado. |
| `122 - Signer with alias @ABC123 already exists in database.` | La llave que se intenta registrar solo en directorio federado ya existe. |
| `123 - DICE error: Duplicate Detected` | La llave ya se encuentra registrada en el directorio federado y centralizado. |
| `123 - DICE error: Key registered by another financial entity` | La llave se encuentra registrada con otra entidad financiera. |
| `123 - DICE error: Key already registered by the same financial entity but different account number` | La llave ya se encuentra registrada en la misma entidad, pero con una cuenta diferente. |
| `123 - DomainRuleViolationError` | Todas las reglas de negocio, por ejemplo, el tiempo después del cual se puede volver a utilizar una clave cancelada. |
| `136 - ApiError` | Todos los errores técnicos, por ejemplo, problemas relacionados con una configuración inválida. |
| `100 - ForbiddenError` | Los errores de seguridad. |
### Alertas sobre esquemas
Por temas de interoperabilidad, Transfiya implemento modelo de advertencias o soft error validations (warrings) para habilitar entidades compatilidad el sistema actual. Eso permite que no tenemos cambios criticos en el entorno de certificacion o produccion de transfiya.
Las advertencias del sistema se adhieren rigurosamente al estándar HTTP y se transmiten a través de los encabezados de error.
A continuación se muestra un ejemplo representativo de una advertencia:
`X-Warning: 118 *labels.type* is required. This will become an error after September 2025`
A partir de la entrada en operación del DICE en producción todos los participantes deben cumplir con el esquema regulatorio, de lo contratio tranfiya no procesara la petición.
### Mapeo de Errores DICE
| DICE error code | DICE response status | DICE operations | DICE error message | Transfiya error code | Transfiya error name | Transfiya error message |
| --------------- | -------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| C401 | RJCT | NEWR, AMND | El NIT debe ser de 9 dígitos | 118 | ResourceValidationError | DICE error: The NIT must be 9 digits long. |
| C402 | RJCT | NEWR, AMND | El número de medio de pago excede 34 dígitos | 118 | ResourceValidationError | DICE error: The payment method number exceeds 34 digits |
| C403 | RJCT | NEWR, AMND | El tipo de medio de pago debe ser uno de los registrados en el diccionario global | 118 | ResourceValidationError | DICE error: The payment method type must be one of those registered in the global dictionary. |
| C404 | RJCT | NEWR, AMND | La EASPBV Receptor debe ser una de las registradas en el diccionario global | 121 | ResourceNotFoundError | DICE error: The EASPBV Receiver must be one of those registered in the global dictionary. |
| C405 | RJCT | NEWR, AMND | El tipo de documento debe ser uno de los registrados en el diccionario global | 118 | ResourceValidationError | DICE error: The document type must be one of those registered in the global dictionary. |
| C406 | RJCT | NEWR, AMND | El tipo de persona debe ser uno de los registrados en el diccionario global | 118 | ResourceValidationError | DICE error: The person type must be one of those recorded in the global dictionary. |
| C407 | RJCT | NEWR, AMND | Para persona natural se debe diligenciar al menos el primer nombre y apellido. En Dsplnm y Nn debe ir una 'N' | 118 | ResourceValidationError | DICE error: For natural persons, at least the first and last name must be entered. The Dsplnm and Nn must be empty. |
| C408 | RJCT | NEWR, AMND | Para persona jurídica debe ser igual el nombre en el Dsplnm y Nn. Los campos de nombres y apellidos de persona natural deben estar vacíos. | 118 | ResourceValidationError | DICE error: For legal entities, the name in the Dsplnm and Nn must be the same. The first and last names fields for natural persons must be empty. |
| C409 | RJCT | NEWR, AMND | Se excede la longitud para nombre de persona jurídica o natural | 118 | ResourceValidationError | DICE error: The length for the name of a legal or natural person is exceeded. |
| C410 | RJCT | NEWR, AMND | La llave debe cumplir las reglas adicionales | 123 | DomainRuleViolationError | DICE error: The key must comply with additional rules. |
| C411 | RJCT | NEWR, DEAC | La llave ha sido cancelada y no cumple el número mínimo de días para registrarse nuevamente. | 123 | DomainRuleViolationError | DICE error: The key has been canceled and does not meet the minimum number of days to register again. |
| C412 | RJCT | DEAC | En la operación DEAC el campo AllowSecIDUpdate debe incluir 'Y' o 'N'. | 118 | ResourceValidationError | DICE error: Field AllowSecIDUpdate must be Y or N in DEAC operation. |
| C413 | RJCT | DEAC | El formato del campo CreDtTm no está en formato UTC-05 | 118 | ResourceValidationError | DICE error: CreDtTm is not on UTC-05:00 time zone |
| C414 | RJCT | DEAC | El año, mes y día del campo CreDtTm no corresponden con la hora Colombiana UTC-05 | 118 | ResourceValidationError | DICE error: CreDtTm field does not correspond to the current date |
| U000 | ACTC | NEWR, AMND | Operación exitosa | 0 | - | Success |
| U101 | RJCT | NEWR, AMND, DEAC, SUSP, SUSB, ACTV, ACTB | Tenant Id no encontrado. Debe ser DICETEST01 | 136 | ApiError | DICE error: Tenant ID not found. Must be DICETEST01. |
| U103 | RJCT | NEWR, AMND, DEAC | El código de la EASPBV no existe | 121 | ResourceNotFoundError | DICE error: The EASPBV code does not exist. |
| U119 | RJCT | NEWR, AMND | Error de sesión (errores de validación) | 136 | ApiError | DICE error: Session error. |
| U122 | RJCT | NEWR, AMND, DEAC, SUSP, SUSB, ACTV, ACTB | Se genera cuando el canal no está abierto211 | 136 | ApiError | DICE error: Channel not open. |
| U212 | RJCT | NEWR, AMND, DEAC, SUSP, SUSB, ACTV, ACTB | Mensaje enviado por un canal que no corresponde | 136 | ApiError | DICE error: Message sent by an inappropriate channel. |
| U250 | RJCT | NEWR, AMND | El tipo de llave debe ser uno de los registrados en el diccionario global | 118 | ResourceValidationError | DICE error: The key type must be one of those registered in the global dictionary. |
| U801 | RJCT | NEWR, AMND | No se puede determinar el participante | 118 | ResourceValidationError | DICE error: The participant cannot be determined. |
| U804 | RJCT | AMND, DEAC, SUSP, SUSB, ACTV, ACTB | La llave no existe o esta Inactiva. | 121 | ResourceNotFoundError | DICE error: The key does not exist or is inactive. |
| U805 | RJCT | AMND, SUSP, SUSB, ACTV, ACTB | La llave está suspendida por el cliente. | 123 | DomainRuleViolationError | DICE error: The key is suspended by the customer. |
| U806 | RJCT | NEWR, SUSP, SUSB, ACTV, ACTB | La llave ya está registrada con la misma entidad financiera, pero cuenta distinta. | 123 | DomainRuleViolationError | DICE error: The key is already registered with the same financial institution, but to a different account. |
| U807 | RJCT | NEWR | La llave ya está registrada con otra entidad financiera. | 123 | DomainRuleViolationError | DICE error: Key registered by another financial entity |
| U808 | RJCT | NEWR | La llave ya se encuentra registrada con la misma cuenta. | 123 | DomainRuleViolationError | DICE error: The key is already registered with the same account. |
| U809 | RJCT | AMND, DEAC, SUSP, SUSB, ACTV, ACTB | Signer no encontrado. | 121 | ResourceNotFoundError | DICE error: Signer not found. |
| U811 | RJCT | AMND, DEAC, SUSP, SUSB, ACTV | La llave está suspendida por el participante. | 123 | DomainRuleViolationError | DICE error: The key is suspended by the participant. |
Sistema DICE no esta en una version estable y no se garantiza que los errores sean consistentes.
DICE y MOL se basan en el Switch ACI, que es fundamentalmente un bus de mensajes tradicional, no una solución basada en web.
Referencia para el mapeo se uso el documento Directorio Centralizado DICE Documento de Especificaciones Técnicas para la Implantación de BRE-B Dirección General de Tecnología Versión 2.2.1 2025-03-07
# Los estados
Source: https://transfiya.me/es/v1.104/directory/about/about-key-status
Descripción sobre los estados de llaves en el DICE
## Introducción
Bre-B ha implementado un modelo sofisticado para gestionar el estado de las llaves que se sincronizan con el directorio centralizado.
Este modelo está diseñado para funcionar de manera transparente, sin requerir trabajo adicional por parte de los participantes, ya que es administrado íntegramente por el sistema Transfiya.
Este modelo solo podrá ser probado e implementado cuando DICE esté completamente funcional.
## Máquina de estados
El directorio centralizado gestionará el estado de las llaves mediante códigos de error específicos. La función de Transfiya en este proceso se limita a mapear estos errores al estándar vigente.
| Estado | ACTV (cliente) | ACTV (participante) | ICTV | SUSP | SUSPB |
| ------ | -------------- | ------------------- | ---- | ---- | ----- |
| ACTV | U805 | U805 | U000 | U000 | U000 |
| ICTV | U804 | U804 | U804 | U804 | U804 |
| SUSP | U000 | U805 | U000 | U805 | U000 |
| SUSPB | U811 | U000 | U811 | U811 | U000 |
Los errores visibles para los participantes se basarán en los errores estándar HTTP:
| Estado | Activo cliente | Activo participante | Inactivo | Suspendido cliente | Suspendido participante |
| --------------------------- | -------------- | ------------------- | -------- | ------------------ | ----------------------- |
| Activo | 123 | 123 | 0 | 0 | 0 |
| Inactivo | 121 | 121 | 121 | 121 | 121 |
| Suspendido por cliente | 0 | 123 | 0 | 123 | 0 |
| Suspendido por participante | 123 | 0 | 123 | 123 | 0 |
Nombres de estaddos registrados en transfiya mapeado a DICE:
| Name | Transfiya | Regulation |
| ---------------------- | -------------------------- | ---------- |
| Active | ACTIVE | ACTV |
| Blocked by client | SUSPENDED\_BY\_CLIENT | SUSP |
| Blocked by participant | SUSPENDED\_BY\_PARTICIPANT | SUSB |
| Inactive (cancelled) | INACTIVE | ICTV |
# Signers (Llaves)
Source: https://transfiya.me/es/v1.104/directory/about/about-signers
Resumen detallado sobre las llaves y signers en el sistema
## Sobre las llaves y signers
Las llaves a nivel de regulación se mapearán a los signers de Transfiya en una relación uno a uno.
Transfiya soporta multiples llaves usando el modelo de signers que representan credenciales de pago que incluye datos personales, el tipo de cuenta y el estado de la cuenta.
Signers se pueden usar para transferencias reguladas y no reguladas.
Una llave es relacionada a un credencial de pago o signer.
```mermaid theme={null}
flowchart LR
classDef alias stroke-dasharray: 5 5;
A1[Llave 1
phone::$5712345]:::alias --> K1[Credencial de pago 1
chck:34243244343]
A2[Llave 2
email::pedro#8203;@perez.co]:::alias --> K2[Credencial de pago 1
svgs:42424234]
```
```mermaid theme={null}
flowchart LR
W1[Wallet 1
phone: $5712345] --> S1[Signer 1
account: 102020]
W1 --> S2[Signer 2
account: 75840]
W2[Wallet 2
phone: $5798745] --> S2
W2 --> S3[Signer 3
Account: 584886]
W3[Wallet 3
phone: $5755849] --> S4[Signer 4
account: 974847]
```
# Marcas de tiempo
Source: https://transfiya.me/es/v1.104/directory/about/about-timestamps
Descripción detallada sobre marcas de tiempo Bre-B
## Marcas de tiempo
### Objetivo Bre-B
Bre-B espera realizar un seguimiento preciso de los tiempos necesarios para resolver las claves y ejecutar las operaciones de transferencia.
El objetivo del banco central es eliminar la latencia de la red en los reportes de marcas de tiempo. La razón principal de este modelo es que la mayoría de los participantes utilizan un sistema basado en colas y comunicación síncrona.
### Monitoreo Transfiya
La plataforma Transfiya es una plataforma nativa en la nube que registra automáticamente todas las interacciones durante las solicitudes y respuestas a las llamadas API.
El monitoreo de las marcas de tiempo se realiza automáticamente por la plataforma, siendo opcional para los participantes la adición de marcas de tiempo específicas.
Mayoria de marcas de tiempo son registradas automáticamente por la plataforma.
### DICE requerimentos
## Mapeo de marcas de tiempo
Las marcas de tiempo del DICE aplican únicamente a dos operaciones: el proceso de incorporación (onboarding) y la resolución de llaves.
Este mapeo se basa en el siguiente documento:
| Código de mensaje | Nombre del mensaje | Descripción del mensaje | Partes involucradas |
| ------------------------------------------------------ | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| `admn.001.001.01` | Solicitud de gestión de red | Utilizado para conectar/desconectar y verificar el estado de la conexión. Operaciones: `SignOn`, `SignOff`, `EchoTest` | TransfiYa → DICE |
| `admn.002.001.01` | Respuesta de gestión de red | Respuesta a `admn.001` | DICE → Transfiya |
| `prxy.001.001.01` | Solicitud de registro de proxy | Utilizado para gestionar llaves. Operaciones: | |
| `NEWR`, `AMND`, `DEAC`, `SUSP`, `SUSB`, `ACTV`, `ACTB` | Transfiya → DICE | | |
| `prxy.002.001.01` | Respuesta de registro de proxy | Respuesta a `prxy.001` | DICE → Transfiya |
| `admi.002.001.01` | Mensaje de rechazo | Parece ser un mensaje de error que puede devolverse como respuesta a otros mensajes. No hay flujos de ejemplo con este mensaje en la documentación. | DICE → TransfiYa |
| `prxy.003.001.01` | Solicitud de resolución de proxy | Utilizado para resolver llaves desde el directorio de alias | Transfiya → DICE |
| `prxy.004.001.01` | Respuesta de resolución de proxy | Respuesta a `prxy.003` | DICE → Transfiya |
### Registro de Llaves
El sistema transfiya ya permite consulta de llaves usando el protocolo de resolución de llaves y registro de marcas de tiempo.
Para cubrir el caso de incorporación (onboarding), TransfiYa añade nuevas etiquetas al payload del firmante. Estas etiquetas representan las marcas de tiempo que los participantes necesitan recopilar:
* `received` → el momento en que un participante recibió una solicitud del usuario para incorporarse, cuando el usuario hace clic en la aplicación
* `dispatched` → el momento en que un participante envió una solicitud de incorporación a Transfiya, cuando se llama a la API de creación de firmante
```mermaid theme={null}
sequenceDiagram
autonumber
participant c as Customer
participant b as Bank
participant ty as Transfiya
participant cd as Centralized
Directory
c ->> +b: Register key
b ->> b: Generate keeper (pubKey, privKey)
b ->> +ty: Create signer (register pubKey)
ty ->> +cd: Register key
cd -->> -ty: Directory response
ty ->> ty: Create signer
ty -->> -b: Return signer
b -->> -c: Return registration result
```
| Paso del flujo de procesamiento | Marca de tiempo DICE | Mensaje DICE | Operación DICE | Campo de mensajería | Parte responsable | Descripción de marca de tiempo |
| ------------------------------- | -------------------- | --------------- | -------------- | --------------------------------- | ----------------- | ----------------------------------------------------------------------------- |
| 1 (fin) | R101 | prxy.001.001.01 | NEWR | `signer.labels.received` | Participante | Un participante recibe una solicitud de registro de llave de un cliente. |
| 3 (inicio) | R103 | prxy.001.001.01 | NEWR | `signer.labels.dispatched` | Participante | El participante envía una solicitud de registro de llave a Transfiya. |
| 3 (fin) | R201 | prxy.001.001.01 | NEWR | no apclicable | Transfiya | Transfiya recibe una solicitud de registro de llave del participante. |
| 4 (inicio) | R203 | prxy.001.001.01 | NEWR | no aplicable | Transfiya | Transfiya envía una solicitud de registro de llave a DICE. |
| 4 (fin) | R301 | prxy.001.001.01 | NEWR | `prxy.002.001.01` (paso 5) `R301` | DICE | DICE recibe una solicitud de registro de llave de Transfiya. |
| 5 (inicio) | R303 | prxy.002.001.01 | NEWR | `prxy.002.001.01` (paso 5) `R303` | DICE | DICE envía una respuesta de registro de llave a Transfiya. |
| 5 (fin) | R205 | prxy.002.001.01 | NEWR | no aplicable | Transfiya | Transfiya recibe una respuesta de registro de llave de DICE. |
| 7 (inicio) | R207 | prxy.002.001.01 | NEWR | no aplicable | Transfiya | Transfiya envía una respuesta de registro de llave al participante. |
| 7 (fin) | R105 | prxy.002.001.01 | NEWR | no aplicable | Participante | El participante recibe una respuesta de registro de llave de Transfiya. |
| 8 (inicio) | R107 | prxy.002.001.01 | NEWR | no aplicable | Participante | El participante notifica al cliente sobre el resultado del registro de llave. |
### Resolución de Llaves
Este modelo es actualmente opcional y no se habilitará hasta que comencemos las pruebas de integración con MOL.
Las marcas de tiempo necesarias para la resolución de llaves siguen un patrón similar a las requeridas durante el proceso de incorporación.
Los requisitos relacionados con los participantes pueden satisfacerse mediante la incorporación de los mismos dos campos mencionados anteriormente. Dado que los participantes deben enviar estos campos y efectivamente almacenan información adicional en el sistema con esta solicitud, la petición de resolución se implementa como una solicitud `POST` en lugar de `GET`:
**POST /v1/signer/lookup.dice**
El cuerpo de esta solicitud contiene el valor del llave que se está resolviendo y las marcas de tiempo requeridas:
```json theme={null}
{
"aliasValue": "@jorge22",
"received": "2025-01-14T20:40:57.322-05:00",
"dispatched": "2025-01-14T20:40:58.322-05:00"
}
```
Flujo de Resolución de Llaves:
```mermaid theme={null}
sequenceDiagram
autonumber
participant c as Persona
participant b as Participante
participant ty as Transfiya
participant cd as Directorio
Centralizado
c ->> +b: Buscar llave
b ->> +ty: Encontrar signer con alias
ty ->> ty: Verificar signer local
alt signer local no existe
ty ->> +cd: Consultar directorio centralizado
cd -->> -ty: Respuesta del directorio
ty ->> ty: Mapear llave a signer
end
ty -->> -b: Devolver signer
b -->> -c: Devolver resultado
```
| Marca de tiempo DICE | Mensaje DICE | Campo de mensajería | Paso del flujo de procesamiento | Parte responsable | Descripción de marca de tiempo |
| -------------------- | --------------- | ---------------------------------------------- | ------------------------------- | ----------------- | --------------------------------------------------------------------------------- |
| C110 | prxy.003.001.01 | solicitud de búsqueda de firmante `received` | 1 (fin) | Participante | Un participante recibe una solicitud de resolución de llave de un cliente. |
| C120 | prxy.003.001.01 | solicitud de búsqueda de firmante `dispatched` | 2 (inicio) | Participante | El participante envía una solicitud de resolución de llave a Transfiya. |
| C210 | prxy.003.001.01 | no disponible sobre API | 2 (fin) | Transfiya | Transfiya recibe una solicitud de resolución de llave del participante. |
| C215 | prxy.003.001.01 | no disponible sobre API | 4 (inicio) | Transfiya | Transfiya envía una solicitud de resolución de llave a DICE. |
| C310 | prxy.003.001.01 | `prxy.004.001.01` (paso 5) `C310` | 4 (fin) | DICE | DICE recibe una solicitud de resolución de llave de Transfiya. |
| C320 | prxy.004.001.01 | `prxy.004.001.01` (paso 5) `C320` | 5 (inicio) | DICE | DICE envía una respuesta de resolución de llave a Transfiya. |
| C230 | prxy.004.001.01 | no disponible sobre API | 5 (fin) | Transfiya | Transfiya recibe una respuesta de resolución de llave de DICE. |
| C240 | prxy.004.001.01 | no disponible sobre API | 7 (inicio) | Transfiya | Transfiya envía una respuesta de resolución de llave al participante. |
| C130 | prxy.004.001.01 | no disponible sobre API | 7 (fin) | Participante | El participante recibe una respuesta de resolución de llave de Transfiya. |
| C140 | prxy.004.001.01 | no disponible sobre API | 8 (inicio) | Participante | El participante notifica al cliente sobre el resultado de la resolución de llave. |
Documento de referencia - Directorio Centralizado DICE Versión 2.2.1
# Las validaciones
Source: https://transfiya.me/es/v1.104/directory/about/about-validations
Descripción detallada sobre validaciones de campos de llaves en el sistema
## Validaciones en Transfiya
La plataforma Transfiya utiliza tipos de datos y esquemas dinámicos para garantizar la integridad y consistencia de los datos en toda la plataforma. Esto incluye reglas de validación para diversos campos dentro del sistema.
Dado que no existe una estructura de datos fija en la plataforma, creamos esquemas que se aplican según el tipo de registro y objeto en la plataforma.
En Transfiya actualmente admitimos diferentes tipos de llaves que incluyen personas y empresas. El campo "type" en los firmantes está asociado a un esquema de validación específico.
**Tipos de Validaciones:**
| Tipo signer | Schema aplicada | Descripción |
| ----------- | --------------- | ------------------------------------------ |
| `PERSON` | PERSON | Representa una persona física |
| `BUSINESS` | BUSINESS | Representa una empresa o persona jurídica. |
Dependiendo del tipo de firmante del registro, se aplica el esquema de validación correspondiente. Por ejemplo, un firmante tipo persona requiere un nombre válido, mientras que un firmante tipo empresa requiere un nombre comercial válido.
### Alertas (Advertencias leves)
Para garantizar la compatibilidad con el sistema actual, las validaciones de firmantes relacionadas con las llaves regulatorias se mostrarán como advertencias en la API REST, sin bloquear la operación.
### Errores (Validaciones estrictas)
Debido a la compatibilidad con otros casos de uso y participantes, las validaciones estrictas solo se aplican cuando una llave se envía al directorio centralizado. Esto permite mantener la flexibilidad del sistema mientras se asegura la integridad de los datos críticos.
Puede encontrar más información sobre los errores aquí\[about-errors]
## Modelo de data
Modelo de data completo para signers se puede ver aca:
| Nombre | Transfiya | Requerido | Condición | Tipo | Validación | Comentario |
| ---------------------------------------- | ------------------------- | ----------------------- | ------------------------------------ | ----- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Tipo de llave | labels.aliasType | Requerido | | Texto | Ver tabla `labels.aliasType` | Nuevo valor requerido por regulación. |
| Valor de llave | labels.aliasValue | Requerido | | Texto | Ver tabla `labels.aliasValue` | No distingue entre mayúsculas y minúsculas, se almacena en mayúsculas. |
| Estado de llave | labels.status | Opcional con condición | No permitido en llamada de creación. | Texto | Ver tabla `labels.status` | ACTIVE por defecto. |
| Identificador | handle | Opcional | | Texto | 26-35 caracteres alfanuméricos con estructura base58 | |
| Tipo de identificación | labels.proprietary | Requerido | | Texto | Ver tabla `labels.proprietary` | |
| Descripción | labels.description | Opcional | | Texto | Máximo 255 caracteres. | |
| Número de identificación | labels.identification | Requerido | | Texto | Máximo 18 caracteres alfanuméricos, caracteres especiales no permitidos. | |
| Tipo de cliente | labels.type | Requerido | | Texto | Uno de los valores: PERSON, BUSINESS, TROUPE | Solo PERSON y BUSINESS son usados para transferencias reguladas. |
| Nombre de entidad legal del cliente | labels.name | Requerido con condición | labels.type = 'BUSINESS' | Texto | 1-140 caracteres | |
| Primer nombre del cliente | labels.firstName | Requerido con condición | labels.type = 'PERSON' | Texto | 1-40 caracteres | |
| Segundo nombre del cliente | labels.secondName | Opcional con condición | labels.type = 'PERSON' | Texto | 1-40 caracteres | Nuevo valor requerido por regulación. |
| Primer apellido del cliente | labels.lastName | Opcional con condición | labels.type = 'PERSON' | Texto | 1-40 caracteres | Cambiado a opcional para coincidir con la regulación. |
| Segundo apellido del cliente | labels.secondLastName | Opcional con condición | labels.type = 'PERSON' | Texto | 1-40 caracteres | Nuevo valor requerido por regulación. |
| País de residencia | labels.countryOfResidence | Opcional | | Texto | Código ISO de país de 2 caracteres. [https://www.iso.org/obp/ui](https://www.iso.org/obp/ui/#search) | |
| Identificación de entidad emisora | labels.createdBy | Generado por Transfiya | | Texto | Referencia de participante Transfiya | Identificador de billetera del banco en Transfiya. |
| Tipo de método de pago | labels.bankAccountType | Requerido | | Texto | Uno de los valores:SVGS, CACC, DBMO, DORD, DBMI | |
| Número de método de pago | labels.bankAccountNumber | Requerido | | Texto | Máximo 34 dígitos | |
| Código nacional del banco | labels.bankBicfi | Opcional | | Texto | 4 dígitos | |
| Nombre del banco | labels.bankName | Opcional | | Texto | Máximo 64 caracteres | |
| Número de identificación del banco | labels.bankId | Opcional | | Texto | Máximo 9 caracteres numéricos | Representa un número NIT del banco sin dígito de verificación o un código asignado por BanRep. |
| Referencia del router del banco | labels.routerReference | Requerido | | Texto | Máximo 34 caracteres alfanuméricos, debe comenzar con `$` | Identificador de billetera del banco en Transfiya. |
| Fecha/hora de creación del registro | labels.created | Generado por Transfiya | | Texto | Fecha y hora en formato ISO 8601 | |
| Fecha/hora de modificación del registro | labels.updated | Generado por Transfiya | | Texto | Fecha y hora en formato ISO 8601 | |
| Código SPBVI objetivo | labels.targetSpbviCode | Opcional | | Texto | Ver tabla `labels.targetSpbviCode` | TFY por defecto. |
| Fecha/hora de consentimiento del usuario | labels.consented | Opcional | | Texto | Fecha y hora en formato ISO 8601, será establecido por Transfiya si no se proporciona. | Nuevo campo para registrar el momento en que el usuario dio consentimiento para registrar datos. |
| Keeper | keeper | Requerido | | Array | Ver tabla `keeper` | Llave pública del firmante. |
### Tipos de llaves
Para hacer que los signers sean compatibles con la regulación, se han añadido nuevas etiquetas que definen claramente el tipo y valor de cada alias (llave). Estas etiquetas permiten una integración fluida entre el sistema Transfiya y los requisitos regulatorios establecidos.
Signer label (`labels.aliasType`):
| Name | Transfiya | Regulation |
| --------------- | --------- | ---------- |
| Phone number | PHONE | M |
| Alphanumeric | ALPHANUM | O |
| Email | EMAIL | E |
| Document number | NRIC | NRIC |
| Merchent Id | MERCHANT | B |
Ejemplo y validaciones de alias label (`labels.aliasValue`):
| Tipo de alias | Ejemplo | Validación | Comentario |
| ------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| Número de teléfono | `3012344567` | Debe comenzar con `3` y tener 9 dígitos después de este prefijo. | |
| Alfanumérico | `@JORGE35` | Comienza con el símbolo `@`. Máximo 20 caracteres alfanuméricos y mínimo 5 caracteres alfanuméricos después del símbolo `@`. | El símbolo `@` está reservado para IDs alfanuméricos, nombres de usuario, etc. |
| Correo electrónico | `TEST@COMPANY.IO` | Máximo 92 caracteres. Debe tener un único carácter `@`. Máximo 30 caracteres antes del `@` y 61 después. | |
| Número de documento | `PR5002499` | Mínimo 3 y máximo 18 caracteres alfanuméricos, no se permiten caracteres especiales. | El número de identificación del documento debe ser único en el sistema, incluso si se repite en Colombia. |
| ID de comerciante | `0012345678` | Comienza con `00` y tiene 10 dígitos en total. | |
### Status de signers (llaves regulatorias)
Signers van a incluir el estado de las llaves regulatorias asociadas a cada signer.
Los estados se manejan usando el label staus an nivel de signer (`labels.status`):
| Name | Transfiya | Regulation |
| ---------------------- | -------------------------- | ---------- |
| Active | ACTIVE | ACTV |
| Blocked by client | SUSPENDED\_BY\_CLIENT | SUSP |
| Blocked by participant | SUSPENDED\_BY\_PARTICIPANT | SUSB |
| Inactive (cancelled) | INACTIVE | ICTV |
### Tipo de documento
Document type enum (`labels.proprietary`):
| Name | Transfiya | Regulation | Comment |
| ------------------------------------- | --------- | ---------- | -------------------------------- |
| Citizenship Card | CC | CC | |
| Foreign ID Card | CE | CE | |
| Passport Number | PA | PAS | |
| Identity Card | TI | TDI | |
| Unique Personal Identification Number | NUIP | NUIP | |
| Tax Identification Number | NIT | NIT | |
| Other | OTR | - | Not supported by regulation |
| Temporary Protection Permit | PPT | PPT | New value required by regulation |
| Special Stay Permit | PEP | PEP | New value required by regulation |
### Tipo de cuenta
Tipo de cuenta (`labels.bankAccountType`):
| Name | Transfiya | Regulation | Comment |
| ----------------------------- | --------- | ---------- | -------------------------------- |
| Savings accounts | SVGS | CAHO | |
| Cash trading account | TRAS | - | Not supported by regulation |
| Current account | CACC | CCTE | |
| Other | OTHR | - | Not supported by regulation |
| Low-amount deposits | DBMO | DBMO | New value required by regulation |
| Ordinary deposits | DORD | DORD | New value required by regulation |
| Inclusive low-amount deposits | DBMI | DBMI | New value required by regulation |
### Codigos de participantes SPBVI
SPBVI codes (`labels.targetSpbviCode`):
| Name | Code |
| ------------- | ---- |
| Transfiya | TFY |
| Entre cuentas | ENT |
| Credibanco | CRB |
| Visionamos | VIS |
### Keeper (firmas digitales)
El objeto Keeper contiene información de la llave almacenada en el lado del banco que se utiliza para asegurar este firmante y autorizar los pagos relacionados con él.
Los campos del keeper se definen a continuación y siguen en el modelo actual:
| Nombre | Campo | Tipo | Requerido | Validación |
| ------------- | ------ | ----- | --------- | --------------------------------------- |
| Tipo de llave | scheme | Texto | Requerido | Uno de:`ecdsa-ed25519`, `eddsa-ed25519` |
| Llave pública | public | Texto | Requerido | 64-130 caracteres |
# Cómo cancelar llaves
Source: https://transfiya.me/es/v1.104/directory/guides/how-to-cancel-keys
Guia del proceso de cancelación de las llaves
## Introducción
En Transfiya, las llaves o credenciales de pago (signers) no se eliminan físicamente del sistema. En su lugar, se utiliza un enfoque de desactivación lógica para mantener la trazabilidad e integridad histórica de las operaciones.
Para cancelar una llave, se debe actualizar el valor del campo status en el objeto del signer y asignarle el valor INACTIVE. Esto marca la llave como inactiva, evitando que pueda ser utilizada para nuevas operaciones, sin eliminar su existencia dentro del sistema.
Este enfoque garantiza que la plataforma mantenga un historial completo de las llaves utilizadas, cumpliendo con los lineamientos regulatorios y de auditoría.
Este proceso no solo marca la llave como inactiva en Transfiya, sino que también la desactiva automáticamente en el DICE. De esta manera, se asegura que el estado de la llave quede sincronizada en todo el ecosistema.
## Ejemplos de API
### Cancelacion de una llave
Para cancelar una llave se realiza actualizando el estado de un signer a INACTIVE.
```java HTTP theme={null}
PUT /v1/signer/{handle}
```
***
| Parameter | Type | Description |
| --------- | ------ | ----------------------------------------------------------------- |
| handle | string | 26-35 characters Alphanumeric characters allowed base58 structure |
| labels | object | Metadata describing the status to cancel the key |
***
```bash theme={null}
ccurl -X PUT \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"status": "INACTIVE",
"allowImmediateReuse":false
}
}' "URL/v1/signer/wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
```
```javascript theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "ALPHANUM",
"aliasValue": "@JORGE22",
"status": "INACTIVE",
"type": "PERSON",
"firstName": "Jorge",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"bankId": "891234918",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00",
"updated": "2024-10-11T12:01:11.121-05:00",
"consented": "2024-10-11T11:59:21.551-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00",
"delivered": "2024-10-11T11:59:24.104-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Códigos de Error
***
| Error Code | Description | HTTP Status |
| ---------- | ------------------------------------------------ | ----------- |
| 99 | Unexpected server error | 400 |
| 100 | You don't have permissions to access this method | 403 |
| 102 | Invalid labels | 400 |
| 118 | Resource schema validation error | 400 |
| 121 | Signer not found in database | 400 |
### 🔒 **Responsabilidad del participante en la cancelación de llaves**
Los participantes del sistema Bre-B tienen la obligación de cancelar las llaves de pago cuando se presenten las causales definidas en la normativa vigente o cuando el usuario lo solicite expresamente. Esta acción debe ejecutarse de manera inmediata y conforme a los procedimientos establecidos, garantizando la seguridad del ecosistema y evitando el uso indebido de medios de pago asociados. El incumplimiento de esta responsabilidad puede generar impactos operativos y financieros atribuibles directamente al participante.
***
# Cómo registrar llaves
Source: https://transfiya.me/es/v1.104/directory/guides/how-to-create-keys
Cómo registrar llaves en Transfiya
## Introducción
Los participantes registran sus llaves en el directorio federado de Transfiya, el cual sincroniza inmediatamente con el directorio centralizado.
Las llaves que cumplen con los requisitos mínimos de regulación se mapearán a los credenciales de pago [signers](../about/about-signers) de Transfiya en una relación de un credencial de pago a una llave.
[Validaciones](../about/about-validations) de llaves son basados en minimos campos requeridos para la creación de una llave por la regulación.
Las billeteras actualmente permiten asignar múltiples cuentas a una sola llave. Esta funcionalidad está disponible por motivos de compatibilidad, pero no se utilizará en las llaves Bre-B.
## Flujo de creación de llave
A continuación se presenta una descripción general del flujo de creación de llaves y una comparativa con el proceso actual de Transfiya.
```mermaid theme={null}
sequenceDiagram
autonumber
participant b as Participante
participant ty as Transfiya
participant cd as DICE
b ->> b: Generar keeper (pubKey, privKey)
b ->> +ty: Generar signer (register pubKey)
ty ->> +cd: Registar llave
cd -->> -ty: Respuesta DICE
ty ->> ty: Crear signer
ty -->> -b: Respuesta signer
```
```mermaid theme={null}
sequenceDiagram
autonumber
participant b as Participante
participant ty as Transfiya
b ->> b: Generar keeper (pubKey, privKey)
b ->> +ty: Crear signer (register pubKey)
ty -->> -b: Respusta participante
b ->> +ty: Buscar billetera ($57...)
ty -->> -b: Respuesta
alt billetera existe
b ->> +ty: Actualizar biletera con signer
ty ->> ty: Actualizar billetera
ty -->> -b: Respuesta
else no existe billetera
b ->> +ty: Crear nueva billetera
ty ->> ty: Crear billetera
ty -->> -b: Respuesta billetera
end
```
## Ejemplo de creación de llave
Para la creación de llaves, se utilizará la interfaz de aplicación destinada a la creación de signers.
La plataforma Transfiya utiliza tipos de datos y [esquemas dinámicos](../about/about-validations) para garantizar la integridad y consistencia de los datos en toda la plataforma. Esto incluye reglas de validación para diversos campos dentro del sistema.
**Tipos de Validaciones:**
| Tipo signer | Schema aplicada | Descripción |
| ----------- | --------------- | ------------------------------------------ |
| `PERSON` | PERSON | Representa una persona física |
| `BUSINESS` | BUSINESS | Representa una empresa o persona jurídica. |
Más sobre [modelo de data](../about/about-data-model)
Para cubrir el caso de incorporación (onboarding), TransfiYa añade nuevas etiquetas al payload del firmante. Estas etiquetas representan las marcas de tiempo que los participantes necesitan recopilar:
* **received** → el momento en que un participante recibió una solicitud del usuario para incorporarse, cuando el usuario hace clic en la aplicación
* **dispatched** → el momento en que un participante envió una solicitud de incorporación a Transfiya, cuando se llama a la API de creación de firmante
* **bankId** → el NIT de la entidad financiera sin el digito de verificación
### Ejemplo llave persona
A continuación se presenta un ejemplo de creación de una llave tipo 'PERSON' y un análisis comparativo con la implementación actual en Transfiya:
```Diff theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
+ "aliasType": "ALPHANUM",
+ "aliasValue": "@jorge22",
"type": "PERSON",
"firstName": "Jorge",
"secondName": "Manuel",
"lastName": "Diaz",
"secondLastName": "Padilla",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"routerReference": "$bancorojo",
"targetSpbviCode": "TFY",
"consented": "2024-10-11T11:59:24.241-05:00",
+ "bankId": "891234918",
+ "received": "2024-10-11T11:59:22.241-05:00",
+ "dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
```json theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "ALPHANUM",
"aliasValue": "@JORGE22",
"status": "ACTIVE",
"type": "PERSON",
"firstName": "Jorge",
"secondName": "Manuel",
"lastName": "Diaz",
"secondLastName": "Padilla",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00"
"consented": "2024-10-11T11:59:24.241-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Ejemplo de creación llave de negocio
A continuación se presenta un ejemplo de creación de una llave tipo 'BUSINESS' y un análisis comparativo con la implementación actual en Transfiya:
```diff theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
+ "aliasType": "ALPHANUM",
+ "aliasValue": "@cognito",
"type": "BUSINESS",
"name": "Cognito Inc",
"proprietary": "NIT",
"identification": "900123456",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"routerReference": "$bancorojo",
"targetSpbviCode": "TFY",
+ "bankId": "891234918",
+ "consented": "2025-03-15T00:44:09-05:00",
+ "received": "2024-10-11T11:59:22.241-05:00",
+ "dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
```json theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "ALPHANUM",
"aliasValue": "@cognito",
"status": "ACTIVE",
"type": "BUSINESS",
"firstName": "Cognito Inc",
"proprietary": "NIT",
"identification": "900123456",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00"
"consented": "2025-03-15T00:44:09-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
# Cómo bloquear llaves
Source: https://transfiya.me/es/v1.104/directory/guides/how-to-lock-keys
Como bloquear llaves en Transfiya
## Introducción
La gestión de llaves en los Sistemas de Pago de Bajo Valor Inmediatos (SPBVI) constituye un elemento esencial para garantizar la seguridad, la interoperabilidad y la trazabilidad de las operaciones financieras entre clientes y participantes. En este marco, la funcionalidad de **bloqueo de llaves** se establece como un mecanismo preventivo que permite suspender temporalmente el uso de una llave asociada a un medio de pago, con el fin de mitigar riesgos asociados a fraude, suplantación, inactividad del medio de pago u otras situaciones que puedan comprometer la confianza del ecosistema.
De acuerdo con la **Circular Reglamentaria Externa DSP-465 del Banco de la República**, el bloqueo puede ser solicitado directamente por el cliente o ejecutado por el participante únicamente en los casos autorizados: suspensión del medio de pago por riesgos de seguridad o cuando este sea clasificado como inactivo. En ambos escenarios, los participantes tienen la obligación de informar a la Entidad Administradora del Sistema de Pago de Bajo Valor Inmediato (EASPBVI), la cual debe reflejar en tiempo real la novedad en el Directorio Federado y posteriormente en el Directorio Centralizado, asegurando así la consistencia y disponibilidad de la información en todo el sistema.
En este sentido, el **participante** adquiere responsabilidades claras:
* Adecuar sus canales de servicio para permitir al cliente el ejercicio pleno de la funcionalidad de bloqueo y reactivación de sus llaves.
* Informar de manera oportuna y transparente al cliente sobre las implicaciones del bloqueo, su alcance y los procedimientos asociados.
* Cumplir estrictamente con las normas de seguridad y protección de datos personales previstas en la Ley 1581 de 2012 y sus reglamentos.
* Reportar de inmediato a la EASPBVI las novedades generadas en los procesos de gestión de llaves, en cumplimiento de los tiempos y lineamientos operativos definidos por el Banco de la República.
De esta forma, la implementación del bloqueo de llaves no solo contribuye a la protección de los usuarios, sino que refuerza la responsabilidad de los participantes en la administración segura y transparente de los medios de pago dentro de los SPBVI, fortaleciendo la confianza en la infraestructura de pagos inmediata del país.
### Ejemplo de bloqueo de llaves por participante
A continuación se presenta un ejemplo de bloqueo de una llave por entidad participante:
```json Request theme={null}
curl -X PUT \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"status": "SUSPENDED_BY_PARTICIPANT"
}
}' "URL/v1/signer/wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
```
```json Response theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "EMAIL",
"aliasValue": "jorge@company.io",
"status": "SUSPENDED_BY_PARTICIPANT",
"type": "PERSON",
"firstName": "Jorge",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00",
"updated": "2024-10-11T12:01:11.121-05:00",
"consented": "2024-10-11T11:59:24.241-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Ejemplo de bloqueo de llaves por cliente
A continuación se presenta un ejemplo de bloqueo de una llave por cliente:
```json Request theme={null}
curl -X PUT \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"status": "SUSPENDED_BY_CLIENT"
}
}' "URL/v1/signer/wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
```
```json Response theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "EMAIL",
"aliasValue": "jorge@company.io",
"status": "SUSPENDED_BY_CLIENT",
"type": "PERSON",
"firstName": "Jorge",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00",
"updated": "2024-10-11T12:01:11.121-05:00",
"consented": "2024-10-11T11:59:24.241-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
# Cómo reactivar llaves
Source: https://transfiya.me/es/v1.104/directory/guides/how-to-reactivate-keys
Guía del proceso de modificación de las llaves
## Introducción
La **reactivación de llaves** es un proceso fundamental que permite restablecer el uso de una llave previamente bloqueada, garantizando así la continuidad de los servicios financieros del cliente una vez mitigadas las causas que originaron su suspensión. Esta funcionalidad asegura que los usuarios puedan recuperar el acceso a sus medios de pago de manera ágil y confiable, sin comprometer la seguridad del ecosistema de pagos.
De acuerdo con la **Circular Reglamentaria Externa DSP-465 del Banco de la República**, la reactivación constituye una operación exclusiva del cliente, quien, previa autenticación y validación por parte del participante, puede solicitar que su llave vuelva a estar disponible para recibir órdenes de pago o transferencias inmediatas. No obstante, cuando el bloqueo haya sido originado por el participante —por riesgos de fraude, suplantación o inactividad del medio de pago—, la reactivación solo procederá una vez se verifique la superación de la condición que motivó la suspensión y solo podrá ser reactivada por el mismo actor (ver *"los estados"*).
En este marco, los **participantes** tienen responsabilidades específicas que aseguran el correcto funcionamiento de la reactivación de llaves:
* Adecuar sus canales de atención para que el cliente pueda solicitar la reactivación de forma sencilla, transparente y segura.
* Verificar que las causas de bloqueo (fraude, suplantación o inactividad) hayan sido atendidas y resueltas antes de habilitar nuevamente la llave.
* Garantizar que la actualización del estado de la llave se refleje en tiempo real en el Directorio Federado y en el Directorio Centralizado, en coordinación con la Entidad Administradora del SPBVI (EASPBVI).
* Informar oportunamente al cliente sobre la activación exitosa, los tiempos de disponibilidad y cualquier condición asociada al restablecimiento de la llave.
* Cumplir con las disposiciones sobre protección de datos y seguridad de la información, en línea con lo previsto en la Ley 1581 de 2012 y normas relacionadas.
En consecuencia, la reactivación de llaves no solo restituye la capacidad transaccional del cliente, sino que también refuerza la confianza en los mecanismos de seguridad del sistema. Asimismo, consolida la responsabilidad del participante en la gestión transparente y eficaz de los procesos asociados al ciclo de vida de las llaves en los SPBVI.
### Ejemplo de reactivación de llaves por participante
A continuación se presenta un ejemplo de reactivación de una llave por entidad participante:
```json Request theme={null}
curl -X PUT \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"status": "ACTIVE"
"participantReactivation": true
}
}' "URL/v1/signer/wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
```
```json Response theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "EMAIL",
"aliasValue": "jorge@company.io",
"status": "ACTIVE",
"type": "PERSON",
"firstName": "Jorge",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00",
"updated": "2024-10-11T12:01:11.121-05:00",
"consented": "2024-10-11T11:59:24.241-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Ejemplo de bloqueo de llaves por cliente
A continuación se presenta un ejemplo de reactivación de una llave por cliente:
```json Request theme={null}
curl -X PUT \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"status": "ACTIVE"
"participantReactivation": false
}
}' "URL/v1/signer/wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
```
```json Response theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "EMAIL",
"aliasValue": "jorge@company.io",
"status": "ACTIVE",
"type": "PERSON",
"firstName": "Jorge",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00",
"updated": "2024-10-11T12:01:11.121-05:00",
"consented": "2024-10-11T11:59:24.241-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
El campo "participantReactivation" nos indica quien intenta realizar la reactivación.
* Si el valor recibido es `true`, significa que la reactivación la realiza el **participante**.
* Si el valor recibido es `false`, significa que la reactivación la realiza el **usuario**.
# Cómo resolver llaves
Source: https://transfiya.me/es/v1.104/directory/guides/how-to-resolve-keys
Cómo hacer la resolución de las llaves
## Introducción
El flujo regulatorio exige la resolución de llaves como requisito previo al inicio de cualquier transferencia, constituyendo el cambio fundamental para los participantes de Transfiya.
Actualmente, el sistema Transfiya permite a los usuarios realizar transferencias monetarias a llaves como ser el numero de teléfono, lo que simplifica significativamente tanto la experiencia de usuario como el proceso de incorporación al sistema.
Transfiya permite el envío de transferencias directamente a los signers, lo que permite completar transacciones de forma inmediata sin requerir la aceptación del destinatario.
Este último modelo, regulado por la normativa Bre-B, establece como obligatoria la resolución de la llave antes de proceder con cualquier operación de transferencia.
Cualquier nuevo participante puede adoptar el modelo regulado y, simultáneamente, continuar enviando y recibiendo transferencias con los participantes existentes, independientemente de si éstos han migrado al nuevo flujo regulado.
## Flujo regulado
Los cambios de regulación requiren resolución de llaves antes de iniciar una transferencia.
```mermaid theme={null}
sequenceDiagram
autonumber
participant b as Participante
participant ty as transfiya
participant cd as DICE
b ->> +ty: Buscar llave (signer)
ty ->> ty: Verificar signer
alt signer no existe
ty ->> +cd: Consultar directorio centralizado
cd -->> -ty: Respuesta del directorio
ty ->> ty: Mapear llave a signer
end
ty -->> -b: Devolver signer
```
Si no se encuentra la llave activa, significa que el usuario no está registrado en el sistema y la transferencia no puede procesarse bajo el modelo regulado.
Los participantes pueden migrar al nuevo flujo de forma independiente, sin necesidad de esperar otros participantes.
Las transferencias a billeteras con aceptación seguirán funcionando hasta la implementación completa de la regulación, garantizando la compatibilidad con los participantes actuales del sistema.
## Ejemplos del API
### Obtener signers para un alias
```javascript HTTP theme={null}
POST /v1/signer/lookup.dice
```
Los signers pueden consultarse a través del endpoint v1/signer/lookup.dice, enviando los parametros correspondientes. Para verificar el estado de un signer, revise el campo `labels.status`
Para cubrir el caso de incorporación (onboarding), TransfiYa añade nuevas etiquetas al payload del firmante. Estas etiquetas representan las marcas de tiempo que los participantes necesitan recopilar:
* **received** → el momento en que un participante recibió una solicitud del usuario para incorporarse, cuando el usuario hace clic en la aplicación
* **dispatched** → el momento en que un participante envió una solicitud de incorporación a Transfiya, cuando se llama a la API de creación de firmante
***
| Parameter | Type | Description |
| ---------- | ------ | ---------------------------------------------------------- |
| aliasValue | string | Alias value. |
| received | string | Date of reception in ISO 8601 with milliseconds precision. |
| dispatched | string | Date of dispatch in ISO 8601 with milliseconds precision. |
***
```js theme={null}
curl --location '{{url}}/v1/signer/lookup.dice' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data-raw '{
"aliasValue": "@testing",
"received": "2025-04-10T15:49:15.015-05:00",
"dispatched": "2025-04-10T15:49:15.015-05:00"
}'
```
```json theme={null}
{
"requestId": "019617d6-bac4-7150-8610-0dc60a0f1bc2",
"signer_id": "0195b009-a139-7ff2-adac-15e3c3ecfc88",
"id": "0195b009-a139-7ff2-adac-15e3c3ecfc88",
"handle": "wYe6h63CNqoLxJet5jP1WWLhGi8D11ZGij",
"keeper": [
{
"public": "7ef44ee7ff1f4527ef44ee7ff1f4527ef44ee7ff1f4527ef44ee7ff1f4527ef4",
"scheme": "ecdsa-ed25519"
}
],
"labels": {
"type": "PERSON",
"status": "ACTIVE",
"created": "2025-03-19T15:12:55.993-05:00",
"updated": "2025-03-19T15:12:55.993-05:00",
"createdBy": "mSJkneiASd",
"aliasType": "ALPHANUM",
"aliasValue": "@jorge",
"proprietary": "CC",
"identification": "1010101010",
"firstName": "Jorge",
"lastName": "Diaz",
"bankId": "900123456",
"bankAccountType": "SVGS",
"bankAccountNumber": "4123456789",
"routerReference": "$bancorojo",
"targetSpbviCode": "TFY",
"consented": "2025-03-13T20:38:07-05:00",
"received": "2025-03-13T20:38:07.123-05:00",
"dispatched": "2025-03-13T20:38:10.123-05:00"
},
"error": {
"code": 0,
"message": "Success"
}
}
```
### Códigos de Error
***
| Error Code | HTTP Status | Description |
| ---------- | ----------- | ------------------------------------------------ |
| 99 | 400 | Unexpected server error |
| 100 | 403 | You don't have permissions to access this method |
| 100 | 500 | Runtime error |
***
# Cómo Enviar Marcas de Tiempo
Source: https://transfiya.me/es/v1.104/directory/guides/how-to-send-timestamps
Cómo enviar Marcas de Tiempo al DICE
DICE utiliza marcas de tiempo para dos operaciones clave: creación (**onboarding**) y resolución de llaves (**key resolution**).
### Creación de Llaves
Para cubrir el caso de creación, Transfiya define un nuevo endpoint:
`POST /v1/signer//timestamps`
Este endpoint requiere que los participantes envíen las dos marcas de tiempo finales asociadas al proceso de creación del firmante:
Momento en que el participante recibió una respuesta de incorporación de firmante desde Transfiya.
Momento en que el participante notificó a su usuario el resultado de la operación de incorporación.
```mermaid theme={null}
sequenceDiagram
autonumber
participant c as Cliente
participant b as Banco
participant ty as Transfiya
participant cd as Directorio
Centralizado
c ->> +b: Registrar llave
b ->> b: Generar keeper (clave pública y privada)
b ->> +ty: Crear firmante (registrar clave pública)
ty ->> +cd: Registrar llave
cd -->> -ty: Respuesta del directorio
ty ->> ty: Crear firmante
ty -->> -b: Devolver firmante
b -->> -c: Devolver resultado del registro
b ->> +ty: Reportar marcas de tiempo
ty -->> -b: Respuesta de marcas de tiempo
```
```json theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
}' "/v1/signer/wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF/timestamps"
```
```json theme={null}
{
"error": {
"code": 0,
"message": "Success"
}
}
```
## Codigos de Error
| Código de error | Descripción | HTTP Status |
| --------------- | ------------------------------------------------------------- | ----------- |
| 99 | Unexpected server error | 400 |
| 100 | You don't have permissions to access this method | 403 |
| 101 | Unauthorized request, invalid or expired token | 401 |
| 118 | Resource schema validation error, field format is not correct | 400 |
| 121 | Signer not found in database | 400 |
| 123 | Domain rules error, timestamps are not in the expected range | 400 |
### Resolución de llave
Las marcas de tiempo requeridas para la resolución de llaves son similares a las que se utilizan durante el proceso de incorporación (onboarding). Dado que una solicitud de resolución no crea un firmante en el sistema, las marcas de tiempo finales se deben reportar utilizando el `request id` que se devuelve como parte de la respuesta de la resolución.
**POST /v1/signer/lookup.dice**
```json theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"aliasValue": "@jorge22",
"received": "2025-01-14T20:39:17.827-05:00",
"dispatched": "2025-01-14T20:39:18.005-05:00"
}' "/v1/signer/lookup.dice"
```
```json theme={null}
{
"requestId": "01961b67-ebad-7997-87b8-d7f663dca76a",
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "ALPHANUM",
"aliasValue": "@JORGE22",
"status": "ACTIVE",
"type": "PERSON",
"firstName": "Jorge",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"bankId": "891234918",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY",
"created": "2024-10-11T11:59:24.241-05:00",
"consented": "2024-10-11T11:59:24.241-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
```mermaid theme={null}
sequenceDiagram
autonumber
participant c as Cliente
participant b as Banco
participant ty as Transfiya
participant cd as Directorio
Centralizado
c ->>+ b: Consultar llave
b ->>+ ty: Buscar firmante con alias
ty ->> ty: Verificar firmante local
alt firmante local no existe
ty ->>+ cd: Consultar directorio centralizado
cd -->>- ty: Respuesta del directorio
ty ->> ty: Mapear llave al firmante
end
ty -->>- b: Devolver firmante
b -->>- c: Devolver resultado
b ->>+ ty: Reportar marcas de tiempo
ty -->>- b: Respuesta de marcas de tiempo
```
Las marcas de tiempo finales se reportan en el paso 9.
Las marcas de tiempo que los participantes deben enviar a Transfiya son las mismas utilizadas en el flujo de resolución:
* `received` → momento en que el participante recibió una respuesta de resolución de firmante desde Transfiya.
* `dispatched` → momento en que el participante notificó al usuario sobre el resultado de la operación de resolución.
**Ejemplo de API:**
**POST /v1/signer/lookup.dice/\/timestamps**
```json theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
}' "/v1/signer/lookup.dice/01961b67-ebad-7997-87b8-d7f663dca76a/timestamps"
```
```json theme={null}
{
"error": {
"code": 0,
"message": "Success"
}
}
```
## Codigos de Error
| Código de error | Descripción | HTTP Status |
| --------------- | ------------------------------------------------------------- | ----------- |
| 99 | Unexpected server error | 400 |
| 100 | You don't have permissions to access this method | 403 |
| 101 | Unauthorized request, invalid or expired token | 401 |
| 118 | Resource schema validation error, field format is not correct | 400 |
| 121 | Signer not found in database | 400 |
| 123 | Domain rules error, timestamps are not in the expected range | 400 |
# Cómo sincronizar llaves
Source: https://transfiya.me/es/v1.104/directory/guides/how-to-sync-dice
Cómo sincronizar llaves con el directorio centralizado
## Introducción
El modelo Bre-B requiere que los participantes seleccionen un directorio federado que sincronizará sus llaves con el directorio centralizado.
El directorio federado cumple la función de administrar copias locales de las llaves y sincronizarlas con el directorio centralizado, los participantes no tienen que interactuar con el directorio centalizado.
## Modelo de singers
Transfiya utiliza el objeto [signer](../about/about-signers) para almacenar y gestionar las llaves en el directorio federado.
Las validaciones para las llaves se aplican en el modelo de alertas antes de la salida a marcha blanca y antes de la sincronización con el directorio centralizado.
Para más información, consulte [validaciones](../about/about-validations).
## Sincronización
Únicamente las llaves que cuentan con el consentimiento del usuario deben sincronizarse con el directorio centralizado.
Para notificar a Transfiya que se desea sincronizar una llave con el directorio centralizado, es necesario agregar una etiqueta (label) de consentimiento durante la creación o modificación de la llave.
El campo "consented" representa el evento que autoriza la sincronización de la llave con el directorio centralizado. El campo representa el tiempo en cual usuario dio su consentimiento de usar una llave centralizada.
```javascript theme={null}
"labels: {
"consented": "2024-10-11T11:59:21.551-05:00"
}
```
Solo las llaves que cuentan con el consentimiento de los usuarios se sincronizan con el directorio centralizado.
# Cómo modificar llaves
Source: https://transfiya.me/es/v1.104/directory/guides/how-to-update-keys
Guia del proceso de modificación de las llaves
## Introducción
Para actualizar las llaves usamos el modelo de actualización de objeto \[signer] (../about/about-signers).
Transfiya funciona como un directorio federado que puede almacenar copias de llaves que no se sincronizan automáticamente con DICE.
Información sobre cómo sincronizar con [DICE](how-to-sync-dice).
## Flujos de actualización
El nuevo modelo regulado simplifica el proceso de actualización, porque no utiliza wallets.
En el flujo actual para actualizar una llave con el que está vinculada la cuenta implica eliminar un singer y crear nuevo vínculo.
```mermaid theme={null}
sequenceDiagram
autonumber
participant b as Participante
participant ty as Transfiya
participant cd as DICE
b ->> +ty: Acutalizar signer
ty ->> +cd: Validar con DICE
cd -->> -ty: Respuesta DICE
ty ->> ty: Actualizar signer
ty -->> -b: Respuesta signer
```
```mermaid theme={null}
sequenceDiagram
autonumber
participant b as Bank
participant ty as Transfiya
b ->> +ty: Buscar wallet
ty -->> -b: Respuesta wallet
b ->> +ty: Actualizar wallet (eliminar signer)
ty -->> -b: Respuesta wallet
b ->> +ty: Mapeo wallet signer
ty -->> -b: Respuesta signer
alt wallet existe
b ->> +ty: Actualizar wallet con signer
ty ->> ty: Actualziar wallet
ty -->> -b: Respuesta
else wallet doesn't exist
b ->> +ty: Crear nuevo wallet con signer
ty ->> ty: Crear wallet
ty -->> -b: Respuesta
end
```
El modelo actual de billeteras permanecerá activo para garantizar compatibilidad con los sistemas existentes.
## Ejemplos de API
### Cambio de información de la cuenta
Para modificar la información de la cuenta de una llave se realiza actualizando las etiquetas de un signer.
```java HTTP theme={null}
PUT /v1/signer/{handle}
```
***
| Parameter | Type | Description |
| --------- | ------ | -------------------------------------------------------------------------------- |
| handle | string | 26-35 characters Alphanumeric characters allowed base58 structure |
| labels | object | Metadata describing the address. Use them to describe the details of the signer. |
***
```bash theme={null}
curl -X PUT \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"bankAccountType": "DBMO",
"bankAccountNumber": "302058294920"
}
}' "URL/v1/signer/wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
```
```javascript theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "ALPHANUM",
"aliasValue": "@JORGE22",
"status": "INACTIVE",
"type": "PERSON",
"firstName": "Jorge",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "DBMO",
"bankAccountNumber": "302058294920",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"bankId": "891234918",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00",
"updated": "2024-10-11T12:01:11.121-05:00",
"consented": "2024-10-11T11:59:24.241-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Códigos de Error
***
| Error Code | Description |
| ---------- | ------------------------------------------------ |
| 99 | Unexpected server error |
| 100 | You don't have permissions to access this method |
| 102 | Invalid labels |
| 118 | Resource schema validation error |
| 121 | Signer not found in database |
***
### Cambio de llave de un signer
La modificación de los alias de **signer** es una de las operaciones de llave contempladas dentro del marco regulatorio del SPI. Esta operación debe entenderse internamente como una **cancelación del valor de la llave actual y la creación de una nueva**.
Para este caso de uso, se habilitó el campo **"**`allowImmediateReuse"`, el cual debe enviarse con el valor:
* `true`: si la operación corresponde a una **modificación** del alias.
* `false`: si se trata de una **cancelación definitiva**.
```java HTTP theme={null}
PUT /v1/signer/{handle}
```
***
| Parameter | Type | Description |
| --------- | ------ | -------------------------------------------------------------------------------- |
| handle | string | 26-35 characters Alphanumeric characters allowed base58 structure |
| labels | object | Metadata describing the address. Use them to describe the details of the signer. |
***
```jsx theme={null}
curl -X PUT \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"status": "INACTIVE",
"allowImmediateReuse":true
}
}' "URL/v1/signer/wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
```
```jsx theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "EMAIL",
"aliasValue": "jorge@company.io",
"status": "INACTIVE",
"type": "PERSON",
"firstName": "Jorge",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00",
"updated": "2024-10-11T12:01:11.121-05:00",
"consented": "2024-10-11T11:59:24.241-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
## Crear Nuevo Alias
Crear un nuevo signer con un alias diferente y asociar los mismos datos de usuario:
**POST /v1/signer/**
```jsx theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"aliasType": "EMAIL",
"aliasValue": "jorge2@company.io",
"type": "PERSON",
"firstName": "Jorge",
"secondName": "Alejandro",
"lastName": "Fernandez",
"secondLastName": "Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"countryOfResidence": "CO",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"routerReference": "$bancorojo",
"targetSpbviCode": "TFY",
"consented": "2024-10-11T11:59:23.241-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
]
} "URL/v1/signer"
```
```jsx theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType: "EMAIL",
"aliasValue": "jorge2@company.io",
"status": "ACTIVE",
"type": "PERSON",
"firstName": "Jorge",
"secondName": "Alejandro",
"lastName": "Fernandez",
"secondLastName": "Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"countryOfResidence": "CO",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00",
"updated": "2024-10-11T11:59:24.241-05:00",
"consented": "2024-10-11T11:59:23.241-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
***
| Error Code | Description |
| ---------- | ------------------------------------------------ |
| 99 | Unexpected server error |
| 100 | You don't have permissions to access this method |
| 102 | Invalid labels |
| 118 | Resource schema validation error |
| 121 | Signer not found in database |
***
### Cambio de información personal de un signer
Para modificar la información personal de un signer, se realiza por medio de la actualización de las etiquetas del signer.
```java HTTP theme={null}
PUT /v1/signer/{handle}
```
***
| Parameter | Type | Description |
| --------- | ------ | -------------------------------------------------------------------------------- |
| handle | string | 26-35 characters Alphanumeric characters allowed base58 structure |
| labels | object | Metadata describing the address. Use them to describe the details of the signer. |
***
```javascript theme={null}
curl -X PUT \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"lastName": "Garcia",
"identification": "54812184282"
}
}' "URL/v1/signer/wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
```
```javascript {10,12} theme={null}
{
"signer_id": "4c57ac39-16f0-489b-89d9-bddfcd352a36",
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"aliasType": "EMAIL",
"aliasValue": "JORGE@COMPANY.IO",
"status": "INACTIVE",
"type": "PERSON",
"firstName": "Jorge",
"lastName": "Garcia",
"proprietary": "CC",
"identification": "54812184282",
"bankAccountType": "DBMO",
"bankAccountNumber": "302058294920",
"bankBicfi": "7095",
"bankName": "Banco Rojo",
"bankId": "891234918",
"routerReference": "$bancorojo",
"createdBy": "$minka",
"targetSpbviCode": "TFY"
"created": "2024-10-11T11:59:24.241-05:00",
"updated": "2024-10-11T12:01:11.121-05:00",
"consented": "2024-10-11T11:59:24.241-05:00",
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
},
"keeper": [
{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}
],
"error": {
"code": 0,
"message": "Success"
}
}
```
### Códigos de Error
***
| Error Code | Description |
| ---------- | ------------------------------------------------ |
| 99 | Unexpected server error |
| 100 | You don't have permissions to access this method |
| 102 | Invalid labels |
| 118 | Resource schema validation error |
| 121 | Signer not found in database |
### 🔐 **Actualización de datos y gestión de llaves en el sistema Bre-B**
La correcta administración de las llaves en los Sistemas de Pago de Bajo Valor Inmediatos (SPBVI) es fundamental para garantizar la seguridad, trazabilidad e interoperabilidad de las transacciones. Cuando un usuario solicita la actualización de sus datos como el tipo de cuenta asociada a una llave es responsabilidad directa de la entidad participante ejecutar dicha modificación de forma inmediata y conforme a los lineamientos establecidos por el Banco de la República.
Cualquier demora en el proceso puede generar acreditaciones erróneas de recursos económicos, afectando la integridad del sistema y la confianza del usuario. Según la normativa Bre-B, en especial la Circular Reglamentaria Externa DSP-465, los participantes deben reportar en tiempo real las novedades a la Entidad Administradora del SPBVI (EASPBVI), asegurando que los cambios se reflejen oportunamente en el Directorio Federado y el Directorio Centralizado.
📌 **Importante:** Si la entidad participante no actualiza oportunamente la llave tras una solicitud válida del usuario, y se generan errores en la acreditación de fondos, será responsable por las consecuencias derivadas de dicha omisión.
Todo ajuste realizado en las llaves a solicitud del usuario ya sea por actualización de datos, cambio de medio de pago o cualquier otra modificación autorizada debe ser reportado en tiempo real a través del canal designado por la entidad financiera. Esta comunicación oportuna garantiza que la novedad se refleje de forma inmediata en el sistema Bre-B, preservando la integridad operativa y evitando errores en la acreditación de recursos.
***
# Directorio Federado
Source: https://transfiya.me/es/v1.104/directory/intro/intro-directory
Resumen sobre el directorio federado Transfiya
## Introducción
Bre-B es la nueva marca establecida por el Banco de la República que identifica el Sistema de Pagos Inmediatos e Interoperables en Colombia.
En los flujos actuales, que incluyen pagos entre personas y pagos a comercios, se implementará la marca Bre-B en la [experiencia de usuario](intro-ux) de todos los participantes del sistema.
La regulación SPI en Colombia establece que todos SPBVI - Sitema de Pago de Bajo Valor Inmediato deben ser interoperables mediante la integración con dos nuevos servicios proporcionados por Banco Repubica como los son el DICE y el MOL.
El DICE es el directorio centralizado administrado por Banco República que unifica las llaves registradas en los Directorios Federados de los participantes de cada SPBVI y el MOL es el Mecanismo Operativo para la Liquidación de las ordenes de pagos y/o transferencias inmediatas.
Bre-B dispone cinco tipos de llaves para que los usuarios seleccionen y registre para recibir ordenes de pago y/o transferencias inmediatas.
## Obligaciones de los participantes
La mayor parte de los requerimientos solicitados por la Regulación del SPI del Banco de la Republica estan implementados en la plataforma de transfiya, no obstante los Participantes debe hacer ajustes internos para el cumplimiento total de la regulación para el flujo de llaves y el flujo transaccional, dentro de los cuales estan:
Los Participantes deben habilitar la Zona Bre-B en los Canales de Prestación de Servicios dispuestos para realizar Órdenes de Pago y/o Transferencias de Fondos Inmediatas, siguiendo las guias de experiencia de usuario.
Los participantes deben obtener el consentimiento explícito de los usuarios para [sincronizar con DICE](../guides/how-to-sync-dice) sus llaves.
Los participantes deben [resolver las llaves](../guides/how-to-resolve-keys) mediante transfiya antes de iniciar cualquier transferencia en el sistema Bre-B.
## Directorio Federado Transfiya
El objetivo de Transfiya es optimizar los esfuerzos de los bancos y generar más valor en todos sus servicios.
Transfiya ya cuenta con un directorio federado que soportab el número de celular como llave, la cual hace parte de las 5 llaves solicitadas por la regulación, se debe hacer los ajustes para soportar el directorio de transfiya multillaves.
Para consultar, modificar y eliminar llaves en Transfiya, puede utilizar la API de Transfiya [signers](../about/about-signers)
Una vez que la regulación entre en vigor, los participantes deberán [resolver](../guides/how-to-resolve-keys) las llaves mediante transfiya antes de iniciar cualquier transferencia. Todas las transferencias en Bre-B se procesarán como transferencias de cuenta a cuenta, o de "signer" a "signer".
Los "signers" representan credenciales de pago vinculadas de manera unívoca con cuentas bancarias. El modelo de [datos](../about/about-data-model) asociado al signer incluye información detallada sobre los propietarios de las cuentas, como números de documento, tipo y número de cuenta, entre otros datos relevantes.
La mayoría de los campos exigidos por la regulación ya se encuentran disponibles en la versión actual de integración para los participantes.
Al sincronizarse con el directorio centralizado, Transfiya implementará validaciones estrictas definidas por la regulación usando el esquema de [validación](../about/about-validations).
Durante la fase de transición, Transfiya habilitará validaciones flexibles o alertas para facilitar la interoperarbilidad y adaptación de los participantes.
# Experiencia de usuario
Source: https://transfiya.me/es/v1.104/directory/intro/intro-ux
Cambios en canales para habilitar Bre-B
## Introducción
La regulación establece directrices específicas para las diferentes secciones que deben incluirse en la zona Bre-B.
Los usuarios deberán tener acceso a la zona sello Bre-B (con su respectivo logo) en un primer nivel después de completar el flujo de autenticación de cada banco. Esta opción debe mostrarse en la pantalla principal (Home) con el mismo nivel jerárquico que acciones importantes como enviar dinero o consultar transacciones.
Si existen otros puntos de acceso a los servicios de Bre-B, tales como las secciones de envío de dinero, configuración o lectura/envío de QR, la entidad financiera podrá incorporar la imagen gráfica y el nombre de Bre-B en dichas áreas.
Puedes descargar la guía de experiencia de usuario (UX) en PDF desde el siguiente enlace. Este documento ha sido elaborado por Transfiya para apoyar a las entidades participantes en la implementación del nuevo flujo regulatorio bajo el modelo SPI. Incluye todos los pasos y lineamientos visuales para una correcta integración.
📥 Descargar Manual UX
### Secciones dentro de la Zona Bre-B
Una vez dentro de la zona Bre-B, se requieren las siguientes secciones y funcionalidades.
A continuación, se presenta una lista general seguida de un apartado para cada sección, donde se detallan sus características junto con ejemplos de experiencia en la aplicación de un banco ficticio.
Transferencias y pagos
1. Con llave
* Con código QR
* Leer
* Generar
2. Procesos de llaves
* Registro
* Modificación
* Cancelación
* Portabilidad
* Bloqueo
* Reactivación
* Consulta
3. Histórico de transacciones
* Historial de movimientos
* Solicitud de devolución
* Solicitud de reversión
4. Peticiones, quejas y reclamos
5. Otras funcionalidades
## Transferencias y pagos
### Envío de dinero
Para enviar dinero a una llave el usuario tiene diferentes posibilidades, digitar la llave directamente en un campo o seleccionar de su lista de contactos para facilitar el acceso a llaves tipo celular o mail. El punto de entrada también puede variar de acuerdo a la experiencia de cada app, siendo impresindíble que uno de estos puntos de entrada sea a través de la zona Bre-B > Transferencias.
### Leer código QR
Permitir al usuario leer un QR para realizar un pago
>
### Crear Código QR
Para la creación de código QR el usuario podrá realizarlo a través de la zona Bre-B, el cual es obligatorio dentro de lo propuesto por la regulación, también cada entidad podrá utilizar cualquier otro punto relacionado a la experiencia QR como punto de ingreso para sus usuarios
## Procesos de llaves
Dentro de los procesos relacionados a llaves, la propuesta es que en una sola sección llamada "Administración de llaves", los usuarios puedan acceder a ejecutar las acciones listadas en la regulación.
### Registro de llave
Operación que realiza el Cliente para elegir la(s) Llave(s) y asociarla(s) con su Medio de Pago, previa autenticación del Cliente en los términos definidos por el Participante y de la autorización para el tratamiento de sus datos personales.
### Modificación de llave
Operación que realiza el Cliente para modificar su(s) Llave(s) inscrita(s) por otra(s) Llave(s) del mismo tipo o de otro tipo, y/o el Medio de Pago asociado a ella(s) por otro Medio de Pago del Participante donde se encuentra registrada la Llave
### Cancelación de llave
Operación que realiza el Cliente para cancelar el registro de la(s) Llave(s) inscrita(s).
### Portabilidad
Este flujo aún no está definido dentro de la regulación, por lo cual no se especifica en esta guía.
### Bloqueo de llave
El usuario puede desactivar su llave y activarla dentro de un periodo de 30 días. Si el usuario no reactiva su llave en este periodo, la llave sera cancelada.
### Activación de llave
Esta acción solo se podrá ejecutar sobre las llaves que el usuario bloqueo anteriormente.
# Documentos de soporte
Source: https://transfiya.me/es/v1.104/directory/support/support-files
Manuales técnicos y guías descargables relacionadas al Directorio Federado y Centralizado.
## Documentación DICE
En esta sección encontrarás manuales técnicos y documentos de soporte asociados al DICE.
Puedes descargar el documento técnico de la versión actual desde el siguiente enlace. Este archivo contiene detalles técnicos del DICE.
📄 Versión 2.3.0 - Manual Técnico DICE 28/04/2025
Ver documento PDF
📄 Versión 2.2.2 - Manual Técnico DICE 04/04/2025
Ver documento PDF
# Sobre Flujo Actual
Source: https://transfiya.me/es/v1.104/transfers-mol/about/about-current-flow
Descripción del flujo actual para transferencias tipo `SEND` en Transfiya, incluyendo detalles sobre llamadas, confirmaciones, y detección de fraude.
## Flujo actual de Transfiya
El flujo actual de procesamiento de transferencias tipo `SEND` en Transfiya funciona de la siguiente manera:
Transfiya **no implementa actualmente** un protocolo de confirmación en dos fases (*two-phase commit*), aunque este podría incorporarse utilizando la llamada de `status` como segunda fase del proceso.
Las entidades financieras realizan los movimientos centrales durante las llamadas de `debit` (débito) y `credit` (crédito), motivo por el cual **estas llamadas son asincrónicas**. En algunos sistemas bancarios, los movimientos contables pueden tardar en completarse.
La acción denominada `movement`, por su parte, **no tiene efecto sobre los saldos reales**; su único propósito es confirmar que los fondos pueden ser enviados al usuario destinatario.
Transfiya puede aceptar una transferencia automáticamente (Aceptación por usuario, Aceptación por transfiya) en casos donde existan firmantes por defecto, enlaces previos u otros mecanismos configurados.
Cuando el usuario tiene múltiples firmantes asociados, se le envía una **notificación para que confirme manualmente** la operación desde su aplicación bancaria.
El sistema de detección de fraude se activa **únicamente después de que la transferencia ha sido aceptada**, ya que es en ese momento cuando se conoce con certeza el destinatario final. Antes de esa etapa, el destinatario puede ser un alias no registrado.
Las llamadas de `status` **no deben generar movimientos de saldo** en los sistemas bancarios. Estas llamadas se utilizan con fines informativos, como notificar al usuario o registrar el estado de la transacción.
### Vista general del proceso
A continuación, se presenta una vista general del procesamiento de transferencias desde una perspectiva de alto nivel.
```mermaid theme={null}
sequenceDiagram
autonumber
participant sb as Banco origen
participant ty as Transfiya
participant tb as Banco destino
participant af as Antifraude
sb ->> ty: Crear transferencia
ty ->> sb: Llamar a débito
ty ->> ty: Esperar aceptación
ty ->> af: Iniciar antifraude
ty ->> sb: Llamar a acción
ty ->> tb: Llamar a crédito
ty ->> sb: Llamar a estado
ty ->> tb: Llamar a estado
ty ->> af: Finalizar antifraude
```
**Diagrama detallado del procesamiento de transferencias:**
```mermaid theme={null}
sequenceDiagram
autonumber
participant sb as Banco Origen
participant ty as Transfiya
participant tb as Banco Destino
participant monitor as Monitor+
sb ->> +ty: Crear transferencia
ty ->> ty: Validar reglas de negocio
ty -->> -sb: Transferencia creada
alt débito (asincrónico)
ty ->> +sb: Llamar a débito
sb ->> ty: Crear acción de subida
sb -->> -ty: Respuesta de débito
sb ->> sb: Debitar usuario origen
sb ->> ty: Asignar tx_id a la acción
sb ->> ty: Firmar pagaré (IOU) de débito
ty ->> ty: Procesar IOU de débito
ty -->> sb: Respuesta del IOU de débito
sb ->> ty: Continuar transferencia
end
ty ->> ty: Esperar aceptación
ty ->> monitor: Iniciar Monitor+
monitor -->> ty: Respuesta de Monitor+
alt acción (sincrónica)
ty ->> +sb: Llamar a acción
sb ->> ty: Firmar pagaré (IOU) de envío
sb -->> -ty: Respuesta de acción
end
alt crédito (asincrónico)
ty ->> +tb: Llamar a crédito
tb ->> ty: Crear acción de descarga
tb -->> -ty: Respuesta de crédito
tb ->> tb: Acreditar usuario destino
tb ->> ty: Asignar tx_id a la acción
tb ->> ty: Firmar pagaré (IOU) de crédito
ty ->> ty: Procesar IOU de crédito
ty -->> tb: Respuesta del IOU de crédito
tb ->> ty: Continuar transferencia
end
ty ->> +sb: Llamar a estado
sb -->> -ty: Respuesta de estado
ty ->> +tb: Llamar a estado
tb -->> -ty: Respuesta de estado
ty ->> +monitor: Finalizar Monitor+
monitor -->> -ty: Respuesta de Monitor+
```
# Errores de MOL
Source: https://transfiya.me/es/v1.104/transfers-mol/about/about-errors
Guía completa sobre el manejo de errores en el sistema MOL
## **Resumen**
Transfiya implementa un sistema de gestión de errores fundamentado en el estándar HTTP, proporcionando una estructura clara y coherente para el manejo de excepciones.Aunque los sistemas externos emplean códigos de error particulares, Transfiya ha desarrollado un mecanismo de mapeo que convierte automáticamente estos códigos a su propia arquitectura estandarizada de errores HTTP. Esta avanzada capacidad de normalización optimiza significativamente el proceso de integración para los participantes del ecosistema, minimizando o incluso eliminando por completo la necesidad de desarrollar lógicas personalizadas para el tratamiento de errores específicos.
Los errores de MOL y DICE se incluyen aquí solo con fines de referencia. El participante no necesita mapear errores de DICE directamente.
Mensajes de error Transfiya Cuando se produce un error durante una transferencia o en el sistema de MOL, la plataforma responde con códigos de estado HTTP específicos y un objeto de error estructurado que proporciona información detallada sobre la incidencia. El sistema implementa una clasificación estratégica de códigos de error organizados en rangos específicos, facilitando una categorización clara, identificación rápida y resolución eficiente de incidencias. La estructura de errores está distribuida estratégicamente según el tipo de participante afectado:
* `1xx` - Errores de sistema TransfiYa
* `3xx` - Errores de participantes
El sistema Transfiya implementa un protocolo de respuesta estandarizado. Todas las solicitudes procesadas exitosamente hacia la plataforma retornan invariablemente un código de estado HTTP`200`. Cuando ocurre algún error durante el procesamiento, el sistema devuelve un objeto de error estructurado que contiene un código numérico específico y una descripción clara del problema, facilitando su identificación y resolución.
```json Estructura theme={null}
{
"error": {
"code": ,
"message": ""
}
}
```
```json Ejemplo theme={null}
{
"error": {
"code": 307,
"message": "Inactive account"
}
}
```
En el caso de respuestas exitosas, un objeto de error con código `0` se añade a la respuesta original.
### [****](https://transfiya.me/es/v1.83/directory/about/about-errors#estrategia-de-mapeo-integral)
Estrategia de mapeo integral TransfiYa implementa validaciones exhaustivas de todos los campos y esquemas según los requisitos regulatorios, lo que mitiga significativamente la posibilidad de que ocurran errores del **MOL.** No obstante, documentamos estos mapeos de errores como medida preventiva para garantizar una respuesta adecuada ante situaciones excepcionales o imprevistas que pudieran presentarse. La estrategia general de mapeo es la siguiente:
| **Categoria** | **Descripcion** |
| :------------------------------- | :------------------------------------------------------------------------------------------------------------------ |
| `118 - ResourceValidationError` | Los errores de validación de campos |
| `121 - ResourceNotFoundError` | Los errores relacionados con referencias inválidas, por ejemplo, ID de participante inválido |
| `123 - DomainRuleViolationError` | Todas las reglas de negocio, por ejemplo, el tiempo después del cual se puede volver a utilizar una clave cancelada |
| `136 - ApiError` | Todos los errores técnicos, por ejemplo, problemas relacionados con una configuración inválida |
| `100 - ForbiddenError` | Los errores de seguridad |
**Mapeo de Errores MOL**
| **MOL Error** | Transfiya Error code | Transfiya Error Message |
| :-----------: | :------------------: | :-----------------------------------------------------------------------------------------------------------------------: |
| | 800 | MOL ERROR: General MOL error |
| U101 | 801 | MOL ERROR U101: Tenant ID not found |
| U103 | 802 | MOL ERROR U103: Tenant undefined validation |
| U106 | 803 | MOL ERROR U106: Transaction not found |
| U111 | 846 | Monto mínimo de una OP/TFI es 1 |
| U112 | 804 | MOL ERROR U112: Amount exceeds the maximum allowed |
| U119 | 805 | MOL ERROR U119: Session error |
| U120 | 806 | MOL ERROR U120: Inbound channel signed out |
| U122 | 807 | MOL ERROR U122: Target participant not active |
| U125 | 808 | MOL ERROR U125: Source participant not configured in the system |
| U126 | 809 | MOL ERROR U126: Target participant not configured in the system |
| U173 | 810 | MOL ERROR U173: Spbvi timeout error. |
| U193 | 800 | MOL Error U193: The balance in the Participant's liquidity account in the MOL is less than or equal to the allowed value. |
| U194 | 811 | MOL ERROR U194: Insufficient funds |
| U204 | 847 | Posición de liquidez no encontrada |
| U212 | 812 | MOL ERROR U212: Message sent by an inappropiate channel |
| U250 | 813 | MOL ERROR U250: The key type must be one of those registered in the global dictionary |
| U272 | 800 | MOL ERROR U272: Error due to rules for source or target |
| U801 | 814 | MOL ERROR U801: The participant cannot be determined |
| U804 | 815 | MOL ERROR U804: Keys not found or inactive |
| U805 | 816 | MOL ERROR U805: Keys suspended by customer |
| U806 | 817 | MOL ERROR U806: Key already registered by the same financial entity but different account number |
| U807 | 818 | MOL ERROR U807: Key registered by another financial entity |
| U808 | 819 | MOL ERROR U808: Key already registered with same account number |
| U809 | 820 | MOL ERROR U809: You do not have sufficient privileges to perform this operation. |
| U811 | 821 | MOL ERROR U811: Key suspended by participant |
| U908 | 822 | MOL ERROR U908: Invalid transaction. One or both participants are locked |
| B001 | 823 | MOL ERROR B001: Source bank timeout |
| B002 | 824 | MOL ERROR B002: Target bank timeout |
| B003 | 838 | Time-Out declarado por el Participante Receptor |
| B004 | 839 | Error técnico en el SPBVI Originador |
| B005 | 840 | Error técnico en el SPBVI Receptor |
| B006 | 841 | Error técnico en el Participante Receptor |
| B009 | 836 | MOL ERROR B009: Payment order arrived out of time at receiving SPBVI |
| B101 | 825 | MOL ERROR B101: Invalid target customer's account number |
| B102 | 826 | MOL ERROR B102: Target account validation error |
| B103 | 827 | MOL ERROR B103: Target id error |
| B104 | 828 | MOL ERROR B104: Target payment method error |
| B105 | 829 | MOL ERROR B105: Target account not found |
| B106 | 830 | MOL ERROR B106: Fraud detection control |
| B107 | 831 | MOL ERROR B107: Exceeds maximum low amount deposits |
| B108 | 832 | MOL ERROR B108: Exceeds spbvi maximum amount |
| B110 | 842 | Falló autorización en el Participante Receptor |
| B111 | 843 | Información del SPBVI Originador incompleta |
| B109 | 833 | MOL ERROR B109: Exceeds target bank maximum amount |
| B112 | 837 | MOL ERROR B112: Required information missing at receiving SPBVI |
| B114 | 845 | Código QR no válido |
| B113 | 844 | Código QR ya fue usado |
| B301 | 834 | MOL ERROR B301: Source spbvi timeout |
| B302 | 835 | MOL ERROR B302: Target spbvi timeout |
# Sobre Flujo Regulatorio
Source: https://transfiya.me/es/v1.104/transfers-mol/about/about-new-flow
Descripción del flujo nuevo segun la regulacion que entra en vigor este 2025
## Procesamiento de Transferencias y MOL
Con la entrada en operación del MOL, todas las transferencias deberán ser enviadas a esta nueva infraestructura. Durante ese proceso, Transfiya suspenderá temporalmente su procesamiento interno hasta recibir la confirmación por parte de MOL.
Gracias a que nuestro sistema ya está basado en procesamiento asincrónico por etapas (flow processor), esta integración se puede lograr simplemente agregando un nuevo paso dentro del flujo existente, de manera similar a como ya lo hacemos con otras integraciones como **Motor de prevensión de fraude**.
## Compatibilidad con el Modelo Regulatorio
La regulación define que todas las transacciones sean de cuenta a cuenta. En Transfiya, las cuentas están representadas por firmantes (*signers*), por lo que nuestras transferencias ya son técnicamente equivalentes a lo exigido (de firmante a firmante). Este modelo ya se usa en flujos B2P actuales, lo que minimiza los cambios requeridos.
Los bancos deben quitar las validaciones existentes con número de teléfono
## Tiempos y Reversión de Transferencias
La regulación establece límites estrictos de tiempo para el procesamiento. Nuestra arquitectura permite registrar el tiempo de cada etapa del flujo, por lo que estamos en capacidad de cumplir con esta exigencia sin mayores ajustes estructurales.
El sistema actual ya incluye un mecanismo de reversión automática ante fallas. Actualmente opera en un plazo de varias horas, pero será optimizado para que actúe en segundos y se integre al flujo regular de procesamiento, asegurando cumplimiento con los estándares regulatorios.
## Mantenimiento de Funcionalidades Existentes
Funcionalidades como las solicitudes de dinero (`REQUEST`) podrán mantenerse sin cambios, ya que no están reguladas. La aceptación de transferencias también continuará funcionando en los escenarios donde ya está deshabilitada por configuración (un solo firmante o firmante predeterminado).
Ver documentación actual
## Flujo de transferencias compatible con la regulación
Esta sección presenta los flujos de procesamiento de transferencias que han sido actualizados para cumplir con los lineamientos de la regulación e integrar la funcionalidad del MOL (Modelo Operativo de Liquidación).
```mermaid theme={null}
sequenceDiagram
autonumber
participant su as Usuario Origen
participant sb as Banco Origen
participant ty as Transfiya
participant tb as Banco Destino
participant monitor as Monitor+
participant mb as Puente MOL
participant mol as MOL
su ->> +sb: Crear transferencia
sb ->> +ty: Crear transferencia
ty ->> ty: Validar reglas de negocio
ty -->> -sb: Transferencia creada
sb -->> -su: Transferencia creada
alt débito
ty ->> +sb: Llamar a débito
sb ->> +ty: Crear acción de subida (UPLOAD)
ty -->> -sb: Respuesta de acción
sb -->> -ty: Respuesta de débito
sb ->> sb: Debitar cuenta origen
sb ->> +ty: Actualizar acción con tx_id
ty -->> -sb: Acción actualizada
sb ->> +ty: Enviar pagaré (IOU)
ty -->> -sb: Respuesta de IOU
sb ->> ty: Continuar transferencia
end
ty ->> +monitor: Iniciar Monitor+
monitor -->> -ty: Respuesta de Monitor+
ty ->> +mb: Reservar fondos
activate mb
mb ->> mol: Reservar fondos (pacs.008)
activate mol
mol ->> mb: Acreditar destino (pacs.008)
activate mb
mb ->> ty: Continuar transferencia
(crédito MOL)
alt aceptación
ty ->> tb: Notificar estado PENDIENTE
tb -->> ty: Respuesta
tb ->> tb: Validar datos del destinatario
tb ->> ty: Aceptar transferencia
end
ty ->> mb: Confirmar crédito
mb -->> mol: Confirmar crédito (pacs.002)
deactivate mb
mol -->> mb: Confirmación (pacs.002)
deactivate mol
mb ->> ty: Continuar transferencia
(reserva MOL)
deactivate mb
ty ->> ty: Esperar confirmación de liquidación
mol ->> +mb: Confirmación de liquidación (pacs.002)
mb ->> -ty: Continuar transferencia
(MOL liquidado)
alt acción
ty ->> +sb: Llamar a Acción
sb ->> +ty: Enviar IOU
ty -->> -sb: Respuesta de IOU
sb -->> -ty: Respuesta de Acción
end
alt crédito
ty ->> +tb: Llamar a crédito
tb ->> +ty: Crear acción de descarga (DOWNLOAD)
ty -->> -tb: Respuesta de acción
tb -->> -ty: Respuesta de crédito
tb ->> tb: Acreditar usuario destino
tb ->> +ty: Actualizar acción con tx_id
ty -->> -tb: Acción actualizada
tb ->> +ty: Enviar IOU
ty -->> -tb: Respuesta de IOU
tb ->> ty: Continuar transferencia
end
alt estado completado
ty ->> +sb: Llamar a estado (COMPLETADO)
sb -->> -ty: Respuesta de estado
sb ->> sb: Notificar a usuario origen
ty ->> +tb: Llamar a estado (COMPLETADO)
tb -->> -ty: Respuesta de estado
tb ->> tb: Notificar a usuario destino
end
ty ->> +monitor: Finalizar Monitor+
monitor -->> -ty: Respuesta de Monitor+
```
```mermaid theme={null}
sequenceDiagram
autonumber
participant su as Usuario Origen
participant sb as Banco Origen
participant ty as Transfiya
participant mb as Puente MOL
participant mol as MOL
participant tb as Banco Destino
participant monitor as Monitor+
su ->> +sb: Crear transferencia
sb ->> +ty: Crear transferencia
ty ->> ty: Validar reglas de negocio
ty -->> -sb: Transferencia creada
sb -->> -su: Transferencia creada
alt débito
ty ->> +sb: Llamar a débito
sb ->> +ty: Crear acción de subida (UPLOAD)
ty -->> -sb: Respuesta de acción
sb -->> -ty: Respuesta de débito
sb ->> sb: Debitar cuenta origen
sb ->> +ty: Actualizar acción con tx_id
ty -->> -sb: Acción actualizada
sb ->> +ty: Enviar pagaré (IOU)
ty -->> -sb: Respuesta de IOU
sb ->> ty: Continuar transferencia
end
ty ->> +monitor: Iniciar Monitor+
monitor -->> -ty: Respuesta de Monitor+
ty ->> +mb: Reservar fondos
mb ->> +mol: Reservar fondos (pacs.008)
mol ->> +tb: Acreditar destino (pacs.008)
tb ->> tb: Validar cuenta destino
tb -->> -mol: Confirmar crédito (pacs.002)
mol -->> -mb: Confirmación (pacs.002)
mb ->> -ty: Continuar transferencia
(reserva MOL)
ty ->> ty: Esperar confirmación de liquidación
mol ->> +mb: Confirmación de liquidación (pacs.002)
mb ->> -ty: Continuar transferencia
(MOL liquidado)
alt acción
ty ->> +sb: Llamar a Acción
sb ->> +ty: Enviar IOU
ty -->> -sb: Respuesta de IOU
sb -->> -ty: Respuesta de Acción
end
alt crédito vía PUENTE MOL
ty ->> +mb: Llamar a crédito
mb ->> +ty: Crear acción de descarga (DOWNLOAD)
ty -->> -mb: Respuesta de acción
mb -->> -ty: Respuesta de crédito
mb ->> mb: Acreditar usuario destino
mb ->> +ty: Actualizar acción con tx_id
ty -->> -mb: Acción actualizada
mb ->> +ty: Enviar IOU
ty -->> -mb: Respuesta de IOU
mb ->> ty: Continuar transferencia
end
alt estado completado
ty ->> +sb: Llamar a estado (COMPLETADO)
sb -->> -ty: Respuesta de estado
sb ->> sb: Notificar a usuario origen
ty ->> +mb: Llamar a estado (COMPLETADO)
mb -->> -ty: Respuesta de estado
end
ty ->> +monitor: Finalizar Monitor+
monitor -->> -ty: Respuesta de Monitor+
```
```mermaid theme={null}
sequenceDiagram
autonumber
participant su as Usuario Origen
participant sb as Banco Origen
participant ss as Sistema RTP
Origen
participant mol as MOL
participant mb as Puente MOL
participant ty as Transfiya
participant tb as Banco Destino
participant monitor as Monitor+
su ->> +sb: Crear transferencia
sb ->> sb: Verificar y reservar fondos
sb ->> +ss: Crear transferencia
ss ->> ss: Validar fraude
ss -->> -sb: Transferencia creada
sb -->> -su: Transferencia creada
ss ->> +mol: Reservar fondos (pacs.008)
mol ->> +mb: Acreditar destino (pacs.008)
mb ->> +ty: Crear transferencia
ty ->> ty: Validar reglas de negocio
ty -->> -mb: Transferencia creada
alt débito
ty ->> +mb: Llamar a débito
mb ->> +ty: Crear acción de subida (UPLOAD)
ty -->> -mb: Respuesta de acción
mb -->> -ty: Respuesta de débito
mb ->> mb: Autorizar débito
mb ->> +ty: Actualizar acción con tx_id
ty -->> -mb: Acción actualizada
mb ->> +ty: Enviar IOU
ty -->> -mb: Respuesta de IOU
mb ->> ty: Continuar transferencia
end
ty ->> +monitor: Iniciar Monitor+
monitor -->> -ty: Respuesta de Monitor+
alt aceptación
ty ->> tb: Notificar estado PENDIENTE
tb -->> ty: Respuesta
tb ->> tb: Validar datos del destinatario
tb ->> ty: Aceptar transferencia
end
ty ->> mb: Confirmar crédito
mb -->> -mol: Confirmar crédito (pacs.002)
mol -->> -ss: Confirmación (pacs.002)
ss ->> ss: Esperar confirmación de liquidación
mol ->> +ss: Confirmación de liquidación (pacs.002)
ss ->> -sb: Finalizar transferencia
activate sb
sb ->> sb: Debitar usuario origen
sb -->> ss: Confirmación final
deactivate sb
ty ->> ty: Esperar confirmación de liquidación
mol ->> +mb: Confirmación de liquidación (pacs.002)
mb ->> -ty: Continuar transferencia
(MOL liquidado)
alt acción
ty ->> +mb: Llamar a Acción
mb ->> +ty: Enviar IOU
ty -->> -mb: Respuesta de IOU
mb -->> -ty: Respuesta de Acción
end
alt crédito
ty ->> +tb: Llamar a crédito
tb ->> +ty: Crear acción de descarga (DOWNLOAD)
ty -->> -tb: Respuesta de acción
tb -->> -ty: Respuesta de crédito
tb ->> tb: Acreditar cuenta destino
tb ->> +ty: Enviar IOU
ty -->> -tb: Respuesta de IOU
tb ->> ty: Continuar transferencia
end
alt estado completado
ty ->> +mb: Llamar a estado (COMPLETADO)
mb -->> -ty: Respuesta de estado
mb ->> mb: Notificar a usuario origen
ty ->> +tb: Llamar a estado (COMPLETADO)
tb -->> -ty: Respuesta de estado
tb ->> tb: Notificar a usuario destino
end
ty ->> +monitor: Finalizar Monitor+
monitor -->> -ty: Respuesta de Monitor+
```
### ⏱ Lineamientos de tiempo para el procesamiento de transacciones Bre-B
Con el fin de dar cumplimiento a lo establecido por el Banco de la República en relación con el esquema Bre-B, la entidad financiera, en conjunto con el nodo correspondiente, debe garantizar que el procesamiento de las transferencias se realice en **20 segundos o menos en el 99.5% de los casos**.
Para lograr este objetivo, se propone la siguiente línea de tiempo que contempla las operaciones principales involucradas en el ciclo de la transacción. Cabe aclarar que para lograr el objetivo no se deben procesar todos los consumos teniendo como referencia el tiempo máximo:
#### 🔄 Débito
* **Tiempo óptimo:** \< 2 segundos
* **Tiempo máximo:** \< 7 segundos
#### ✅ Aceptación de la transferencia
* **Tiempo óptimo:** \< 2 segundos
* **Tiempo máximo (timeout):** \< 7 segundos
#### ✍️ Firma de la acción principal
* **Tiempo óptimo:** \< 2 segundos
* **Tiempo máximo:** \< 7 segundos
#### 💳 Crédito
* **Tiempo óptimo:** \< 2 segundos
* **Tiempo máximo:** \< 7 segundos
Este esquema operativo permite asegurar el cumplimiento de los requisitos de eficiencia y oportunidad definidos en la normativa Bre-B del Banco de la República, contribuyendo a la confiabilidad y agilidad del sistema de pagos.
# Sobre Cambios Regulatorios
Source: https://transfiya.me/es/v1.104/transfers-mol/about/about-regulatory-changes
Descripción del los cambios regulatorios y mandatorios
## Cambios Mandatorios
Esta sección describe los cambios necesarios para que los bancos sean completamente compatibles con el modelo SPI (Sistema de Pagos Inmediatos). Transfiya mantendrá compatibilidad con los flujos actuales, por lo que las entidades pueden implementar estas modificaciones de forma independiente y en fases. Los cambios enumerados como 1, 2, 3 y 4 son suficientes para comenzar a operar bajo el nuevo modelo regulado.
El cambio número 5 está relacionado con el cumplimiento de los tiempos máximos de procesamiento definidos por la normativa. Si los bancos no lo implementan, podrán iniciar operaciones con otros participantes, pero estarán expuestos a posibles penalidades por demoras en las transferencias.
Omitir el cambio 6 podría generar complicaciones solo en caso de problemas técnicos con Transfiya o con MOL. Si bien la plataforma Transfiya ha demostrado una alta disponibilidad durante el último año, la estabilidad del sistema dependerá en gran medida del comportamiento de MOL una vez esté en funcionamiento. No implementar este cambio puede traducirse en un esfuerzo operativo adicional para resolver posibles incidentes.
A continuación, se detallan los cambios obligatorios para lograr la compatibilidad con SPI:
### 1. Obtener los datos del beneficiario (firmante destino) antes de enviar la transferencia
En el modelo SPI, las transferencias se realizan de cuenta a cuenta, lo que en términos de Transfiya significa de firmante a firmante. Antes de realizar una transferencia, los bancos deben consultar el directorio federado para identificar un firmante válido que ya esté registrado en el sistema. Para cumplir con la regulación, el destinatario de las transferencias tipo `SEND` debe ser obligatoriamente un firmante.
### 2. Eliminar validaciones relacionadas con billeteras
Algunos bancos validan que una billetera represente un número de teléfono al procesar transferencias. Este tipo de validaciones deben eliminarse, ya que ahora se deben admitir distintos tipos de alias. Además, las billeteras dejarán de usarse en este contexto. Al tratarse de transferencias de cuenta a cuenta, los bancos no deben realizar validaciones sobre el alias en sí, sino únicamente sobre los datos del cliente: nombre, identificación y datos bancarios.
### 3. Generar un `tx_id` único conforme a la regulación
Cada transferencia SPI debe contar con un identificador único (`tx_id`) generado siguiendo las reglas establecidas por la normativa. Este campo ya existe actualmente en las transferencias de Transfiya, pero no está sujeto a validaciones estrictas. A partir de la entrada en vigor del modelo SPI, este identificador será validado conforme a las reglas regulatorias.
### 4. Registrar los tiempos de recepción y despacho de operaciones
Los bancos deberán registrar el momento exacto en que reciben una operación desde Transfiya y el momento en que envían una respuesta. Esta información se incluirá en cada tipo de operación de la siguiente manera:
* **Creación de transferencia**
* `received`: momento en que el usuario generó la solicitud.
* `dispatched`: momento en que se envió la solicitud a Transfiya.
* **Continuación de transferencia**
* `received`: hora de la última interacción previa con Transfiya.
* `dispatched`: hora en que se envía la solicitud de continuación.
* **Aceptación de transferencia**
* `received`: momento en que el usuario aceptó la operación.
* `dispatched`: momento en que se envió la solicitud de aceptación a Transfiya.
Estos registros de tiempo son fundamentales para generar reportes de desempeño ante MOL y verificar el cumplimiento de los tiempos establecidos por la regulación.
### 5. Cumplir con los límites de tiempo establecidos por la regulación
La normativa define límites estrictos para el procesamiento de distintos segmentos de una transferencia. Los bancos deberán revisar sus integraciones para garantizar que pueden cumplir con estos tiempos dentro de los márgenes establecidos.
### 6. Soportar el estado `PENDING` en el endpoint `/status`
El modelo regulado exige que el banco receptor valide el estado de la cuenta y los detalles de la transferencia antes de que esta sea completada. Esta validación no acredita aún los fondos, sino que se trata de una verificación previa. Para soportar esto, Transfiya emplea el modelo de aceptación que ya existe en su arquitectura.
Para automatizar este proceso, se utiliza el endpoint `/status`. Al recibir un estado `PENDING`, el banco debe validar que la cuenta destino exista, esté activa y que el usuario pueda recibir el pago entrante. Si todo es correcto, la transferencia debe ser aceptada.
# Sobre Liquidación
Source: https://transfiya.me/es/v1.104/transfers-mol/about/about-settlement
Guia sobre modelos de liquidación en transfiya
## Sobre Liquidación
En el contexto bancario, la liquidación (o settlement) es el proceso mediante el cual se completan las transacciones financieras entre entidades bancarias. Este proceso implica la transferencia efectiva de fondos para saldar obligaciones entre instituciones financieras.
### Terminología
**Compensación (clearing)**:
Proceso previo donde se calculan posiciones netas entre entidades en tiempo real.
**Liquidación bruta**:
Cada transacción se liquida individualmente y en tiempo real.
**Liquidación neta**:
Las transacciones se acumulan durante un período y se liquidan por el valor neto.
### Sistema de liquidación en Transfiya
Transfiya implementa un modelo de liquidación neta basado en garantías. La plataforma opera mediante un sofisticado sistema de compensación en tiempo real que calcula con precisión las posiciones netas entre entidades participantes.
Las garantías dentro del sistema se establecen mediante un mecanismo de prefondeo en las cuentas CUD del banco central, las cuales funcionan como respaldo financiero para todas las transacciones efectuadas en la plataforma.
Este sistema tiene ventajas en términos de felxibilidad de casos de uso.
### Sistema de liquidación en Bre-B
Bre-B implementa un sistema de liquidación bruta en tiempo real para sus participantes. En este modelo, cada transferencia procesada bajo el marco regulatorio es canalizada a través del banco central, donde se debita automáticamente la posición financiera de los participantes durante el proceso completo de la transacción.
Este sistema no requiere recursos en modelo de garantías para la liquidación.
# Sobre Transferencias
Source: https://transfiya.me/es/v1.104/transfers-mol/about/about-transfers
Guia sobre los transferencias en transfiya
El flujo completo para procesar una transferencia en Transfiya bajo el modelo regulado involucra varios pasos distribuidos entre el banco origen, Transfiya, MOL y el banco destino. A continuación se describen las etapas principales desde una perspectiva de alto nivel:
El usuario inicia una transferencia desde su aplicación bancaria. El banco origen comunica la solicitud a TransfiYa, quien valida reglas de negocio internas y devuelve una respuesta para confirmar la creación.
TransfiYa solicita al banco origen ejecutar la operación de débito. El banco crea una acción de tipo `UPLOAD`, debita los fondos y responde con un IOU firmado que TransfiYa valida.
Si se requiere aceptación, TransfiYa notifica al banco destino con estado `PENDING`. Este valida la cuenta, registra el firmante si es necesario y acepta la operación para continuar.
TransfiYa llama al banco origen para firmar la acción principal (`mainAction`). El banco genera y firma un IOU con los detalles de la operación, el cual TransfiYa valida y marca como `COMPLETED`.
TransfiYa llama al banco destino para acreditar los fondos. Este crea una acción `DOWNLOAD`, acredita la cuenta y envía un IOU firmado que TransfiYa valida.
TransfiYa envía una notificación de estado `COMPLETED` (o `REJECTED` si hubo un error) a ambos bancos para cerrar el proceso. Cada banco puede notificar al usuario y realizar tareas internas de limpieza si lo requiere.
Este flujo está diseñado para asegurar consistencia y trazabilidad completa en cada paso, incluyendo criptografía para garantizar integridad y autenticación en las operaciones.
## Modelo de transferencia
### Concepto "Transfer"
Transfiya utiliza el concepto de "transfer" para iniciar pagos en el sistema.
El *Transfer* es un inciacion de pago compuesta de transacciones que representan dos o más movimientos de dinero entre los participantes.
Este modelo es agnóstico al caso de uso y soporta cualquier tipo de movimiento de fondos, dependiendo de las reglas configuradas del sistema sobre el flujo y las [llaves](../about/about-signers) de origen y destino.
Para crear transferencias se usa el interfaz aplicativo de crear un transfer.
El uso del modelo de transfer para iniciar pagos en el sistema permite emplear el mismo protocolo y REST API para cualquier caso de uso o flujo de dinero, incluyendo el nuevo flujo regulatorio.
### Origen y destino de transferencia
La plataforma de Transfiya permite, desde sus inicios, realizar envíos de fondos entre diferentes credenciales de pago registradas en el sistema, conocidas como signers. Estas se representan a través de los campos source (origen) y target (destino).
El tipo de transferencia —por ejemplo, P2P, B2P, P2B o G2P— se determina en función del tipo de participantes involucrados (es decir, el tipo de signer) y de las reglas asociadas a cada uno.
El modelo basado en source y target tiene como objetivo simplificar la integración para los participantes, permitiendo cualquier tipo de movimiento de fondos entre entidades sin necesidad de realizar modificaciones adicionales en sus integraciones actuales.
Origen de la transferencia.
Destino de la transferencia.
[Sobre llaves y credenciales de pago (signers)](../about/about-signers)
Esta flexibilidad facilita la implementación de diferentes casos de uso de negocio sin la necesidad de modificar la integración existente de los participantes.
```mermaid theme={null}
sequenceDiagram
autonumber
participant sb as Banco Origen
participant ty as Transfiya
participant tb as Banco Destino
sb ->> ty: Crear transferencia
ty ->> sb: Debitar usuario origen
ty ->> tb: Aceptar transferencia
ty ->> sb: Firmar acción principal
ty ->> tb: Acreditar usuario destino
ty ->> sb: Notificación final de estado
ty ->> tb: Notificación final de estado
```
# Como firmar la transferencia
Source: https://transfiya.me/es/v1.104/transfers-mol/guides/como-firmar-una-transferencia
Autorización de movimiento de fondos (action)
Una vez se han completado con éxito todas las validaciones relacionadas con el procesamiento de la transferencia y la información del destinatario ha sido completamente resuelta, Transfiya realiza una llamada al endpoint action del banco originador.
El propósito de esta operación es autorizar el movimiento de los fondos hacia la custodia del banco destinatario.
Esta operación no requiere que el banco originador realice movimientos contables en su sistema interno. Su único objetivo es autorizar el movimiento de saldos dentro del sistema de Transfiya, desde el usuario originador (cuya clave es gestionada por el banco de origen) hacia el usuario destinatario (cuya clave es gestionada por el banco de destino).
Al momento de invocar el endpoint `action`, todos los datos tanto del usuario de origen como del destinatario ya están completamente resueltos. Antes de este punto, en algunos casos de uso, la información del destinatario podría no estar completamente disponible si aún no había sido registrado en el sistema.
```mermaid theme={null}
sequenceDiagram
autonumber
participant sb as Banco Originador
participant ty as Transfiya
ty ->> +sb: Llamar al endpoint de acción
sb ->> +ty: Enviar IOU
ty ->> ty: Validar y almacenar IOU
ty -->> -sb: Respuesta de IOU
sb -->> -ty: Respuesta de la acción
```
## Firma de la acción principal (Sign main action)
Una vez Transfiya ha resuelto completamente la información de origen y destino, se procede a autorizar el movimiento de fondos dentro del sistema. Esta operación consiste en la firma de la acción principal por parte del banco originador. La firma se realiza a través de un objeto IOU (prueba criptográfica), que garantiza que el banco autoriza la transacción y que esta no fue modificada.
Este proceso tiene como finalidad asegurar la integridad y validez de la operación antes de que se ejecute el movimiento final hacia el banco destinatario.
Transfiya realiza una solicitud al endpoint `/action` del banco originador, incluyendo todos los datos relevantes de la acción principal. Esta llamada tiene como objetivo solicitar autorización para mover fondos entre usuarios.
```json theme={null}
POST https://ban.co/transfiya/action
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "SENDMOL",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "PENDING",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:40:57.322-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
El banco crea un objeto IOU con los datos de la acción principal, lo firma con la clave privada asociada al firmante origen y lo envía a Transfiya para su validación.
La variable `mainAction` representa el payload enviado al banco en el endpoint `/action`.
El objeto IOU se utiliza para autorizar un movimiento de saldo entre los firmantes de usuario origen y destino en Transfiya. Este objeto DEBE reflejar fielmente la acción principal que representa. Por ello, la mayoría de los datos del IOU se copian desde `mainAction`.
Transfiya utiliza firmas criptográficas como prueba de que los participantes autorizaron movimientos de saldo. Los datos se hashean primero y luego se firman usando claves privadas, las cuales nunca deben compartirse con TransfiYa. Los algoritmos de firma y hash están documentados, y los SDKs de TransfiYa ofrecen soporte para simplificar estas integraciones.
Transfiya validates the signature of the received IOU object and stores it in the ledger, if everything is valid. This operation also marks the main action as COMPLETED.
```json theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"hash": {
"types": "sha256:sha256",
"steps": "stringify:data",
"value": "31abac5167fbb603d9300e9dfaf94b721efdc12c0728a615f9717b944a3fa779"
},
"data": {
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"symbol": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"amount": "100.00",
"domain": "tin",
"expiry": "2025-01-14T20:41:11.812-05:00",
"random": "d50860eb2209de5cfbfd"
},
"meta": {
"signatures": [
{
"scheme": "ecdsa-ed25519",
"signer": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"public": "0420b4b9dc4b022b5251aacee333f496f9c7fe6555824be9ecf96bc9adbcd5e7a813e7e03d63542a240ed4d58f0f079fe36c2a73e9c9a9068606f1a8f5aba9f243",
"string": "304402200fd7a0cef6e4ab4936aa2d15be933a5aab82cd556bf98fd5090e779819cb1afe02200e327d0b3ce44291c23bff4387ee9cd8cdb7308fa0453f4bac007d0c621c1a13",
}
]
}
}' "/v1/action//sendit"
```
| Field name | Descripción en español |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `` | ID de la acción principal que se usa en la URL. Esta es la acción recibida como payload en la llamada a `/action`. En el ejemplo es `35de4d3d-3aba-4fb3-b110-d004ce2aabb2`. |
| `data.source` | `mainAction.snapshot.source.signer.handle` |
| `data.target` | `mainAction.snapshot.target.signer.handle` |
| `data.symbol` | `mainAction.snapshot.symbol.signer.handle` |
| `data.amount` | `mainAction.amount` |
| `data.domain` | `mainAction.labels.domain` |
| `data.expiry` | `currentTime + 1 minuto` en formato ISO 8601. Indica el momento a partir del cual Transfiya puede expirar la operación pendiente. |
| `hash` | Un hash del objeto `data`, que puede ser generado utilizando los SDKs. El campo `hash.value` es el hash en sí; los demás campos son metadatos de hashing. |
| `meta.signatures` | Firma del hash generada con la clave privada del firmante (IOU source). Estas firmas pueden ser generadas con los SDKs. `schema`: algoritmo usado. `signer`: handle del firmante. `public`: clave pública. `string`: valor de la firma. |
```json theme={null}
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "82de7c0b8b34c7ca6c52547161b2629b1c1e6bdef402999ad60266e6760e4d24",
"iouHash": "31abac5167fbb603d9300e9dfaf94b721efdc12c0728a615f9717b944a3fa779",
"type": "SENDMOL",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "COMPLETED",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:41:00.841-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
```json theme={null}
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "SENDMOL",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "ERROR",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:41:00.841-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 127,
"message": "Action cannot be signed."
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
Para finalizar el proceso, el banco responde confirmando el `action_id` recibido, cerrando así la etapa de firma de la acción principal.
Pueden devolverse campos adicionales en la respuesta, pero solo el campo `action_id` es obligatorio.
```json theme={null}
{
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
En caso de errores no recuperables durante el procesamiento, se puede devolver un objeto `error` a Transfiya como parte de la respuesta.
Los códigos de error devueltos por los bancos deben estar en el rango `3xx`.
```json theme={null}
{
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"error": {
"code": 300,
"message": "Transfer timeout"
}
}
```
| Field name | Descripción |
| --------------- | ------------------------------------------------------------------------------- |
| `error.code` | Un código de error válido soportado por Transfiya que indica el error ocurrido. |
| `error.message` | Un mensaje con información adicional sobre el error. |
# Como aceptar la transferencia
Source: https://transfiya.me/es/v1.104/transfers-mol/guides/how-to-accept-transfers
Como aceptar la solicitud de pago
## Validación de aceptación por el banco destino
Una vez realizado el débito, Transfiya ejecuta controles antifraude sobre la transferencia y contacta al banco destino para solicitar la aceptación del pago. Este paso permite al banco receptor validar la información de la cuenta destino y confirmar que el pago puede ser recibido correctamente.
Durante esta etapa, el banco DEBE realizar las siguientes validaciones:
Que la cuenta destino exista.
Que la cuenta esté activa y habilitada para recibir pagos.
Que la moneda de la cuenta coincida con la moneda de la transferencia.
Que el monto de la transferencia no supere los límites previamente definidos.
La notificación de este paso se realiza mediante el endpoint status. Este endpoint es utilizado por Transfiya para comunicar los cambios de estado de las transferencias a las entidades participantes.
Los estados actualmente soportados por este endpoint son:
PENDING: la transferencia está pendiente de aceptación por parte del banco destino.
COMPLETED: la transferencia se ha completado exitosamente.
REJECTED: la transferencia fue rechazada debido a un error durante el procesamiento.
Las validaciones de aceptación DEBEN realizarse inmediatamente cuando la transferencia entra en estado PENDING.
```mermaid theme={null}
flowchart TD
tya[Transfiya] -->| POST /status | banco[Banco]
banco --> estado{Procesar notificación
de estado}
estado -->| COMPLETADO | completado[Finalizar
transferencia]:::deshabilitado
estado -->| PENDIENTE | pendiente[Validar
y aceptar]
estado -->| RECHAZADO | rechazado[Limpiar
transferencia]:::deshabilitado
classDef deshabilitado color:gray,stroke:gray,stroke-dasharray:5,5
```
Para aceptar una transferencia, el banco debe reaccionar a la notificación enviada por Transfiya con estado PENDING. Esta notificación indica que la transferencia está en espera de validación por parte del banco destino.
En este capítulo nos enfocaremos exclusivamente en el manejo del estado PENDING a través del endpoint status. Los demás estados (COMPLETED y REJECTED) serán abordados más adelante en el flujo de procesamiento.
## Aceptación de transferencia – Pasos detallados
```mermaid theme={null}
sequenceDiagram
autonumber
participant ty as Transfiya
participant tb as Banco Destino
ty ->> tb: Notificar estado PENDIENTE
tb -->> ty: Respuesta
tb ->> tb: Validar que
la cuenta exista
tb ->> tb: Validar que
la cuenta esté activa
tb ->> tb: Validar monto
y moneda de la transferencia
tb ->> tb: Validar que
la cuenta esté registrada
alt la cuenta no está registrada
tb ->> tb: Crear y almacenar
keeper
tb ->> +ty: Crear signer
ty -->> -tb: Respuesta del signer
end
tb ->> ty: Aceptar transferencia
```
A continuación detallamos los pasos del diagrama de secuencia con el detalle tecnico.
Una vez realizado el débito al usuario origen y ejecutados los controles antifraude, Transfiya contacta al banco destino para solicitar la aceptación de la transferencia. Esta etapa es crítica para asegurar que el pago pueda ser recibido correctamente.
Durante esta fase, el banco receptor debe validar la cuenta de destino, el monto, la moneda y el registro del usuario dentro del ecosistema Transfiya. Esta validación se notifica mediante el endpoint status, el cual indica que la transferencia se encuentra en estado PENDING.
A continuación, se detallan los pasos que debe seguir el banco para aceptar correctamente una transferencia:
Se realiza una solicitud `POST` al endpoint del banco con todos los datos relevantes de la transferencia. El campo `labels.status` estará en `PENDING`.
```json Request expandable theme={null}
POST https://ban.co/transfiya/status
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "SENDMOL",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "PENDING",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"received": "2025-01-14T20:40:57.322-05:00",
"dispatched": "2025-01-14T20:40:58.322-05:00",
"delivered": "2025-01-14T20:40:58.522-05:00",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:40:57.322-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
```json Response expandable theme={null}
{
"error": {
"code": 0,
"message": "Success"
}
}
```
Puede ser un `signer.handle` (si el usuario ya está registrado) o una referencia bancaria del tipo `tipo-cuenta:número-cuenta@dominio-banco`, por ejemplo:
`svgs:1001001000@bank.io`.
Si la cuenta está cerrada, bloqueada o suspendida, el banco debe rechazar la transferencia mediante el endpoint `/reject`, incluyendo un código como `825 - `**Target account validation error.**
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"received": "2025-01-14T20:41:00.252-05:00",
"dispatched": "2025-01-14T20:41:00.552-05:00",
"error": {
"code": 825,
"message": "Target account validation error"
}
}' "/v1/transfer//reject"
```
Los bancos pueden rechazar transferencias llamando al endpoint `reject` de la transferencia e incluyendo un objeto `error` en el cuerpo con información adicional sobre el motivo del rechazo.
Los códigos de error devueltos por los bancos deben estar dentro del rango `3xx`.
| Field name | Descripción en español |
| :----------- | :------------------------------------------------------------------------------------------------------------------------------------- |
| `` | El campo `` en la URL representa la referencia de la transferencia, que puede encontrarse en `labels.tx_ref` del `mainAction`. |
| `received` | Marca de tiempo en formato ISO 8601. Representa el momento en que se recibió la llamada `status` desde Transfiya. |
| `dispatched` | Marca de tiempo en formato ISO 8601. Representa el momento en que se envió la llamada `reject` hacia Transfiya. |
En caso de discrepancia, la operación debe rechazarse con un código de error como **833**`-`**Exceeds target bank maximum amount.**
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"received": "2025-01-14T20:41:00.252-05:00",
"dispatched": "2025-01-14T20:41:00.552-05:00",
"error": {
"code": 833,
"message": "Exceeds target bank maximum amount"
}
}' "/v1/transfer//reject"
```
Los bancos pueden rechazar transferencias llamando al endpoint `reject` de la transferencia y proporcionando un objeto `error` en el cuerpo con información adicional sobre el motivo del rechazo.
Los códigos de error devueltos por los bancos deben estar en el rango `8xx`.
| Field name | Descripción en español |
| :----------- | :-------------------------------------------------------------------------------------------------------------------------------- |
| `` | El campo `` en la URL representa la referencia de la transferencia, que se encuentra en `labels.tx_ref` del `mainAction`. |
| `received` | Timestamp en formato ISO 8601. Representa el momento en que se recibió la llamada `status` desde Transfiya. |
| `dispatched` | Timestamp en formato ISO 8601. Representa el momento en que se envió la llamada `reject` a Transfiya. |
Se valida que exista un `signer` en el sistema y que cuente con una clave pública (`keeper`) válida asociada. Esta validacion la realiza el banco internamente, no debe ir a transfiya para realizarla.
Cada cuenta debe tener una clave criptográfica única. Esta se usa para firmar operaciones bajo el modelo de Transfiya.
La seguridad de Transfiya se basa en criptografía de clave pública/privada. Esta clave se utiliza para autorizar cualquier pago asociado a la cuenta, por lo que **cada cuenta debe tener una clave única asociada**. Se recomienda utilizar los SDKs de Transfiya para generar estas claves de manera segura.
El banco destino registra una cuenta en Transfiya creando un signer vinculado a una clave pública, la cual está asociada a la clave privada generada previamente. Este signer contiene también metadatos adicionales sobre la cuenta y su titular, los cuales son necesarios para el correcto procesamiento de las transacciones dentro del sistema.
```json Request Account Signer expandable theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"aliasType": "NONE",
"type": "PERSON",
"firstName": "Jorge",
"secondName": "Alejandro",
"lastName": "Fernandez",
"secondLastName": "Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"routerReference": "$bancorojo"
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
```json Response Account Signer expandable theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"aliasType": "NONE",
"type": "PERSON",
"firstName": "Jorge",
"secondName": "Alejandro",
"lastName": "Fernandez",
"secondLastName": "Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"routerReference": "$bancorojo"
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
```json Request Alias Signer expandable theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"aliasType": "ALPHANUM",
"aliasValue": "@jorge22",
"type": "PERSON",
"firstName": "Jorge",
"secondName": "Alejandro",
"lastName": "Fernandez",
"secondLastName": "Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"routerReference": "$bancorojo",
"targetSpbviCode": "TFY"
"consented": "2025-01-14T20:42:00.152-05:00",
"received": "2025-01-14T20:41:00.252-05:00",
"dispatched": "2025-01-14T20:41:00.552-05:00"
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
```json Response Alias Signer expandable theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"aliasType": "ALPHANUM",
"aliasValue": "@jorge22",
"type": "PERSON",
"firstName": "Jorge",
"secondName": "Alejandro",
"lastName": "Fernandez",
"secondLastName": "Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"routerReference": "$bancorojo",
"targetSpbviCode": "TFY",
"consented": "2025-01-14T20:42:00.152-05:00",
"received": "2025-01-14T20:41:00.252-05:00",
"dispatched": "2025-01-14T20:41:00.552-05:00"
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
```json Error Response expandable theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"labels": {
"aliasType": "ALPHANUM",
"aliasValue": "@jorge22",
"type": "PERSON",
"firstName": "Jorge",
"secondName": "Alejandro",
"lastName": "Fernandez",
"secondLastName": "Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"routerReference": "$bancorojo",
"targetSpbviCode": "TFY"
"consented": "2025-01-14T20:42:00.152-05:00",
"received": "2025-01-14T20:41:00.252-05:00",
"dispatched": "2025-01-14T20:41:00.552-05:00"
},
"keeper": [{
"scheme": "ecdsa-ed25519",
"public": "0463e75c8b975f069813ca8e6c36c0b6fd246eac708affb7ed2c6480fa201defe8725322d6380ec66e94f6dcb49f635c0ca51296e48da4a12b3ec66582a1297adf"
}]
}' "/v1/signer"
```
El banco debe llamar al endpoint `/accept` incluyendo los campos `received`, `dispatched` y el `signer.handle` correspondiente.
Esta aceptación es obligatoria antes de que se realice la operación de crédito que ocurre posterior a la liquidación con MOL.
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"received": "2025-01-14T20:42:00.252-05:00",
"dispatched": "2025-01-14T20:42:00.552-05:00",
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
}
}' "/v1/transfer//accept"
```
# Como acreditar al beneficiario
Source: https://transfiya.me/es/v1.104/transfers-mol/guides/how-to-credit-receiver
Como acreditar al beneficiario
## Acreditar al usuario destino
Acreditar al usuario destino es el último paso en el procesamiento de la transferencia. Para realizar esta operación, Transfiya
llama al endpoint `credit` del banco destino y envía la acción principal (`main action`) en estado `COMPLETED` como payload.
El endpoint `credit` funciona de manera muy similar al endpoint `debit`, pero contempla un escenario adicional que debe ser manejado correctamente:
El crédito se utiliza tanto para acreditar al usuario destino —que es el caso más común de este endpoint— como para acreditar al usuario origen
en escenarios de error, cuando los fondos deben ser devueltos al origen.
```mermaid theme={null}
flowchart TD
tya[Transfiya] -->| POST /credit | bank[Banco]
bank --> status{Estado de la
acción principal}
status -->| COMPLETED | completed["Acreditar al destino
(caso exitoso)"]
```
La implementación de la operación es la misma; la única diferencia está en determinar si se debe acreditar al origen
o al destino
de la acción principal. Esta decisión se toma en función del estado de la acción principal:
* Si el estado de la acción principal es
COMPLETED
→ caso exitoso, se debe acreditar al destino
de la acción principal.
* Si el estado de la acción principal es
REJECTED
→ caso de reversa, se debe acreditar al origen
de la acción principal para devolver los fondos a la cuenta de origen en caso de errores durante el procesamiento.
```mermaid theme={null}
sequenceDiagram
autonumber
participant ty as Transfiya
participant tb as Banco Destino
ty ->> +tb: Llamar a crédito
tb ->> +ty: Crear acción de tipo DOWNLOAD
ty -->> -tb: Respuesta de acción
tb -->> -ty: Respuesta de crédito
tb ->> tb: Resolver cuenta de destino
tb ->> tb: Acreditar cuenta de destino
tb ->> +ty: Actualizar acción con tx_id
ty -->> -tb: Respuesta de acción
tb ->> +ty: Enviar IOU
ty ->> ty: Validar y almacenar IOU
ty -->> -tb: Respuesta de IOU
tb ->> ty: Continuar transferencia
```
## Crédito al usuario destino
Una vez que la transferencia ha sido aprobada y confirmada por el banco originador, Transfiya procede a acreditar los fondos en la cuenta del usuario receptor. Este proceso se realiza mediante una llamada al endpoint credit del banco destino, la cual activa una nueva acción de tipo DOWNLOAD en el sistema.
El flujo de acreditación contempla tanto casos exitosos como escenarios de reversa. En ambos casos, el procedimiento técnico es el mismo: el banco receptor valida la información de la cuenta, acredita los fondos y firma un objeto IOU que sirve como prueba criptográfica de la operación.
A continuación, se describe el paso a paso de este proceso:
Se invoca el endpoint `credit` con todos los datos necesarios para iniciar el abono de fondos.
```json expandable theme={null}
POST https://ban.co/transfiya/credit
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "82de7c0b8b34c7ca6c52547161b2629b1c1e6bdef402999ad60266e6760e4d24",
"type": "SENDMOL",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "COMPLETED",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:41:00.841-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
Esta acción representa la operación de crédito y se registra con estado inicial `PENDING`.
`mainAction` en los valores hace referencia a los datos de la acción principal que se recibe desde Transfiya. En otras palabras, representa el cuerpo de una llamada `POST https://ban.co/transfiya/credit`.
`bankSigner` representa el firmante de liquidación que es registrado por el banco durante su incorporación con Transfiya. Este firmante mantiene el balance total disponible para el banco dentro del sistema.
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"source": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"symbol": "$tin",
"amount": "100.00",
"labels": {
"type": "DOWNLOAD",
"domain": "tin",
"tx_ref": "Lf13jsK83omPv3bOt",
"received": "2025-01-14T20:42:17.322-05:00",
"dispatched": "2025-01-14T20:42:17.831-05:00"
}
}' "/v1/action"
```
| Field name | Descripción |
| ------------------- | ---------------------------------------------------------------------------------------------------------- |
| `source` | `mainAction.snapshot.target.signer.handle` — Usuario destino de la transferencia (cliente del banco). |
| `target` | `bankSigner.handle` — Firmante de liquidación del banco destino. |
| `symbol` | `mainAction.symbol` — Moneda de la transferencia. |
| `amount` | `mainAction.amount` — Monto de la transferencia. |
| `labels.type` | `DOWNLOAD` — Siempre debe ser `DOWNLOAD` en operaciones de crédito. |
| `labels.tx_ref` | `mainAction.labels.tx_ref` — Referencia única de la transferencia. |
| `labels.received` | Timestamp en formato ISO 8601 — Momento en que Transfiya recibió la solicitud de abono. |
| `labels.dispatched` | Timestamp en formato ISO 8601 — Momento en que se envió la solicitud de creación de la acción a Transfiya. |
Pueden añadirse campos adicionales a estas respuestas como parte de nuevas funcionalidades. Las implementaciones de los bancos DEBEN ser resilientes ante la adición de nuevos campos.
```json expandable theme={null}
{
"source": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "DOWNLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "Lf13jsK83omPv3bOt",
"received": "2025-01-14T20:42:17.322-05:00",
"dispatched": "2025-01-14T20:42:17.831-05:00"
"delivered": "2025-01-14T20:42:18.002-05:00",
"created": "2025-01-14T20:42:18.305-05:00",
"updated": "2025-01-14T20:42:18.305-05:00"
},
"snapshot": {
"source": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2023-01-21T11:16:11-05:00",
"bankName": "Banco Verde",
"bankId": "801982554",
"bankBicfi": "8924",
"createdBy": "A16iU3t38Tygr70uO1qf",
"routerReference": "$bancoverde",
"bankAccountNumber": "100101"
}
}
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278"
}
```
La respuesta de error se devuelve cuando una solicitud no es válida, cuando quien llama no tiene los permisos suficientes o cuando el sistema se encuentra en mantenimiento.
El código de estado HTTP para errores será `4xx` o `5xx`. El cuerpo de la respuesta puede incluir información adicional del error en el formato descrito anteriormente, si dicha información está disponible.
```json expandable theme={null}
{
"error": {
"code": 121,
"message": "Signer not found in database."
}
}
```
Esta respuesta cierra la parte síncrona de la operación; el resto se ejecuta de forma asíncrona.
```json expandable theme={null}
{
"source": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"target": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "DOWNLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "Ss84Vb42kGa6gPV57",
"created": "2022-08-04T07:05:26-05:00",
"updated": "2022-08-04T07:05:26-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"type": "PERSON",
"email": "Florida_Sawayn@yahoo.com",
"mobile": "573123224352",
"created": "2022-06-10T09:50:25-05:00",
"bankName": "bancosanti",
"lastName": "Sanford",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Cale",
"description": "Investor",
"proprietary": "CC",
"identification": "1231231",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "689",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00",
"channelSms": "573123224352"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
}
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb",
"error": {
"code": 0,
"message": "Success"
}
}
```
Este identificador permite rastrear y conciliar la operación dentro del sistema bancario.
```json expandable theme={null}
curl -X PUT \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"labels": {
"tx_id": "39288282838"
}
}' "/v1/action/"
```
| Field name | Descripción del valor del campo |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `` | El `` en la URL representa el ID de la acción de tipo `DOWNLOAD` creada en el paso 2. En el ejemplo, este valor es `2aa49d5d-3dcc-4841-bb3e-baeb9fef4278`. |
| `labels.tx_id` | Identificador único de la transacción que el banco ejecutó para acreditar los fondos en la cuenta de destino. |
```json expandable theme={null}
{
"source": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "DOWNLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "39288282838",
"created": "2025-01-14T20:42:18.305-05:00",
"updated": "2025-01-14T20:42:20.174-05:00"
},
"snapshot": {
"source": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2023-01-21T11:16:11-05:00",
"bankName": "Banco Verde",
"bankId": "801982554",
"bankBicfi": "8924",
"createdBy": "A16iU3t38Tygr70uO1qf",
"routerReference": "$bancoverde",
"bankAccountNumber": "100101"
}
}
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278"
}
```
El IOU incluye los datos del abono y debe ser firmado criptográficamente.
Transfiya valida la firma del objeto IOU recibido y lo almacena en el libro mayor si todo es válido. Esta operación también marca la acción `DOWNLOAD` como `COMPLETED`.
El IOU se utiliza como prueba de que una operación ha sido realizada en el core bancario. Debe coincidir exactamente con la acción que representa. Por este motivo, la mayoría de los datos del IOU se copian desde el objeto `downloadAction`.
Transfiya utiliza firmas criptográficas como prueba de que los participantes autorizaron los movimientos de saldo. Los datos se hashean primero y luego se firman utilizando claves privadas que **nunca deben compartirse** con TransfiYa. Los algoritmos de firma y hash están documentados, y los SDKs de TransfiYa permiten realizar estas operaciones de forma sencilla para facilitar la integración.
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"hash": {
"types": "sha256:sha256",
"steps": "stringify:data",
"value": "cacb220e5efe342b0a82f3e932fd3eb22d8d153de210736b80050e4fc2b488ab"
},
"data": {
"source": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"symbol": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"amount": "100.00",
"domain": "tin",
"expiry": "2025-01-14T20:43:19.122-05:00",
"random": "226bf3dd2033ff6ae837"
},
"meta": {
"signatures": [
{
"scheme": "ecdsa-ed25519",
"signer": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"public": "040644265c15370ddc3e73f86699bbe0e221bec50ff06862787408c63aa835306278acccce5b4e6765018aee748cd7682e7100b915590ee074138d4ec60a2e0fd5",
"string": "3044022002d97125f106bf60c652152d19387ec4f503e6e8710214d37993dbe9571a8098022003890339168fde030100402cda929883ca7ba815a971cf4ad7cce48c128e8ac9",
}
]
}
}' "/v1/action//sendit"
```
| Field name | Descripción del valor del campo |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `` | El `` en la URL es el ID de la acción de tipo `DOWNLOAD` creada en el paso 2. En el ejemplo es `2aa49d5d-3dcc-4841-bb3e-baeb9fef4278`. |
| `data.source` | `downloadAction.snapshot.source.signer.handle` – Firmante fuente del abono. |
| `data.target` | `downloadAction.snapshot.target.signer.handle` – Firmante destino del abono. |
| `data.symbol` | `downloadAction.snapshot.symbol.signer.handle` – Identificador del símbolo o moneda. |
| `data.amount` | `downloadAction.amount` – Monto a acreditar. |
| `data.domain` | `downloadAction.labels.domain` – Dominio asociado a la transacción. |
| `data.expiry` | `currentTime + 1 minuto` en formato ISO 8601 – Momento a partir del cual Transfiya puede expirar una operación pendiente. |
| `hash` | Hash del objeto `data`, generado por los SDKs. `hash.value` es el valor calculado, y los demás campos indican los pasos de hash. |
| `meta.signatures` | Firma del `hash` generada con la clave privada del firmante fuente. Incluye: `schema` (algoritmo), `signer`, `public` (clave pública) y `string` (firma). |
```json expandable theme={null}
{
"source": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "320224cb6dd4b8a656baea948222c1263c1dd49f7151f4304880fe3226728579",
"iouHash":"cacb220e5efe342b0a82f3e932fd3eb22d8d153de210736b80050e4fc2b488ab",
"type": "DOWNLOAD",
"domain": "tin",
"status": "COMPLETED",
"tx_ref": "Lf13jsK83omPv3bOt",
"created": "2025-01-14T20:42:18.305-05:00",
"updated": "2025-01-14T20:42:58.151-05:00"
},
"snapshot": {
"source": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2023-01-21T11:16:11-05:00",
"bankName": "Banco Verde",
"bankId": "801982554",
"bankBicfi": "8924",
"createdBy": "A16iU3t38Tygr70uO1qf",
"routerReference": "$bancoverde",
"bankAccountNumber": "100101"
}
}
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278"
}
```
```json expandable theme={null}
{
"source": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "DOWNLOAD",
"domain": "tin",
"status": "ERROR",
"tx_ref": "Lf13jsK83omPv3bOt",
"created": "2025-01-14T20:42:18.305-05:00",
"updated": "2025-01-14T20:42:58.151-05:00"
},
"snapshot": {
"source": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2023-01-21T11:16:11-05:00",
"bankName": "Banco Verde",
"bankId": "801982554",
"bankBicfi": "8924",
"createdBy": "A16iU3t38Tygr70uO1qf",
"routerReference": "$bancoverde",
"bankAccountNumber": "100101"
}
}
}
},
"error": {
"code": 127,
"message": "Action cannot be signed."
},
"action_id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278"
}
```
Esta llamada indica que el flujo puede continuar. Debe incluir los campos `received` y `dispatched` requeridos por regulación.
Para continuar con el procesamiento de la transferencia, basta con llamar al endpoint `continue` y proporcionar las marcas de tiempo requeridas por la regulación.
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d
'{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "cacb220e5efe342b0a82f3e932fd3eb22d8d153de210736b80050e4fc2b488ab",
"type": "DOWNLOAD",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "COMPLETED",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:40:57.322-05:00",
"received": "2025-01-14T20:40:57.322-05:00",
"dispatched": "2025-01-14T20:40:58.322-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}'
"/v1/transfer//continue"
```
| Field name | Valor del campo |
| ------------ | --------------------------------------------------------------------------------------------------------------------------- |
| `` | El campo `` en la URL representa la referencia de la transferencia, ubicada en `labels.tx_ref` del `mainAction`. |
| `received` | Timestamp en formato ISO 8601. Representa el momento en que se recibió la última respuesta de Transfiya (llamada `sendit`). |
| `dispatched` | Timestamp en formato ISO 8601. Representa el momento en que se envió la llamada `continue` a Transfiya. |
Los bancos pueden reportar errores en la parte asincrónica del procesamiento de una transferencia llamando al endpoint `continue` e incluyendo un objeto `error` en el cuerpo de la solicitud con información adicional sobre el error.
Los códigos de error devueltos por los bancos deben estar en el rango `3xx`.
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"received": "2025-01-14T20:42:58.252-05:00",
"dispatched": "2025-01-14T20:42:58.552-05:00",
"error": {
"code": 300,
"message": "Transfer timeout"
}
}' "/v1/transfer//continue"
```
| Field name | Descripción |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `` | El campo `` en la URL representa la referencia de la transferencia. Se encuentra en `labels.tx_ref` del `mainAction`. |
| `received` | Marca de tiempo en formato ISO 8601. Representa el momento en que se recibió la respuesta de la última llamada de Transfiya (`sendit`). |
| `dispatched` | Marca de tiempo en formato ISO 8601. Representa el momento en que se envió la llamada `continue` a Transfiya. |
| `error.code` | Código de error válido, soportado por Transfiya, correspondiente a un error ocurrido. |
| `error.message` | Mensaje con información adicional sobre el error ocurrido. |
# Como debitar al beneficiario
Source: https://transfiya.me/es/v1.104/transfers-mol/guides/how-to-debit-sender
Como debitar al usuario origen (beneficiario)
## Débito al usuario origen
El endpoint de débito se invoca al inicio del procesamiento de una transferencia, con el objetivo de debitar la cuenta del usuario origen. Este endpoint debe garantizar que la cuenta esté activa y sea válida, y debe **reservar los fondos necesarios** para que la operación pueda ejecutarse.
Los bancos pueden optar por registrar la transacción de forma definitiva o simplemente realizar una reserva de fondos.
En cualquiera de los casos, esta operación debe ser **finalizada una vez que la transferencia se haya completado**, o bien los fondos deben ser **liberados obligatoriamente** en caso de que ocurra un error durante el proceso.
En Transfiya, una operación de débito se representa como una acción de tipo `UPLOAD`. Si esta acción se marca como `COMPLETED` exitosamente, pero más adelante ocurre un error en el procesamiento, Transfiya ejecutará una operación opuesta (de tipo `credit`) para **revertir el movimiento de saldo** y restablecer el estado original de la cuenta.
**Flujo de debito al usuario origen**
## Proceso de débito paso a paso
A continuación, se describe detalladamente el flujo de procesamiento para una transferencia tipo `SEND`, enfocándonos en la etapa de **débito al usuario origen**. Este flujo se ejecuta en múltiples etapas, combinando interacciones entre Transfiya y el banco originador, tanto en fases síncronas como asincrónicas.
El objetivo principal de este proceso es asegurar que los fondos del usuario origen estén disponibles y sean reservados o debitados correctamente antes de avanzar con el resto de la operación. El flujo también contempla los mecanismos necesarios para revertir movimientos en caso de errores, así como el uso de pruebas criptográficas (IOU) y el cumplimiento de los tiempos regulatorios.
Cada paso está alineado con los lineamientos del nuevo modelo SPI (Sistema de Pagos Inmediatos) y busca mantener la compatibilidad con la arquitectura existente de Transfiya. A continuación se detallan las acciones involucradas, junto con ejemplos prácticos y consideraciones técnicas relevantes.
```mermaid theme={null}
sequenceDiagram
autonumber
participant sb as Banco Origen
participant ty as Transfiya
ty ->> +sb: Llamar a débito
sb ->> +ty: Crear acción de subida (UPLOAD)
ty -->> -sb: Respuesta de acción
sb -->> -ty: Respuesta de débito
sb ->> sb: Debitar cuenta del usuario origen
sb ->> +ty: Actualizar acción con tx_id
ty -->> -sb: Respuesta de acción
sb ->> +ty: Enviar pagaré (IOU)
ty ->> ty: Validar y almacenar IOU
ty -->> -sb: Respuesta de IOU
sb ->> ty: Continuar transferencia
```
Transfiya inicia el proceso mediante una solicitud **POST** al endpoint de débito del banco origen, con la información completa de la transferencia.
```json expandable theme={null}
POST https://ban.co/transfiya/debit
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "SENDMOL",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "PENDING",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:40:57.322-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
Esto representa la reserva o débito de fondos. Se debe generar una acción usando el API de Transfiya, referenciando la transferencia original.
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"source": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"target": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"symbol": "$tin",
"amount": "100.00",
"labels": {
"type": "UPLOAD",
"domain": "tin",
"tx_ref": "Lf13jsK83omPv3bOt"
}
}' "URL/v1/action"
```
| Atributo | Valor |
| --------------- | -------------------------------------------------------------------------------- |
| `source` | `bankSigner.handle` — Bank settlement signer. |
| `target` | `mainAction.snapshot.source.signer.handle` — Source of the transfer (bank user). |
| `symbol` | `mainAction.symbol` — Currency of the transfer. |
| `labels.type` | `UPLOAD` — Always `UPLOAD` for debits. |
| `labels.tx_ref` | `mainAction.labels.tx_ref` — Transfer reference. |
`mainAction` en los valores se utiliza al hacer referencia a los datos de la acción principal recibida desde TransfiYa. En otras palabras, representa el cuerpo de una llamada **POST** a `https://ban.co/transfiya/debit`.
`bankSigner` representa el firmante de liquidación que es registrado por el banco durante el proceso de incorporación con TransfiYa. Este firmante mantiene el balance total disponible para el banco dentro del sistema.
```json theme={null}
{
"source": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"target": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "UPLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "Lf13jsK83omPv3bOt",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:40:57.322-05:00"
},
"snapshot": {
"source": {
"signer": {
"handle": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "Banco Rojo",
"bankId": "895554821",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"routerReference": "$bancorojo",
"bankAccountNumber": "160101"
}
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
}
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb"
}
```
```json theme={null}
{
"error": {
"code": 121,
"message": "Signer not found in database."
}
}
```
Esta respuesta marca el cierre de la fase síncrona. El campo obligatorio es `action_id`.
```json expandable theme={null}
{
"source": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"target": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "UPLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "Ss84Vb42kGa6gPV57",
"created": "2022-08-04T07:05:26-05:00",
"updated": "2022-08-04T07:05:26-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"type": "PERSON",
"email": "Florida_Sawayn@yahoo.com",
"mobile": "573123224352",
"created": "2022-06-10T09:50:25-05:00",
"bankName": "bancosanti",
"lastName": "Sanford",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Cale",
"description": "Investor",
"proprietary": "CC",
"identification": "1231231",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "689",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00",
"channelSms": "573123224352"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
}
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb",
"error": {
"code": 0,
"message": "Success"
}
}
```
Se pueden incluir campos adicionales en la respuesta, pero solo `action_id` es obligatorio.
```json theme={null}
{
"source": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"target": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "UPLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "Ss84Vb42kGa6gPV57",
"created": "2022-08-04T07:05:26-05:00",
"updated": "2022-08-04T07:05:26-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"type": "PERSON",
"email": "Florida_Sawayn@yahoo.com",
"mobile": "573123224352",
"created": "2022-06-10T09:50:25-05:00",
"bankName": "bancosanti",
"lastName": "Sanford",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Cale",
"description": "Investor",
"proprietary": "CC",
"identification": "1231231",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "689",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00",
"channelSms": "573123224352"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
}
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb",
"error": {
"code": 0,
"message": "Success"
}
"error": {
"code": 300,
"message": "Transfer timeout"
}
}
```
En caso de errores no recuperables durante el procesamiento, se puede devolver un objeto `error` a Transfiya.
El campo `action_id` es opcional en caso de errores, pero debe incluirse si el error ocurrió después de que la acción fue creada exitosamente.
Los códigos de error devueltos por los bancos deben estar en el rango de `3xx`.
Se realizan validaciones sobre la cuenta y se ejecuta la operación interna de débito.
El identificador `tx_id` permite posteriores conciliaciones entre Transfiya y el banco.
```json expandable theme={null}
curl -X PUT \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"labels": {
"tx_id": "K3.392894.29480"
}
}' "/v1/action/"
```
| Field name | Field value |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `` | The `` used in the URL is the ID of the `UPLOAD` action created in step 2. In our example, it is `5954ac04-b4db-4c6f-86f6-43df30f6bacb`. |
| `labels.tx_id` | Unique identifier of the transaction executed by the bank to debit the funds from the source account. |
La acción incluirá el nuevo campo `tx_id` como parte de los metadatos.
```json theme={null}
{
"source": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"target": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "UPLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "K3.392894.29480",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:40:58.581-05:00"
},
"snapshot": {
"source": {
"signer": {
"handle": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "Banco Rojo",
"bankId": "895554821",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"routerReference": "$bancorojo",
"bankAccountNumber": "160101"
}
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
}
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb"
}
```
Este IOU contiene la información de la transacción y su firma digital, generada con claves privadas del firmante.
Transfiya valida la firma del objeto IOU recibido y lo almacena en el libro mayor, si todo es válido. Esta operación también marca la acción `UPLOAD` como `COMPLETED`.
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"hash": {
"types": "sha256:sha256",
"steps": "stringify:data",
"value": "263b8cebe62473ad9bb6ca6a92db7e5c8b16492b359515375ae8bf05094c3a14"
},
"data": {
"source": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"target": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"symbol": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"amount": "100.00",
"domain": "tin",
"expiry": "2025-01-14T20:41:59.122-05:00",
"random": "7f19c57edb362726da0c"
},
"meta": {
"signatures": [
{
"scheme": "ecdsa-ed25519",
"signer": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"public": "046a23ccc4585f6105a199ec5202d4019d589a3370b52a783268016751e2db9281371fe2cc28901e24ece5d47b29ed0b7d741d17dd8221b9735bf922dc40a621b1",
"string": "3043021f17472d781f6873203671439fc1277b085971f38928da9165ab4f386117966302200c518cfef98841aa353eb0832a87eca44929df7d2d475c70203effca27ca6241",
}
]
}
}' "/v1/action//sendit"
```
Transfiya devuelve una acción con estado `COMPLETED` al banco o una acción con estado `ERROR` en caso de errores.
```json theme={null}
{
"source": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"target": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "3ca7af8dcccaed3f7f1821456eaece8746310b566687401ae11c0b22624874a9",
"iouHash": "263b8cebe62473ad9bb6ca6a92db7e5c8b16492b359515375ae8bf05094c3a14",
"type": "UPLOAD",
"domain": "tin",
"status": "COMPLETED",
"tx_ref": "Lf13jsK83omPv3bOt",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:41:00.152-05:00"
},
"snapshot": {
"source": {
"signer": {
"handle": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "Banco Rojo",
"bankId": "895554821",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"routerReference": "$bancorojo",
"bankAccountNumber": "160101"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb"
}
```
Transfiya devuelve una acción con estado `COMPLETED` al banco o una acción con estado `ERROR` en caso de errores.
```json theme={null}
{
"source": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"target": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "UPLOAD",
"domain": "tin",
"status": "ERROR",
"tx_ref": "Lf13jsK83omPv3bOt",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:41:00.152-05:00"
},
"snapshot": {
"source": {
"signer": {
"handle": "wSjXPK5uocHQdY81THFG3VL8G5vN6mU7Ro",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "Banco Rojo",
"bankId": "895554821",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"routerReference": "$bancorojo",
"bankAccountNumber": "160101"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 127,
"message": "Action cannot be signed."
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb"
}
```
Esta llamada debe incluir los campos `received` y `dispatched`. Se puede incluir un objeto `error` si aplica.
Para continuar con el procesamiento de la transferencia, es suficiente con llamar al endpoint `continue` y proporcionar las marcas de tiempo requeridas por la regulación.
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d
'{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "263b8cebe62473ad9bb6ca6a92db7e5c8b16492b359515375ae8bf05094c3a14",
"type": "UPLOAD",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "COMPLETED",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"received": "2025-01-14T20:40:57.322-05:00",
"dispatched": "2025-01-14T20:40:58.322-05:00",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:40:57.322-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}'
"/v1/transfer//continue"
```
| Field name | Descripción |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| `` | El campo `` en la URL representa la referencia de la transferencia, que se encuentra en `labels.tx_ref` del `mainAction`. |
| `received` | Marca de tiempo en formato ISO 8601. Representa el momento en que se recibió la última respuesta de Transfiya (llamada `sendit`). |
| `dispatched` | Marca de tiempo en formato ISO 8601. Representa el momento en que se envió la llamada `continue` a Transfiya. |
Los bancos pueden reportar errores en la parte asincrónica del procesamiento de la transferencia llamando al endpoint `continue` y proporcionando el objeto `error` en el cuerpo de la solicitud, con información adicional sobre el problema.
Los códigos de error devueltos por los bancos deben estar en el rango `3xx`.
```json theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"received": "2025-01-14T20:41:00.252-05:00",
"dispatched": "2025-01-14T20:41:00.552-05:00",
"error": {
"code": 300,
"message": "Transfer timeout"
}
}' "/v1/transfer//continue"
```
| Field name | Descripción en español |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `` | El campo `` en la URL representa la referencia de la transferencia, que se encuentra en `labels.tx_ref` del `mainAction`. |
| `received` | Timestamp en formato ISO 8601. Representa la hora en que se recibió la respuesta de la última llamada de Transfiya (`sendit`). |
| `dispatched` | Timestamp en formato ISO 8601. Representa la hora en que se envió la llamada `continue` a Transfiya. |
| `error.code` | Un código de error válido soportado por Transfiya que describe el error ocurrido. |
| `error.message` | Un mensaje con información adicional sobre el error. |
# Como notificar la transferencia
Source: https://transfiya.me/es/v1.104/transfers-mol/guides/how-to-notify
Como notificar la transferencia
## Notificación final de estado
La última llamada del procesamiento de una transferencia es una notificación al endpoint `status`, el cual ya fue cubierto anteriormente. En este paso final, TransfiYa llama al endpoint `status` con una transferencia en uno de los siguientes estados:
* `COMPLETED`: si el procesamiento fue exitoso.
* `REJECTED`: si ocurrió un error, pero la transferencia fue correctamente revertida y todos los movimientos de saldo fueron deshechos.
Esta notificación es enviada tanto al banco **origen** como al banco **destino**.
**Acciones esperadas por parte del banco:**
* Notificar al usuario final que la transferencia ha sido **finalizada**, ya sea con éxito o con rechazo.
* Ejecutar cualquier **limpieza final** o actualización interna relacionada con la transferencia.
```mermaid theme={null}
flowchart TD
tya[Transfiya] -->| POST /status | bank[Banco]
bank --> status{Procesar
notificación de estado}
status -->| COMPLETADO | completed[Finalizar
transferencia]
status -->| PENDIENTE | pending[Validar
y aceptar]:::disabled
status -->| RECHAZADO | rejected[Limpiar
transferencia]
classDef disabled color:gray,stroke:gray,stroke-dasharray:5,5
```
La implementación recomendada en este caso es notificar al usuario únicamente sobre el estado final de la operación, **si esta fue realizada con retraso**.
```mermaid theme={null}
sequenceDiagram
autonumber
participant ty as Transfiya
participant tb as Banco
ty ->> tb: Llamada al endpoint /status
tb -->> ty: Respuesta
tb ->> tb: Notificar al usuario,
si es necesario
tb ->> tb: Realizar operaciones de limpieza,
si es necesario
```
### Notificación final del estado de la transferencia
Una vez que el procesamiento de la transferencia ha concluido, **Transfiya notifica tanto al banco origen como al banco destino** mediante una llamada al endpoint `status`. Esta llamada incluye toda la información relevante de la transferencia y su estado final, el cual puede ser:
* `COMPLETED`: si la operación fue exitosa.
* `REJECTED`: si la operación fue revertida correctamente tras un fallo en el proceso.
A partir de esta notificación, el banco debe confirmar su recepción, y de forma opcional, realizar tareas como la notificación al usuario o limpieza de recursos internos.
Transfiya realiza una solicitud `POST` al endpoint `status` del banco origen y del banco destino con una transferencia marcada como `COMPLETED` o `REJECTED`, según sea el caso.
```json expandable theme={null}
POST https://ban.co/transfiya/status
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "82de7c0b8b34c7ca6c52547161b2629b1c1e6bdef402999ad60266e6760e4d24",
"iouHash": "31abac5167fbb603d9300e9dfaf94b721efdc12c0728a615f9717b944a3fa779",
"type": "SENDMOL",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "COMPLETED",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:43:00.483-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
```json expandable theme={null}
POST https://ban.co/transfiya/status
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "82de7c0b8b34c7ca6c52547161b2629b1c1e6bdef402999ad60266e6760e4d24",
"iouHash": "31abac5167fbb603d9300e9dfaf94b721efdc12c0728a615f9717b944a3fa779",
"type": "SENDMOL",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "REJECTED",
"tx_ref": "Lf13jsK83omPv3bOt",
"tx_id": "20250114890915944TFY123456789012345",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:43:00.483-05:00",
"description": "Payment for lunch",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Maria Fernanda Gomez",
"proprietary": "CC",
"identification": "2020202020",
"bankAccountType": "SVGS",
"bankAccountNumber": "95445654254",
"bankId": "895554821",
"targetSpbviCode": "TFY"
}
},
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
}
},
"target": {
"signer": {
"handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
"proprietary": "CC",
"identification": "1010101010",
"bankAccountType": "SVGS",
"bankAccountNumber": "12345654321",
"bankId": "891234918",
"targetSpbviCode": "TFY"
}
},
}
},
"error": {
"code": 300,
"message": "Transfer timeout."
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
```json expandable theme={null}
{
"error": {
"code": 0,
"message": "Success"
}
}
```
El banco debe responder con un HTTP `200 OK`. También puede incluir un objeto `error` con código `0` como confirmación explícita de éxito. A partir de este punto, el procesamiento es completamente asincrónico.
Si la transferencia fue completada con retraso, se recomienda notificar al usuario con un mensaje final. Si el usuario ya visualizó el resultado en pantalla, no es necesario enviar otra notificación.
El banco puede llevar a cabo operaciones de cierre, auditoría, registros contables o cualquier otro proceso que dependa del estado final de la transferencia.
# Como enviar a Bre-B
Source: https://transfiya.me/es/v1.104/transfers-mol/guides/how-to-send-mol
Como iniciar un flujo regulatorio en Transfiya
## Envio con liquidacion en MOL
### Resumen de cambios para entidad
Para cumplir con el flujo regulatorio, se usaría la misma integración del participante utilizando el concepto de Transfer para iniciar transferencias.
Las interfaces de interacción no cambian para la entidad, ya que la plataforma cumple actualmente con la mayoría de los requisitos regulatorios.
La liquidación con MOL y el manejo de tiempos ya están gestionados por la plataforma y no requieren cambios por parte de los participantes.
Los participantes únicamente deben asegurar para envio de transferencias:
* **Utilizar API de transferencias**: Mantener la misma integración para iniciar transferencias
* **Especificar tipo de transferencia**: Durante la marcha blanca, identificar las transferencias que se comunican con MOL usando "label.type":"SENDMOL"
* **Incluir marcas de tiempo**: Agregar marca de tiempo externa a la plataforma: "dispateched" para notificar tiempo de inicio de transferncia
### Origen y destino de transferencia
Las transferencias reguladas se definen como transferencias de cuenta a cuenta. Estas transacciones no deberían diferenciarse de las transferencias actuales entre cuentas en Transfiya.
La resolución de llaves debe realizarse antes de crear una transferencia.
El modelo actual de Transfiya facilita las transferencias de cuenta a cuenta mediante el uso de credenciales de pago (signer handles) como origen y destino de una transferencia.
En caso de modelo regulado origen y destino de transferencia son conocidos por proceso previo de [resolucion de llaves](how-to-keys) y se realiza una cuenta a cuenta.
Mas sobre [signers](../es/about/about-signers).
### Concepto Transfer
Transfiya utiliza el concepto de "transfer" para iniciar pagos en el sistema agnosticos a caso a uso o tipo de transferencia.
El uso del modelo de transfer para iniciar pagos en el sistema permite emplear el mismo protocolo y REST API para cualquier caso de uso o flujo de dinero, incluyendo el nuevo flujo regulatorio.
### Identificador de flujo
Cuando se inicia un transfer se activa uno de los flujos de pago orchestrados por la plataforma.
Flujo que se va usar en la marcha blanca y despues de 1 de Semptiembre para flujo regulatorio es **SENDMOL**.
Tipo de transferencia.
Cambio principal de este flujo comparado con envio no regulado es en modelo de [liquidacion](../about/about-settelement) de fondos con MOL y [confirmacion de la cuenta](../about/about-accept).
Mas sobre flujos pueden conocer [aqui](../es/about/about-flows).
### Ejemplo de un transfer regulatorio
Para realizar un transfer con modelo regulatorio es necesario definir que el modelo de flujo y asegurar envio de marca de timepo de inicio.
Los cambios en el modelo son mostrados en el ejemplo de diferencias en codigo.
```json expandable theme={null}
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-d '{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"target": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
"symbol": "$tin",
"amount": "100",
"labels": {
"description": "Payment for lunch",
"domain": "tin",
"type": "SENDMOL",
"sourceChannel": "APP",
"tx_id": "20250114890915944TFY123456789012345",
"received": "2025-01-14T20:40:57.322-05:00",
"dispatched": "2025-01-14T20:40:58.322-05:00",
"deviceFingerPrint": {
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"country": "Colombia",
"city": "Bogotá",
"mobileDevice": "990000862471854",
"SIMCardId": "8991101200003204510",
"model": "Huawei Mate 20 Pro",
"operator": "Bharti Airtel Limited"
}
}
}' "/v1/transfer"
```
```json expandable theme={null}
{
"source": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
- "target": "$573002414263",
+ "target": "wfvmRir8XxRtoEuUBDkv3BP4T7BQezwm1f",
"amount": "100.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "SENDMOL",
"domain": "tin",
"flowId": "Lf13jsK83omPv3bOt",
"status": "PENDING",
"tx_ref": "Lf13jsK83omPv3bOt",
+ "tx_id": "20250114890915944TFY123456789012345", // nuevo campo
+ "received": "2025-01-14T20:40:57.322-05:00",
+ "dispatched": "2025-01-14T20:40:57.322-05:00",
"created": "2025-01-14T20:40:57.322-05:00",
"updated": "2025-01-14T20:40:57.322-05:00",
"description": "DEV - SEND trx 01",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
+ "proprietary": "CC",
+ "identification": "1010101010",
+ "bankAccountType": "SVGS",
+ "bankAccountNumber": "12345654321",
+ "bankId": "891234918",
+ "targetSpbviCode": "TFY",
- "created": "2022-04-12T16:17:49.322-05:00",
- "createdBy": "tcYV0MRoklTXUwSFFkkQ",
- "description": "new descr",
- "routerReference": "$bancorojo"
}
},
- "wallet": {
- "handle": "$575555544444",
- "labels": {
- "name": "Test user 9",
- "type": "PERSON",
- "created": "2022-04-12T16:17:33.322-05:00",
- "updated": "2022-04-14T09:30:33.322-05:00",
- "createdBy": "$bancorojo"
- },
- "signer": [
- "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2",
- "weqYJCU6MN193yJ63XehjT3VWFAAguAHHV"
- ],
- "default": "wXxwpxB32saqfmfMxAQD4SVWWhhn6akLC2"
- }
- },
- "symbol": {
- "signer": {
- "handle": "wfvmRir8XxRtoEuUBDkv3BP4T7BQezwm1f",
- "labels": {
- "type": "SYMBOL",
- "created": "2022-03-17T22:08:07.322-05:00",
- "createdBy": "$minka"
- }
- },
- "wallet": {
- "handle": "$tin",
- "labels": {
- "name": "tin",
- "type": "SYMBOL",
- "created": "2022-03-17T22:08:09.234-05:00",
- "updated": "2022-04-13T12:36:46.234-05:00",
- "createdBy": "$minka"
- },
- "signer": [
- "wfvmRir8XxRtoEuUBDkv3BP4T7BQezwm1f"
- ],
- "default": "wfvmRir8XxRtoEuUBDkv3BP4T7BQezwm1f"
- }
},
"target": {
"signer": {
+ "handle": "wfvmRir8XxRtoEuUBDkv3BP4T7BQezwm1f",
"labels": {
"name": "Jorge Alejandro Fernandez Garcia",
+ "proprietary": "CC",
+ "identification": "1010101010",
+ "bankAccountType": "SVGS",
+ "bankAccountNumber": "12345654321",
+ "bankId": "891234918",
+ "targetSpbviCode": "TFY",
- "created": "2022-04-12T16:17:49-05:00",
- "createdBy": "tcYV0MRoklTXUwSFFkkQ",
- "description": "new descr",
- "routerReference": "$bancorojo"
}
},
- "wallet": {
- "handle": "$573002414263",
- "labels": {
- "type": "PERSON",
- "created": "2022-03-23T11:00:55.332-05:00",
- "updated": "2022-03-23T11:00:55.334-05:00"
- }
- }
}
},
"error": {
"code": 0,
"message": "Success"
},
"action_id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2",
"id": "35de4d3d-3aba-4fb3-b110-d004ce2aabb2"
}
```
```json expandable theme={null}
{
"error": {
"code": 118,
"message": "Parameter labels.tx_id contains unsupported characters"
}
}
```
**tx\_id:** identificación única asignada por el SPBVI Originador para identificar inequívocamente la transacción en el ecosistema. Esta identificación se transmite sin cambios, a lo largo del flujo de pago después de que el SPBVI Originador asigna la identificación:
"**YYYYMMDD#########TFY000000000000005**"
* **YYYYMMDD:** fecha (8 caracteres), en horario local y que corresponde a la fecha del momento en que el SPBVI originador recibe la confirmación de la orden de pago y/o transferencia de fondo inmediata por parte del Participante Originador.
* **NIT:** (9 caracteres - **#########**) NIT del Participante Originador (sin dígito de verificación) o código asignado por el BR.
* **Sigla del SPBVI Originador TFY:** Corresponde a la abreviación del Sistema de Pago de Bajo ValorInmediato Originador.
* **Secuencia (15 dígitos):** Número ascendente que debe ser único para cada fecha en formato “**YYYYMMDD**”. Si el valor tiene menos de 15 dígitos, se debe completar con ceros a la izquierda como en el ejemplo.
**Para iniciar órdenes de pago en Bre-B, no es obligatorio que el signer de origen incluya todas las etiquetas regulatorias.**\
Sin embargo, es fundamental garantizar un conjunto mínimo de campos para asegurar el correcto envío del dinero:
* firstName
* lastName
* bankAccountNumber
* bankAccountType
* proprietary
* identification
* bankId
* targetSpbviCode
* type
* routerReference
Es importante tener en cuenta que se puede continuar utilizando la estructura anterior, siempre que se aseguren estos campos mínimos. Alternativamente, se puede emplear la estructura basada en llaves que ya los incluye. En este último caso, la entidad deberá considerar los sus controles y excepciones aplicables según el estado del signer.
## Aceptación en el flujo regulado
En el modelo regulado, la aceptación de una transferencia no depende de una acción explícita por parte del usuario final, como podría suceder en flujos tradicionales. Sin embargo, sí requiere de una validación formal por parte de la entidad financiera que actúa como banco receptor.
Este paso de aceptación es obligatorio antes de continuar con el procesamiento y consiste en que la entidad receptora verifique que la cuenta destino:
* Existe y está activa.
* Está habilitada para recibir pagos.
* Cumple con los requisitos establecidos por la regulación, como los límites de monto o tipo de moneda.
Una vez realizada esta validación, el banco destinatario confirma la aceptación utilizando el mecanismo estándar ya existente en TransfiYa para flujos asincrónicos. Esta aceptación por parte de la entidad equivale a una aprobación regulatoria que habilita a continuar con la operación de crédito y la posterior liquidación a través del MOL.
Este modelo permite cumplir con la normativa vigente sin necesidad de cambiar los componentes fundamentales de la arquitectura de TransfiYa, facilitando así la adaptación de los bancos al nuevo flujo SPI.
## Modelo de liquidación
Una vez que MOL entre en funcionamiento, cada transferencia deberá enviarse a MOL para su procesamiento y se pausará el procesamiento interno hasta recibir una llamada de continuación desde MOL.
Transfiya ya cuenta con un sistema de procesamiento asíncrono que continúa mediante llamadas API. El procesamiento de transferencias está implementado como un flujo de múltiples pasos, por lo que para soportar este cambio solo necesitamos extender el sistema internamente añadiendo nuevos pasos asíncronos al proceso, lo cual resulta sencillo gracias a la arquitectura actual.
Mas sobre liquidación pueden ver [aca](../about/about-settelement)
Cambios de flujo que incluyen llamadas a MOL e orchestraacion con otros sistemas de pago se manejan por parte de plataforma usando [orchestracion de flujos](../about/about-flows).
# Cómo Enviar Marcas de Tiempo
Source: https://transfiya.me/es/v1.104/transfers-mol/guides/how-to-send-timestamps
Cómo enviar Marcas de Tiempo al DICE
Aunque la regulación exige únicamente al banco originador reportar las marcas de tiempo finales, solicitamos que tanto el banco origen como el banco destino las reporten para mantener consistencia en el proceso.
Para reportar estas marcas de tiempo finales del procesamiento de una transferencia, se ha agregado un nuevo endpoint:
**POST /v1/transfer/:txRef/timestamps**
Las marcas de tiempo a enviar mantienen los mismos nombres utilizados en los casos anteriores:
* `received` → momento en que el participante recibió la notificación de estado final por parte de Transfiya.
* `dispatched` → momento en que el participante notificó al usuario sobre el resultado de la transferencia.
```mermaid theme={null}
sequenceDiagram
autonumber
participant su as Usuario Origen
participant sb as Banco Origen
participant ty as Transfiya
participant tb as Banco Destino
participant monitor as Monitor+
participant mb as Puente MOL
participant mol as MOL
su ->> +sb: Crear transferencia
sb ->> +ty: Crear transferencia
ty ->> ty: Validar reglas de negocio
ty -->> -sb: Transferencia creada
sb -->> -su: Transferencia creada
alt débito
ty ->> +sb: Llamar a débito
sb ->> +ty: Crear acción UPLOAD
ty -->> -sb: Respuesta de acción
sb -->> -ty: Respuesta de débito
sb ->> sb: Debitar cuenta origen
sb ->> +ty: Actualizar acción con tx_id
ty -->> -sb: Acción actualizada
sb ->> +ty: Enviar IOU
ty -->> -sb: Respuesta de IOU
sb ->> ty: Continuar transferencia
end
ty ->> +monitor: Iniciar Monitor+
monitor -->> -ty: Respuesta de Monitor+
ty ->> +mb: Reservar fondos
activate mb
mb ->> mol: Reservar fondos (pacs.008)
activate mol
mol ->> mb: Acreditar destino (pacs.008)
activate mb
mb ->> ty: Continuar transferencia
(crédito MOL)
alt aceptación
ty ->> tb: Notificar estado PENDIENTE
tb -->> ty: Respuesta
tb ->> tb: Validar datos destino
tb ->> ty: Aceptar transferencia
end
ty ->> mb: Confirmar crédito
mb -->> mol: Confirmar crédito (pacs.002)
deactivate mb
mol -->> mb: Confirmación (pacs.002)
deactivate mol
mb ->> ty: Continuar transferencia
(reserva MOL)
deactivate mb
ty ->> ty: Esperar confirmación de liquidación
mol ->> +mb: Confirmación de liquidación (pacs.002)
mb ->> -ty: Continuar transferencia
(MOL liquidado)
alt acción
ty ->> +sb: Llamar a acción
sb ->> +ty: Enviar IOU
ty -->> -sb: Respuesta de IOU
sb -->> -ty: Respuesta de acción
end
alt crédito
ty ->> +tb: Llamar a crédito
tb ->> +ty: Crear acción DOWNLOAD
ty -->> -tb: Respuesta de acción
tb -->> -ty: Respuesta de crédito
tb ->> tb: Acreditar usuario destino
tb ->> +ty: Actualizar acción con tx_id
ty -->> -tb: Acción actualizada
tb ->> +ty: Enviar IOU
ty -->> -tb: Respuesta de IOU
tb ->> ty: Continuar transferencia
end
alt estado completado
ty ->> +sb: Llamar a estado (COMPLETADO)
sb -->> -ty: Respuesta de estado
sb ->> sb: Notificar a usuario origen
sb ->> +ty: Reportar timestamps finales
ty -->> -sb: Respuesta de timestamps
ty ->> +tb: Llamar a estado (COMPLETADO)
tb -->> -ty: Respuesta de estado
tb ->> tb: Notificar a usuario destino
tb ->> +ty: Reportar timestamps finales
ty -->> -tb: Respuesta de timestamps
end
ty ->> +monitor: Finalizar Monitor+
monitor -->> -ty: Respuesta de Monitor+
```
Los timestamps finales
son reportados por los bancos origen y destino en los pasos 50
y 55
.
### Ejemplo de API
**POST /v1/transfer/:txRef/timestamps**
```json expandable theme={null}
curl -X POST \
-H "x-api-key: " \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"received": "2024-10-11T11:59:22.241-05:00",
"dispatched": "2024-10-11T11:59:22.517-05:00"
}' "/v1/transfer/Lf13jsK83omPv3bOt/timestamps"
```
```json expandable theme={null}
{
"error": {
"code": 0,
"message": "Success"
}
}
```
## Codigos de Error
| Código de error | Descripción | HTTP Status |
| --------------- | ------------------------------------------------------------- | ----------- |
| 99 | Unexpected server error | 400 |
| 100 | You don't have permissions to access this method | 403 |
| 101 | Unauthorized request, invalid or expired token | 401 |
| 118 | Resource schema validation error, field format is not correct | 400 |
| 121 | Signer not found in database | 400 |
| 123 | Domain rules error, timestamps are not in the expected range | 400 |
# Flujos regulados
Source: https://transfiya.me/es/v1.104/transfers-mol/intro/intro-mol
Resumen sobre transferencias reguladas Transfiya
## Contexto
**La regulación de pagos en tiempo real en Colombia entrará en vigor en 2025.**
Esta normativa tiene como objetivo que los SPBVI (sistemas de pago de bajo valor inmediato) sean interoperables, mediante la implementación de los siguientes componentes:
1. **DICE: Un directorio centralizado de llaves**
2. **MOL: Mecanismo Operativo de liquidación**
Actualmente, **Transfiya es el sistema de pagos P2P en tiempo real más grande del país**, y ya incorpora muchas de las funcionalidades requeridas por esta nueva regulación.
Este documento resume los cambios necesarios en el procesamiento de transferencias para que **Transfiya** cumpla con los lineamientos regulatorios.
## ¿Porque lo hacemos?
El objetivo es claro: adaptar el procesamiento de transferencias para que sea compatible con los flujos definidos por la regulación, sin perder compatibilidad con los bancos que ya operan con Transfiya. Esta es una condición fundamental para asegurar una transición fluida y sin fricciones para nuestros participantes actuales.
Nuestro enfoque se basa en mantener compatibilidad con los bancos actualmente integrados a Transfiya, evitando la necesidad de migraciones complejas y costosas. Esto nos permite preservar nuestra base de usuarios y consolidar nuestra posición de liderazgo en el mercado.
## Conclusión
Transfiya cuenta con una arquitectura moderna y flexible, que le permite adaptarse rápidamente a los cambios regulatorios sin necesidad de rediseños profundos. Apostamos por una estrategia de integración progresiva que proteja nuestra base de usuarios actual y refuerce nuestra posición como el sistema de pagos en tiempo real más robusto del país.
# Documentos de soporte
Source: https://transfiya.me/es/v1.104/transfers-mol/support/support-files
Manuales técnicos y guías descargables relacionadas al MOL
## Documentación MOL
En esta sección encontrarás manuales técnicos y documentos de soporte asociados al MOL.
Puedes descargar el documento técnico de la versión actual desde el siguiente enlace. Este archivo contiene detalles técnicos del MOL.
📄 Versión 2.3.0 - Manual Técnico MOL 28/04/2025
Descargar PDF
📄 Versión 2.2.0 - Manual Técnico MOL 04/04/2025
Descargar PDF
# Actualizar an accion
Source: https://transfiya.me/transfers-mol-2/action/actualizar-an-accion
/public/tinapiv8.yaml put /v1/action/{action_id}
# Crear una accion
Source: https://transfiya.me/transfers-mol-2/action/crear-una-accion
/public/tinapiv8.yaml post /v1/action
# Enviar una accion
Source: https://transfiya.me/transfers-mol-2/action/enviar-una-accion
/public/tinapiv8.yaml post /v1/action/{action_id}/sendit
# Obtener accion por ID
Source: https://transfiya.me/transfers-mol-2/action/obtener-accion-por-id
/public/tinapiv8.yaml get /v1/action/{action_id}
# Create credentials
Source: https://transfiya.me/transfers-mol-2/credentials/create-credentials
/public/tinapiv8.yaml post /oauth
Endpoint used for creating of credentials
# Get api key
Source: https://transfiya.me/transfers-mol-2/credentials/get-api-key
/public/tinapiv8.yaml get /oauth/key/{handle}
Endpoint used to get api key
# Get credentials
Source: https://transfiya.me/transfers-mol-2/credentials/get-credentials
/public/tinapiv8.yaml get /oauth/client/{handle}
Endpoint used to get credentials
# Regenerate secrets
Source: https://transfiya.me/transfers-mol-2/credentials/regenerate-secrets
/public/tinapiv8.yaml put /oauth/{handle}
Endpoint used to regenerate secrets
# Rollback secrets
Source: https://transfiya.me/transfers-mol-2/credentials/rollback-secrets
/public/tinapiv8.yaml put /oauth/rollback/{handle}
Endpoint used to rollback secrets
# Update credentials
Source: https://transfiya.me/transfers-mol-2/credentials/update-credentials
/public/tinapiv8.yaml put /oauth/credentials/{handle}
Endpoint used for updating of credentials
# Authorize token
Source: https://transfiya.me/transfers-mol-2/token/authorize-token
/public/tinapiv8.yaml get /oauth/authorize
Endpoint used to authorize token
# Create token
Source: https://transfiya.me/transfers-mol-2/token/create-token
/public/tinapiv8.yaml post /oauth/token
Endpoint used for creating of token
# Aceptar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/aceptar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/accept
# Actualizar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/actualizar-una-transferencia
/public/tinapiv8.yaml put /v1/transfer/{transfer_id}
# Continuar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/continuar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/continue
# Crear una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/crear-una-transferencia
/public/tinapiv8.yaml post /v1/transfer
# Inicializar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/inicializar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{transferId}/initiate
# Rechazar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/rechazar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/reject
# Actualiza la transferencia.
Source: https://transfiya.me/transfers-mol/action/actualiza-la-transferencia
/public/spi-banksv3.yaml post /v1/action
TIN Cloud will call this endpoint when bank needs to sign the pending action. Depending on the key handling strategy it can use keys stored in the TIN Cloud or keys stored on local Key management system.
# Acreditar al destino.
Source: https://transfiya.me/transfers-mol/credit/acreditar-al-destino
/public/spi-banksv3.yaml post /v1/credit
Executes download on TIN Cloud side and credit on banking core side.
# Debitar al origen.
Source: https://transfiya.me/transfers-mol/debit/debitar-al-origen
/public/spi-banksv3.yaml post /v1/debit
Executes upload on TIN Cloud side and debit on banking core side.
# Notificacion de la transferencia.
Source: https://transfiya.me/transfers-mol/status/notificacion-de-la-transferencia
/public/spi-banksv3.yaml post /v1/status
Notification channel. It receives action object as a confirmation of transfer acceptance or reject action.
# This is the endpoint to get a temporal token to set in the oauth2 header
Source: https://transfiya.me/transfers-mol/token/this-is-the-endpoint-to-get-a-temporal-token-to-set-in-the-oauth2-header
/public/spi-banksv3.yaml post /oauth/token
# Rollback secrets
Source: https://transfiya.me/b2b-2/credentials/rollback-secrets
/public/tinapiv8.yaml put /oauth/rollback/{handle}
Endpoint used to rollback secrets
# Authorize token
Source: https://transfiya.me/b2b-2/token/authorize-token
/public/tinapiv8.yaml get /oauth/authorize
Endpoint used to authorize token
# Create token
Source: https://transfiya.me/b2b-2/token/create-token
/public/tinapiv8.yaml post /oauth/token
Endpoint used for creating of token
# Actualiza la transferencia.
Source: https://transfiya.me/b2b/action/actualiza-la-transferencia
/public/spi-banksv3.yaml post /v1/action
TIN Cloud will call this endpoint when bank needs to sign the pending action. Depending on the key handling strategy it can use keys stored in the TIN Cloud or keys stored on local Key management system.
# Acreditar al destino.
Source: https://transfiya.me/b2b/credit/acreditar-al-destino
/public/spi-banksv3.yaml post /v1/credit
Executes download on TIN Cloud side and credit on banking core side.
# Debitar al origen.
Source: https://transfiya.me/b2b/debit/debitar-al-origen
/public/spi-banksv3.yaml post /v1/debit
Executes upload on TIN Cloud side and debit on banking core side.
# Notificacion de la transferencia.
Source: https://transfiya.me/b2b/status/notificacion-de-la-transferencia
/public/spi-banksv3.yaml post /v1/status
Notification channel. It receives action object as a confirmation of transfer acceptance or reject action.
# This is the endpoint to get a temporal token to set in the oauth2 header
Source: https://transfiya.me/b2b/token/this-is-the-endpoint-to-get-a-temporal-token-to-set-in-the-oauth2-header
/public/spi-banksv3.yaml post /oauth/token
# Create a new signer
Source: https://transfiya.me/directory/signer/create-a-new-signer
/public/spi-v3.yaml post /v1/signer
Endpoint to create a signer with necessary details.
# Get a signer with signer handle.
Source: https://transfiya.me/directory/signer/get-a-signer-with-signer-handle
/public/spi-v3.yaml get /v1/signer/{signerAddress}
Endpoint to get a signer.
# Resolves SPI signer
Source: https://transfiya.me/directory/signer/resolves-spi-signer
/public/spi-v3.yaml post /v1/signer/lookup.dice
Endpoint to resolve signer in DICE
# Retrieve signers
Source: https://transfiya.me/directory/signer/retrieve-signers
/public/spi-v3.yaml get /v1/signer
Get signers with support for filtering.
# Update a signer
Source: https://transfiya.me/directory/signer/update-a-signer
/public/spi-v3.yaml put /v1/signer/{signerAddress}
Endpoint to update a signer.
# Tipos de Flujos
Source: https://transfiya.me/es/v1.104/generals/flows/intro-flows
Tipos de Flujos para los participantes
**TIN Cloud** soporta 5 tipos diferentes de flujos de transferencia inmediata. Dos de ellos están orientados al envío de dinero y tres al uso de solicitudes de pago P2P.
### Tipos de flujo
* **Tipo 1**: Transferencia P2P SEND, con SMS y aceptación (sin relación de confianza)
* **Tipo 2**: Transferencia P2P SEND, transferencia inmediata (con relación de confianza)
* **Tipo 3**: Transferencia P2P REQUEST
* **Tipo 4**: Transferencia P2P SEND, transferencia inmediata a número de cuenta
* **Tipo 5**: Transferencia P2P REQUEST, solicitud a un número de cuenta
Cada transferencia P2P se representa con **3 acciones** dentro del núcleo de TIN Cloud:
* **UPLOAD**: Débito de la cuenta bancaria del usuario origen y creación de la acción UPLOAD.
* **SEND o REQUEST**: Movimiento de fondos entre cuentas de usuario.
* **DOWNLOAD**: Crédito en la cuenta bancaria del usuario destino y creación de la acción DOWNLOAD.
***
### Relaciones de Confianza
Los usuarios pueden optar por crear una relación de confianza con otros usuarios. Esta relación de confianza se establece entre el **wallet del usuario origen** (número de teléfono) y el **signer del usuario destino** (cuenta bancaria). Es una relación unidireccional. Que el signer destino confíe en el wallet del origen **no implica** que el origen confíe en el destino.
* Si **existe** relación de confianza, TIN Cloud ejecuta el flujo completo de forma automática y el usuario destino recibe el dinero inmediatamente. En este caso, **no se envía un SMS** desde TIN Cloud. Esta funcionalidad puede ser implementada opcionalmente por la aplicación del banco.
* Si **no existe** relación de confianza:
* El usuario destino debe **aceptar o rechazar** manualmente la transferencia pendiente.
* TIN Cloud enviará un **SMS** notificando al usuario destino sobre la transferencia pendiente.
* El usuario destino tiene **24 horas** para ingresar a la aplicación del banco y aceptar la transferencia. Si no lo hace, la transferencia será automáticamente **rechazada**.
***
### Tipo 1: Transferencia P2P SEND con aceptación (sin relación de confianza)
Este flujo se ejecuta en dos casos:
1. El wallet del usuario destino **no tiene una relación de confianza** con el signer del usuario origen.
2. El wallet del usuario destino **no tiene un signer registrado** (cuenta bancaria) para recibir transferencias TIN.
```mermaid theme={null}
sequenceDiagram
autonumber
participant UO as Usuario Origen
participant EO as Entidad Originadora
participant ACH as ACH Colombia
participant PF as Motor Prevención Fraude ACH
participant ER as Entidad Receptora
participant UR as Usuario Receptor
UO->>EO: 1. Ingresa al canal del banco
EO->>UO: 2. Autentica usuario
UO->>EO: 3. Selecciona Transferencias inmediatas
EO->>UO: 4. Presenta opción enviar $
UO->>EO: 5. Ingresa datos de transferencia y envía
EO->>ACH: 6. Envía transferencia
ACH->>ACH: 7. Asigna CUS
ACH->>PF: 8. Envía Tx a evaluar
PF-->>ACH: 10. Retorna fraude sí/no
ACH->>EO: 9. Envía #CUS
ACH->>UR: 11. Envía SMS usuario receptor
UR->>ER: 12. Ingresa al canal Banco y selecciona transf inmediatas
ER->>UR: 15. Presenta Tx pendientes
UR->>ER: 16. Elige cuenta, ingresa número celular originador y aprueba
ER->>ACH: 13. Consulta Tx pendientes
ACH->>ER: 14. Envía Tx pendientes
ER->>ACH: 17. Envía confirmación
ACH->>EO: 18. Envía estado final
EO->>UO: 20. Confirma al usuario
EO->>ACH: 19. Envía estado final
```
## Flujos de Acción
```mermaid theme={null}
flowchart TB
%% Estilo de nodos
classDef wallet fill:#dddddd,stroke:#444,stroke-width:1px
classDef signer fill:#cc9999,stroke:#444,stroke-width:1px
classDef keeper fill:#884444,stroke:#444,stroke-width:1px,color:#fff
%% Usuario origen
subgraph "Usuario emisor (Wallet bridge)"
SUW_W["W"]:::wallet
SUW_S["S"]:::signer
SUW_K["K"]:::keeper
end
%% Banco origen
subgraph "Banco emisor (Wallet límite)"
SBW_W["W"]:::wallet
SBW_S["S"]:::signer
SBW_K["K"]:::keeper
end
%% Usuario receptor
subgraph "Usuario receptor (Wallet bridge)"
TUW_W["W"]:::wallet
TUW_S["S"]:::signer
TUW_K["K"]:::keeper
end
%% Banco receptor
subgraph "Banco receptor (Wallet límite)"
TBW_W["W"]:::wallet
TBW_S["S"]:::signer
TBW_K["K"]:::keeper
end
%% Relaciones internas (visual, no funcional)
SUW_W --> SUW_S --> SUW_K
SBW_W --> SBW_S --> SBW_K
TUW_W --> TUW_S --> TUW_K
TBW_W --> TBW_S --> TBW_K
%% Acciones entre entidades
SUW_K -->|Action UPLOAD
Débito| SBW_K
SUW_K -->|Action SEND| TUW_K
TUW_K -->|Action DOWNLOAD
Crédito| TBW_K
SBW_K -->|REJECT
Action DOWNLOAD
Crédito| SUW_K
```
## Codigo de Flujo
```mermaid theme={null}
sequenceDiagram
autonumber
participant UO as Usuario Originador
participant CFO as Canal Entidad Financiera Originadora
participant IO as Integración Entidad Financiera Originadora
participant SDK_O as SDK Integración Entidad Originadora
participant TI as Transferencias Inmediatas
participant SDK_R as SDK Integración Entidad Receptora
participant IR as Integración Entidad Financiera Receptora
participant CFR as Canal Entidad Financiera Receptora
participant UR as Usuario Receptor
UO->>CFO: Ingresa al canal de la entidad financiera
CFO->>UO: Presenta mecanismos de autenticación
UO->>CFO: Se autentica en la entidad financiera
CFO->>UO: Propone opciones de menú
UO->>CFO: Selecciona transferencias inmediatas
CFO->>UO: Presenta formulario de transferencia
UO->>CFO: Ingresa información de la transferencia
CFO->>IO: Envía información
IO->>CFO: return
IO->>SDK_O: generar llaves
SDK_O-->>IO: return
IO->>TI: createWalletUsuario
TI-->>IO: return
IO->>TI: newTransfer
TI-->>IO: return
IO->>TI: createSigner
TI-->>IO: return
IO->>TI: activarWallet
TI-->>IO: return
IO->>TI: createTransferencias
TI-->>IO: return con CUS
IO->>SDK_O: realiza débito
SDK_O->>TI: consume servicio débito
TI-->>SDK_O: return
SDK_O-->>IO: return
IO->>TI: Consume débito
TI-->>IO: return
IO->>TI: realizaUpdate
TI-->>IO: return
TI->>UR: Enviar SMS tiene transferencia pendiente
UR-->>TI: return
UR->>CFR: Ingresa a entidad financiera
CFR->>UR: return
UR->>CFR: Selecciona transferencias pendientes
CFR->>UR: return
CFR->>IR: consulta transferencias pendientes
IR->>CFR: return
IR->>IR: Envía consulta
IR-->>IR: return
IR->>CFR: return
CFR->>UR: Presenta transferencias pendientes
UR->>CFR: Acepta transferencia
CFR->>IR: callback
IR->>IR: Acepta transferencia
IR-->>CFR: return
CFR-->>UR: return
IR->>TI: llama servicio crédito
TI->>SDK_R: Realiza crédito
SDK_R->>TI: return
TI->>TI: realizar crédito
TI->>TI: dispone recursos
TI-->>SDK_R: return
SDK_R-->>TI: return
IO->>TI: Firma transacción entre signer de usuarios
TI-->>IO: return
IO->>TI: consume servicio transfer
TI-->>IO: return
IO->>TI: consume servicio status
TI-->>IO: return
IO->>IO: self actualizar estado final
IO-->>TI: return
IO->>CFO: informar al usuario
CFO-->>UO: informar al usuario
UO-->>CFO: return
```
## Tipo 2: Transferencia P2P - Envío inmediato (con relación de confianza)
Este flujo ejecuta una transferencia P2P inmediata de extremo a extremo en el caso de que el **firmante del usuario destino tenga una relación de confianza con el wallet del usuario origen**.
Cuando existe una relación de confianza, el sistema Transfiya realiza automáticamente el flujo completo de la transferencia sin necesidad de aceptación manual por parte del usuario receptor.
```mermaid theme={null}
sequenceDiagram
autonumber
participant UO as Usuario Final
participant EO as Entidad Originadora
participant ACH as ACH Colombia
participant PF as Motor Prevención Fraude ACH
participant ER as Entidad Receptora
participant UR as Usuario Final Receptor
UO->>EO: 1. Ingresa al canal del Banco
EO->>UO: 2. Autentica usuario
UO->>EO: 3. Selecciona Transferencias inmediatas
EO->>UO: 4. Presenta opción enviar $
UO->>EO: 5. Ingresa datos de transferencia y envía
EO->>ACH: 6. Envía transferencia
ACH->>ACH: 7. Asigna CUS
ACH->>PF: 8. Envía Tx a evaluar
PF-->>ACH: 10. Retorna fraude sí/no
ACH->>EO: 9. Envía #CUS
ACH->>ER: 11. Envía transferencia Banco receptor
ER->>ACH: 12. Confirma transacción
ACH->>ER: 13. Confirma transacción
ACH->>EO: 14. Envía estado final
EO->>UO: 16. Confirma al usuario
EO->>ACH: 15. Enviar estado final
```
## Flujo de Acción
\##Flujo de Código
```mermaid theme={null}
sequenceDiagram
autonumber
participant UO as Usuario Originador
participant CEO as Canal Entidad Financiera Originadora
participant IEO as Integración Entidad Financiera Originadora
participant SDKO as SDK Integración Entidad Originador
participant TI as Transferencias Inmediatas
participant SDKR as SDK Integración Entidad Receptora
participant IER as Integración Entidad Financiera Receptora
participant CER as Canal Entidad Financiera Receptora
participant UR as Usuario Receptor
UO->>CEO: Ingresa al canal de la entidad financiera
CEO->>UO: Presenta mecanismos de autenticación
UO->>CEO: Se autentica ante la entidad financiera
CEO->>UO: Propone opciones de menú
UO->>CEO: Selecciona transferencias inmediatas
CEO->>UO: Presenta formulario de transferencia
UO->>CEO: Ingresa información de la transferencia
CEO->>IEO: Envía información
IEO->>SDKO: Generar llaves
SDKO-->>IEO: return
IEO->>TI: createWalletUsuario
TI-->>IEO: return
IEO->>TI: newTransfer
TI-->>IEO: return
IEO->>TI: createWallet
TI-->>IEO: return
IEO->>TI: activateWallet
TI-->>IEO: return
IEO->>TI: createTransferencias
TI-->>IEO: return
IEO->>TI: Consume debit
TI-->>IEO: return
IEO->>TI: realizarUpdate
TI-->>IEO: return
CEO->>TI: Firma transacción entre signer de usuarios
TI-->>CEO: return
CEO->>TI: consume servicio transfer
TI-->>CEO: return
CEO->>TI: consume servicio status
TI-->>CEO: return
TI->>SDKR: llama servicio crédito
SDKR->>IER: realizar download
IER->>CER: Realiza crédito
CER->>UR: Notifica al usuario
CER-->>IER: return
IER-->>SDKR: return
SDKR-->>TI: return
CEO->>UO: Informar al usuario
CEO->>TI: self actualizar estado final
TI-->>CEO: return
CEO-->>UO: return
```
## TIPO 3: Transferencia P2P de Solicitud (Request)
Este flujo se ejecuta en el caso en que el firmante del usuario receptor está solicitando un pago desde el monedero del usuario originador.
```mermaid theme={null}
sequenceDiagram
autonumber
participant UO as Usuario Final
Entidad Originadora
participant EO as Entidad Originadora
participant ACH as ACH Colombia
participant PF as Motor Prevención
Fraude ACH
participant ER as Entidad Receptora
participant UR as Usuario Final
Entidad Receptora
UO->>EO: 1. Ingresa al canal del Banco
EO-->>UO: 2. Autentica usuario
UO->>EO: 3. Selecciona Transferencias inmediatas
EO-->>UO: 4. Presenta opción solicitar $
UO->>EO: 5. Ingresa datos de transferencia y envía
EO->>ACH: 6. Envía transferencia
ACH->>ACH: 7. Asigna CUS
ACH->>PF: 8. Envía Tx a evaluar
PF-->>ACH: 10. Retorna fraude sí/no
ACH->>EO: 9. Envía # CUS
ACH->>UR: 11. Envía SMS usuario receptor
UR->>ER: 12. Ingresa al canal Banco
Selecciona transf inmediatas
ER-->>UR: 15. Presenta Tx pendientes
UR->>ER: 16. Elige cuenta, ingresa
# cel originador y aprueba
ER->>ACH: 13. Consulta Tx pendientes
ACH-->>ER: 14. Envía Tx pendientes
ER->>ACH: 17. Envía confirmación
ACH->>EO: 18. Envía estado final
EO->>ACH: 19. Enviar estado final
EO-->>UO: 20. Confirma al usuario
```
## Flujo de Acción
## Flujo de Código
```mermaid theme={null}
sequenceDiagram
autonumber
participant UO as Usuario Originador
participant CEO as Canal Entidad Financiera Originadora
participant IEO as Integración Entidad Financiera Originadora
participant SDKO as SDK Integración Entidad Originadora
participant TI as Transferencias Inmediatas
participant SDKR as SDK Integración Entidad Receptora
participant IER as Integración Entidad Financiera Receptora
participant CER as Canal Entidad Financiera Receptora
participant UR as Usuario Receptor
UO->>CEO: Ingresa al canal de la entidad financiera
CEO->>UO: presenta mecanismo de autenticación
UO->>CEO: Se autentica ante la entidad financiera
CEO->>UO: Presenta opciones de menú
UO->>CEO: Selecciona transferencias inmediatas
CEO->>UO: presenta formulario de transferencia
UO->>CEO: Ingresa información de la transferencia
CEO->>IEO: Envía información
IEO->>SDKO: generar llaves
SDKO->>SDKO: createWalletUsuario
SDKO-->>IEO: return
SDKO->>SDKO: newSigner
SDKO-->>IEO: return
SDKO->>SDKO: newKeeper
SDKO-->>IEO: return
SDKO->>SDKO: activarWallet
SDKO-->>IEO: return
SDKO->>SDKO: crearTransferencia
SDKO-->>IEO: return
TI->>UR: Enviar SMS tiene transferencia pendiente
UR->>CER: Ingresa entidad financiera
CER->>UR: return
UR->>CER: selecciona transferencias pendientes
CER->>IER: Envía consulta
IER->>SDKR: consulta transferencias pendientes
SDKR-->>IER: return
IER-->>CER: return
CER-->>UR: return
UR->>CER: Acepta transferencia
CER->>IER: callback
IER->>SDKR: Acepta transferencia
SDKR-->>IER: return
IER-->>CER: return
CER-->>UR: return
IER->>SDKR: llama servicio débito
SDKR->>SDKR: realizar upload
SDKR-->>IER: return
IER->>TI: realiza débito
TI-->>IER: return
TI->>SDKO: consume servicio transfer
SDKO->>TI: return
TI->>SDKR: consume servicio crédito
SDKR->>SDKR: realiza download
SDKR-->>TI: return
SDKR->>IER: realizar crédito
IER->>CER: notifica al canal
CER->>UR: notifica al usuario
TI->>CEO: informar al usuario
CEO->>UO: informar al usuario
```
### Tipo 4: Transferencia P2P SEND, transferencia inmediata a un número de cuenta
Este flujo se ejecuta en el caso en que el destino de una transferencia SEND sea una referencia de cuenta (`:@`). El flujo de procesamiento es el mismo que para transferencias SEND regulares, con la única diferencia en el comportamiento de aceptación.
En lugar de notificar al usuario mediante SMS, el sistema notificará directamente al banco de destino a través del bridge para registrar al usuario y aceptar la transferencia. Este modelo de aceptación nos permite procesar pagos hacia cualquier cuenta sin que los usuarios tengan que registrarse manualmente en el sistema antes de recibir transferencias.
> 💡 **Nota:** Si el usuario ya se encuentra registrado en el sistema, el flujo de la transferencia es idéntico al de las transferencias Tipo 2.
```mermaid theme={null}
sequenceDiagram
autonumber
participant BancoOrigen as Banco Emisor
participant Transfiya as TransfiYa
participant BancoDestino as Banco Receptor
BancoOrigen->>Transfiya: Crear transferencia
loop Validación de reglas
Transfiya-->>Transfiya: Validar reglas de negocio
end
Transfiya-->>BancoOrigen: Transferencia creada
alt [débito (asíncrono)]
Transfiya->>BancoOrigen: Llamar endpoint de débito
loop Procesar débito
BancoOrigen-->>BancoOrigen: Procesar débito
end
BancoOrigen->>Transfiya: Continuar transferencia
end
loop Resolución
Transfiya-->>Transfiya: Resolver signer de destino
Transfiya-->>Transfiya: Aceptar transferencia
end
alt [acción (síncrona)]
Transfiya->>BancoOrigen: Llamar endpoint de acción
loop Procesar acción
BancoOrigen-->>BancoOrigen: Procesar acción
end
BancoOrigen->>Transfiya: Respuesta de acción
end
alt [crédito (asíncrono)]
Transfiya->>BancoDestino: Llamar endpoint de crédito
loop Procesar crédito
BancoDestino-->>BancoDestino: Procesar crédito
end
BancoDestino->>Transfiya: Continuar transferencia
end
BancoOrigen->>Transfiya: Llamar estado
Transfiya-->>BancoOrigen: Respuesta estado
Transfiya->>BancoDestino: Llamar estado
BancoDestino-->>Transfiya: Respuesta estado
```
El procesamiento de la transferencia en el caso en que el usuario destinatario **no esté registrado en el sistema** es similar, con la única diferencia de que **la transferencia no se aceptará automáticamente**. En su lugar, **TransfiYa notificará al banco receptor para registrar al usuario**, y el banco deberá aceptar la transferencia una vez finalizado el proceso de onboarding.
```mermaid theme={null}
sequenceDiagram
autonumber
participant SB as Source Bank
participant TY as TransfiYa
participant TB as Target Bank
SB->>TY: 1. Create transfer
TY->>TY: 2. Validate business rules
TY-->>SB: 3. Transfer created
alt debit (async)
TY->>SB: 4. Call debit
SB->>SB: 5. Process debit
SB->>TY: 6. Continue transfer
end
TY->>TY: 7. Resolve target signer
alt accept (async)
TY->>TB: 8. Call status (PENDING)
TB-->>TY: 9. Confirm receipt
TB->>TB: 10. Validate account
TB-->>TY: 11. Create signer
TY-->>TB: 12. Signer response
TB-->>TY: 13. Accept transfer
end
alt action (sync)
TY->>SB: 14. Call Action
SB->>SB: 15. Process action
SB-->>TY: 16. Action response
end
alt credit (async)
TY->>TB: 17. Call credit
TB->>TB: 18. Process credit
TB-->>TY: 19. Continue transfer
end
SB->>TY: 20. Call status
TY-->>SB: 21. Status response
TY->>TB: 22. Call status
TB-->>TY: 23. Status response
```
# Tipo 1 Aceptar o Rechazar
Source: https://transfiya.me/es/v1.104/generals/flows/type1-accept-reject
Aceptar o Rechazar una transacción
### Aceptar una transferencia P2P
Para aceptar una transferencia P2P, el banco debe usar un **POST** al endpoint `/v1/transfer/:tx_ref/accept` de la API de TIN.
El parámetro `tx_ref` (CUS) se obtiene de la lista de transferencias pendientes.
Para aceptar una transferencia es obligatorio enviar el `signer` en el cuerpo de la solicitud. El cuerpo **no debe estar vacío**.
```json theme={null}
curl -X POST -H "API_KEY: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" -d '{
"signer": {
"handle": "wuser_bridge_address",
}
}' "https://ach-minka-stg.transferenciasinmediatas.com/v1/transfer/oXnhHqKaaDOYVlhYd/accept"
```
```json theme={null}
// tx_ref (CUS)
String txRef = "oXnhHqKaaDOYVlhYd";
AcceptTransferRequest req =new AcceptTransferRequest();
WalletObject wallet = new WalletObject();
SignerObject signer = new SignerObject();
// Signer and wallet of target user
signer.setHandle("wabpqXPdBA19dB3h2QmVHoniRTnd52J4SX");
wallet.setHandle("$573004431529");
req.setWallet(wallet);
req.setSigner(signer);
CreateTransferResponse createTransferResponse = sdkApiClient.acceptTransfer(req, txRef);
System.out.println(createTransferResponse);
```
```json theme={null}
TransferApi instance = new TransferApi();
instance.Configuration.AddApiKey("API_KEY","5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c");
AcceptTransferRequest acceptTransReq = new AcceptTransferRequest();
string txRef = "oXnhHqKaaDOYVlhYd";
acceptTransReq.Signer = new SignerObject();
acceptTransReq.Signer.Handle = "Signer target"
instance.AcceptP2Ptranfer(txRef, acceptTransReq);
```
```json theme={null}
TransferApi instance = new TransferApi();
instance.Configuration.AddApiKey("API_KEY","5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c");
AcceptTransferRequest acceptTransReq = new AcceptTransferRequest();
string txRef = "oXnhHqKaaDOYVlhYd";
acceptTransReq.Signer = new SignerObject();
acceptTransReq.Signer.Handle = "Signer target"
instance.AcceptP2Ptranfer(txRef, acceptTransReq);
```
### Rechazar una transferencia P2P
Para rechazar una transferencia P2P, el banco debe usar un **POST** al endpoint `/v1/transfer/:tx_ref/reject` de la API de TIN.
El parámetro `tx_ref` (CUS) se obtiene de la lista de transferencias pendientes.
```json theme={null}
curl -X POST -H "API_KEY: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" -d '{
}' "https://ach-minka-stg.transferenciasinmediatas.com/v1/transfer/oXnhHqKaaDOYVlhYd/reject"
```
```json theme={null}
// tx_ref (CUS)
String txRef = "oXnhHqKaaDOYVlhYd";
RejectTransferRequest req =new RejectTransferRequest();
WalletObject wallet = new WalletObject();
SignerObject signer = new SignerObject();
// Signer and wallet of target user
signer.setHandle("wabpqXPdBA19dB3h2QmVHoniRTnd52J4SX");
wallet.setHandle("$573004431529");
req.setWallet(wallet);
req.setSigner(signer);
CreateTransferResponse createTransferResponse = sdkApiClient.rejectTransfer(req, txRef);
System.out.println(createTransferResponse);
```
```json theme={null}
TransferApi instance = new TransferApi();
instance.Configuration.AddApiKey("API_KEY","5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c");
string txRef = "oXnhHqKaaDOYVlhYd";
instance.RejectTransferRequest(txRef);
```
```json theme={null}
var Tinapi = require('tin_api')
var defaultClient = Tinapi.ApiClient.instance
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth']
ApiKeyAuth.apiKey = 'YOUR API KEY'
var apiInstance = new Tinapi.TransferApi()
var txRef = 'oXnhHqKaaDOYVlhYd' // String |
apiInstance.rejectP2Ptranfer(txRef).then(
function (data) {
console.log('API called successfully. Returned data: ' + data)
},
function (error) {
console.error(error)
},
)
```
# Tipo 1 Listar transacciones
Source: https://transfiya.me/es/v1.104/generals/flows/type1-transaction-history
Listar transacciones pendientes e historicas
### Listar transferencias pendientes de tipo TYPE1
Obtiene una lista de transferencias pendientes en las que el teléfono del usuario es el receptor.
**GET** `/v1/transfer?labels.type="SEND"&target="$userPhone"&labels.status="PENDING"&sortBy="created"&sort="desc"`
```json theme={null}
ApiResponse response = transferApi.GetTransfersWithCustomQuery("target=$57XXXXXXXXXX" + "&labels.type=SEND" + "&labels.status=PENDING");
```
```json theme={null}
var API_KEY = "5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c"; // String |
var Tinapi = require('tinapi_');
var defaultClient = Tinapi.ApiClient.instance;
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth'];
ApiKeyAuth.apiKey = API_KEY;
const transferApi = new tinapi.TransferApi()
const customQuery =
"labels.type=SEND&labels.status=PENDING&target=$573002414263"
transferApi.getTransfers(customQuery)
.then(transfers => {
console.log(transfers)
}).catch(console.log)
```
```json theme={null}
Transfers transfers = sdkApiClient.getTransfersWithCustomQuery("?labels.type=SEND&labels.status=PENDING");
System.out.println(transfers);
```
### Obtener historial de transferencias recibidas
**GET** `/v1/transfer?type="SEND"&target="$userPhone"`
Consulta el historial de transferencias en las que el teléfono del usuario es el receptor.
```json theme={null}
var API_KEY = "5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c"; // String |
var Tinapi = require('tinapi_');
var defaultClient = Tinapi.ApiClient.instance;
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth'];
ApiKeyAuth.apiKey = API_KEY;
var apiInstance = new Tinapi.ActionApi();
var type = "SEND"; // String |
var opts = {
'target': "$userPhone" // String |
};
apiInstance.getTransfer(type, opts).then(function(data) {
console.log('API called successfully. Returned data: ' + data);
console.log(data);
}, function(error) {
console.error(error);
});
```
```json theme={null}
string type = "SEND";
string target = "$userPhone";
string source = null;
string API_KEY = "5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c";
instance.Configuration.AddApiKey("API_KEY", API_KEY);
var response = instance.GetTransfersWithCustomQuery(type, source, target);
Console.WriteLine(response.Entities.Count);
Console.WriteLine(response.Entities[0]);
```
```json theme={null}
Transfers transfers = sdkApiClient.getTransfersWithCustomQuery("?targetWallet=$userPhone&labels.type=SEND&labels.status=PENDING");
System.out.println(transfers);
```
### Obtener historial de transferencias enviadas
**GET** `/v1/action?filter=type="SEND"&source="$userPhone"`
Consulta el historial de acciones tipo SEND en las que el teléfono del usuario es el remitente.
```json theme={null}
var API_KEY = "5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c"; // String |
var Tinapi = require('tin_api');
var defaultClient = Tinapi.ApiClient.instance;
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth'];
ApiKeyAuth.apiKey = API_KEY;
var apiInstance = new Tinapi.ActionApi();
var type = "SEND"; // String |
var opts = {
'source': "$userPhone" // String |
};
apiInstance.getTransfer(type, opts).then(function(data) {
console.log('API called successfully. Returned data: ' + data);
console.log(data);
}, function(error) {
console.error(error);
});
```
```json theme={null}
string type = "SEND";
string source = "$userPhone";
string target = null;
string API_KEY = "5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c";
instance.Configuration.AddApiKey("API_KEY", API_KEY);
var response = instance.GetTransfersWithCustomQuery(type, source, target);
Console.WriteLine(response.Entities.Count);
Console.WriteLine(response.Entities[0]);
```
```json theme={null}
Transfers transfers = sdkApiClient.getTransfersWithCustomQuery("?sourceWallet=$573004431529&labels.type=SEND&labels.status=PENDING");
System.out.println(transfers);
```
# Tipo 1 Gestion de Relaciones de Confianza
Source: https://transfiya.me/es/v1.104/generals/flows/type1-trust-transactions
Para implementar TIN en las aplicaciones bancarias, existen elementos comunes de experiencia de usuario (UX) que la mayoría de los bancos utilizarán. Estos elementos incluyen:
* Listas de billeteras confiables (trusted wallets)
* Listas de transferencias
* Actualización de los datos de la billetera del usuario
Una relación de confianza se establece entre la billetera de un usuario y un firmante (signer) de otro usuario. Esta relación es unidireccional y **no aplica para transferencias de tipo REQUEST**.
Cuando existe una relación de confianza, la transferencia se ejecuta automáticamente **sin necesidad de que sea aceptada**.
📌 **Nota:** Quien acepta o crea una relación de confianza es siempre el **usuario receptor**.
```mermaid theme={null}
sequenceDiagram
autonumber
participant UO as Usuario Final (Origen)
participant EO as Entidad Originadora
participant ACH as ACH Colombia
participant PF as Motor Prev Fraude ACH
participant ER as Entidad Receptora
participant UR as Usuario Final (Receptor)
UO ->> EO: 1. Ingresa a canal del Banco
EO ->> UO: 2. Autentica usuario
UO ->> EO: 3. Selecciona Transferencias Ya
EO ->> UO: 4. Presenta opción enviar $
UO ->> EO: 5. Ingresa datos de transferencia y envía
EO ->> ACH: 6. Envía transferencia
ACH ->> ACH: 7. Asigna CUS / Valida relación confianza
ACH ->> EO: 8. Envía #CUS
ACH ->> PF: 9. Envía trx a evaluar
PF -->> ACH: 10. Retorna fraude sí/no
ACH ->> EO: 11. Llamado endpoint debit
EO ->> EO: 12. Débito core bancario
EO -->> ACH: 13. Response debit
ACH ->> EO: 14. Llamado endpoint transfer
EO -->> ACH: 15. Response transfer
ACH ->> ER: 16. Llamado endpoint credit
ER ->> ER: 17. Crédito core bancario
ER -->> ACH: 18. Response credit
ACH ->> EO: 19. Llamado endpoint status
EO -->> ACH: Response status
ACH ->> ER: 20. Llamado endpoint status
ER -->> ACH: Response status
ACH ->> EO: 21. Envía estado final trx
EO ->> UO: Confirma al usuario
ER ->> UR: Confirma al usuario
```
## Crear un link de confianza
```json theme={null}
curl -X POST -H "x-api-key: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" -d '{
source: "$sourceWallet",
target: "targetSigner",
type: "TRUST"
}' "https://ach-minka-stg.transferenciasinmediatas.com/v1/link/"
```
```json theme={null}
const link = new TinApi.LinksApi()
link
.createLink({
source: '$573010071856',
target: 'wck4oHkeP9YUojTH1LRUf8sXRFMbCaxPDT',
type: CreateLinkRequest.TypeEnum.TRUST,
})
.then((response) => console.log(response))
.catch((error) => console.log(error))
```
```json theme={null}
LinksApi linksApi = new LinksApi();
CreateLinkRequest createLinkRequest = new CreateLinkRequest();
createLinkRequest.Source = "$573010071856";
createLinkRequest.Target = "wck4oHkeP9YUojTH1LRUf8sXRFMbCaxPDT";
createLinkRequest.Type = CreateLinkRequest.TypeEnum.TRUST;
LinkItem linkResponse = linksApi.CreateLink(createLinkRequest);
Console.WriteLine(linkResponse);
```
```json theme={null}
try {
String source = "$573010071856";
String target = "wck4oHkeP9YUojTH1LRUf8sXRFMbCaxPDT";
LinkItem link = sdkApiClient.createLink(source, target,
io.minka.api.model.CreateLinkRequest.TypeEnum.TRUST);
System.out.println(link);
} catch (ExceptionResponseTinApi exceptionResponseTinApi) {
exceptionResponseTinApi.printStackTrace();
}
```
## Eliminar un Link de Confianza
```json theme={null}
curl -X DELETE -H "x-api-key: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" "https://ach-minka-stg.transferenciasinmediatas.com/v1/link/da7726e4-c2bd-4bc3-a8f6-cdeb0378164a"
```
```json theme={null}
sdkApiClient.deleteLink("LINK_ID");
```
```json theme={null}
LinkItem linkResponse = linksApi.DeleteLink("LINK_ID");
```
```json theme={null}
link.deleteLink('LINK_ID')
.then(response => console.log(response))
.catch(error => console.log(error));
```
## Listar todos los links de confianza
```json theme={null}
curl -X GET -H "x-api-key: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" "https://ach-minka-stg.transferenciasinmediatas.com/v1/link?target=targetSigner&type=TRUST"
```
```json theme={null}
String target = "targetSigner";
ListLinks links = sdkApiClient.getLinks(null, target, "TRUST");
System.out.println(links);
```
```json theme={null}
string target = "targetSigner";
string API_KEY = "5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c";
instance.Configuration.AddApiKey("x-api-key", API_KEY);
var response = instance.GetLink(null, target, "TRUST");
Console.WriteLine(response);
```
```json theme={null}
var Tinapi = require('tinapi_');
var defaultClient = Tinapi.ApiClient.instance;
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth'];
ApiKeyAuth.apiKey = API_KEY;
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//ApiKeyAuth.apiKeyPrefix = 'Token';
var apiInstance = new Tinapi.LinksApi();
var opts = {
'target': "targetSigner",
'type': 'TRUST'
};
apiInstance.getLink(opts).then(function(data) {
console.log('API called successfully. Returned data: ' + data);
console.log(JSON.stringify(data));
}, function(error) {
console.error(error);
});
```
# Tipo1, Tipo 2 - Envío de transferecia
Source: https://transfiya.me/es/v1.104/generals/flows/type1-type2-send-transfer
Tipos de Flujos para los participantes
### Tipo 1 y Tipo 2: Transferencias P2P (SEND)
Para iniciar una nueva transferencia P2P del tipo **Tipo 1** o **Tipo 2**, se debe realizar una solicitud `POST` al endpoint: POST /v1/transfer
Este método orquesta la ejecución completa del flujo de transferencia P2P en TIN Cloud.
* **Tipo 1**: Transferencia con aceptación (sin relación de confianza).
* **Tipo 2**: Transferencia inmediata (con relación de confianza).
La ejecución de este endpoint permite iniciar la acción `SEND`, que a su vez gestionará las acciones necesarias como `UPLOAD` (débito), `SEND` (transferencia) y `DOWNLOAD` (crédito), dependiendo del tipo de flujo que se aplique.
Antes de iniciar una transferencia, debes agregar los detalles del dispositivo (`Device Fingerprint`) en el objeto `labels.deviceFingerPrint`.
#### Ejemplo de solicitud cURL
```json theme={null}
curl -X POST -H "API_KEY: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" -d '{
"source": "wsource_user_bridge_address",
"target": "$target_user_phone_number",
"symbol": "$tin",
"amount": "AMOUNT",
"labels": {
"type": "SEND",
"description": "Description of a transfer",
"sourceCreated": "ISO_TIMESTAMP",
"transactionPurpose": "TRANSFER",
"numberOfTransactions": "1",
"sourceChannel": "APP",
"deviceFingerprint": {
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"ipAddress": "190.242.46.190",
"geolocation": " ",
"country": "Colombia",
"city": "Bogota",
"mobileDevice": "a",
"SIMCardId": "a",
"model": "a",
"operator": "D"
}
}
}' "https://ach-minka-tst.transferenciasinmediatas.com/v1/transfer"
```
```json theme={null}
Response 200 OK
{
"source": "wsource_user_bridge_address",
"target": "$target_user_phone_number",
"symbol": "$tin",
"amount": "AMOUNT",
"labels": {
"tx_ref": "15368665012276089",
"type": "SEND",
"status": "PENDING",
"description": "Description of a transfer",
"transactionPurpose": "TRANSFER",
"sourceCreated": "2018-08-03T09:58:01.906Z",
"created": "2018-08-03T09:58:01.906Z",
"numberOfTransactions": "1",
"deviceFingerprint": {
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"ipAddress": "190.242.46.190",
"geolocation": " ",
"country": "Colombia",
"city": "Bogota",
"mobileDevice": "a",
"SIMCardId": "a",
"model": "a",
"operator": "D"
}
},
"error": {
"code": 0,
"message": "Success"
}
}
```
```json theme={null}
Response 400 Bad Request
{
"source": "wsource_user_bridge_address",
"target": "$target_user_phone_number",
"symbol": "$tin",
"amount": "AMOUNT",
"labels": {
"tx_ref": "15368665012276089",
"type": "SEND",
"status": "REJECTED",
"description": "Description of a transfer",
"transactionPurpose": "TRANSFER",
"sourceCreated": "2018-08-03T09:58:01.906Z",
"created": "2018-08-03T09:58:01.906Z",
"numberOfTransactions": "1",
"deviceFingerprint": {
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"ipAddress": "190.242.46.190",
"geolocation": " ",
"country": "Colombia",
"city": "Bogota",
"mobileDevice": "a",
"SIMCardId": "a",
"model": "a",
"operator": "D"
}
},
"error": {
"code": 123,
"message": "Number of transactions exceeded."
}
}
```
```json theme={null}
CreateTransferRequest createTransferRequest = new CreateTransferRequest();
createTransferRequest.Source = "wsource_user_bridge_address";
createTransferRequest.Target = "$target_user_phone_number";
Dictionary labels = new Dictionary();
createTransferRequest.Labels = labels;
labels["type"] = "SEND";
labels["description"] = "Description of a transfer";
createTransferRequest.Amount = "AMOUNT";
createTransferRequest.Symbol = "$tin";
instance.Configuration.AddApiKey("x-api-key","5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c");
var response = instance.CreateTinTransfer(createTransferRequest);
```
```json theme={null}
CreateTransferRequest tinTranfer = new CreateTransferRequest();
CreateTransferRequestLabels labels = new CreateTransferRequestLabels();
DeviceFingerPrint deviceFingerPrint = new DeviceFingerPrint();
deviceFingerPrint.setCity("Bogota");
deviceFingerPrint.setCountry("Colombia");
deviceFingerPrint.setGeolocation(" ");
deviceFingerPrint.setHash("26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58");
deviceFingerPrint.setIpAddress("190.242.46.190");
deviceFingerPrint.setMobileDevice("a");
deviceFingerPrint.setSiMCardId("a");
deviceFingerPrint.setModel("a");
deviceFingerPrint.setOperator("a");
labels.setTxId("34242342sdfe3432r23");
labels.setType("SEND");
labels.setDescription("Description of a transfer");
labels.setTransactionPurpose("transactionPurpose");
labels.setSourceCreated("2018-08-03T09:58:01.906Z");
labels.setNumberOfTransactions("1");
labels.setDeviceFingerPrint(deviceFingerPrint);
tinTranfer.setSource("wsource_user_bridge_address");
tinTranfer.setTarget("$target_user_phone_number");
tinTranfer.setAmount("10000");
tinTranfer.setSymbol("$tin");
tinTranfer.setLabels(labels);
CreateTransferResponse tinTransfer = sdkApiClient.createTinTransfer(tinTranfer);
System.out.println(tinTransfer);
```
```json theme={null}
var Tinapi = require('tinapi_');
var defaultClient = Tinapi.ApiClient.instance;
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth'];
ApiKeyAuth.apiKey = '5b481fc2ae177010e197026b39c58cdb000f4c3897e841714e82c84c';
var apiInstance = new Tinapi.TransferApi();
var createTransferRequest = new Tinapi.CreateTransferRequest(); // CreateTransferRequest |
createTransferRequest.source = "wsource_user_bridge_address";
createTransferRequest.target = "$target_user_phone_number";
var labels = {};
createTransferRequest.Labels = labels;
labels.type = "SEND";
labels.description. = "Description of a transfer";
createTransferRequest.amount = "AMOUNT";
createTransferRequest.symbol = "$tin";
apiInstance.createTinTransfer(createTransferRequest).then(function(data) {
console.log(data);
console.log('API called successfully. Returned data: ' + data);
}, function(error) {
console.error(error);
});
```
### Crear Relación de Confianza
Para realizar una transferencia de tipo **TYPE2**, se requiere crear un vínculo de confianza (*trust link*) antes de ejecutar la solicitud de transferencia.
Cuando existe una relación de confianza, cualquier transacción generada desde un `signer` dentro del `wallet` origen será transferida inmediatamente al `signer` de destino definido en el vínculo de confianza, sin necesidad de aceptación manual por parte del usuario receptor.
Las relaciones de confianza permiten ejecutar flujos de transferencia inmediatos sin enviar notificaciones ni requerir aceptación por parte del receptor.
```json theme={null}
curl -X PUT -H "x-api-key: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" -d '{
"source": "$USER1_PHONE_NUMBER",
"target": "USER2_SIGNER",
"type": "TRUST"
}' "https://ach-minka-stg.transferenciasinmediatas.com/v1/link/"
```
```json theme={null}
CreateLinkRequest createLinkRequest = new CreateLinkRequest();
createLinkRequest.Source = "$USER1_PHONE_NUMBER";
createLinkRequest.Target = "USER2_SIGNER";
createLinkRequest.Type = CreateLinkRequest.TypeEnum.TRUST;
string X_API_KEY = "5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e";
instance.Configuration.AddApiKey("X_API_KEY", X_API_KEY);
var response = instance.CreateLink(createLinkRequest);
Console.WriteLine(response);
```
```json theme={null}
LinkItem link = sdkApiClient.createLink("$USER1_PHONE_NUMBER", "USER2_SIGNER", io.minka.api.model.CreateLinkRequest.TypeEnum.TRUST);
System.out.println(link);
```
```json theme={null}
var Tinapi = require('tin_api')
var defaultClient = Tinapi.ApiClient.instance
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth']
ApiKeyAuth.xApiKey = '5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e'
var apiInstance = new Tinapi.LinksApi()
var createLinkRequest = new Tinapi.CreateLinkRequest() //
createLinkRequest.source = '$USER1_PHONE_NUMBER'
createLinkRequest.target = 'USER2_SIGNER'
createLinkRequest.type = 'TRUST'
apiInstance.createLink(createLinkRequest).then(
function (data) {
console.log('API called successfully. Returned data: ' + data)
},
function (error) {
console.error(error)
},
)
```
### Buscar transferencia en el Dashboard
Para consultar una transferencia, ve a la sección **Transferencias** en el Dashboard, donde encontrarás el listado completo de todas las transferencias realizadas.
Haz clic en **"detalles"** para ver la información detallada de una transferencia específica.
# Tipo 3 Aceptar o Rechazar
Source: https://transfiya.me/es/v1.104/generals/flows/type3-accept-reject
Aceptar o Rechazar una transacción
## Aceptar transferencia P2P (Tipo 3)
Para aceptar una transferencia P2P de tipo `REQUEST`, el banco debe utilizar el siguiente endpoint de la API de TIN: POST /v1/transfer/CUS/accept
El parámetro `{CUS}` (también conocido como `tx_ref`) se obtiene de la **lista de transferencias pendientes** que el usuario puede visualizar desde su canal bancario.
Es obligatorio enviar el **signer** (cuenta firmante del usuario) en el cuerpo de la petición.\
El cuerpo **no puede estar vacío**.
Una vez aceptada, se inicia el proceso de débito automático desde el usuario originador hacia el usuario solicitante.
```json theme={null}
curl -X POST -H "x-api-key: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" -d '{
"signer": {
"handle": "wabpqXPdBA19dB3h2QmVHoniRTnd52J4SX",
}
}' "https://ach-minka-stg.transferenciasinmediatas.com/v1/transfer/oXnhHqKaaDOYVlhYd/accept"
```
```json theme={null}
String cus = "oXnhHqKaaDOYVlhYd";
AcceptTransferRequest req =new AcceptTransferRequest();
SignerObject signer = new SignerObject();
signer.setHandle("wabpqXPdBA19dB3h2QmVHoniRTnd52J4SX");
req.setSigner(signer);
CreateTransferResponse createTransferResponse = sdkApiClient.acceptTransfer(req, cus);
System.out.println(createTransferResponse);
```
```json theme={null}
string cus = "oXnhHqKaaDOYVlhYd";
AcceptTransferRequest acceptTransReq = new AcceptTransferRequest();
acceptTransReq.Signer = new SignerObject();
acceptTransReq.Signer.Handle = "wabpqXPdBA19dB3h2QmVHoniRTnd52J4SX"
instance.AcceptP2Ptranfer(cus, acceptTransReq);
```
```json theme={null}
var transferApi = new Tinapi.TransferApi()
var cus = 'oXnhHqKaaDOYVlhYd'
var acceptReq = new Tinapi.AcceptTransferRequest()
acceptReq.handle = 'wabpqXPdBA19dB3h2QmVHoniRTnd52J4SX'
var opts = {
acceptTransferRequest: acceptReq,
}
transferApi.acceptP2Ptranfer(cus, opts).then(
function (data) {
console.log('API called successfully. Returned data: ' + data)
},
function (error) {
console.error(error)
},
)
```
### Rechazar una transferencia P2P
Para rechazar una transferencia P2P, el banco debe usar un **POST** al endpoint `/v1/transfer/{CUS}/reject` de la API de TIN.
El parámetro `tx_ref` (CUS) se obtiene de la lista de transferencias pendientes.
```json theme={null}
curl -X POST -H "x-api-key: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" -d '{
}' "https://ach-minka-stg.transferenciasinmediatas.com/v1/transfer/oXnhHqKaaDOYVlhYd/reject"
```
```json theme={null}
String cus = "oXnhHqKaaDOYVlhYd";
CreateTransferResponse createTransferResponse = sdkApiClient.rejectTransfer(null, cus);
System.out.println(createTransferResponse);
```
```json theme={null}
TransferApi transferApi = new TransferApi();
var cus = "oXnhHqKaaDOYVlhYd";
transferApi.RejectP2Ptranfer(cus);
```
```json theme={null}
var transferApi = new Tinapi.TransferApi()
var cus = 'oXnhHqKaaDOYVlhYd'
transferApi.rejectP2Ptranfer(cus).then(
function (data) {
console.log('API called successfully. Returned data: ' + data)
},
function (error) {
console.error(error)
},
)
```
# Tipo 3 - Solicitar Transferencia
Source: https://transfiya.me/es/v1.104/generals/flows/type3-request-transfer
## Crear transferencia P2P de tipo REQUEST
Para crear una nueva transferencia P2P tipo **REQUEST**, el banco debe utilizar el endpoint: POST /v1/transfer de la API de TIN. Este método encapsula todos los pasos necesarios para preparar y ejecutar una nueva solicitud de transferencia P2P.
En este flujo, **el usuario receptor es quien crea la transacción de tipo REQUEST**, mientras que **el usuario originador (quien dará el dinero)** tiene la posibilidad de aceptar o rechazar dicha transacción.
Una vez que la transacción es creada exitosamente, se envía un **SMS al usuario originador** con la instrucción de ingresar a cualquiera de los canales del banco para **aprobar o rechazar la solicitud de dinero**.
Para este tipo de transferencias **no existe una relación de confianza definida**.
En transferencias donde `type="REQUEST"`:
* El campo `target` representa el **signer (cuenta)** del usuario receptor.
* El campo `source` representa el **número de teléfono (wallet)** del usuario originador.
Esto es **lo opuesto** al tipo de transferencia `SEND`, donde `source` es el signer y `target` el wallet.
```json theme={null}
curl -X POST -H "x-api-key: 5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Content-Type: application/json" -d '{
"source": "$source_user_phone_number",
"target": "wtarget_user_bridge_address",
"symbol": "$tin",
"amount": "10.00",
"labels": {
"sourceChannel": "APP",
"type": "REQUEST",
"description": "Description of a transfer",
"transactionPurpose": "TRANSFER",
"numberOfTransactions": "1",
"deviceFingerprint": {
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"ipAddress": "190.242.46.190",
"country": "Colombia",
"city": "Bogotá",
"mobileDevice": "990000862471854",
"SIMCardId": "8991101200003204510",
"model": "Huawei Mate 20 Pro",
"operator": "Bharti Airtel Limited",
}
}
}' "https://ach-minka-stg.transferenciasinmediatas.com/v1/transfer"
```
```json theme={null}
CreateTransferRequest tinTranfer = new CreateTransferRequest();
tinTranfer.setSource("$source_user_phone_number");
tinTranfer.setTarget("wtarget_user_bridge_address");
tinTranfer.setAmount("10.00");
tinTranfer.setSymbol("$tin");
CreateTransferRequestLabels labels = new CreateTransferRequestLabels();
labels.setType("REQUEST");
labels.setDescription = "Description of a transfer";
labels.setSourceChannel = "APP";
labels.setTransactionPurpose = "TRANSFER";
labels.setNumberOfTransactions = "1";
DeviceFingerPrint deviceFingerPrint = new DeviceFingerPrint();
deviceFingerPrint.setCity("Bogotá");
deviceFingerPrint.setCountry("Colombia");
deviceFingerPrint.setHash("26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58");
deviceFingerPrint.setIpAddress("190.242.46.190");
deviceFingerPrint.setMobileDevice("990000862471854");
deviceFingerPrint.setSiMCardId("8991101200003204510");
deviceFingerPrint.setModel("Huawei Mate 20 Pro");
deviceFingerPrint.setOperator("Bharti Airtel Limited");
labels.setDeviceFingerPrint(deviceFingerPrint);
tinTranfer.setLabels(labels);
CreateTransferResponse tinTransfer = sdkApiClient.createTinTransfer(tinTranfer);
System.out.println(tinTransfer);
```
```json theme={null}
CreateTransferRequest createTransferRequest = new CreateTransferRequest();
createTransferRequest.Source = "$source_user_phone_number";
createTransferRequest.Target = "wtarget_user_bridge_address";
createTransferRequest.Amount = "10.00";
createTransferRequest.Symbol = "$tin";
CreateTransferRequestLabels labels = new CreateTransferRequestLabels();
labels.type = "REQUEST";
labels.description = "Description of a transfer";
labels.SourceChannel = "APP";
labels.TransactionPurpose = "TRANSFER";
labels.NumberOfTransactions = "1";
DeviceFingerPrint deviceFingerPrint = new DeviceFingerPrint();
deviceFingerPrint.City = "Bogotá";
deviceFingerPrint.Country = "Colombia";
deviceFingerPrint.Hash = "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58";
deviceFingerPrint.IpAddress = "190.242.46.190";
deviceFingerPrint.MobileDevice = "990000862471854";
deviceFingerPrint.SiMCardId = "8991101200003204510";
deviceFingerPrint.Model = "Huawei Mate 20 Pro";
deviceFingerPrint.Operator = "Bharti Airtel Limited";
labels.DeviceFingerPrint = deviceFingerPrint;
createTransferRequest.Labels = labels;
instance.Configuration.AddApiKey("xApiKey","5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e");
var response = instance.CreateTinTransfer(createTransferRequest);
```
```json theme={null}
const Tinapi = require('tin_api')
const defaultClient = Tinapi.ApiClient.instance
// Configure API key authorization: ApiKeyAuth
const ApiKeyAuth = defaultClient.authentications['ApiKeyAuth']
ApiKeyAuth.apiKey = '5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e'
const apiInstance = new Tinapi.TransferApi()
const createTransferRequest = new Tinapi.CreateTransferRequest() // CreateTransferRequest |
createTransferRequest.source = '$source_user_phone_number'
createTransferRequest.target = 'wtarget_user_bridge_address'
createTransferRequest.amount = '10.00'
createTransferRequest.symbol = '$tin'
createTransferRequest.Labels = {
type: 'REQUEST',
description: 'Description of a transfer',
transactionPurpose: 'TRANSFER',
numberOfTransactions: '1',
deviceFingerprint: {
hash: '26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58',
ipAddress: '190.242.46.190',
country: 'Colombia',
city: 'Bogota',
mobileDevice: '990000862471854',
SIMCardId: '8991101200003204510',
model: 'Huawei Mate 20 Pro',
operator: 'Bharti Airtel Limited',
},
}
apiInstance
.createTinTransfer(createTransferRequest)
.then(function (data) {
console.log('API called successfully. Returned data: ' + data)
})
.catch(function (error) {
console.error(error)
})
```
```json theme={null}
{
"action_id": "51bfcf60-314c-4b66-b7ff-8a0675918ee5",
"source": "$source_user_phone_number",
"target": "wtarget_user_bridge_address",
"symbol": "$tin",
"amount": "10.00",
"labels": {
"description": "Description of a transfer",
"domain": "tin",
"type": "REQUEST",
"sourceChannel": "APP",
"transactionPurpose": "TRANSFER",
"numberOfTransactions": "1",
"tx_ref": "CUS (Código Único de Seguimiento)",
"status": "PENDING",
"hash": "PENDING",
"created": "YYYY-MM-DDTHH:MM:SS-05:00",
"updated": "YYYY-MM-DDTHH:MM:SS-05:00"
"deviceFingerPrint": {
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"ipAddress": "190.242.46.190",
"country": "Colombia",
"city": "Bogotá",
"mobileDevice": "990000862471854",
"SIMCardId": "8991101200003204510",
"model": "Huawei Mate 20 Pro",
"operator": "Bharti Airtel Limited"
}
},
"snapshot": {
"source": {
"wallet": {
"handle": "$source_user_phone_number",
"signer": [
"wsource_user_bridge_address_1",
"wsource_user_bridge_address_2",
"wsource_user_bridge_address_3"
],
"labels": {
"type": "PERSON",
"created": "YYYY-MM-DDTHH:MM:SS-05:00"
}
},
"signer": {
"labels": {}
}
},
"target": {
"wallet": {
"labels": {
"channelSms": "target_user_phone_number",
"type": "PERSON",
"created": "YYYY-MM-DDTHH:MM:SS-05:00"
},
"signer": [
"wtarget_user_bridge_address_1",
"wtarget_user_bridge_address_2",
"wtarget_user_bridge_address_3"
],
"handle": "$target_user_phone_number"
},
"signer": {
"handle": "wtarget_user_bridge_address_1",
"labels": {
"bankAccountType": "TRAS",
"routerFormat": "ISO20022",
"proprietary": "CE",
"countryOfResidence": "AT",
"email": "ludwig.boltzmann@minka.io",
"sourceChannel": "WEB",
"bankBicfi": "7095",
"firstName": "Ludwig Eduard",
"mobile": "3120021844",
"createdBy": "EAGWCCSvcTKdR3AVOXWB",
"routerReference": "$bancorojo",
"bankName": "Banco Rojo",
"created": "2020-02-24T15:22:41-05:00",
"lastName": "Boltzmann",
"identification": "9876543210",
"bankAccountNumber": "12345678902"
}
}
},
"symbol": {
"wallet": {
"labels": {
"created": "YYYY-MM-DDTHH:MM:SS-05:00",
"type": "symbol"
},
"signer": [
"wsymbol_user_bridge_address"
],
"handle": "$tin",
"default": "wsymbol_user_bridge_address"
},
"signer": {
"handle": "wsymbol_user_bridge_address",
"labels": {
"createdBy": "SYMBOL_ID",
"created": "YYYY-MM-DDTHH:MM:SS.SSSZ"
}
}
}
},
"error": {
"code": 0,
"message": "Success"
}
}
```
## Dashboard - Transferencias
# Tipo 3 Listar transacciones
Source: https://transfiya.me/es/v1.104/generals/flows/type3-transaction-history
Listar transacciones pendientes e historicas
### Listar transferencias pendientes de tipo TYPE3
Obtiene una lista de transferencias pendientes en las que el teléfono del usuario es el receptor.
**GET** `/v1/transfer?labels.type="REQUEST"&source="$userPhone"&labels.status="PENDING"&sortBy=created&sort=desc`
```json theme={null}
ApiResponse response = transferApi.GetTransfersWithCustomQuery("source=$userPhone" + "&labels.type=REQUEST" + "&labels.status=PENDING" + "&sortBy=created" + "&sort=desc");
```
```json theme={null}
var xApiKey = '5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e' // String |
var Tinapi = require('tinapi_')
var defaultClient = Tinapi.ApiClient.instance
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth']
ApiKeyAuth.apiKey = xApiKey
const transferApi = new tinapi.TransferApi()
const customQuery =
'labels.type=REQUEST&source=$userPhone&labels.status=PENDING&sortBy=created&sort=desc'
transferApi
.getTransfers(customQuery)
.then((transfers) => {
console.log(transfers)
})
.catch(console.log)
```
```json theme={null}
Transfers transfers = sdkApiClient.getTransfersWithCustomQuery("?labels.type=REQUEST&source=$userPhone&labels.status=PENDING&sortBy=created&sort=desc");
System.out.println(transfers);
```
### Obtener historial de transferencias recibidas
**GET** `/v1/transfer?labels.type="REQUEST"&targetWallet="$userPhone"&labels.status="COMPLETED"&sortBy=created&sort=desc`
```json theme={null}
var xApiKey = '5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e' // String |
var Tinapi = require('tinapi_')
var defaultClient = Tinapi.ApiClient.instance
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth']
ApiKeyAuth.apiKey = xApiKey
var apiInstance = new Tinapi.ActionApi()
var type = 'REQUEST' // String |
var opts = {
targetWallet: '$userPhone', // String |
status: 'COMPLETED', // String |
}
apiInstance.getTransfers(type, opts).then(
function (data) {
console.log('API called successfully. Returned data: ' + data)
console.log(data)
},
function (error) {
console.error(error)
},
)
```
```json theme={null}
string type = "REQUEST";
string target = "$userPhone";
string source = null;
string status = "COMPLETED";
string xApiKey = "5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e";
instance.Configuration.AddApiKey("x-api-key", xApiKey);
var response = instance.GetTransfersWithCustomQuery(type, source, target, status);
Console.WriteLine(response.Entities.Count);
Console.WriteLine(response.Entities[0]);
```
```json theme={null}
Transfers transfers = sdkApiClient.getTransfersWithCustomQuery("?targetWallet=$userPhone&labels.type=REQUEST&labels.status=COMPLETED");
System.out.println(transfers);
```
### Obtener historial de transferencias enviadas
**GET** `/v1/transfer?labels.type="REQUEST"&source="$userPhone"&labels.status="COMPLETED"&sortBy=created&sort=desc`
```json theme={null}
var xApiKey = '5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e' // String |
var Tinapi = require('tin_api')
var defaultClient = Tinapi.ApiClient.instance
// Configure API key authorization: ApiKeyAuth
var ApiKeyAuth = defaultClient.authentications['ApiKeyAuth']
ApiKeyAuth.apiKey = xApiKey
var apiInstance = new Tinapi.ActionApi()
var type = 'REQUEST' // String |
var opts = {
source: '$userPhone', // String |
status: 'COMPLETED', // String |
}
apiInstance.getTransfers(type, opts).then(
function (data) {
console.log('API called successfully. Returned data: ' + data)
console.log(data)
},
function (error) {
console.error(error)
},
)
```
```json theme={null}
string type = "REQUEST";
string source = "$userPhone";
string target = null;
string status = "COMPLETED";
string xApiKey = "5b481fc2ae177010e197026ba5b51227c44243cd9a18e41be536566e";
instance.Configuration.AddApiKey("x-api-key", xApiKey);
var response = instance.GetTransfersWithCustomQuery(type, source, target, status);
Console.WriteLine(response.Entities.Count);
Console.WriteLine(response.Entities[0]);
```
```json theme={null}
Transfers transfers = sdkApiClient.getTransfersWithCustomQuery("?source=$userPhone&labels.type=REQUEST&labels.status=COMPLETED");
System.out.println(transfers);
```
# Cómo hacer autenticación
Source: https://transfiya.me/es/v1.104/generals/guides/how-to-authorize
Guia del proceso de autorización
TIN utiliza **API KEY** y el protocolo **OAuth 2.0** para facilitar la autorización.\
OAuth es un marco de autorización que permite a una aplicación cliente obtener acceso a recursos protegidos (como transferencias, enlaces, etc.).\
El acceso a la API de TIN puede otorgarse a una aplicación en nombre de un usuario o en nombre de la propia aplicación.
Esta sección cubre la autenticación **de aplicación**, que está diseñada para aplicaciones de servidor a servidor que consumen la API de TIN.
### Acceso a la nube de ACH TIN
Antes de poder comenzar a realizar solicitudes OAuth, necesitas obtener tus **credenciales de cliente**.\
Estas credenciales están disponibles en la sección **Integración** del Dashboard de TIN.
Primero, ACH debe crear una billetera (wallet) y un usuario administrador para la entidad/organización.\
Este usuario será el responsable de realizar los accesos iniciales al Dashboard de TIN.
### Credenciales y autenticación
La credencial de cliente es la **API\_KEY**.
Las credenciales OAuth 2.0 son **client\_id** y **client\_secret**, las cuales deben utilizarse para obtener un **access\_token** desde el endpoint de autenticación.
⚠️ Tus credenciales deben almacenarse de forma segura.
### Llamadas a la API de TIN
Para realizar llamadas a los endpoints de la API de TIN es necesario incluir la `API_KEY` y el `access_token` en el encabezado (**header**) de cada solicitud.
El token es válido por una hora. Una vez vencido, debes solicitar uno nuevo.
### Encabezados (Headers)
| Nombre | Valor |
| ------------- | ---------------------- |
| Authorization | Bearer *access\_token* |
| x-api-key | *API\_KEY* |
### Códigos de error
| Código | Mensaje | Descripción |
| ------ | --------- | ----------------------------------------------------- |
| 403 | Forbidden | El token ha expirado o las credenciales son inválidas |
# Cómo crear Rechazos Automáticos
Source: https://transfiya.me/es/v1.104/generals/guides/how-to-create-automatic-reject
Cualquier transacción será rechazada automáticamente si el usuario no la acepta a tiempo. Para gestionar esto, existe un **Cron Job** que se ejecuta cada minuto para revertir las transferencias desactualizadas que estén en estado regular, reversible y pendiente, marcándolas como **REJECTED**.
Las transferencias que quedan atascadas en un estado irreversible **no deben ser revertidas** automáticamente por el cron job, sino que deben ser marcadas como **ERROR** y dejadas para revisión manual.
⏱️ **El parámetro de tiempo es configurado por ACH en el Dashboard.**
El tiempo configurado se aplica a transacciones en estado **PENDING** y reversibles. Para aquellas que se encuentren en estado **INITIATED** o **ACCEPTED**, el cron job esperará **3 minutos** antes de marcarlas como **ERROR**.
### Escenarios a considerar
1. **Transferencia tipo SEND en estado PENDING**\
Será procesada por el cron job y marcada como **REJECTED**.\
Si ocurre algún error del lado del banco, se marcará como **ERROR**.
2. **Transferencia tipo SEND en estado INITIATED**\
Será procesada por el cron job y marcada como **ERROR**.
3. **Transferencia tipo SEND en estado ACCEPTED**\
Será procesada por el cron job y marcada como **ERROR**.
4. **Transferencia tipo REQUEST en estado PENDING**\
Será procesada por el cron job y marcada como **REJECTED**.
5. **Transferencia tipo REQUEST en estado ACCEPTED**\
Será procesada por el cron job y marcada como **ERROR**.
# Cómo crear claims
Source: https://transfiya.me/es/v1.104/generals/guides/how-to-create-claims
Guia del proceso de CLAIMS
Cuando el operador del banco originador crea un **Claim**, se genera una acción con tipo `CLAIM` a través del API. Esta acción contendrá los detalles del motivo por el cual fue creada dentro del objeto `labels.reason`.
Por ejemplo, si la transferencia tuvo un crédito doble o un valor incorrecto, el motivo específico será incluido en esa propiedad del `label`, lo que permite a los bancos destino validar y responder adecuadamente a la solicitud de devolución.
```json theme={null}
{
"action_id": "0bac12c0-53a4-4dd8-b284-41af1a8311ed",
"amount": "150000.00",
"source": "",
"target": "",
"symbol": "$tin",
"tx_ref": "",
"labels": {
"type": "CLAIM",
"reason": {
"code": "",
"description": ""
**}**,
"rejectDescription": "",
****"status": "",
"domain": "tin",
"hash": "",
"created": "",
"updated": ""
},
"snapshot": {
"source": {
"wallet": { ... },
"signer": { ... }
},
"target": {
"wallet": { ... },
"signer": { ... }
},
"symbol": {
"wallet": { ... },
"signer": { ... }
}
},
"error": {
"code": ,
"message": ""
}
}
```
## Aceptación y rechazo de Claims
### Aceptación
Una vez que el operador del banco destinatario acepta la acción de tipo `CLAIM`, el Dashboard invoca el endpoint:
POST /v1/action//accept
La API enviará la acción de tipo `CLAIM` al endpoint `/transfer` del banco destinatario para ser firmada. Según la respuesta del banco, pueden ocurrir dos casos:
**Proceso exitoso de firma:**
* El estado de la transferencia cambiará de `COMPLETED` a `REJECTED`.
* El estado de la acción cambiará a `COMPLETED`.
* El objeto `labels.reason` de la acción se guardará dentro del objeto de error de la transferencia.
* Se invocarán los endpoints `/status` tanto del banco originador como del banco destinatario.
**Proceso fallido de firma:**
* El error se guardará dentro del objeto de error de la acción `CLAIM`.
* El estado de la transferencia se mantendrá en `COMPLETED`.
* El estado de la acción cambiará a `ERROR`.
### Rechazo
Si el operador del banco destinatario rechaza la acción `CLAIM`, la entidad financiera debe especificar el motivo del rechazo. Este será guardado en `labels.rejectDescription`.
En este caso:
* El estado de la transferencia permanece en `COMPLETED`.
* La acción `CLAIM` cambia su estado a `REJECTED`.
* El endpoint `/status` **no es invocado**.
* El objeto de error tendrá la siguiente estructura:
```json theme={null}
{
"error": {
"code": 0,
"message": "Success"
}
}
```
Finalmente, el Dashboard llamará al endpoint: POST /v1/action/ para actualizar los campos `labels.status` y `labels.rejectDescription`.
# Cómo crear la conciliación
Source: https://transfiya.me/es/v1.104/generals/guides/how-to-create-reconciliation
Guia para generar la conciliación
Para apoyar los procesos operativos internos, los bancos deben integrar un método para consultar archivos de conciliación. Estos archivos son archivos de texto en formato estándar ACH y contienen un listado de transferencias para un período de tiempo determinado.
El banco puede programar la consulta de estos archivos según su estrategia interna de operación.
## Endpoint
Para recuperar un archivo de conciliación, el banco debe consumir el siguiente endpoint: GET /v1/conciliation?bankId=\[\$BANKBICFI]\&startDate=\[STARTDATE]\&endDate=\[ENDDATE]\&field=\[created | updated]
### Parámetros
* `bankId`: Código BankBicfi del banco.
* `startDate`: Fecha de inicio de los registros de transferencia que se desean recuperar.
* `endDate`: Fecha final de los registros de transferencia.
* `field`: Campo a usar como filtro: `created` o `updated` (valor por defecto: `created`).
La fecha más antigua que se puede utilizar para generar el archivo de conciliación es de **hasta 1 año atrás**.
Este proceso utiliza tecnología de streaming para recuperar los registros y producir el archivo. El tamaño del archivo dependerá de:
* Cantidad de registros.
* Lapso de tiempo definido.
* Velocidad de descarga disponible.
* Tiempo de espera interno máximo de la plataforma: **5 minutos**.
## Ejemplo real
Al generar el archivo desde el dashboard para un período de **1 año** con una conexión de **150 Mbps**, se obtuvo un archivo de más de **40,000 registros**, de aproximadamente **13 MB**, en menos de **1 minuto**.
Con la mejora continua de la plataforma, se espera que estos tiempos se reduzcan aún más en el futuro.
## Ejemplo de consulta
Consulta para generar archivo de conciliación del Banco Rojo (Bank BICFI: `1234`) para el período del **18/02/2019 al 19/02/2019**:
GET /v1/conciliation?bankId=1234\&startDate=2019-02-18\&endDate=2019-02-19\&field=created
## Vista previa del archivo de conciliación
### Módulo de conciliación en el Dashboard
Opcionalmente, puedes descargar el archivo de conciliación manualmente utilizando el Dashboard.
# Cómo crear llaves y firmas offline
Source: https://transfiya.me/es/v1.104/generals/guides/how-to-generate-keys-signing
Guia para generar las llaves y poder firmar las peticiones offline
Las entidades bancarias son responsables de almacenar y gestionar sus propios **Keepers**.
Los **Keepers** se utilizan para generar **Signers** y firmar **Actions** de forma offline.
Una vez firmado, el **Action** debe enviarse al núcleo de TIN Cloud utilizando el endpoint:
**POST /v1/action/:action\_id/sendit**
* Si el **Action** firmado es aceptado por TIN Cloud, recibirá `labels.status: COMPLETED` y un valor en `labels.hash`.
* Si es rechazado, el estado será `labels.status: REJECTED` y `labels.hash` tendrá el valor `none`.
**Recomendación:** Guarda localmente la relación entre Keeper, Signer, Wallet y la cuenta bancaria del usuario. Un esquema sugerido es:
`public`, `secret`, `signer`, `wallet`, `phone`, `bank account reference`
### Firmar Action offline
Los **Keepers** deben cargarse desde el sistema de gestión de llaves (KMS) antes de firmar un **Action**.
Para firmar un **Action**, necesitas su `action_id` y el **Keeper** correspondiente a `Action.source`.
💻 Código de ejemplo en Java
```code theme={null}
import java.security.MessageDigest;
import java.security.Signature;
import net.i2p.crypto.eddsa.EdDSAEngine;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.Utils;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
public class SignatureUtil {
public static String OfflineSigning(String claimsHash, String secretKey) {
try {
// Convert private key to EdDSAPrivateKey
EdDSANamedCurveSpec ed25519 = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
EdDSAPrivateKeySpec keySpec = new EdDSAPrivateKeySpec(Utils.hexToBytes(secretKey), ed25519);
EdDSAPrivateKey privateKey = new EdDSAPrivateKey(keySpec);
// Sign the hash
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
sgr.initSign(privateKey);
sgr.update(Utils.hexToBytes(claimsHash));
byte[] signature = sgr.sign();
// Convert signature to hex string
return Utils.bytesToHex(signature);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
```
```code theme={null}
package minka.crypto.dtos;
import java.security.KeyPair;
import net.i2p.crypto.eddsa.KeyPairGenerator;
import net.i2p.crypto.eddsa.EdDSAPublicKey;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.Utils;
public class KeeperDto {
private String publicKey;
private String secretKey;
private String scheme = "eddsa-ed25519";
public KeeperDto(String publicKey, String secretKey) {
this.publicKey = publicKey;
this.secretKey = secretKey;
}
public static KeeperDto GenerateKeys() {
KeyPairGenerator keyPairGenerator = new KeyPairGenerator();
KeyPair keyPair = keyPairGenerator.generateKeyPair();
EdDSAPublicKey publicKey = (EdDSAPublicKey) keyPair.getPublic();
EdDSAPrivateKey secretKey = (EdDSAPrivateKey) keyPair.getPrivate();
String publicKeyHexStr = Utils.bytesToHex(publicKey.getA().toByteArray());
String secretKeyHexStr = Utils.bytesToHex(secretKey.getSeed());
return new KeeperDto(publicKeyHexStr, secretKeyHexStr);
}
}
```
## Ejemplo C#\#
```code theme={null}
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Utilities.Encoders;
namespace Keeper {
public class SignatureDto
{
private List signatures;
public SignatureDto(HashDto hashDto, string address, string publicKey, string secretKey)
{
var decodedPrivateBytes = Hex.Decode(secretKey);
var ed25519PrivateKeyParameters = new Ed25519PrivateKeyParameters(decodedPrivateBytes, 0);
var ed25519Signer = new Ed25519Signer();
ed25519Signer.Init(true, ed25519PrivateKeyParameters);
byte[] msg = Hex.Decode(hashDto.Value);
ed25519Signer.BlockUpdate(msg, 0, msg.Length);
var signature = ed25519Signer.GenerateSignature();
var signatureHexString = Hex.ToHexString(signature);
List theSignatures = new List();
Signatures oneSignature = new Signatures();
oneSignature.Scheme = "eddsa-ed25519";
oneSignature.String = signatureHexString;
oneSignature.Signer = address;
oneSignature.Public = publicKey;
theSignatures.Add(oneSignature);
this.signatures = theSignatures;
}
public List Signatures
{
get => signatures;
set => signatures = value;
}
}
}
```
## Ejemplo Node JSON
```code theme={null}
const crypto = require('crypto')
const elliptic = require('elliptic')
const eddsa25519 = new elliptic.eddsa('ed25519')
const getClaims = () => {
const date = new Date()
return {
source: 'source-address',
symbol: 'symbol-address',
target: 'target-address',
amount: '1000',
domain: 'tin',
expiry: date.toISOString(),
}
}
function signIOU(claims, privateKey) {
let eddsaKeyPair = eddsa25519.keyFromSecret(privateKey)
let signature = eddsaKeyPair.sign(claims)
return signature.toHex()
}
```
# Cómo hacer una reversión
Source: https://transfiya.me/es/v1.104/generals/guides/how-to-reverse
Guia del proceso de reversiones en Transfiya
Un **flujo de reversión** es el conjunto de acciones necesarias para devolver el dinero al origen. Cuando ocurre un error en algún punto del flujo regular, se generan las acciones necesarias para revertir el movimiento de fondos. Al igual que las acciones regulares, estas acciones de reversión deben ser firmadas por las entidades financieras.
Actualmente existen **dos tipos de acciones** asociadas al flujo de reversión:
* **REJECT**: es la acción que permite devolver el dinero del usuario destino al usuario origen. Es la acción opuesta a la acción principal (SEND / REQUEST). Esta acción es creada por **TIN Cloud** y firmada por la entidad financiera que actuó como receptora en la transacción a través del endpoint `/action`.
* **REVERSE DOWNLOAD**: es la acción que devuelve el dinero del usuario origen al banco origen. Es la inversa de la acción **UPLOAD**. Tanto la creación como la firma dependen del endpoint `/credit` de la entidad financiera que actuó como origen.
Es importante destacar que cuando ocurre un error en el flujo regular, el **estado de la transferencia cambia a ERROR**, y la acción principal pasa a estado **REJECTED**, manteniéndose así hasta que la acción **REVERSE DOWNLOAD** sea firmada con éxito. En ese momento, la transferencia cambia su estado a **REJECTED**.
⚠️ **IMPORTANTE:** Si ocurre un error durante la ejecución del flujo de reversión, el estado de la transferencia permanecerá en **ERROR**.
***
### Acciones realizadas por el flujo de reversión
**Cuando inicia:**
* Cambia el estado de la transferencia a `ERROR`.
* Cambia el estado de la acción que falló a `ERROR` (la acción principal pasa a `REJECTED`).
**Si finaliza con éxito:**
* Cambia el estado de la transferencia a `REJECTED`.
* Llama al endpoint `/status`.
* Llama a **Motor de prevensión de fraude (341)**.
***
### Definiciones y Validaciones
Si ocurre un error durante el proceso de reversión, la transferencia pasará a estado `ERROR` y será gestionada por el equipo de soporte.
El objeto `error` de la transferencia se enviará al endpoint `/status` del banco (solo si la transferencia tiene estado final `REJECTED` o `COMPLETED`).
Para revertir una acción, se deben cumplir las siguientes condiciones:
* La acción debe tener un `hash`.
* El proceso de reversión para la acción **no debe haber sido iniciado previamente**.
Si el banco llama a `/continue` con una acción en error mientras el flujo de reversión ya ha comenzado, **la API ignorará la solicitud**.
***
### Comportamientos por tipo de error
* Si el endpoint `/debit` retorna un error pero la acción **UPLOAD** fue completada, se llamará al endpoint `/credit` del origen.
* Si el error ocurre después de completar la acción principal (**SEND** o **REQUEST**), se creará una acción **REJECT** y se llamará al endpoint `/credit` del origen.
* Si el error ocurre con una acción **DOWNLOAD** completada, se cambiará el estado de la transferencia a **ERROR**.
***
### Validaciones en la respuesta de los bancos
La respuesta de los endpoints `/debit`, `/transfer` y `/credit` del banco será validada. Si la respuesta no cumple con los requisitos, la transferencia permanecerá en el estado anterior y **no se generará flujo de reversión**. La transacción se detendrá en el punto donde el banco no respondió correctamente.
**Respuestas inválidas incluyen:**
* Objeto vacío
* Acción sin `action_id`
* Acción sin `labels.tx_ref`
* Acción sin `labels.type`
* Acción sin `labels.status`
* Acción sin objeto `error` (solo si la respuesta es un error)
* Incoherencia en `code` y `message` (por ejemplo, deben ser `"code": 0, "message": "Success"`)
***
### Impacto en el flujo
#### Flujo Asíncrono
* **/debit**: Sin efecto (el banco usa `/continue`).
* **/transfer**: Transferencia queda en `ACCEPTED` o `ERROR`, acción principal en `COMPLETED` o `PENDING`.
* **/credit**: Sin efecto (el banco usa `/continue`).
#### Flujo Síncrono
* **/debit**: Transferencia queda en `INITIATED`, acción **UPLOAD** en `COMPLETED` o `PENDING`.
* **/transfer**: Transferencia queda en `ACCEPTED` o `ERROR`, acción principal en `COMPLETED` o `PENDING`.
* **/credit**: Transferencia queda en `ACCEPTED` o `ERROR`, acción **DOWNLOAD** en `COMPLETED` o `PENDING`.
# Cómo Firmar Acciones
Source: https://transfiya.me/es/v1.104/generals/guides/untitled-page
**Firmado de Acciones:** El sistema de la entidad deberá realizar el firmado de las acciones (Upload, Download, SEND, SENDMOL, Withdraw y Claim) generando un hash y enviandolo al siguiente endpoint de Tranfiya **POST /v1/action/:action\_id/sendit**
**Ejemplo**: \\
```json theme={null}
{
"hash": {
"types": "sha256:sha256",
"steps": "stringify:data",
"value": "9f30b856fa06d1f65e9695dcb89302e9ad742cf044a88708a514af2befd2ecc4"
},
"data": {
"amount": "25000.00",
"domain": "tin",
"expiry": "2026-02-24T15:21:02.742Z",
"random": "c83c4326fe0a64dd40f9",
"source": "whPHgQnXAXSvk61KwpnNdhE2JuWD97Abqy",
"symbol": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"target": "wRRsRi4j2G15bwMuBqsYw5dpRywhECHVXL"
},
"meta": {
"signatures": [
{
"scheme": "eddsa-ed25519",
"signer": "whPHgQnXAXSvk61KwpnNdhE2JuWD97Abqy",
"public": "b8c7cb10858c4ef77f1cf53c0b94aa7ab5e749b4e8973b7a9770e46d766911cd",
"string": "fb38f001f82201b4430b8d0c3b180547109ebbffabf2eb2ce8a850fab3bf1fc0efc0487fc8dd2ece495fa597e152e5816f81891304813025a582e6788f7b020a"
}
]
}
}
```
| **Objeto** | **Campo** | **Descripción** | **Valor** |
| :-------------------- | :---------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------- | :------------------------- |
| **hash** | types | Algoritmo(s) usados para calcular el hash final del contenido. | "sha256:sha256" |
| steps | Método o procedimiento aplicado para preparar los datos antes del hash. | "stringify:data" | |
| value | Resultado del doble proceso de hashing aplicado al objeto data serializado en orden alfabetico. | string hexadecimal de 64 caracteres (SHA‑256 = 32 bytes). | |
| **data** | amount | Monto exacto de la operación expresado como texto decimal. | Obtener de (action.amount) |
| domain | Identificador del entorno o sistema donde se genera la firma. | "tin" | |
| expiry | Momento límite en que la firma deja de ser válida. | Hora actual + 1 minuto en formato ISO8601, ejemplo "2021-11-03T13:50:41.431Z" | |
| random | Nonce - valor único aleatorio usado para evitar reutilización de firmas. | string en hex o base64 | |
| source | Signer del origen que inicia la operación. | Signer de banco / usuario | |
| symbol | Signer del sistema Transfiya | Obtener de (action.snapshot.symbol.signer.handle) | |
| target | Signer del destino afectado por la operación. | Signer de banco / usuario | |
| **meta (signatures)** | scheme | Algoritmo criptográfico utilizado para firmar. | eddsa25519 - ecdsa25519 |
| signer | Signer del firmante que generó la firma. | Signer de banco / usuario | |
| public | Clave pública asociada al firmante para verificar la firma. | Llave publica del signer | |
| string | Firma digital generada a partir del hash final. | Firma digital | |
**Proceso de firma:**
* **Preparar la data**\
Arma el objeto data con los campos acordados (amount, domain, expiry, random, source, symbol, target).
* **Importante**: normaliza expiry a **UTC con Z** (ej. "2026-02-13T15:32:43.701Z").
* **Convertir la data a JSON canónico**\
Serializa la data a JSON **determinístico**:
* **Claves ordenadas alfabéticamente**.
* **Sin espacios extra** (separators (",", ":")).
* **Mismos tipos** (ej. amount como *string* si así lo usas).
* **Calcular hash.value (doble SHA‑256)**
* **Hash #1** = SHA256( UTF‑8(canonical\_json) ) → (hex).
* **Hash #2** = SHA256( bytes.fromhex(Hash #1) ) → (hex).\
El **Hash #2** es tu hash.value.
* **Firmar hash.value**
* Convierte hash.value (hex) a **bytes**.
* Firma **esos bytes** con **Ed25519 *prehash* (Ed25519ph)** usando tu **secretKey** (seed Ed25519 de 32 bytes).
* Obtén la firma (64 bytes) y conviértela a **HEX (128 caracteres)**.\
Ese **HEX** es lo que va en **meta.signatures\[0].string**.
* **Armar la firma en el body**\
Dentro de meta.signatures\[0]:
* scheme: "eddsa-ed25519"
* signer: data.source
* string: **firma HEX (128)**
* public: **clave pública RAW (32 bytes) en HEX (64)**, derivada de la **misma** secretKey
**Nota**: Es importante resaltar que las acciones se firman con las llaves de quien origina la petición (source)
**Generación de Kepers:**
Las keepers son un par de llaves (pública y privada) utilizadas para crear los signers dentro del servicio y firmar las distintas acciones durante el flujo; para crear las keepers se deberán tener en cuenta las siguientes condiciones dependiendo del lenguaje utilizado:
El sistema de la entidad debe generar un **par de llaves criptográficas** que se usan para garantizar la seguridad y autenticidad de la información
Este proceso produce dos llaves:
1. **Llave pública**
* Es la llave que **sí puede compartirse**
* Permite verificar que un mensaje o acción realmente proviene de quien dice enviarlo.
2. **Llave secreta**
* Debe **protegerse y mantenerse privada**.
* Es la que se utiliza para **firmar digitalmente** información.
* Funciona como “la firma personal” del sistema.
Ambas llaves se generan con estandares modernos de seguridad **Eddsa25519 - Ecdsa25519,** que es uno de los algoritmos más rápidos y seguros actualmente utilizados para firmas digitales.
Una vez generadas, las dos llaves se convierten a un formato de texto (una cadena de caracteres en formato hexadecimal) para que puedan almacenarse o transmitirse fácilmente dentro del sistema.
**Ejemplo generación de keepers en java**
```json theme={null}
import java.security.KeyPair;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.EdDSAPublicKey;
import net.i2p.crypto.eddsa.KeyPairGenerator;
import net.i2p.crypto.eddsa.Utils;
public class KeeperDto {
private String publicKey;
private String secretKey;
private String scheme = "eddsa-ed25519";
public KeeperDto() {
this.publicKey = "";
this.secretKey = "";
}
public KeeperDto(String publicKey, String secretKey) {
this.publicKey = publicKey;
this.secretKey = secretKey;
}
public static KeeperDto GenerateKeys() {
KeyPairGenerator keyPairGenerator = new KeyPairGenerator();
KeyPair keyPair = keyPairGenerator.generateKeyPair();
EdDSAPublicKey publicKey = (EdDSAPublicKey) keyPair.getPublic();
EdDSAPrivateKey secretKey = (EdDSAPrivateKey) keyPair.getPrivate();
String publicKeyHexStr = Utils.bytesToHex(publicKey.getA().toByteArray());
String secretKeyHexStr = Utils.bytesToHex(secretKey.getSeed());
return new KeeperDto(publicKeyHexStr, secretKeyHexStr);
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public String getPublicKey() {
return this.publicKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getSecretKey() {
return this.secretKey;
}
public String getScheme() {
return this.scheme;
}
}
```
# Como configurar nuevo signer de banco
Source: https://transfiya.me/es/v1.104/generals/guides/untitled-page-1
Guia configurar nuevo signer de banco
Para la creación del Signer tipo TROUPE a continuación, se relacionan algunas indicaciones que pueden seguir como guía:
**Configuración según el estándar**
El estándar define una configuración simple y específica:
* *Keeper* con esquema ecdsa-ed25519.
* Labels limitados a identificación bancaria y enrutamiento:
* bankAccountNumber
* bankName
* bankBicfi
* routerReference
* description
En efecto, cualquier atributo adicional queda fuera de la definición esperada.
## Ejemplo Request
```text theme={null}
{
"keeper": [
{
"scheme": "ecdsa-ed25519"
}
],
"labels": {
"description": "SignerBank",
"bankAccountNumber": "{{cuenta}}",
"bankName": "{{bankName}}",
"bankBicfi": "{{bankBicfi}}",
"routerReference": "{{walletBank}}"
}
}
```
Con base en lo anterior, se debe crear el signer tipo \*\*TROUPE \*\*y asociarlo al wallet **\$Banco** aplicando estrictamente la configuración estándar descrita.
## Request:
```json theme={null}
PUT https://ach-minka-stg.transferenciasinmediatas.com/v1/wallet/{{walletUser}}
```
## Body:
```json theme={null}
{
"signer": [ "{{newsigneruser}}" ],
"default": "{{newsigneruser}}"
}
```
# API Acción
Source: https://transfiya.me/es/v1.104/generals/participant-apis/action-endpoint
⚠️ **IMPORTANTE:**\
Los objetos de error mostrados en los diagramas son ilustrativos. Pueden variar según la causa del error. El banco debe enviar el objeto de error correspondiente a la causa específica del fallo.
TIN Cloud enviará acciones al banco a través de este endpoint para que sean firmadas.
```mermaid theme={null}
sequenceDiagram
autonumber
participant minka as Minka
participant bridge as Bank Bridge
Note over minka,bridge: 1. Flujo exitoso
minka->>bridge: POST /action (mainAction en body)
bridge->>bridge: Verifica acción (tipo y validación)
bridge->>bridge: Crear IOU desde mainAction
bridge->>bridge: Cargar llaves de firma
bridge->>bridge: Firmar IOU
bridge->>minka: POST /v1/action/{mainActionId}/sendit
minka-->>bridge: HTTP 200 OK (acción firmada con hash)
bridge-->>minka: POST /action (status COMPLETED)
minka-->>bridge: HTTP 200 OK
Note over minka,bridge: Fin de flujo exitoso
alt Error - rechazo o error en Core
bridge-->>minka: HTTP 400
minka-->>bridge: mainAction con status ERROR y objeto error
end
alt Error - fallo en sendit
bridge->>minka: POST /v1/action/{mainActionId}/sendit
minka-->>bridge: HTTP 400 (error)
bridge-->>minka: POST /action (status ERROR)
end
```
## Solicitud de Minka en una transferencia tipo SEND
```json theme={null}
{
"source":"wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"target":"$573123224353",
"amount":"200.00",
"symbol":"$tin",
"labels":{
"hash":"PENDING",
"type":"SEND",
"domain":"tin",
"flowId":"buDwBxynDK4hvumBG",
"status":"PENDING",
"tx_ref":"buDwBxynDK4hvumBG",
"created":"2022-08-04T10:46:51-05:00",
"updated":"2022-08-04T10:47:59-05:00",
"description":"DEV - REQUEST trx 01",
"sourceChannel":"APP",
"deviceFingerPrint":{
"city":"Bogotá",
"hash":"26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model":"Huawei Mate 20 Pro",
"country":"Colombia",
"operator":"Bharti Airtel Limited",
"SIMCardId":"8991101200003204510",
"ipAddress":"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice":"990000862471854"
}
},
"snapshot":{
"source":{
"signer":{
"handle":"wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels":{
"type":"PERSON",
"email":"Florida_Sawayn@yahoo.com",
"mobile":"573123224352",
"created":"2022-06-10T09:50:25-05:00",
"bankName":"bancosanti",
"lastName":"Sanford",
"bankBicfi":"9574",
"createdBy":"A16iU3t38Tygr70uO1qf",
"firstName":"Cale",
"description":"Investor",
"proprietary":"CC",
"identification":"1231231",
"bankAccountType":"SVGS",
"routerReference":"$bancosanti",
"bankAccountNumber":"689",
"countryOfResidence":"CO"
}
},
"wallet":{
"handle":"$573123224352",
"labels":{
"type":"PERSON",
"created":"2022-06-10T09:54:42-05:00",
"updated":"2022-06-10T09:54:42-05:00",
"channelSms":"573123224352"
},
"signer":[
"wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"
]
}
},
"symbol":{
"signer":{
"handle":"wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels":{
"created":"2018-10-19T20:23:22.041Z",
"createdBy":"ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet":{
"handle":"$tin",
"labels":{
"type":"SYMBOL",
"created":"2018-10-19T20:22:48.350Z",
"updated":"1970-01-01T15:38:20-05:00",
"createdBy":"ZhrQA3vcm17h2RRO4LrJ"
},
"signer":[
"wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
],
"default":"wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target":{
"signer":{
"handle":"wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"labels":{
"firstName":"Otha",
"lastName":"Lehner",
"identification":"123456",
"bankBicfi":"9574",
"bankName":"bancosanti",
"proprietary":"CC"
}
},
"wallet":{
"handle":"$573123224353",
"labels":{
"type":"PERSON",
"created":"2022-06-10T09:57:21-05:00",
"updated":"2022-06-10T11:19:10-05:00"
},
"signer":[
"wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"wVXQDT59RzXdPZD4CyK6z8FWebZmyZ9aHm"
]
}
}
},
"action_id":"bbffb8db-466c-403f-8c60-0bbd06261a6e",
"error":{
"code":0,
"message":"Success"
},
"id":"bbffb8db-466c-403f-8c60-0bbd06261a6e"
}
```
El endpoint debe cargar la información local desde la base de datos usando `action.snapshot.source.signer.handle` y la cuenta bancaria relacionada.
Con base en la información cargada, el banco debe determinar si acepta o rechaza la transferencia.
Dependiendo del tipo de acción (`action.labels.type`), el endpoint debe cargar el Keeper correspondiente:
* **SEND**: Cargar el Keeper del firmante del usuario origen.
* **REQUEST**: Cargar el Keeper del firmante del usuario origen.
* **REJECT**: Cargar el Keeper del firmante del usuario origen.
* **WITHDRAW**: Cargar el Keeper de la cuenta de liquidación del banco.
* **UPLOAD**: Cargar el Keeper de la cuenta de liquidación del banco. Esta acción se envía para firma en caso de transferencias fallidas en proceso. Es importante que el banco registre esta llamada, pero no debe ejecutar ningún movimiento en su core bancario. Solo debe firmar la acción con el Keeper correspondiente.
* **DOWNLOAD**: Cargar el Keeper del firmante del usuario origen. Al igual que UPLOAD, se usa para firmar transferencias fallidas. No se deben ejecutar movimientos en el core bancario, solo firmar la acción.
* **CLAIM**: Cargar el Keeper de la cuenta de liquidación del banco. Este tipo de acción se firma en caso de reclamos para devolver fondos luego de que la transferencia esté en estado COMPLETED. Este proceso es gestionado entre los bancos y se administra a través del Dashboard.
Si se recibe un error como respuesta a esta llamada, se puede reintentar de forma segura usando exactamente la misma solicitud.
El banco firma la acción con las llaves mencionadas anteriormente y envía el IOU firmado a `POST /v1/action/{action_id}/sendit`.
### Crear Claims
```json theme={null}
{
"source": action.snapshot.source.signer.handle, //Bank Signer Handle
"target": action.snapshot.target.signer.handle, //User Signer Handle
"symbol": action.snapshot.symbol.signer.handle, //Symbol Signer Handle
"amount": action.amount,
"domain": "tin",
"expiry": "${expirationTime}" // currentTime + 1 minute in ISO8601 format, example "2021-11-03T13:50:41.431Z"
}
```
### Cargar las llaves (dependiendo del caso descrito en el paso 3)
```json theme={null}
[
{
"public": "PUBLIC_KEY",
"secret": "SECRET_KEY",
"scheme": "KEEPER_SCHEME",
"signer": "SIGNER_HANDLE"
}
]
```
## Firmar el IOU
```json theme={null}
{
"hash": {
"types": "sha256:sha256",
"steps": "stringify:data",
"value": "31abac5167fbb603d9300e9dfaf94b721efdc12c0728a615f9717b944a3fa779"
},
"data": {
"source": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"target": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"symbol": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"amount": "200.00",
"domain": "tin",
"expiry": "2022-08-04T16:36:56.631Z",
"random": "d50860eb2209de5cfbfd"
},
"meta": {
"signatures": [
{
"scheme": "ecdsa-ed25519",
"signer": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"public": "0420b4b9dc4b022b5251aacee333f496f9c7fe6555824be9ecf96bc9adbcd5e7a813e7e03d63542a240ed4d58f0f079fe36c2a73e9c9a9068606f1a8f5aba9f243",
"string": "304402200fd7a0cef6e4ab4936aa2d15be933a5aab82cd556bf98fd5090e779819cb1afe02200e327d0b3ce44291c23bff4387ee9cd8cdb7308fa0453f4bac007d0c621c1a13",
"linker": "sha256:ripemd160"
}
]
}
}
```
## Enviar IOU firmado a /v1/action//sendit y recibir acción con estado COMPLETED
```json theme={null}
{
"source": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"target": "$573123224353",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "82de7c0b8b34c7ca6c52547161b2629b1c1e6bdef402999ad60266e6760e4d24",
"type": "SEND",
"domain": "tin",
"flowId": "buDwBxynDK4hvumBG",
"status": "COMPLETED",
"tx_ref": "buDwBxynDK4hvumBG",
"created": "2022-08-04T10:46:51-05:00",
"updated": "2022-08-04T10:47:59-05:00",
"description": "DEV - REQUEST trx 01",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
},
"iouHash": "31abac5167fbb603d9300e9dfaf94b721efdc12c0728a615f9717b944a3fa779"
},
"error": {
"code": 0,
"message": "Success"
}
}
```
Respuesta 400 - ERROR
```json theme={null}
{
"action_id": "ee991f91-e118-4ecf-9fa7-fadd36a15c0e",
"source": "wsource_user_bridge_address",
"target": "$target_user_phone_number",
"symbol": "$tin",
"amount": "AMOUNT",
"labels": {
"tx_ref": "CUS",
"type": "SEND",
"status": "ERROR",
...
},
"error": {
"code": 3XX,
"message": "BANK_ERROR_MESSAGE"
}
}
```
# Configuración General
Source: https://transfiya.me/es/v1.104/generals/participant-apis/configuration-endpoints
Cada participante debe registrar las URLs de sus endpoints utilizando el Dashboard de TransfiYa. Estos endpoints permiten que TIN Cloud se comunique correctamente con los sistemas del banco durante todo el ciclo de vida de la transferencia.
Desde el Dashboard se deben configurar las URLs de los siguientes 4 endpoints junto con sus métodos de autenticación.
## Métodos de Autenticación
TransfiYa permite que cada banco configure uno o más métodos de autenticación para proteger sus endpoints de API REST. A continuación se explican los métodos compatibles y su configuración.
La nube de TIN requiere un token válido en cada llamada. Actualmente no existe un mecanismo de reintento automático en caso de error al obtener el token, por lo tanto, cualquier error activa el flujo de reversión.
### Método: `NONE`
No se utiliza ningún mecanismo de autenticación. Este es el comportamiento por defecto.
* `routerAuthMethod` debe configurarse como `NONE`.
```json theme={null}
"routerAuthMethod": "NONE"
```
***
### Método: `API_KEY`
Permite que el banco configure una clave de API como mecanismo de autenticación.
* El valor de la clave debe incluirse en el header `x-api-key`.
* `routerAuthMethod` debe ser `API_KEY`.
* En `routerAuthParams` se define el campo `x-api-key` con su valor.
```json theme={null}
"routerAuthMethod": "API_KEY",
"routerAuthParams": {
"x-api-key": "API_KEY_VALUE"
}
```
***
### Método: `OAUTH2.0`
Permite autenticación vía OAuth 2.0. Soporta dos flujos:
#### Flujo: `client_credentials`
* Requiere el `tokenUrl`, `grantType`, `clientId`, `clientSecret` y `scope`.
* El `grantType` debe ser `client_credentials`.
```json theme={null}
"routerAuthMethod": "OAUTH2.0",
"routerAuthParams": {
"tokenUrl": "https://www.bankdomain.com/oauth/token",
"grantType": "client_credentials",
"clientId": "CLIENT_ID",
"clientSecret": "CLIENT_SECRET",
"scope": "SCOPE"
}
```
#### Flujo: `password`
* Requiere el `tokenUrl`, `grantType`, `username`, `password` y `scope`.
* El `grantType` debe ser `password`.
```json theme={null}
"routerAuthMethod": "OAUTH2.0",
"routerAuthParams": {
"tokenUrl": "https://www.bankdomain.com/oauth/token",
"grantType": "password",
"username": "USERNAME",
"password": "PASSWORD",
"scope": "SCOPE"
}
```
Una vez generado el token, se incluye en el cuerpo de las solicitudes realizadas al banco junto con las credenciales.
***
### Autenticación con Múltiples Métodos
Es posible combinar mecanismos de autenticación.
* En `routerAuthMethod` se listan los métodos separados por `+`, por ejemplo: `OAUTH2.0+API_KEY`.
* En `routerAuthParams` se deben incluir los parámetros correspondientes a cada método.
***
```json theme={null}
"routerAuthMethod": "OAUTH2.0+API_KEY",
"routerAuthParams": {
"tokenUrl": "https://www.bankdomain.com/oauth/token",
"grantType": "client_credentials",
"clientId": "CLIENT_ID",
"clientSecret": "CLIENT_SECRET",
"scope": "SCOPE",
"x-api-key": "API_KEY_VALUE"
}
```
### Integración con IBM API Connect
Si el banco utiliza IBM API Connect, es necesario añadir el campo adicional `apiConnect: true` en `routerAuthParams`.
* Esto indica a TIN Cloud que debe aplicar configuraciones específicas para integrarse correctamente con IBM API Connect.
```json theme={null}
"routerAuthMethod": "OAUTH2.0+API_KEY",
"routerAuthParams": {
"tokenUrl": "https://www.bankdomain.com/oauth/token",
"grantType": "client_credentials",
"clientId": "CLIENT_ID",
"clientSecret": "CLIENT_SECRET",
"scope": "SCOPE",
"apiConnect": true
"x-api-key": "API_KEY_VALUE"
}
```
# API Credito
Source: https://transfiya.me/es/v1.104/generals/participant-apis/credit-endpoint
Este endpoint ejecuta la descarga (download) en el sistema de TIN Cloud y acredita los fondos en el núcleo bancario (`core bancario`) de la entidad financiera.
**IMPORTANTE:** Para evitar el riesgo de procesar créditos duplicados, es indispensable que el banco valide si la operación de crédito **ya ha sido procesada** para esta transferencia.
Esta verificación puede implementarse consultando si existe una acción de tipo `DOWNLOAD` con el ID correspondiente (CUS) en la base de datos del banco.
**IMPORTANTE:** Los objetos de error mostrados en los diagramas son **ilustrativos**. Pueden variar según la causa del error.
El banco debe construir y enviar el objeto de error correspondiente a la causa real del fallo.
```mermaid theme={null}
sequenceDiagram
autonumber
participant tfy as TIN Cloud
participant bridge as Bank Bridge
participant core as Bank Core
Note over tfy,core: 1. Successful flow
tfy->>bridge: POST /credit (mainAction)
bridge->>bridge: Create DOWNLOAD action (POST /v1/actions)
bridge-->>tfy: HTTP 200 (DOWNLOAD created)
tfy-->>bridge: HTTP 200 OK
bridge->>bridge: Load target signer data
bridge->>core: Process credit in bank core
core-->>bridge: Return tx_id (coreTxId)
bridge->>bridge: Update DOWNLOAD action (PUT /v1/actions/:id)
bridge-->>tfy: HTTP 200 OK
bridge->>bridge: Create IOU
bridge->>bridge: Sign IOU
bridge->>tfy: POST /v1/actions/:id/sendit
tfy-->>bridge: HTTP 200 OK
bridge->>tfy: POST /transfer/:tx_ref/continue
Note over tfy,bridge: END Success Flow
alt Error - action creation fails
bridge-->>tfy: HTTP 400 (Validation error)
tfy-->>bridge: Return unchanged /credit
end
alt Error - core responds with ERROR
bridge-->>tfy: HTTP 200 OK
bridge->>bridge: Update action to ERROR
bridge->>tfy: POST /continue (status: ERROR)
end
alt Error - IOU send fails
bridge->>tfy: POST /sendit (fails)
tfy-->>bridge: HTTP 400
bridge->>tfy: POST /continue (status: ERROR)
end
```
## Casos de crédito
En este caso, el banco acredita la cuenta del usuario **destino** como parte de un flujo exitoso `SEND` o `REQUEST`. Este paso representa el tercero en el flujo `UPLOAD → SEND → DOWNLOAD` (o `DEBIT → SEND → CREDIT`).
Aquí, el banco acredita nuevamente la cuenta del **usuario origen** como parte de un flujo fallido de `SEND` o `REQUEST`. Es decir, el usuario original recupera el dinero como parte del proceso de reversión (`REJECT`).
## Pasos para procesar el crédito
Crear la acción con los siguientes valores:
```json theme={null}
{
"source": "Action.target",
"target": "bank_limit_account",
"amount": "Action.amount"
}
```
Usar la información de `Action.snapshot.target.signer.handle` y recuperar los datos de la cuenta bancaria localmente.
Analizar `Action.labels.type` para determinar si se trata de un crédito normal por `SEND`, `REQUEST` o una reversión por `REJECT`.
Si se decide rechazar, devolver la acción con `status: "REJECT"`. Si se acepta, retornar con `status: "PENDING"`.
Cargar el firmante relacionado con el campo `Action.snapshot.target.signer.handle`.
Actualizar `labels` de la acción con información necesaria como `tx_ref`, `description`, `domain`, entre otros.
Firmar la acción usando el Keeper del firmante.
Enviar la acción con estado `COMPLETED` al endpoint de TIN Cloud para continuar el flujo.
## Continuar procesamiento
⚠️ IMPORTANTE: La referencia de la transacción en el sistema bancario debe ser guardada en labels.tx\_id. Esta referencia será usada en el proceso de conciliación y debe ser única por cada acción DOWNLOAD.
💡 NOTA: La llamada al endpoint /v1/transfer/:tx\_ref/continue debe ejecutarse antes de 8 minutos después de la aceptación de la transferencia. Si no se hace, el estado de la transferencia se actualizará automáticamente a ERROR.
## Flujo Exitoso
TIN Cloud calls `/credit` bank endpoint.
```json theme={null}
{
"source": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"target": "$573123224353",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "0e2dd63b3132df7e6f5224983c0beb47ab5fa1e97c40f9d1960d8cfe6e856cda",
"type": "SEND",
"domain": "tin",
"flowId": "buDwBxynDK4hvumBG",
"status": "COMPLETED",
"tx_ref": "buDwBxynDK4hvumBG",
"created": "2022-08-04T10:46:51-05:00",
"iouHash": "0c50763b8627e796dd7680cbca5fdeeb8e3cfa0d847d1cc1dcbcfa3e85caec64",
"updated": "2022-08-04T10:48:01-05:00",
"description": "DEV - REQUEST trx 01",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"firstName": "Cale",
"lastName": "Sanford",
"identification": "1231231",
"bankBicfi": "9574",
"bankName": "bancosanti",
"proprietary": "CC"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"labels": {
"type": "PERSON",
"email": "Noemi_Ruecker18@yahoo.com",
"mobile": "573123224353",
"bankName": "bancosanti",
"lastName": "Lehner",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Otha",
"description": "Global",
"proprietary": "CC",
"identification": "123456",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "971",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224353",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:57:21-05:00",
"updated": "2022-06-10T11:19:10-05:00",
"channelSms": "573123224353"
},
"signer": [
"wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"wVXQDT59RzXdPZD4CyK6z8FWebZmyZ9aHm"
]
}
}
},
"action_id": "bbffb8db-466c-403f-8c60-0bbd06261a6e",
"error": {
"code": 0,
"message": "Success"
},
"id": "bbffb8db-466c-403f-8c60-0bbd06261a6e"
}
```
The Bank creates the action `DOWNLOAD` by making a `POST` request to `/v1/action`.
```json theme={null}
{
"source": mainAction.snapshot.target.signer.handle,
"target": bankKey.signer
"symbol": mainAction.symbol,
"amount": mainAction.amount,
"labels": {
"type": "DOWNLOAD",
"deviceFingerPrint": mainAction.labels.deviceFingerPrint,
"domain": mainAction.labels.domain,
"tx_ref": mainAction.labels.tx_ref
}
}
```
El endpoint del banco devuelve a TIN Cloud la acción `DOWNLOAD` con el estado `PENDING` en el cuerpo de la respuesta.\
La respuesta debe incluir un objeto `error` con código `0` y el mensaje `"success"`.
```json theme={null}
{
"action_id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278",
"source": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"type": "DOWNLOAD",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
},
"domain": "tin",
"tx_ref": "buDwBxynDK4hvumBG",
"description": "",
"status": "PENDING",
"hash": "PENDING",
"created": "2022-08-04T10:48:03-05:00",
"updated": "2022-08-04T10:48:03-05:00"
},
"snapshot": {
"source": {
"wallet": {
"handle": "$573123224353",
"labels": {
"updated": "2022-06-10T11:19:10-05:00",
"type": "PERSON",
"channelSms": "573123224353",
"created": "2022-06-10T09:57:21-05:00"
},
"signer": [
"wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"wVXQDT59RzXdPZD4CyK6z8FWebZmyZ9aHm"
]
},
"signer": {
"labels": {
"type": "PERSON",
"bankAccountNumber": "971",
"bankBicfi": "9574",
"bankName": "bancosanti",
"lastName": "Lehner",
"countryOfResidence": "CO",
"created": "2022-06-10T09:57:02-05:00",
"identification": "123456",
"mobile": "573123224353",
"email": "Noemi_Ruecker18@yahoo.com",
"routerReference": "$bancosanti",
"firstName": "Otha",
"bankAccountType": "SVGS",
"proprietary": "CC",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Global"
},
"handle": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v"
}
},
"target": {
"wallet": {
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"handle": "$bancosanti",
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"url": "http://bancosanti.com",
"limitAlert": "5000000",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"bankName": "bancosanti",
"bankBicfi": "9574",
"routerAuthParams": {},
"createdBy": "A16iU3t38Tygr70uO1qf",
"type": "TROUPE",
"domain": "tin",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"created": "2022-06-09T14:55:38-05:00",
"entityType": "Bancos",
"updated": "2022-08-04T07:03:45-05:00"
}
},
"signer": {
"labels": {
"bankAccountNumber": "160101",
"bankBicfi": "9574",
"routerReference": "$bancosanti",
"created": "2022-06-10T10:46:35-05:00",
"createdBy": "A16iU3t38Tygr70uO1qf",
"bankName": "bancosanti",
"description": "Bank",
"type": "TROUPE"
},
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
},
"symbol": {
"wallet": {
"handle": "$tin",
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:22:48.350Z",
"type": "SYMBOL",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"]
},
"signer": {
"labels": {
"createdBy": "ZhrQA3vcm17h2RRO4LrJ",
"created": "2018-10-19T20:23:22.041Z"
},
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
}
},
"error": {
"code": 0,
"message": "Success"
}
}
```
El banco procesa la operación de crédito en su Core bancario.\
El sistema bancario responde con una referencia de la transacción que debe almacenarse en el campo `labels.tx_id` de la acción `DOWNLOAD`.
Esta referencia será utilizada posteriormente en los procesos de conciliación y debe identificar de forma clara y única la transacción en el banco asociada a esta acción.
El banco debe actualizar la acción `DOWNLOAD` utilizando la referencia proporcionada, realizando una llamada `PUT` a `/v1/action/{downloadAction_id}`.
```json theme={null}
{
"labels": {
"tx_id": "BANKING_CORE_TX_ID"
}
}
```
```json theme={null}
{
"source": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "DOWNLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "buDwBxynDK4hvumBG",
"created": "2022-08-04T10:48:03-05:00",
"updated": "2022-08-04T10:48:03-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
},
"tx_id": 0.4979154374821342
},
"snapshot": {
"source": {
"signer": {
"handle": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"labels": {
"type": "PERSON",
"email": "Noemi_Ruecker18@yahoo.com",
"mobile": "573123224353",
"created": "2022-06-10T09:57:02-05:00",
"bankName": "bancosanti",
"lastName": "Lehner",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Otha",
"description": "Global",
"proprietary": "CC",
"identification": "123456",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "971",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224353",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:57:21-05:00",
"updated": "2022-06-10T11:19:10-05:00",
"channelSms": "573123224353"
},
"signer": [
"wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"wVXQDT59RzXdPZD4CyK6z8FWebZmyZ9aHm"
]
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
}
},
"action_id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278",
"error": {
"code": 0,
"message": "Success"
},
"id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278"
}
```
El banco debe firmar la acción `DOWNLOAD` utilizando las llaves de la cuenta del usuario (es decir, las llaves del firmante `source`).\
Luego, debe enviar el IOU firmado a través de una llamada `POST` a `/v1/action/{downloadAction_id}/sendit`.\
Al hacerlo correctamente, recibirá la acción `DOWNLOAD` con estado `COMPLETED` y un `hash` de transacción en la etiqueta `labels.hash`.
Los pasos detallados para completar esta operación son:
1. **Crear el objeto Claims (IOU)**\
Utiliza los campos de la acción `DOWNLOAD` para construir el objeto con `source`, `target`, `amount`, `symbol`, `domain`, y `expiry`.
```json theme={null}
{
"source": downloadAction.snapshot.source.signer.handle, //Target user signer handle from MAINACTION (Same as source from DOWNLOAD action)
"target": downloadAction.snapshot.target.signer.handle, //Bank Signer Handle
"symbol": downloadAction.snapshot.symbol.signer.handle, //Symbol Signer Handle
"amount": downloadAction.amount,
"domain": "tin",
"expiry": "${expirationTime}" // currentTime + 1 minute in ISO8601 format, example "2021-11-03T13:50:41.431Z"
}
```
2. **Cargar las llaves del firmante**\
Carga las llaves públicas y privadas del firmante correspondiente (cuenta de usuario).
```json theme={null}
keys = [
{
"public": "TARGET_USER_PUBLIC_KEY",
"secret": "TARGET_USER_SECRET_KEY",
"scheme": "TARGET_USER_KEEPER_SCHEME",
"signer": "TARGET_USER_SIGNER_HANDLE"
}
]
```
3. **Firmar el IOU**\
Aplica la firma criptográfica sobre el `hash` del objeto `Claims`, generando una estructura con la metadata de la firma.
```json theme={null}
{
"hash": {
"types": "sha256:sha256",
"steps": "stringify:data",
"value": "cacb220e5efe342b0a82f3e932fd3eb22d8d153de210736b80050e4fc2b488ab"
},
"data": {
"source": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"symbol": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"amount": "200.00",
"domain": "tin",
"expiry": "2022-08-04T15:49:03.328Z",
"random": "226bf3dd2033ff6ae837"
},
"meta": {
"signatures": [
{
"scheme": "ecdsa-ed25519",
"signer": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"public": "040644265c15370ddc3e73f86699bbe0e221bec50ff06862787408c63aa835306278acccce5b4e6765018aee748cd7682e7100b915590ee074138d4ec60a2e0fd5",
"string": "3044022002d97125f106bf60c652152d19387ec4f503e6e8710214d37993dbe9571a8098022003890339168fde030100402cda929883ca7ba815a971cf4ad7cce48c128e8ac9",
"linker": "sha256:ripemd160"
}
]
}
}
```
4. **Enviar el IOU firmado**\
Realiza la llamada `POST /v1/action/{downloadAction_id}/sendit` con el contenido firmado.
```json theme={null}
{
"source": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "320224cb6dd4b8a656baea948222c1263c1dd49f7151f4304880fe3226728579",
"type": "DOWNLOAD",
"tx_id": 0.4979154374821342,
"domain": "tin",
"status": "COMPLETED",
"tx_ref": "buDwBxynDK4hvumBG",
"created": "2022-08-04T10:48:03-05:00",
"updated": "2022-08-04T10:48:03-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
},
"iouHash": "cacb220e5efe342b0a82f3e932fd3eb22d8d153de210736b80050e4fc2b488ab"
},
"snapshot": {
"source": {
"signer": {
"handle": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"labels": {
"type": "PERSON",
"email": "Noemi_Ruecker18@yahoo.com",
"mobile": "573123224353",
"created": "2022-06-10T09:57:02-05:00",
"bankName": "bancosanti",
"lastName": "Lehner",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Otha",
"description": "Global",
"proprietary": "CC",
"identification": "123456",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "971",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224353",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:57:21-05:00",
"updated": "2022-06-10T11:19:10-05:00",
"channelSms": "573123224353"
},
"signer": [
"wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"wVXQDT59RzXdPZD4CyK6z8FWebZmyZ9aHm"
]
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
}
},
"action_id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278",
"error": {
"code": 0,
"message": "Success"
},
"id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278"
}
```
Una vez enviada y validada la firma correctamente, TransfiYa devolverá la acción firmada con estado `COMPLETED` y el `hash` correspondiente.
El banco debe llamar al endpoint `/v1/transfer/{mainAction_id}/continue` o `/v1/transfer/{tx_ref}/continue` (ambos son válidos) utilizando como cuerpo del mensaje la acción `DOWNLOAD` firmada previamente en el paso anterior.
Esta acción `DOWNLOAD` debe tener:
* `status` con valor `COMPLETED`
* el `hash` firmado en el campo `labels.hash`
Esta llamada sirve para notificar a TIN Cloud que la transferencia fue acreditada correctamente y que el flujo puede continuar su procesamiento.
✅ La respuesta esperada por parte del banco debe incluir el objeto `error` con:
```json theme={null}
{
"source": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "320224cb6dd4b8a656baea948222c1263c1dd49f7151f4304880fe3226728579",
"type": "DOWNLOAD",
"tx_id": 0.4979154374821342,
"domain": "tin",
"status": "COMPLETED",
"tx_ref": "buDwBxynDK4hvumBG",
"created": "2022-08-04T10:48:03-05:00",
"updated": "2022-08-04T10:48:03-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
},
"iouHash": "cacb220e5efe342b0a82f3e932fd3eb22d8d153de210736b80050e4fc2b488ab"
},
"snapshot": {
"source": {
"signer": {
"handle": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"labels": {
"type": "PERSON",
"email": "Noemi_Ruecker18@yahoo.com",
"mobile": "573123224353",
"created": "2022-06-10T09:57:02-05:00",
"bankName": "bancosanti",
"lastName": "Lehner",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Otha",
"description": "Global",
"proprietary": "CC",
"identification": "123456",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "971",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224353",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:57:21-05:00",
"updated": "2022-06-10T11:19:10-05:00",
"channelSms": "573123224353"
},
"signer": [
"wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"wVXQDT59RzXdPZD4CyK6z8FWebZmyZ9aHm"
]
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
}
},
"action_id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278",
"error": {
"code": 0,
"message": "Success"
},
"id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278"
}
```
Una vez realizada esta llamada correctamente, la operación queda oficialmente registrada y completada en el sistema.
TIN Cloud llama al endpoint `/credit` del banco para iniciar el proceso de acreditación de fondos.
El banco crea una acción de tipo `DOWNLOAD` basada en la información de la transferencia principal.
El banco responde a TIN Cloud con la acción `DOWNLOAD` en el cuerpo, con estado `PENDING` y un objeto `error` con código `0` y mensaje `Success`.
El banco intenta acreditar los fondos en su sistema Core, pero ocurre un error durante el procesamiento.
El banco debe invocar el endpoint `/v1/transfer/{tx_ref}/continue` para continuar el flujo, incluyendo:
* El `action_id` de la acción principal (`SEND` o `REQUEST`)
* La acción `DOWNLOAD` con el estado `ERROR` en `labels.status`
* Un objeto `error` con el `code` y `message` que describen la causa del error
> ⚠️ Nota: Esta llamada es obligatoria cuando el proceso en el Core retorna un error. Permite que TIN Cloud actualice el estado de la transferencia de manera adecuada.
## Ejemplo de respuesta de Error
```json theme={null}
{
"action_id": "DOWNLOAD action_id",
"source": "wsource_signer_user",
"target": "wsigner_bank",
"symbol": "$tin",
"amount": "AMOUNT",
"labels": {
"tx_ref": "As8BVbC2kDa62P1DL",
"type": "DOWNLOAD",
"status": "ERROR"
},
"error": {
"code": "described below",
"message": "described below"
}
}
```
**Código:** El código de error debe estar basado en la tabla de códigos de error definida en la documentación técnica del servicio. En caso exitoso, debe enviarse el código `0`.
**Mensaje:** El mensaje de error debe corresponder al código utilizado, también basado en la tabla de errores. En caso exitoso, debe enviarse el mensaje `"Success"`.
**Conclusión:**\
El banco realiza una llamada al endpoint `/continue` enviando una acción de tipo `UPLOAD` o `DOWNLOAD` con estado `COMPLETED` o `ERROR`. A partir de esta llamada, TIN Cloud puede determinar cómo continuar el flujo de la transferencia. Las posibles rutas son:
* Continuar con el proceso (flujo exitoso)
* Dejar la transferencia en estado `ERROR`
* Revertir la transferencia (flujo de reversa)
# API Debito
Source: https://transfiya.me/es/v1.104/generals/participant-apis/debit-endpoint
# Endpoint `/debit`
Este endpoint es invocado por TransfiYa para iniciar el procesamiento de una transferencia. Su propósito es ejecutar una acción de tipo `UPLOAD` en la nube de TIN y realizar el débito correspondiente en el núcleo bancario.
⚠️ **IMPORTANTE:** Para evitar el riesgo de ejecutar un doble débito, es fundamental que el banco verifique si la operación de débito ya fue procesada para esa transferencia. Esta verificación puede implementarse validando si una acción de tipo `UPLOAD` con el mismo identificador (CUS) ya existe en la base de datos del banco.
⚠️ **IMPORTANTE:** Los objetos de error mostrados en los diagramas son ilustrativos. El contenido específico puede variar según la causa del error. El banco debe enviar el objeto de error correspondiente a la causa real del fallo.
```mermaid theme={null}
sequenceDiagram
autonumber
participant tfy as TransfiYa
participant bridge as Bank Bridge
participant core as Bank Core
%% Flujo exitoso
tfy->>bridge: POST /debit (mainAction)
bridge->>bridge: Crear acción UPLOAD
bridge-->>tfy: HTTP 200 OK
tfy-->>bridge: HTTP 200 OK
bridge->>bridge: Validar firmante y datos
bridge->>core: Debitar cuenta bancaria
core-->>bridge: tx_id
bridge->>bridge: Actualizar acción con tx_id
bridge-->>tfy: HTTP 200 OK
bridge->>bridge: Crear y firmar IOU
bridge->>tfy: POST /sendit (IOU)
tfy-->>bridge: HTTP 200 OK
bridge->>tfy: POST /continue
note over tfy,bridge: Fin del flujo exitoso
%% Flujo de error 1 - creación de acción UPLOAD falla
alt Error: creación UPLOAD falla
bridge-->>tfy: HTTP 400 Validation error
tfy-->>bridge: Retornar /debit sin cambios
end
%% Flujo de error 2 - débito rechazado en core
alt Error: core rechaza débito
core-->>bridge: error de negocio
bridge->>bridge: Marcar acción como ERROR
bridge->>tfy: POST /continue con error
end
%% Flujo de error 3 - fallo en /sendit
alt Error: falla en envío de IOU
bridge->>tfy: POST /sendit (IOU)
tfy-->>bridge: HTTP 400
bridge->>tfy: POST /continue con error
end
```
## 🧭 Pasos generales del flujo
El banco crea una acción con tipo `UPLOAD` llamando a `POST /v1/action`, utilizando como destino el firmante fuente (`mainAction.snapshot.source.signer.handle`) de la transferencia.
Cargar los datos relacionados al firmante fuente desde la base de datos local del banco para validar su existencia, estado y cuenta asociada.
Con base en la validación previa, el banco decide si se puede continuar con el débito o si debe rechazarse. El estado de la acción será `PENDING` o `REJECT`.
Identificar y preparar el `keeper` del firmante del banco (signer de liquidación) para poder firmar la operación.
El banco actualiza la acción con el campo `labels.tx_id` que corresponde al identificador de transacción interna del core bancario (`PUT /v1/action/:id`).
El banco firma el hash de la acción utilizando su llave privada y genera el objeto IOU (prueba criptográfica del movimiento).
El IOU firmado se envía a `POST /v1/action/:id/sendit`. TransfiYa valida la firma y marca la acción como `COMPLETED`.
Para continuar el flujo, el banco debe invocar `POST /v1/transfer/:tx_ref/continue` con la acción `UPLOAD` firmada y finalizada.
***
## CONTINUAR PROCESAMIENTO
Después de procesar la operación de débito en el núcleo bancario, el banco **debe invocar el endpoint** `/v1/transfer/:tx_ref/continue` para continuar con el flujo de la transferencia.
La referencia de la transacción en el sistema bancario **debe ser almacenada en `labels.tx_id`**. Esta información se utilizará en el proceso de conciliación y será la referencia única para identificar la transacción en el banco en relación con la acción `UPLOAD` en TransfiYa.
La llamada al endpoint `/v1/transfer/:tx_ref/continue` **debe ejecutarse dentro de los 8 minutos** siguientes a la inicialización de la transferencia. De lo contrario, el estado de la transferencia cambiará automáticamente a `ERROR`.
## Flujo Exitoso
Se inicia la operación de débito. El payload enviado por TIN contiene la información de la acción principal que se desea ejecutar.
```json theme={null}
{
"source": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"target": "$573148514092",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "SEND",
"domain": "tin",
"flowId": "Ss84Vb42kGa6gPV57",
"status": "PENDING",
"tx_ref": "Ss84Vb42kGa6gPV57",
"created": "2022-08-04T07:08:41-05:00",
"updated": "2022-08-04T07:08:41-05:00",
"description": "DEV - REQUEST trx 01",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"type": "PERSON",
"email": "Florida_Sawayn@yahoo.com",
"mobile": "573123224352",
"created": "2022-06-10T09:50:25-05:00",
"bankName": "bancosanti",
"lastName": "Sanford",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Cale",
"description": "Investor",
"proprietary": "CC",
"identification": "1231231",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "689",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00",
"channelSms": "573123224352"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"labels": {}
},
"wallet": {
"handle": "$573148514092",
"labels": {
"type": "PERSON",
"created": "2022-06-15T11:17:19-05:00",
"updated": "2022-06-15T11:17:19-05:00"
},
"signer": ["wgsAjQJDaehqmZouBHLaiN7DTZBPN5TyFT"]
}
}
},
"action_id": "5c2d931d-67c6-41b3-ae08-1f42a3d094a0",
"error": {
"code": 0,
"message": "Success"
},
"id": "5c2d931d-67c6-41b3-ae08-1f42a3d094a0"
}
```
Se utiliza la información contenida en `mainAction` para crear la acción. El estado inicial será `PENDING` y se devolverá un error code `0` si fue exitosa.
```json theme={null}
{
"source": bankKey.signer,//Bank Signer
"target": mainAction.snapshot.source.signer.handle,
"symbol": mainAction.symbol,
"amount": mainAction.amount,
"labels": {
"type": "UPLOAD",
"deviceFingerPrint": mainAction.labels.deviceFingerPrint,
"domain": mainAction.labels.domain,
"tx_ref": mainAction.labels.tx_ref
}
}
```
```json theme={null}
{
"source": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"target": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "UPLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "Ss84Vb42kGa6gPV57",
"created": "2022-08-04T07:05:26-05:00",
"updated": "2022-08-04T07:05:26-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"type": "PERSON",
"email": "Florida_Sawayn@yahoo.com",
"mobile": "573123224352",
"created": "2022-06-10T09:50:25-05:00",
"bankName": "bancosanti",
"lastName": "Sanford",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Cale",
"description": "Investor",
"proprietary": "CC",
"identification": "1231231",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "689",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00",
"channelSms": "573123224352"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
}
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb",
"error": {
"code": 0,
"message": "Success"
}
}
```
La operación se ejecuta en el core, y si es exitosa, se obtiene una referencia única (tx\_id) que será almacenada en la etiqueta `labels.tx_id`.
```json theme={null}
{
"labels": {
"tx_id": "BANKING_CORE_TX_ID"
}
}
```
```json theme={null}
{
"source": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"target": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "PENDING",
"type": "UPLOAD",
"domain": "tin",
"status": "PENDING",
"tx_ref": "Ss84Vb42kGa6gPV57",
"created": "2022-08-04T07:05:26-05:00",
"updated": "2022-08-04T07:05:26-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
},
"tx_id": 3
},
"snapshot": {
"source": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"type": "PERSON",
"email": "Florida_Sawayn@yahoo.com",
"mobile": "573123224352",
"created": "2022-06-10T09:50:25-05:00",
"bankName": "bancosanti",
"lastName": "Sanford",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Cale",
"description": "Investor",
"proprietary": "CC",
"identification": "1231231",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "689",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00",
"channelSms": "573123224352"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
}
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb",
"error": {
"code": 0,
"message": "Success"
},
"id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb"
}
```
El banco firma la acción UPLOAD utilizando las claves asociadas al firmante de origen, es decir, las claves de la cuenta límite del banco, y envía el pagaré firmado (IOU) a través de la llamada POST /v1/action//sendit.
```json theme={null}
{
"source": uploadAction.snapshot.source.signer.handle, //Bank Signer Handle
"target": uploadAction.snapshot.target.signer.handle, //User Signer Handle
"symbol": uploadAction.snapshot.symbol.signer.handle, //Symbol Signer Handle
"amount": uploadAction.amount,
"domain": "tin",
"expiry": "${expirationTime}" // currentTime + 1 minute in ISO8601 format, example "2021-11-03T13:50:41.431Z"
}
```
```json theme={null}
keys = [
{
"public": "BANK_PUBLIC_KEY",
"secret": "BANK_SECRET_KEY",
"scheme": "BANK_KEEPER_SCHEME",
"signer": "BANK_SIGNER_HANDLE"
}
]
```
```json theme={null}
{
"source": uploadAction.snapshot.source.signer.handle, //Bank Signer Handle
"target": uploadAction.snapshot.target.signer.handle, //User Signer Handle
"symbol": uploadAction.snapshot.symbol.signer.handle, //Symbol Signer Handle
"amount": uploadAction.amount,
"domain": "tin",
"expiry": "${expirationTime}" // currentTime + 1 minute in ISO8601 format, example "2021-11-03T13:50:41.431Z"
}
```
```json theme={null}
{
"hash": {
"types": "sha256:sha256",
"steps": "stringify:data",
"value": "263b8cebe62473ad9bb6ca6a92db7e5c8b16492b359515375ae8bf05094c3a14"
},
"data": {
"source": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr", //Bank Signer
"target": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U", //User signer
"symbol": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"amount": "200.00",
"domain": "tin",
"expiry": "2022-08-04T14:15:04.189Z",
"random": "7f19c57edb362726da0c"
},
"meta": {
"signatures": [
{
"scheme": "ecdsa-ed25519",
"signer": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr", //Bank Signer
"public": "046a23ccc4585f6105a199ec5202d4019d589a3370b52a783268016751e2db9281371fe2cc28901e24ece5d47b29ed0b7d741d17dd8221b9735bf922dc40a621b1", //Bank signer public key
"string": "3043021f17472d781f6873203671439fc1277b085971f38928da9165ab4f386117966302200c518cfef98841aa353eb0832a87eca44929df7d2d475c70203effca27ca6241",
"linker": "sha256:ripemd160"
}
]
}
}
```
Envía el pagaré firmado (IOU), como se explicó en el paso anterior, mediante POST /v1/action//sendit y recibe la acción UPLOAD firmada con estado COMPLETED y el hash de la transacción en el campo labels.
```json theme={null}
{
"source": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"target": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "3ca7af8dcccaed3f7f1821456eaece8746310b566687401ae11c0b22624874a9",
"type": "UPLOAD",
"tx_id": 3,
"domain": "tin",
"status": "COMPLETED",
"tx_ref": "Ss84Vb42kGa6gPV57",
"created": "2022-08-04T07:05:26-05:00",
"updated": "2022-08-04T07:05:27-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
},
"iouHash": "9e68de4bf2095ca0328252e6cb66fe957ac0b62ecde0f74b8ddc6314717c07a1"
},
"snapshot": {
"source": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"type": "PERSON",
"email": "Florida_Sawayn@yahoo.com",
"mobile": "573123224352",
"created": "2022-06-10T09:50:25-05:00",
"bankName": "bancosanti",
"lastName": "Sanford",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Cale",
"description": "Investor",
"proprietary": "CC",
"identification": "1231231",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "689",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00",
"channelSms": "573123224352"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
}
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb",
"error": {
"code": 0,
"message": "Success"
},
"id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb"
}
```
El banco puede invocar el endpoint continue utilizando cualquiera de las siguientes opciones:
POST /v1/transfer//continue o POST /v1/transfer//continue.
Esta llamada debe hacerse desde la acción de tipo SEND/REQUEST (denominada mainAction en el paso 1), usando como cuerpo (body) la acción UPLOAD firmada recibida en el paso anterior (con estado COMPLETED y el valor de hash).
La respuesta al TIN Cloud debe incluir el objeto error con code: 0 y message: "Success".
```json theme={null}
{
"source": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"target": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "3ca7af8dcccaed3f7f1821456eaece8746310b566687401ae11c0b22624874a9",
"type": "UPLOAD",
"tx_id": 3,
"domain": "tin",
"status": "COMPLETED",
"tx_ref": "Ss84Vb42kGa6gPV57",
"created": "2022-08-04T07:05:26-05:00",
"updated": "2022-08-04T07:05:27-05:00",
"description": "",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
},
"iouHash": "9e68de4bf2095ca0328252e6cb66fe957ac0b62ecde0f74b8ddc6314717c07a1"
},
"snapshot": {
"source": {
"signer": {
"handle": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
"labels": {
"type": "TROUPE",
"created": "2022-06-10T10:46:35-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"description": "Bank",
"routerReference": "$bancosanti",
"bankAccountNumber": "160101"
}
},
"wallet": {
"handle": "$bancosanti",
"labels": {
"url": "http://bancosanti.com",
"type": "TROUPE",
"domain": "tin",
"created": "2022-06-09T14:55:38-05:00",
"updated": "2022-08-04T07:03:45-05:00",
"bankName": "bancosanti",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"entityType": "Bancos",
"limitAlert": "5000000",
"routerAction": "https://3ad0-186-170-222-190.ngrok.io/action",
"routerStatus": "https://3ad0-186-170-222-190.ngrok.io/status",
"routerUpload": "https://3ad0-186-170-222-190.ngrok.io/debit",
"routerDownload": "https://3ad0-186-170-222-190.ngrok.io/credit",
"routerAuthMethod": "NONE",
"routerAuthParams": {}
},
"signer": [
"wcyq8otjHN789tVTMQ4Xx7Dyk7GB9FUsUj",
"wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
],
"default": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr"
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"type": "PERSON",
"email": "Florida_Sawayn@yahoo.com",
"mobile": "573123224352",
"created": "2022-06-10T09:50:25-05:00",
"bankName": "bancosanti",
"lastName": "Sanford",
"bankBicfi": "9574",
"createdBy": "A16iU3t38Tygr70uO1qf",
"firstName": "Cale",
"description": "Investor",
"proprietary": "CC",
"identification": "1231231",
"bankAccountType": "SVGS",
"routerReference": "$bancosanti",
"bankAccountNumber": "689",
"countryOfResidence": "CO"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00",
"channelSms": "573123224352"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
}
},
"action_id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb",
"error": {
"code": 0,
"message": "Success"
},
"id": "5954ac04-b4db-4c6f-86f6-43df30f6bacb"
}
```
## Flujo de Error
TransfiYa realiza una llamada HTTP `POST /debit` al endpoint configurado por el banco.
El banco genera una acción de tipo `UPLOAD` en su sistema, basada en los datos recibidos en el `mainAction`.
El endpoint del banco responde a TIN Cloud con la acción `UPLOAD` en estado `PENDING` dentro del cuerpo de la respuesta.
La respuesta **debe contener** un objeto `error` con `code: 0` y `message: "Success"`.
El banco intenta realizar el débito en su sistema central. En este caso, el Core responde con un **ERROR**.
Ante un fallo en el Core, el banco **debe** invocar el endpoint `/v1/transfer/{tx_ref}/continue` con los parámetros indicados más abajo.
En caso de error, la acción enviada debe tener el estado `ERROR` dentro de `labels.status`, así como un objeto `error` que incluya `code` y `message`.
Además, **es obligatorio** incluir el `action_id` de la acción principal `SEND/REQUEST` al invocar el endpoint `continue`.
### Ejemplo de cuerpo - Error
```json theme={null}
{
"action_id": "UPLOAD action_id",
"source": "wsigner_bank",
"target": "wsource_signer_user",
"symbol": "$tin",
"amount": "AMOUNT",
"labels": {
"tx_ref": "XsC3VbB2kGa6gPS51",
"type": "UPLOAD",
"status": "ERROR"
},
"error": {
"code": "described below",
"message": "described below"
}
}
```
**Código:** el campo `code` debe basarse en la tabla de códigos de error incluida en la documentación técnica del servicio. En caso exitoso, debe enviarse `0`.
**Mensaje:** el campo `message` debe describir la causa del error según la tabla mencionada. Para una respuesta exitosa, se debe usar `"Success"`.
## Conclusión
Una vez completado el proceso de débito (ya sea exitoso o con error), el banco debe llamar al endpoint `/v1/transfer/{tx_ref}/continue` utilizando la acción `UPLOAD` o `DOWNLOAD`, con estado `COMPLETED` o `ERROR`. A partir de este punto, TIN Cloud puede continuar con el flujo.
Este paso es obligatorio para que TransfiYa pueda determinar el resultado final de la transferencia.
Las posibilidades a partir del uso del endpoint `continue` son:
* ✅ Continuar con el procesamiento normal (flujo exitoso)
* ⚠️ Finalizar la transferencia con estado `ERROR`
* 🔁 Iniciar un flujo de reversa de fondos
# Introduccion APIs
Source: https://transfiya.me/es/v1.104/generals/participant-apis/intro-apis
Introducción a la sección de los apis que debe integrar los participantes
# Endpoints de API del Banco
💡 **IMPORTANTE:** El banco puede elegir cualquier convención de nombres para definir sus endpoints. Se sugiere usar `/v1/debit`, `/v1/credit`, `/v1/transfer` y `/v1/status`, pero no es obligatorio.
## `/v1/debit`
Ejecuta una acción de tipo `UPLOAD` en la nube de TIN y realiza el débito en el core bancario.
## `/v1/credit`
Ejecuta una acción de tipo `DOWNLOAD` en la nube de TIN y realiza el crédito en el core bancario.
## `/v1/action`
Firma la transferencia del lado del banco.
## `/v1/status`
Canal de notificación para informar el estado de la transferencia.
***
## Motivos de Rechazo o Error
En caso de que una transferencia sea rechazada por el banco, se debe incluir un código de error en la respuesta.
| Código | Descripción | Tipo Original | Tipo Actual |
| ------ | --------------------------------------------------- | ------------- | ----------- |
| 300 | Tiempo de espera excedido | Error | Rechazo |
| 301 | Fuente rechazó la transacción | Rechazo | Rechazo |
| 302 | Destino rechazó la transferencia | Rechazo | Rechazo |
| 303 | Datos de acceso inválidos en el banco | Rechazo | Rechazo |
| 304 | Información de la transferencia inválida | Rechazo | Rechazo |
| 305 | Usuario abandonó la transacción en el banco | Error | Rechazo |
| 306 | Cuenta embargada | Rechazo | Rechazo |
| 307 | Cuenta inactiva | Rechazo | Rechazo |
| 308 | Cuenta cancelada | Rechazo | Rechazo |
| 309 | Cuenta no existe | Rechazo | Rechazo |
| 310 | Cuenta no habilitada | Rechazo | Rechazo |
| 311 | Cuenta no asignada | Rechazo | Rechazo |
| 312 | Cuenta saldada | Rechazo | Rechazo |
| 313 | Usuario excede el límite transaccional autorizado | Rechazo | Rechazo |
| 314 | Banco no disponible | Rechazo | Rechazo |
| 315 | Fondos insuficientes | Rechazo | Rechazo |
| 316 | Inconsistencia en los datos de la transacción | Rechazo | Rechazo |
| 317 | Banco no confirma estado de la transacción | Error | Rechazo |
| 318 | Transacción no registrada por el banco | Error | Rechazo |
| 319 | Transferencia marcada como fraude | Rechazo | Rechazo |
| 320 | Usuario no tiene habilitados pagos TIN | Error | Rechazo |
| 321 | Estado de la transacción ha cambiado | Error | Rechazo |
| 322 | Transacción rechazada por antifraude | Rechazo | Rechazo |
| 323 | Navegador del usuario no compatible con TIN | Error | Rechazo |
| 324 | Usuario inactivo en TIN (timeout) | Error | Rechazo |
| 325 | Banco no acepta la inicialización de la transacción | Error | Rechazo |
| 329 | Límite de transacción excedido por el usuario | Rechazo | Rechazo |
| 330 | No se puede conectar con el banco | Error | Rechazo |
| 331 | Plazo de transacción vencido | Error | Rechazo |
| 332 | Error no definido del banco | Rechazo | Rechazo |
| 333 | Doble abono | Reclamación | Rechazo |
| 334 | Se abonó un valor diferente | Reclamación | Rechazo |
| 335 | Se abonó a un usuario diferente | Reclamación | Rechazo |
| 336 | Crédito no autorizado | Reclamación | Rechazo |
| 337 | Transacción no autorizada | Reclamación | Rechazo |
# API Status
Source: https://transfiya.me/es/v1.104/generals/participant-apis/status-endpoint
Los objetos de error mostrados en los diagramas son ilustrativos. Pueden variar dependiendo de la causa del error. El banco **debe enviar** el objeto `error` con la información correspondiente a la causa real del fallo.
## Endpoint `/status`
Este endpoint funciona como **canal de notificación**. TransfiYa lo utiliza para enviar una acción (`action`) como confirmación de aceptación o rechazo de la transferencia por parte del destinatario.
El banco puede implementar lógica personalizada para procesar estas notificaciones según su arquitectura o necesidades operativas.
```mermaid theme={null}
sequenceDiagram
participant tin as TIN-ACH
participant status as END-POINT STATUS
tin ->> status: Envía action transferencia
status ->> status: Valida datos transferencia
status ->> status: Toma estado final
status ->> status: Actualiza estado final y cierra transferencia
```
```json theme={null}
{
"source": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"target": "$573123224353",
"amount": "200.00",
"symbol": "$tin",
"labels": {
"hash": "51e8c19c57e846d7dc5665203665f5202df549bed703fe63ad7511c44606843d",
"type": "SEND",
"domain": "tin",
"flowId": "BeK495NIBA4j7x48z",
"status": "COMPLETED",
"tx_ref": "BeK495NIBA4j7x48z",
"created": "2022-08-04T11:57:50-05:00",
"iouHash": "cca34be82af60bf6aa262cf86249d97e07367bc1b367f5416659b4a0f9e321e4",
"updated": "2022-08-04T11:58:10-05:00",
"description": "DEV - REQUEST trx 01",
"sourceChannel": "APP",
"deviceFingerPrint": {
"city": "Bogotá",
"hash": "26fff5af6441f8e15a71e8d62c361714484b1b308c99e8eb68ca85e2a7e0dc58",
"model": "Huawei Mate 20 Pro",
"country": "Colombia",
"operator": "Bharti Airtel Limited",
"SIMCardId": "8991101200003204510",
"ipAddress": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"mobileDevice": "990000862471854"
}
},
"snapshot": {
"source": {
"signer": {
"handle": "wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U",
"labels": {
"firstName": "Cale",
"lastName": "Sanford",
"identification": "1231231",
"bankBicfi": "9574",
"bankName": "bancosanti",
"proprietary": "CC"
}
},
"wallet": {
"handle": "$573123224352",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:54:42-05:00",
"updated": "2022-06-10T09:54:42-05:00"
},
"signer": ["wLd9MEASjQQTYywoXnDNwTRpgwiDfyHj6U"]
}
},
"symbol": {
"signer": {
"handle": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d",
"labels": {
"created": "2018-10-19T20:23:22.041Z",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
}
},
"wallet": {
"handle": "$tin",
"labels": {
"type": "SYMBOL",
"created": "2018-10-19T20:22:48.350Z",
"updated": "1970-01-01T15:38:20-05:00",
"createdBy": "ZhrQA3vcm17h2RRO4LrJ"
},
"signer": ["wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"],
"default": "wMxKCAzsQBiUURDU3xD3xuSbVo1S9jmf3d"
}
},
"target": {
"signer": {
"handle": "wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"labels": {
"firstName": "Otha",
"lastName": "Lehner",
"identification": "123456",
"bankBicfi": "9574",
"bankName": "bancosanti",
"proprietary": "CC"
}
},
"wallet": {
"handle": "$573123224353",
"labels": {
"type": "PERSON",
"created": "2022-06-10T09:57:21-05:00",
"updated": "2022-06-10T11:19:10-05:00"
},
"signer": [
"wVVPzAGAkv5a2AANEdmeActMpWhbByQ81v",
"wVXQDT59RzXdPZD4CyK6z8FWebZmyZ9aHm"
]
}
}
},
"action_id": "98f2f910-fcf2-4937-9ba3-6fb5f9080a17",
"error": {
"code": 0,
"message": "Success"
},
"id": "98f2f910-fcf2-4937-9ba3-6fb5f9080a17"
}
```
```json theme={null}
{
"error": {
"code": 0,
"message": "Success"
}
}
```
```json theme={null}
{
"error": {
"code": 600,
"message": "Error receiving status notification."
}
}
```
**Nota:**
La información privada contenida en `signer.labels` y `wallet.labels` se incluye en la acción enviada al endpoint `/status` **solo si el `source` y el `target` pertenecen al mismo banco**. En caso contrario, el banco receptor únicamente recibe información **pública**.
Además, la información del usuario `target` **solo se incluye si la transferencia fue aceptada**.
A continuación se detallan los campos considerados públicos y privados:
**Campos públicos del signer (todo lo no listado se considera privado):**
* `firstName`
* `lastName`
* `identification`
* `bankBicfi`
* `bankName`
* `proprietary`
**Campos privados del wallet (todo lo no listado se considera público):**
* `channelSms`
# Notas de despliegue
Source: https://transfiya.me/es/v1.104/release-notes/release-notes-stg
Historial de despliegues en ambiente de pruebas
* Se agrega el apartado **Como reintentar créditos**
* Se actualizan los códigos de error del MOL para diferenciarlos de los que actualmente utiliza el servicio. Además, se reorganizan conforme a los códigos que el MOL retorna en la actualidad.
* Se adiciona la funcionalidad de crear *signer genérico* en el sistema de Transfiya para Empresas.
* Se agregan los atributos de tipo de identificación, número de identificación y nombre en el flujo de cuenta a cuenta al momento de inicializar la transacción.
* Se habilita el uso de *signer genérico* en el flujo de cuenta a cuenta para acreditar transferencias sin necesidad de que la cuenta destino esté previamente registrada, evitando así el onboarding previo por parte de la entidad receptora.
* Se ajustan los campos mínimos del signer para poder originar transacciones en el flujo SENDMOL.
* Se Ajustan las descripciones de los códigos de error retornados por el DICE. (120 timeout - 123 cuando la llave está registrada por otra entidad financiera).
* Se agrega la homologación de códigos de eror del MOL
* Nuevas funcionalidad: Se suprime la obligatoriedad de que el signer origen sea una llave regulatorio en el flujo SENDMOL.
* Nueva funcionalidad ¿como reactivar llave?.
* Nueva funcionalidad ¿como bloquear llave?
# SDK
Source: https://transfiya.me/es/v1.104/release-notes/sdk-releases
Historial de despliegues del SDK oficial
## Notas de versión - 31/10/2025
* Adición de atributos en los métodos actions que permiten inicializar transacciones cuenta a cuenta.
* Adición del tipo de signer GENERIC en el método signers para la creación de firmantes genéricos por parte de los participantes.
* Adición de la lógica en el action del credit para permitir la recepción de los atributos de la cuenta de origen y destino.
### Descargas disponibles
* 📦 SDK para **Java JDK1.7** (v0.1.28.11)
[Descargar](https://storage.googleapis.com/tin-sdks/2025-11-07/2025-11-07_java_jdk1.7_0.1.28.11_62d61c878bb14c113fcc14ab64aca181.zip)
* 📦 SDK para **Java JDK1.8** (v0.1.28.11)
[Descargar](https://storage.googleapis.com/tin-sdks/2025-11-07/2025-11-07_java_jdk1.8_0.1.28.11_503c4cbe8baa9ae70accc60a285cf633.zip)
* 📦 SDK para **C#** (v1.1.11)
[Descargar](https://storage.googleapis.com/tin-sdks/2025-11-07/2025-11-07_csharp_1.1.11_71c2b85a1bb351915d4f5593dd944e61.zip)
* 📦 SDK para **Node.js** (v0.4.11)
[Descargar](https://storage.googleapis.com/tin-sdks/2025-11-07/2025-11-07_nodejs_0.4.11_47699509ac13d28726c1394d258cd882.zip)
## Notas de versión - 26/05/2025
* Nuevos endpoints para enviar las dos últimas marcas de tiempo durante la creación y resolución de llaves en la integración con DICE.
* Nuevo endpoint para enviar las dos últimas marcas de tiempo al realizar una transferencia regulada de llaves en la conexión con DICE.
* Documentación del caso de uso Empresa (cuenta a cuenta).
* Publicación de la documentación base inicial de Transfiya.
### Descargas disponibles
* 📦 SDK para **Java JDK1.7** (v0.1.28.6)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-05-27/2025-05-27_java_jdk1.7_0.1.28.6_08ccb49d270b03789881f44e189a6fd9.zip)
* 📦 SDK para **Java JDK1.8** (v0.1.28.6)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-05-27/2025-05-27_java_jdk1.8_0.1.28.6_b07cb5df8b95ee38b2ca06171f46829a.zip)
* 📦 SDK para **C#** (v1.1.6)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-05-27/2025-05-27_csharp_1.1.6_2e46d22198335e2c53bafe91d9f7117d.zip)
* 📦 SDK para **Node.js** (v0.4.6)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-05-27/2025-05-27_nodejs_0.4.6_a6bea4852a7d1b2c94c8b415981dcd76.zip)
## Notas de versión - 15/05/2025
Modificación en el endpoint de cancelación de signers: se introduce una nueva etiqueta booleana `allowImmediateReuse` en el firmante. Este campo se mapea con el valor `AllowSecIdUpdate` en DICE (Y/N) para permitir la reutilización inmediata de la clave, ignorando la regla de espera de 5 días tras cancelación.
### Descargas disponibles
* 📦 SDK para **Java JDK1.7** (v0.1.28.5)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-05-15/2025-05-15_java_jdk1.7_0.1.28.5_e992957f4463f36390bfae525ee5afdd.zip)
* 📦 SDK para **Java JDK1.8** (v0.1.28.5)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-05-15/2025-05-15_java_jdk1.8_0.1.28.5_fdf068e79bb29ba8b9178f1457b49ab5.zip)
* 📦 SDK para **C#** (v1.1.5)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-05-15/2025-05-15_csharp_1.1.5_e9dc987814739e05d1d48a43c3ca1aad.zip)
* 📦 SDK para **Node.js** (v0.4.5)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-05-15/2025-05-15_nodejs_0.4.5_9e0aecbd387cfed2eaa83a1622a1e111.zip)
## Notas de versión - 14/04/2025
Se agregó soporte para el endpoint lookup.dice que permite consultar signers registrados en el sistema DICE. Esta funcionalidad facilita la resolución de claves públicas asociadas a un signer específico y mejora la interoperabilidad entre instituciones.
### Descargas disponibles
* 📦 SDK para **Java JDK1.7** (v0.1.28.3)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-04-14/java_jdk1.7_0.1.28.3_e085563ac99fd93ddc5915adef1bd895.zip)
* 📦 SDK para **Java JDK1.8** (v0.1.28.3)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-04-14/java_jdk1.8_0.1.28.3_a39fadc04a700f13a206aad21e86399a.zip)
* 📦 SDK para **C#** (v1.1.3)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-04-14/csharp_1.1.3_34ee48f1c502d8a2fc96b647f423e722.zip)
* 📦 SDK para **Node.js** (v0.4.3)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-04-14/nodejs_0.4.3_72871d27fa40c716f22a697df2861823.zip)
## Notas de versión - 07/04/2025
Se han añadido nuevas etiquetas de tiempo (timestamp) reguladas por MOL a las entidades `signer` y `transfer`. Ambas etiquetas utilizan el formato de fecha y hora ISO 8601.
* `received`: representa el momento en que el banco recibió la solicitud del usuario.
* `dispatched`: representa el momento en que el banco realizó la llamada a TransfiYa.
Estas etiquetas permiten cumplir con los requisitos regulatorios de trazabilidad y control de tiempos para operaciones en tiempo real.
Estas mejoras permiten a los participantes reportar y auditar el flujo de operaciones con mayor precisión y alineación con el modelo SPI.
### Descargas disponibles
* 📦 SDK para **Java JDK1.7** (v0.1.28.2)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-04-01/java_jdk1.7_0.1.28.2_a592328e4e15d0b102a17bf6b705b00b.zip)
* 📦 SDK para **Java JDK1.8** (v0.1.28.2)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-04-01/java_jdk1.8_0.1.28.2_c8d86c9c053ba9dcac3137e1c2d3453c.zip)
* 📦 SDK para **C#** (v1.1.2)\
[Descargar](https://storage.googleapis.com/tin-sdks/2025-04-01/csharp_1.1.2_8b604778c2ee25798746ef371ed6fd84.zip)
# Actualizar an accion
Source: https://transfiya.me/transfers-mol-2/action/actualizar-an-accion
/public/tinapiv8.yaml put /v1/action/{action_id}
# Crear una accion
Source: https://transfiya.me/transfers-mol-2/action/crear-una-accion
/public/tinapiv8.yaml post /v1/action
# Enviar una accion
Source: https://transfiya.me/transfers-mol-2/action/enviar-una-accion
/public/tinapiv8.yaml post /v1/action/{action_id}/sendit
# Obtener accion por ID
Source: https://transfiya.me/transfers-mol-2/action/obtener-accion-por-id
/public/tinapiv8.yaml get /v1/action/{action_id}
# Create credentials
Source: https://transfiya.me/transfers-mol-2/credentials/create-credentials
/public/tinapiv8.yaml post /oauth
Endpoint used for creating of credentials
# Get api key
Source: https://transfiya.me/transfers-mol-2/credentials/get-api-key
/public/tinapiv8.yaml get /oauth/key/{handle}
Endpoint used to get api key
# Get credentials
Source: https://transfiya.me/transfers-mol-2/credentials/get-credentials
/public/tinapiv8.yaml get /oauth/client/{handle}
Endpoint used to get credentials
# Regenerate secrets
Source: https://transfiya.me/transfers-mol-2/credentials/regenerate-secrets
/public/tinapiv8.yaml put /oauth/{handle}
Endpoint used to regenerate secrets
# Rollback secrets
Source: https://transfiya.me/transfers-mol-2/credentials/rollback-secrets
/public/tinapiv8.yaml put /oauth/rollback/{handle}
Endpoint used to rollback secrets
# Update credentials
Source: https://transfiya.me/transfers-mol-2/credentials/update-credentials
/public/tinapiv8.yaml put /oauth/credentials/{handle}
Endpoint used for updating of credentials
# Authorize token
Source: https://transfiya.me/transfers-mol-2/token/authorize-token
/public/tinapiv8.yaml get /oauth/authorize
Endpoint used to authorize token
# Create token
Source: https://transfiya.me/transfers-mol-2/token/create-token
/public/tinapiv8.yaml post /oauth/token
Endpoint used for creating of token
# Aceptar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/aceptar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/accept
# Actualizar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/actualizar-una-transferencia
/public/tinapiv8.yaml put /v1/transfer/{transfer_id}
# Continuar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/continuar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/continue
# Crear una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/crear-una-transferencia
/public/tinapiv8.yaml post /v1/transfer
# Inicializar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/inicializar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{transferId}/initiate
# Rechazar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/rechazar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/reject
# Actualiza la transferencia.
Source: https://transfiya.me/transfers-mol/action/actualiza-la-transferencia
/public/spi-banksv3.yaml post /v1/action
TIN Cloud will call this endpoint when bank needs to sign the pending action. Depending on the key handling strategy it can use keys stored in the TIN Cloud or keys stored on local Key management system.
# Acreditar al destino.
Source: https://transfiya.me/transfers-mol/credit/acreditar-al-destino
/public/spi-banksv3.yaml post /v1/credit
Executes download on TIN Cloud side and credit on banking core side.
# Debitar al origen.
Source: https://transfiya.me/transfers-mol/debit/debitar-al-origen
/public/spi-banksv3.yaml post /v1/debit
Executes upload on TIN Cloud side and debit on banking core side.
# Notificacion de la transferencia.
Source: https://transfiya.me/transfers-mol/status/notificacion-de-la-transferencia
/public/spi-banksv3.yaml post /v1/status
Notification channel. It receives action object as a confirmation of transfer acceptance or reject action.
# This is the endpoint to get a temporal token to set in the oauth2 header
Source: https://transfiya.me/transfers-mol/token/this-is-the-endpoint-to-get-a-temporal-token-to-set-in-the-oauth2-header
/public/spi-banksv3.yaml post /oauth/token
# Actualizar an accion
Source: https://transfiya.me/b2b-2/action/actualizar-an-accion
/public/tinapiv8.yaml put /v1/action/{action_id}
# Crear una accion
Source: https://transfiya.me/b2b-2/action/crear-una-accion
/public/tinapiv8.yaml post /v1/action
# Enviar una accion
Source: https://transfiya.me/b2b-2/action/enviar-una-accion
/public/tinapiv8.yaml post /v1/action/{action_id}/sendit
# Obtener accion por ID
Source: https://transfiya.me/b2b-2/action/obtener-accion-por-id
/public/tinapiv8.yaml get /v1/action/{action_id}
# Create credentials
Source: https://transfiya.me/b2b-2/credentials/create-credentials
/public/tinapiv8.yaml post /oauth
Endpoint used for creating of credentials
# Get api key
Source: https://transfiya.me/b2b-2/credentials/get-api-key
/public/tinapiv8.yaml get /oauth/key/{handle}
Endpoint used to get api key
# Get credentials
Source: https://transfiya.me/b2b-2/credentials/get-credentials
/public/tinapiv8.yaml get /oauth/client/{handle}
Endpoint used to get credentials
# Regenerate secrets
Source: https://transfiya.me/b2b-2/credentials/regenerate-secrets
/public/tinapiv8.yaml put /oauth/{handle}
Endpoint used to regenerate secrets
# Rollback secrets
Source: https://transfiya.me/b2b-2/credentials/rollback-secrets
/public/tinapiv8.yaml put /oauth/rollback/{handle}
Endpoint used to rollback secrets
# Update credentials
Source: https://transfiya.me/b2b-2/credentials/update-credentials
/public/tinapiv8.yaml put /oauth/credentials/{handle}
Endpoint used for updating of credentials
# Authorize token
Source: https://transfiya.me/b2b-2/token/authorize-token
/public/tinapiv8.yaml get /oauth/authorize
Endpoint used to authorize token
# Create token
Source: https://transfiya.me/b2b-2/token/create-token
/public/tinapiv8.yaml post /oauth/token
Endpoint used for creating of token
# Aceptar una transferencia
Source: https://transfiya.me/b2b-2/transfer/aceptar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/accept
# Actualizar una transferencia
Source: https://transfiya.me/b2b-2/transfer/actualizar-una-transferencia
/public/tinapiv8.yaml put /v1/transfer/{transfer_id}
# Continuar una transferencia
Source: https://transfiya.me/b2b-2/transfer/continuar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/continue
# Crear una transferencia
Source: https://transfiya.me/b2b-2/transfer/crear-una-transferencia
/public/tinapiv8.yaml post /v1/transfer
# Inicializar una transferencia
Source: https://transfiya.me/b2b-2/transfer/inicializar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{transferId}/initiate
# Rechazar una transferencia
Source: https://transfiya.me/b2b-2/transfer/rechazar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/reject
# Create a new signer
Source: https://transfiya.me/directory/signer/create-a-new-signer
/public/spi-v3.yaml post /v1/signer
Endpoint to create a signer with necessary details.
# Get a signer with signer handle.
Source: https://transfiya.me/directory/signer/get-a-signer-with-signer-handle
/public/spi-v3.yaml get /v1/signer/{signerAddress}
Endpoint to get a signer.
# Resolves SPI signer
Source: https://transfiya.me/directory/signer/resolves-spi-signer
/public/spi-v3.yaml post /v1/signer/lookup.dice
Endpoint to resolve signer in DICE
# Retrieve signers
Source: https://transfiya.me/directory/signer/retrieve-signers
/public/spi-v3.yaml get /v1/signer
Get signers with support for filtering.
# Update a signer
Source: https://transfiya.me/directory/signer/update-a-signer
/public/spi-v3.yaml put /v1/signer/{signerAddress}
Endpoint to update a signer.
# Actualizar an accion
Source: https://transfiya.me/transfers-mol-2/action/actualizar-an-accion
/public/tinapiv8.yaml put /v1/action/{action_id}
# Crear una accion
Source: https://transfiya.me/transfers-mol-2/action/crear-una-accion
/public/tinapiv8.yaml post /v1/action
# Enviar una accion
Source: https://transfiya.me/transfers-mol-2/action/enviar-una-accion
/public/tinapiv8.yaml post /v1/action/{action_id}/sendit
# Obtener accion por ID
Source: https://transfiya.me/transfers-mol-2/action/obtener-accion-por-id
/public/tinapiv8.yaml get /v1/action/{action_id}
# Create credentials
Source: https://transfiya.me/transfers-mol-2/credentials/create-credentials
/public/tinapiv8.yaml post /oauth
Endpoint used for creating of credentials
# Get api key
Source: https://transfiya.me/transfers-mol-2/credentials/get-api-key
/public/tinapiv8.yaml get /oauth/key/{handle}
Endpoint used to get api key
# Get credentials
Source: https://transfiya.me/transfers-mol-2/credentials/get-credentials
/public/tinapiv8.yaml get /oauth/client/{handle}
Endpoint used to get credentials
# Regenerate secrets
Source: https://transfiya.me/transfers-mol-2/credentials/regenerate-secrets
/public/tinapiv8.yaml put /oauth/{handle}
Endpoint used to regenerate secrets
# Rollback secrets
Source: https://transfiya.me/transfers-mol-2/credentials/rollback-secrets
/public/tinapiv8.yaml put /oauth/rollback/{handle}
Endpoint used to rollback secrets
# Update credentials
Source: https://transfiya.me/transfers-mol-2/credentials/update-credentials
/public/tinapiv8.yaml put /oauth/credentials/{handle}
Endpoint used for updating of credentials
# Authorize token
Source: https://transfiya.me/transfers-mol-2/token/authorize-token
/public/tinapiv8.yaml get /oauth/authorize
Endpoint used to authorize token
# Create token
Source: https://transfiya.me/transfers-mol-2/token/create-token
/public/tinapiv8.yaml post /oauth/token
Endpoint used for creating of token
# Aceptar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/aceptar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/accept
# Actualizar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/actualizar-una-transferencia
/public/tinapiv8.yaml put /v1/transfer/{transfer_id}
# Continuar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/continuar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/continue
# Crear una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/crear-una-transferencia
/public/tinapiv8.yaml post /v1/transfer
# Inicializar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/inicializar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{transferId}/initiate
# Rechazar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/rechazar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/reject
# Actualiza la transferencia.
Source: https://transfiya.me/transfers-mol/action/actualiza-la-transferencia
/public/spi-banksv3.yaml post /v1/action
TIN Cloud will call this endpoint when bank needs to sign the pending action. Depending on the key handling strategy it can use keys stored in the TIN Cloud or keys stored on local Key management system.
# Acreditar al destino.
Source: https://transfiya.me/transfers-mol/credit/acreditar-al-destino
/public/spi-banksv3.yaml post /v1/credit
Executes download on TIN Cloud side and credit on banking core side.
# Debitar al origen.
Source: https://transfiya.me/transfers-mol/debit/debitar-al-origen
/public/spi-banksv3.yaml post /v1/debit
Executes upload on TIN Cloud side and debit on banking core side.
# Notificacion de la transferencia.
Source: https://transfiya.me/transfers-mol/status/notificacion-de-la-transferencia
/public/spi-banksv3.yaml post /v1/status
Notification channel. It receives action object as a confirmation of transfer acceptance or reject action.
# This is the endpoint to get a temporal token to set in the oauth2 header
Source: https://transfiya.me/transfers-mol/token/this-is-the-endpoint-to-get-a-temporal-token-to-set-in-the-oauth2-header
/public/spi-banksv3.yaml post /oauth/token
# Create a new signer
Source: https://transfiya.me/directory/signer/create-a-new-signer
/public/spi-v3.yaml post /v1/signer
Endpoint to create a signer with necessary details.
# Get a signer with signer handle.
Source: https://transfiya.me/directory/signer/get-a-signer-with-signer-handle
/public/spi-v3.yaml get /v1/signer/{signerAddress}
Endpoint to get a signer.
# Resolves SPI signer
Source: https://transfiya.me/directory/signer/resolves-spi-signer
/public/spi-v3.yaml post /v1/signer/lookup.dice
Endpoint to resolve signer in DICE
# Retrieve signers
Source: https://transfiya.me/directory/signer/retrieve-signers
/public/spi-v3.yaml get /v1/signer
Get signers with support for filtering.
# Update a signer
Source: https://transfiya.me/directory/signer/update-a-signer
/public/spi-v3.yaml put /v1/signer/{signerAddress}
Endpoint to update a signer.
# Actualizar an accion
Source: https://transfiya.me/transfers-mol-2/action/actualizar-an-accion
/public/tinapiv8.yaml put /v1/action/{action_id}
# Crear una accion
Source: https://transfiya.me/transfers-mol-2/action/crear-una-accion
/public/tinapiv8.yaml post /v1/action
# Enviar una accion
Source: https://transfiya.me/transfers-mol-2/action/enviar-una-accion
/public/tinapiv8.yaml post /v1/action/{action_id}/sendit
# Obtener accion por ID
Source: https://transfiya.me/transfers-mol-2/action/obtener-accion-por-id
/public/tinapiv8.yaml get /v1/action/{action_id}
# Create credentials
Source: https://transfiya.me/transfers-mol-2/credentials/create-credentials
/public/tinapiv8.yaml post /oauth
Endpoint used for creating of credentials
# Get api key
Source: https://transfiya.me/transfers-mol-2/credentials/get-api-key
/public/tinapiv8.yaml get /oauth/key/{handle}
Endpoint used to get api key
# Get credentials
Source: https://transfiya.me/transfers-mol-2/credentials/get-credentials
/public/tinapiv8.yaml get /oauth/client/{handle}
Endpoint used to get credentials
# Regenerate secrets
Source: https://transfiya.me/transfers-mol-2/credentials/regenerate-secrets
/public/tinapiv8.yaml put /oauth/{handle}
Endpoint used to regenerate secrets
# Rollback secrets
Source: https://transfiya.me/transfers-mol-2/credentials/rollback-secrets
/public/tinapiv8.yaml put /oauth/rollback/{handle}
Endpoint used to rollback secrets
# Update credentials
Source: https://transfiya.me/transfers-mol-2/credentials/update-credentials
/public/tinapiv8.yaml put /oauth/credentials/{handle}
Endpoint used for updating of credentials
# Authorize token
Source: https://transfiya.me/transfers-mol-2/token/authorize-token
/public/tinapiv8.yaml get /oauth/authorize
Endpoint used to authorize token
# Create token
Source: https://transfiya.me/transfers-mol-2/token/create-token
/public/tinapiv8.yaml post /oauth/token
Endpoint used for creating of token
# Aceptar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/aceptar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/accept
# Actualizar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/actualizar-una-transferencia
/public/tinapiv8.yaml put /v1/transfer/{transfer_id}
# Continuar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/continuar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/continue
# Crear una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/crear-una-transferencia
/public/tinapiv8.yaml post /v1/transfer
# Inicializar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/inicializar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{transferId}/initiate
# Rechazar una transferencia
Source: https://transfiya.me/transfers-mol-2/transfer/rechazar-una-transferencia
/public/tinapiv8.yaml post /v1/transfer/{action_id}/reject
# Actualiza la transferencia.
Source: https://transfiya.me/transfers-mol/action/actualiza-la-transferencia
/public/spi-banksv3.yaml post /v1/action
TIN Cloud will call this endpoint when bank needs to sign the pending action. Depending on the key handling strategy it can use keys stored in the TIN Cloud or keys stored on local Key management system.
# Acreditar al destino.
Source: https://transfiya.me/transfers-mol/credit/acreditar-al-destino
/public/spi-banksv3.yaml post /v1/credit
Executes download on TIN Cloud side and credit on banking core side.
# Debitar al origen.
Source: https://transfiya.me/transfers-mol/debit/debitar-al-origen
/public/spi-banksv3.yaml post /v1/debit
Executes upload on TIN Cloud side and debit on banking core side.
# Notificacion de la transferencia.
Source: https://transfiya.me/transfers-mol/status/notificacion-de-la-transferencia
/public/spi-banksv3.yaml post /v1/status
Notification channel. It receives action object as a confirmation of transfer acceptance or reject action.
# This is the endpoint to get a temporal token to set in the oauth2 header
Source: https://transfiya.me/transfers-mol/token/this-is-the-endpoint-to-get-a-temporal-token-to-set-in-the-oauth2-header
/public/spi-banksv3.yaml post /oauth/token
# Get api key
Source: https://transfiya.me/transfers-mol-2/credentials/get-api-key
/public/tinapiv8.yaml get /oauth/key/{handle}
Endpoint used to get api key
# Get credentials
Source: https://transfiya.me/transfers-mol-2/credentials/get-credentials
/public/tinapiv8.yaml get /oauth/client/{handle}
Endpoint used to get credentials
# Regenerate secrets
Source: https://transfiya.me/transfers-mol-2/credentials/regenerate-secrets
/public/tinapiv8.yaml put /oauth/{handle}
Endpoint used to regenerate secrets
# Rollback secrets
Source: https://transfiya.me/transfers-mol-2/credentials/rollback-secrets
/public/tinapiv8.yaml put /oauth/rollback/{handle}
Endpoint used to rollback secrets
# Update credentials
Source: https://transfiya.me/transfers-mol-2/credentials/update-credentials
/public/tinapiv8.yaml put /oauth/credentials/{handle}
Endpoint used for updating of credentials
# Authorize token
Source: https://transfiya.me/transfers-mol-2/token/authorize-token
/public/tinapiv8.yaml get /oauth/authorize
Endpoint used to authorize token
# Create token
Source: https://transfiya.me/transfers-mol-2/token/create-token
/public/tinapiv8.yaml post /oauth/token
Endpoint used for creating of token