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.

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.

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:

1

Transfiya llama al banco destino para procesar la operación de abono.

Se invoca el endpoint credit con todos los datos necesarios para iniciar el abono de fondos.

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"
    }
2

El banco destino crea una acción de tipo `DOWNLOAD` en Transfiya.

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.

curl -X POST \
    -H "Content-Type: application/json" \
    -H "x-api-key: <API_KEY>" \
    -H "Authorization: Bearer <TOKEN>" \
    -d '{
        "source": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF",
        "target": "wNbBi3CcZzggFJ9dvDWk35srVGgaAVLzUr",
        "symbol": "$tin",
        "amount": "100.00",
        "labels": {
        "type": "DOWNLOAD",
        "tx_ref": "Lf13jsK83omPv3bOt",
        "received": "2025-01-14T20:42:17.322-05:00",
        "dispatched": "2025-01-14T20:42:17.831-05:00"
        }
    }' "<TRANSFIYA URL>/v1/action"
Field nameDescripción
sourcemainAction.snapshot.target.signer.handle — Usuario destino de la transferencia (cliente del banco).
targetbankSigner.handle — Firmante de liquidación del banco destino.
symbolmainAction.symbol — Moneda de la transferencia.
amountmainAction.amount — Monto de la transferencia.
labels.typeDOWNLOAD — Siempre debe ser DOWNLOAD en operaciones de crédito.
labels.tx_refmainAction.labels.tx_ref — Referencia única de la transferencia.
labels.receivedTimestamp en formato ISO 8601 — Momento en que Transfiya recibió la solicitud de abono.
labels.dispatchedTimestamp en formato ISO 8601 — Momento en que se envió la solicitud de creación de la acción a Transfiya.
3

El banco responde a la llamada inicial de abono.

Esta respuesta cierra la parte síncrona de la operación; el resto se ejecuta de forma asíncrona.

{
"action_id": "2aa49d5d-3dcc-4841-bb3e-baeb9fef4278"
}
4

El banco actualiza la acción con un `tx_id`.

Este identificador permite rastrear y conciliar la operación dentro del sistema bancario.

curl -X PUT \
-H "Content-Type: application/json" \
-H "x-api-key: <API_KEY>" \
-H "Authorization: Bearer <TOKEN>" \
-d '{
    "labels": {
    "tx_id": "39288282838"
    }
}' "<TRANSFIYA URL>/v1/action/<download_action_id>"
Field nameDescripción del valor del campo
<download_action_id>El <download_action_id> 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_idIdentificador único de la transacción que el banco ejecutó para acreditar los fondos en la cuenta de destino.
5

El banco crea y firma un objeto IOU como prueba de la operación.

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.

curl -X POST \
    -H "Content-Type: application/json" \
    -H "x-api-key: <API_KEY>" \
    -H "Authorization: Bearer <TOKEN>" \
    -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",
            }
        ]
        }
    }' "<TRANSFIYA URL>/v1/action/<download_action_id>/sendit"
Field nameDescripción del valor del campo
<download_action_id>El <download_action_id> 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.sourcedownloadAction.snapshot.source.signer.handle – Firmante fuente del abono.
data.targetdownloadAction.snapshot.target.signer.handle – Firmante destino del abono.
data.symboldownloadAction.snapshot.symbol.signer.handle – Identificador del símbolo o moneda.
data.amountdownloadAction.amount – Monto a acreditar.
data.domaindownloadAction.labels.domain – Dominio asociado a la transacción.
data.expirycurrentTime + 1 minuto en formato ISO 8601 – Momento a partir del cual Transfiya puede expirar una operación pendiente.
hashHash del objeto data, generado por los SDKs. hash.value es el valor calculado, y los demás campos indican los pasos de hash.
meta.signaturesFirma del hash generada con la clave privada del firmante fuente. Incluye: schema (algoritmo), signer, public (clave pública) y string (firma).
6

El banco realiza validaciones finales y envía una llamada `continue`.

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.

curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: <API_KEY>" \
-H "Authorization: Bearer <TOKEN>" \
-d '{
    "received": "2025-01-14T20:42:58.252-05:00",
    "dispatched": "2025-01-14T20:42:58.552-05:00",
}' "<TRANSFIYA URL>/v1/transfer/<tx_ref>/continue"
Field nameValor del campo
<tx_ref>El campo <tx_ref> en la URL representa la referencia de la transferencia, ubicada en labels.tx_ref del mainAction.
receivedTimestamp en formato ISO 8601. Representa el momento en que se recibió la última respuesta de Transfiya (llamada sendit).
dispatchedTimestamp en formato ISO 8601. Representa el momento en que se envió la llamada continue a Transfiya.