> ## Documentation Index
> Fetch the complete documentation index at: https://transfiya.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Como aceptar la transferencia

> 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.

<Info>
  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.
</Info>

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.

<Tip>
  Las validaciones de aceptación DEBEN realizarse inmediatamente cuando la transferencia entra en estado PENDING.
</Tip>

```mermaid theme={null}
flowchart TD
   tya[Transfiya] -->|&nbsp;POST /status&nbsp;| banco[Banco]
   banco --> estado{Procesar notificación<br />de estado}
   estado -->|&nbsp;COMPLETADO&nbsp;| completado[Finalizar<br />transferencia]:::deshabilitado
   estado -->|&nbsp;PENDIENTE&nbsp;| pendiente[Validar<br />y aceptar]
   estado -->|&nbsp;RECHAZADO&nbsp;| rechazado[Limpiar<br />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.

<Info>
  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.
</Info>

## 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<br/> la cuenta exista
 tb ->> tb: Validar que<br/> la cuenta esté activa
 tb ->> tb: Validar monto<br/> y moneda de la transferencia
 tb ->> tb: Validar que<br/> la cuenta esté registrada

 alt la cuenta no está registrada
   tb ->> tb: Crear y almacenar<br />keeper
   tb ->> +ty: Crear signer
   ty -->> -tb: Respuesta del signer
 end

 tb ->> ty: Aceptar transferencia
```

<Info>
  A continuación detallamos los pasos del diagrama de secuencia con el detalle tecnico.
</Info>

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:

<Steps>
  <Step title="Transfiya llama al endpoint &#x22;status&#x22; del banco destino con estado &#x22;PENDING&#x22;">
    Se realiza una solicitud `POST` al endpoint del banco con todos los datos relevantes de la transferencia. El campo `labels.status` estará en `PENDING`.

    <CodeGroup>
      ```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"
      }
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="El banco valida que la cuenta de destino exista">
    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`.
  </Step>

  <Step title="Banco destino verifica que la cuenta esté activa y pueda recibir pagos">
    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: <API_KEY>" \
    -H "Authorization: Bearer <TOKEN>" \
    -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"
    }
    }' "<TRANSFIYA URL>/v1/transfer/<tx_ref>/reject"
    ```

    <Info>
      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`.
    </Info>

    | Field name   | Descripción en español                                                                                                                 |
    | :----------- | :------------------------------------------------------------------------------------------------------------------------------------- |
    | `<tx_ref>`   | El campo `<tx_ref>` 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.                        |
  </Step>

  <Step title="Banco destino valida que la moneda y el monto sean válidos para la cuenta">
    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: <API_KEY>" \
    -H "Authorization: Bearer <TOKEN>" \
    -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"
    }
    }' "<TRANSFIYA URL>/v1/transfer/<tx_ref>/reject"
    ```

    <Info>
      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`.
    </Info>

    | Field name   | Descripción en español                                                                                                            |
    | :----------- | :-------------------------------------------------------------------------------------------------------------------------------- |
    | `<tx_ref>`   | El campo `<tx_ref>` 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.                             |
  </Step>

  <Step title="Banco Destino verifica si la cuenta está registrada en Transfiya (onboarded)">
    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.
  </Step>

  <Step title="Genera una clave privada (`keeper`) si la cuenta no está registrada">
    Cada cuenta debe tener una clave criptográfica única. Esta se usa para firmar operaciones bajo el modelo de Transfiya.

    <Info>
      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.
    </Info>
  </Step>

  <Step title="Banco Destino Registra el &#x22;signer&#x22; en Transfiya">
    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.

    <CodeGroup>
      ```json Request Account Signer expandable theme={null}
      curl -X POST \
          -H "x-api-key: <API_KEY>" \
          -H "Authorization: Bearer <TOKEN>" \
          -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"
          }]
          }' "<TRANSFIYA URL>/v1/signer"
      ```

      ```json Response Account Signer expandable theme={null}
      curl -X POST \
      -H "x-api-key: <API_KEY>" \
      -H "Authorization: Bearer <TOKEN>" \
      -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"
      }]
      }' "<TRANSFIYA URL>/v1/signer"
      ```

      ```json Request Alias Signer expandable theme={null}
      curl -X POST \
         -H "x-api-key: <API_KEY>" \
         -H "Authorization: Bearer <TOKEN>" \
         -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"
         }]
         }' "<TRANSFIYA URL>/v1/signer"
      ```

      ```json Response Alias Signer expandable theme={null}
      curl -X POST \
      -H "x-api-key: <API_KEY>" \
      -H "Authorization: Bearer <TOKEN>" \
      -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"
      }]
      }' "<TRANSFIYA URL>/v1/signer"
      ```

      ```json Error Response expandable theme={null}
      curl -X POST \
      -H "x-api-key: <API_KEY>" \
      -H "Authorization: Bearer <TOKEN>" \
      -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"
      }]
      }' "<TRANSFIYA URL>/v1/signer"
      ```
    </CodeGroup>
  </Step>

  <Step title="El banco destino acepta la transferencia &#x22;PENDING&#x22;">
    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: <API_KEY>" \
    -H "Authorization: Bearer <TOKEN>" \
    -d '{
        "received": "2025-01-14T20:42:00.252-05:00",
        "dispatched": "2025-01-14T20:42:00.552-05:00",
        "signer": {
        "handle": "wRFmYXS2sP9ho9VCZ3j4FuP1j55ABeFvsF"
        }
    }' "<TRANSFIYA URL>/v1/transfer/<tx_ref>/accept"
    ```
  </Step>
</Steps>
