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

# Aceptar pagos con split

> Distribuye un único pago de Checkout Session de Fintoc entre varias Entities, transfiriendo cada parte a su propia cuenta bancaria sin conciliación manual.

Split Payments permite a las plataformas y marketplaces distribuir los fondos de un único pago entre varios destinatarios. Cuando un cliente paga a través de un Checkout Session, Fintoc divide el payout según las reglas que definas y transfiere cada parte a la cuenta bancaria del destinatario — sin transferencias manuales ni conciliaciones de tu lado.

Cada destinatario es una **Entity**: el titular legal que recibe una parte del pago. Una Entity declara la cuenta donde recibe el pago como parte de su onboarding, así que no hay un recurso de cuenta separado que gestionar.

Hay tres pasos para aceptar pagos con split:

1. **Crear una Entity** para cada destinatario
2. **Hacer el onboarding de la Entity**, incluyendo la cuenta donde recibirá el pago
3. **Crear un Checkout Session con un arreglo `split`** y enviar al cliente a su `redirect_url`

## Antes de comenzar

* Una cuenta de Fintoc con **Collects** habilitado
* Tu [clave secreta y clave pública](/es/api/fintoc-api/authentication)
* Al menos una Entity en estado `operational` (ver los pasos 1 y 2)

***

## Paso 1: Crear una Entity

Una Entity representa al titular legal que recibe una parte del pago: un vendedor, un socio, un profesional, una unidad de negocio.

```bash theme={null}
curl --request POST "https://api.fintoc.com/v2/entities" \
--header 'Authorization: YOUR_SECRET_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
  "country_code": "CL",
  "holder_name": "Estudio Rojas SpA",
  "holder_id": "761234567"
}'
```

| Parámetro      | Tipo   | Requerido | Descripción                                                                                              |
| -------------- | ------ | --------- | -------------------------------------------------------------------------------------------------------- |
| `country_code` | string | Sí        | Código de país ISO 3166-1 alpha-2. `CL` o `MX`.                                                          |
| `holder_name`  | string | Sí        | Razón social del titular de la entidad.                                                                  |
| `holder_id`    | string | Sí        | Identificador fiscal sin formato. RUT en Chile, RFC en México. Debe ser único dentro de tu organización. |

```json theme={null}
{
  "id": "ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN",
  "object": "entity",
  "country_code": "cl",
  "holder_id": "761234567",
  "holder_name": "Estudio Rojas SpA",
  "is_root": false,
  "mode": "live",
  "status": "waiting_initialization"
}
```

Una Entity nueva comienza en `waiting_initialization`. No puede recibir un split hasta que llegue a `operational`, lo que sucede cuando se aprueba su onboarding.

<Info>
  Si el destinatario ya existe como Entity en tu organización, reutiliza su `id`. Crear una segunda Entity con el mismo `holder_id` devuelve `409 entity_holder_id_already_exists_for_organization`.
</Info>

Lista y recupera entities con `GET /v2/entities` — que acepta filtros `holder_id`, `status` y `is_root` — y `GET /v2/entities/{id}`.

***

## Paso 2: Hacer el onboarding de la Entity

El onboarding es donde la Entity declara quién es y, lo más importante para Split Payments, **la cuenta bancaria donde recibirá el pago**. Fintoc lo revisa, y cuando se aprueba, la Entity pasa a `operational`.

El onboarding se completa a través de la API, tanto en **Chile como en México**.

### Crear el onboarding

```bash theme={null}
curl --request POST "https://api.fintoc.com/v2/entities/ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN/onboardings" \
--header 'Authorization: YOUR_SECRET_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
  "type": "settlement_recipient",
  "data": {
    "company_information": {
      "business_activity": "Servicios de arquitectura",
      "business_address": "Av. Apoquindo 100, Santiago, Region Metropolitana, 7550000, Chile",
      "phone": "+56 9 1111 1111",
      "settlement_account": {
        "institution_id": "cl_banco_de_chile",
        "account_number": "123456789",
        "account_type": "checking_account"
      }
    },
    "legal_representatives": [
      {
        "first_name": "Camila",
        "last_name": "Rojas",
        "email": "test@mail.com",
        "nationality": "CL",
        "identification_number": "15123456K",
        "position": "Representante legal"
      }
    ]
  }
}'
```

### Tipo de onboarding

**`type` es requerido al crear el onboarding.** Declara qué hará la Entity con Fintoc, no se puede cambiar después y determina cuánta información pide el onboarding.

**`settlement_recipient`** — la Entity solo *recibe* dinero. Su parte de cada split se transfiere a la cuenta bancaria que declara en `settlement_account`, y nada más: no mantiene balance en Fintoc, no puede recibir transferencias de terceros y no puede enviar dinero. Como solo recibe pagos, el onboarding pide lo mínimo necesario para identificar a quién se le paga. **Este es el valor a usar para Split Payments.**

**`account_holder`** — la Entity *opera* una cuenta en Fintoc. Puede recibir transferencias entrantes, enviar salientes y mantener balance. Esa capacidad conlleva un perfil de riesgo más alto, por lo que el onboarding requiere el conjunto completo de información: perfil transaccional, estructura de propiedad y documentos de respaldo.

### La cuenta de liquidación

`data.company_information.settlement_account` es la cuenta donde se transfiere la parte de esta Entity en cada split. Es el único campo que Split Payments agrega al onboarding.

| Parámetro        | Tipo   | Requerido | Descripción                                                                                                        |
| ---------------- | ------ | --------- | ------------------------------------------------------------------------------------------------------------------ |
| `institution_id` | string | Sí        | Identificador del banco. Consulta [Códigos de instituciones de Chile](/es/api/fintoc-api/chile-institution-codes). |
| `account_number` | string | Sí        | Número de cuenta.                                                                                                  |
| `account_type`   | string | Sí        | Uno de `checking_account` o `sight_account`.                                                                       |

No lleva campos de titular: el titular de la cuenta es la empresa que se está onboardeando, así que el identificador fiscal ya se conoce.

<Warning>
  Una Entity tiene exactamente una cuenta de liquidación. Para cambiarla, crea un nuevo onboarding — ver [Cambiar la cuenta de liquidación](#cambiar-la-cuenta-de-liquidaci%C3%B3n).
</Warning>

### Campos del onboarding

| Bloque                         | Requerido | Qué declara                                                                                                                                                                                                                                                              |
| ------------------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `type`                         | Sí        | Se envía al crear el onboarding. `settlement_recipient` o `account_holder`. Usa `settlement_recipient` para Split Payments.                                                                                                                                              |
| `data`                         | Sí        | Envuelve todos los demás bloques del onboarding.                                                                                                                                                                                                                         |
| `data.company_information`     | Sí        | Información de negocio de la Entity. Para Entities de persona natural, `settlement_account` es el único subcampo requerido — los demás (`business_activity`, `business_address`, `phone`) son opcionales. Para Entities de empresa, los cuatro subcampos son requeridos. |
| `data.legal_representatives[]` | No        | Nombre, email, nacionalidad, identificación y cargo de cada representante legal.                                                                                                                                                                                         |
| `data.transactional_profile`   | No        | Volumen mensual esperado, número de operaciones y origen de los fondos.                                                                                                                                                                                                  |
| `data.shareholders[]`          | No        | Estructura de propiedad, con el identificador fiscal y porcentaje de participación de cada accionista.                                                                                                                                                                   |
| Documentos                     | No        | Archivos de respaldo, subidos por slot con `PUT`. Hasta 20 MB cada uno; volver a subir un slot reemplaza el archivo.                                                                                                                                                     |

### Enviar el onboarding

Una vez completa la información, envíala a revisión:

```bash theme={null}
curl --request POST "https://api.fintoc.com/v2/entities/ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN/onboardings/onbprc_9kQ2mZpLtR4vXn/submit" \
--header 'Authorization: YOUR_SECRET_KEY'
```

El onboarding pasa por estos estados:

| Estado        | Significado                                                                     |
| ------------- | ------------------------------------------------------------------------------- |
| `pending`     | Creado, aún no se ha enviado nada.                                              |
| `in_progress` | Siendo completado. Los campos y documentos aún se pueden editar.                |
| `submitted`   | Bajo revisión de Fintoc. Sin más ediciones.                                     |
| `approved`    | Revisión aprobada. **La Entity ahora es `operational` y puede recibir splits.** |
| `rejected`    | Revisión rechazada. Crea un nuevo onboarding para reintentar.                   |

Dos webhooks te avisan del resultado:

* `entity.onboarding.approved` — la Entity está lista para recibir splits
* `entity.onboarding.rejected` — la revisión falló

<Info>
  La revisión de compliance típicamente toma uno a dos días hábiles. Diseña tu flujo para que el destinatario pueda crearse y mostrarse como pendiente mientras corre la revisión.
</Info>

### Cambiar la cuenta de liquidación

Crea un **nuevo onboarding** para la misma Entity con la nueva cuenta. Mientras está bajo revisión, la cuenta anterior sigue vigente y la Entity sigue recibiendo splits. Cuando el nuevo onboarding se aprueba, la nueva cuenta reemplaza a la anterior. Si se rechaza, no cambia nada.

***

## Paso 3: Crear un Checkout Session con split

Agrega un arreglo `split` al Checkout Session. Cada entrada nombra a una Entity y su parte.

```bash theme={null}
curl --request POST "https://api.fintoc.com/v2/checkout_sessions" \
--header 'Authorization: YOUR_SECRET_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
  "amount": 150000,
  "currency": "CLP",
  "customer_email": "buyer@example.com",
  "success_url": "https://merchant.example/success",
  "cancel_url": "https://merchant.example/cancel",
  "metadata": { "order_id": "ORD-1234" },
  "split": [
    { "entity_id": "ent_3fXq9tLbnKmWzR4dHs2VcJ7yP5N", "type": "flat", "amount": 50000 },
    { "entity_id": "ent_5jMw7rTkqZbNxH3cLs9YdV2pF8Q", "type": "flat", "amount": 45000 },
    { "entity_id": "ent_9hPz4mVtkXbLwN6cRs1YdJ5qG3T", "type": "flat", "amount": 30000 },
    { "entity_id": "ent_1cKp8sWnvYbMtQ5hLr7XdF3jZ2R", "type": "flat", "amount": 25000,
      "charge_processing_fee": true }
  ]
}'
```

| Campo                           | Tipo    | Requerido                      | Descripción                                                                                                 |
| ------------------------------- | ------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| `split`                         | array   | No                             | Reglas que se usan para dividir el pago. Omítelo y el 100% del payout va a ti. Entre 1 y 10 entradas.       |
| `split[].entity_id`             | string  | Sí                             | ID de una Entity `operational`.                                                                             |
| `split[].type`                  | string  | Sí                             | `flat` o `percentage`. Todas las entradas deben usar el mismo tipo.                                         |
| `split[].amount`                | integer | Sí                             | Para `flat`, el monto en la unidad menor de la moneda. Para `percentage`, puntos base donde `10000` = 100%. |
| `split[].charge_processing_fee` | boolean | Sí, en exactamente una entrada | El destinatario que absorbe la comisión de procesamiento del pago.                                          |
| `split[].metadata`              | object  | No                             | Datos clave-valor adjuntos a esta regla. Se devuelven en los webhooks.                                      |

<Warning>
  **Las reglas del split deben sumar exactamente el monto del pago.** No hay residuo: si te quedas con parte del pago, declara tu propia entity raíz como otra entrada, como en el ejemplo de arriba. Recupérala con `GET /v2/entities?is_root=true`.
</Warning>

<Info>
  **Los porcentajes se expresan en puntos base.** `10000` = 100%, `1000` = 10%, `1` = 0.01%. Para asignar el 90%, envía `9000`.
</Info>

La respuesta hace eco del arreglo `split` tal como lo enviaste, junto con el `redirect_url` de la página de pago. Envía al cliente allí para completar el pago.

***

## Paso 4: Manejar los eventos posteriores al pago

Cuando el pago llega a un estado final, `checkout_session.finished` y `payment_intent.succeeded` incluyen un arreglo `split_applied` con el monto resuelto para cada destinatario.

```json theme={null}
{
  "id": "evt_a4xK32BanKWYn",
  "object": "event",
  "type": "checkout_session.finished",
  "data": {
    "id": "cs_li5531onlFDi235",
    "object": "checkout_session",
    "amount": 150000,
    "currency": "CLP",
    "status": "finished",
    "metadata": { "order_id": "ORD-1234" },
    "split": [
      { "entity_id": "ent_3fXq9tLbnKmWzR4dHs2VcJ7yP5N", "type": "flat", "amount": 50000 },
      { "entity_id": "ent_5jMw7rTkqZbNxH3cLs9YdV2pF8Q", "type": "flat", "amount": 45000 },
      { "entity_id": "ent_9hPz4mVtkXbLwN6cRs1YdJ5qG3T", "type": "flat", "amount": 30000 },
      { "entity_id": "ent_1cKp8sWnvYbMtQ5hLr7XdF3jZ2R", "type": "flat", "amount": 25000,
        "charge_processing_fee": true }
    ],
    "split_applied": [
      {
        "entity_id": "ent_3fXq9tLbnKmWzR4dHs2VcJ7yP5N",
        "calculated_amount": 50000,
        "charge_processing_fee": false
      },
      {
        "entity_id": "ent_5jMw7rTkqZbNxH3cLs9YdV2pF8Q",
        "calculated_amount": 45000,
        "charge_processing_fee": false
      },
      {
        "entity_id": "ent_9hPz4mVtkXbLwN6cRs1YdJ5qG3T",
        "calculated_amount": 30000,
        "charge_processing_fee": false
      },
      {
        "entity_id": "ent_1cKp8sWnvYbMtQ5hLr7XdF3jZ2R",
        "calculated_amount": 25000,
        "charge_processing_fee": true
      }
    ],
    "payment_resource": {
      "payment_intent": {
        "id": "pi_38DNJo3rbvGUzKFvCGZ6dxR1Kxx",
        "object": "payment_intent",
        "status": "succeeded"
      }
    }
  }
}
```

<Warning>
  `checkout_session.finished` puede llegar antes de que el pago haya alcanzado un estado final. Marca la orden como pagada solo cuando `data.payment_resource.payment_intent.status` sea `succeeded`.
</Warning>

Eventos a manejar:

| Evento                           | Cuándo                                                                |
| -------------------------------- | --------------------------------------------------------------------- |
| `checkout_session.finished`      | La sesión llegó a un estado final. Incluye `split` y `split_applied`. |
| `checkout_session.expired`       | La sesión expiró antes del pago.                                      |
| `payment_intent.succeeded`       | El pago fue exitoso.                                                  |
| `payment_intent.failed`          | El pago falló.                                                        |
| `payment_intent.requires_action` | El pago necesita una acción adicional del pagador.                    |
| `payout.created`                 | Se creó un payout hacia un destinatario para el ciclo de liquidación. |
| `payout.succeeded`               | El payout llegó a la cuenta del destinatario.                         |
| `payout.canceled`                | El payout fue cancelado y no se enviará.                              |
| `payout.returned`                | Un payout exitoso fue devuelto por el banco. Solo México.             |
| `entity.onboarding.approved`     | La Entity pasó la revisión y puede recibir splits.                    |
| `entity.onboarding.rejected`     | La revisión falló.                                                    |

### Cómo y cuándo se paga a los destinatarios

Los payouts siguen el calendario de liquidación de tu organización. En cada ciclo, Fintoc agrupa cada parte que se le debe a la misma Entity en **una única transferencia** a su cuenta de liquidación: un destinatario que aparece en 200 pagos durante un ciclo recibe una única transferencia.

Recupera un payout con `GET /v1/payouts/{id}`, lístalos con `GET /v1/payouts` y obtén los pagos que cubre con `GET /v1/payouts/{id}/resources`.

<Warning>
  Los eventos `payout.*` solo se emiten en modo `live`. Los payouts se liquidan contra balances reales, por lo que el modo `test` no los emite.
</Warning>

***

## Reglas y validaciones

La solicitud falla con `400 invalid_request_error` si se viola alguna regla.

**Por entrada**

* `entity_id` debe referenciar una Entity en estado `operational`
* El `country_code` de la Entity debe coincidir con la moneda del pago
* Para `flat`: `0 < amount <= amount_total`
* Para `percentage`: `0 < amount <= 10000`

**Globales**

* Entre 1 y 10 entradas
* Sin valores `entity_id` duplicados
* Todas las entradas deben usar el mismo `type`
* La suma de todos los montos, después de convertir los porcentajes, debe ser exactamente igual a `amount_total`
* Para `percentage`, los valores deben sumar exactamente `10000` bps

**Redondeo.** Los montos en porcentaje se calculan como `floor(amount_total * amount / 10000)`. La diferencia de redondeo acumulada se asigna a la entrada con `charge_processing_fee: true`.

### Errores

| Código                           | Significado                                                 |
| -------------------------------- | ----------------------------------------------------------- |
| `ENTITY_NOT_FOUND`               | El `entity_id` no existe en tu organización.                |
| `ENTITY_NOT_OPERATIONAL`         | La Entity no ha completado su onboarding.                   |
| `DUPLICATE_ENTITY_IN_SPLIT`      | El mismo `entity_id` aparece más de una vez.                |
| `MIXED_SPLIT_TYPES`              | El arreglo mezcla `flat` y `percentage`.                    |
| `SPLIT_SUM_MISMATCH`             | Los montos no suman exactamente `amount`.                   |
| `MISSING_CHARGE_PROCESSING_FEE`  | Ninguna entrada tiene `charge_processing_fee` en `true`.    |
| `MULTIPLE_CHARGE_PROCESSING_FEE` | Más de una entrada tiene `charge_processing_fee` en `true`. |

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "message": "Split rules must add up to the total amount",
    "code": "SPLIT_SUM_MISMATCH",
    "param": "split"
  }
}
```
