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

# Guardar un método de pago para cobros futuros

> >-

Guarda el método de pago de un cliente una vez y cóbralo más tarde para pagos on-demand o de monto variable, sin crear una suscripción recurrente.

A diferencia del [flujo de suscripción](/es/docs/payments/accept-recurring-payments), el flujo de setup no acopla el registro con facturación recurrente, por lo que tú decides cuándo y cuánto cobrar.

Configura un método de pago y cóbralo más tarde en cuatro pasos:

1. En tu backend, crea una Checkout Session con `flow: setup`.
2. Redirige a tu cliente para completar el registro en la página de checkout alojada por Fintoc.
3. Maneja los eventos posteriores a la sesión para guardar el `payment_method` y `customer`.
4. Crea cargos contra el método de pago guardado usando la API de Payment Intent.

El siguiente diagrama muestra cómo funciona el flujo de setup:

<Frame>
  <img src="https://mintcdn.com/fintoc-49b8bee8/YQmOnq8Zegydl6oL/images/631ce18a4aba7161afa8a940208b2248df08d83804b3c1060792ec1e4d58cd54-setup-diagram.png?fit=max&auto=format&n=YQmOnq8Zegydl6oL&q=85&s=2456dfcdc845a652cbae71a182a3a9fa" width="1824" height="1330" data-path="images/631ce18a4aba7161afa8a940208b2248df08d83804b3c1060792ec1e4d58cd54-setup-diagram.png" />
</Frame>

***

## Crea una Checkout Session

El [Checkout Session](/es/reference/payments-api/checkout-sessions/checkout-session-object) con el flujo `setup` representa tu intención de guardar un método de pago para cobros futuros, sin crear una suscripción recurrente.

Usando tu [Secret Key](/es/docs/home/api-keys), crea una Checkout Session en tu backend con `flow` en `setup`:

**Servidor**

```curl theme={null}
curl --request POST "https://api.fintoc.com/v2/checkout_sessions" \
  --header "Authorization: YOUR_SECRET_API_KEY" \
  --header "Content-Type: application/json" \
  --data-raw '{
    "flow": "setup",
    "currency": "CLP",
    "success_url": "https://merchant.com/success",
    "cancel_url": "https://merchant.com/cancel",
    "customer_data": {
      "tax_id": {
        "type": "cl_rut",
        "value": "11.111.111-1"
      },
      "name": "Felipe Castro",
      "email": "jon@snow.com"
    },
    "metadata": {}
  }'
```

```javascript Node theme={null}
const { Fintoc } = require('fintoc');

const fintoc = new Fintoc('YOUR_SECRET_API_KEY');

const checkoutSession = await fintoc.checkoutSessions.create({
  flow: 'setup',
  currency: 'CLP',
  success_url: 'https://merchant.com/success',
  cancel_url: 'https://merchant.com/cancel',
  customer_data: {
    tax_id: {
      type: 'cl_rut',
      value: '11.111.111-1'
    },
    name: 'Felipe Castro',
    email: 'jon@snow.com'
  },
  metadata: {}
});
```

```python theme={null}
from fintoc import Fintoc

client = Fintoc('YOUR_SECRET_API_KEY')

checkout_session = client.checkout_sessions.create(
    flow='setup',
    currency='CLP',
    success_url='https://merchant.com/success',
    cancel_url='https://merchant.com/cancel',
    customer_data={
        'tax_id': {
            'type': 'cl_rut',
            'value': '11.111.111-1'
        },
        'name': 'Felipe Castro',
        'email': 'jon@snow.com'
    },
    metadata={}
)
```

Después de crear la Checkout Session, Fintoc responde con los detalles de la sesión y un `redirect_url`:

```json theme={null}
{
  "id": "cs_li5531onlFDi235",
  "object": "checkout_session",
  "flow": "setup",
  "status": "created",
  "currency": "CLP",
  "customer": {
    "id": "cus_NffrFeUfNV2Hib",
    "object": "customer",
    "email": "jon@snow.com",
    "metadata": {},
    "name": "Felipe Castro",
    "tax_id": {
      "type": "cl_rut",
      "value": "11.111.111-1"
    }
  },
  "success_url": "https://merchant.com/success",
  "cancel_url": "https://merchant.com/cancel",
  "redirect_url": "https://pay.fintoc.com/checkout/cs_li5531onlFDi235",
  "metadata": {}
}
```

| Parámetro                | Ejemplo                           | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------------ | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `flow`                   | `setup`                           | **Requerido.** Tipo de flujo para la sesión. Uno de `payment`, `setup` o `subscription`. Usa `setup` para guardar un método de pago sin cobrar.                                                                                                                                                                                                                                                                             |
| `currency`               | `CLP`                             | **Requerido.** Código ISO 4217 de tres letras de la moneda. Uno de `CLP` o `MXN`.                                                                                                                                                                                                                                                                                                                                           |
| `success_url`            | `https://merchant.com/success`    | **Requerido.** URL a la que redirigir al cliente después de un registro exitoso.                                                                                                                                                                                                                                                                                                                                            |
| `cancel_url`             | `https://merchant.com/cancel`     | **Requerido.** URL a la que redirigir al cliente si cancela el registro.                                                                                                                                                                                                                                                                                                                                                    |
| `payment_method_types`   | `["pac"]`                         | Métodos de pago disponibles para el registro. Uno o más de `pac` (débito directo chileno), `direct_debit` (México) o `card`.                                                                                                                                                                                                                                                                                                |
| `customer`               | `cus_3B2bODrQFje7ZVkT69xyaTSDwXQ` | **Requerido si no hay `customer_data`.** ID de un `Customer` existente.                                                                                                                                                                                                                                                                                                                                                     |
| `customer_data`          | `{ tax_id: {...}, ... }`          | **Requerido si no hay `customer`.** Datos para crear un customer en línea. Envía al menos uno de `email` o `tax_id`. Si ya existe un `Customer` con el mismo `tax_id`, la solicitud devuelve un error `409 Conflict`. Para reutilizar un `Customer` existente, envía su `id` en `customer` en lugar de `customer_data`.                                                                                                     |
| `payment_method_options` | `{ pac: { ... } }`                | Opciones específicas para cada método de pago, indexadas por los valores de `payment_method_types` (por ejemplo, `pac`). Para `pac`, restringe el `sender_account` con `types` (`checking_account`), `institution_id` o `holder_id`; para `card`, restringe `kinds` (`credit`, `debit`). Para no aplicar ninguna restricción, omite la opción en lugar de enviar un arreglo vacío, porque un arreglo vacío no permite nada. |
| `metadata`               | `{ "order": "987654321" }`        | Conjunto de pares clave-valor para almacenar información adicional.                                                                                                                                                                                                                                                                                                                                                         |

<Info>
  ****Diferencia con el flujo de suscripción****

  Cuando creas una Checkout Session con `flow: setup`, Fintoc registra el método de pago del cliente y crea un `PaymentMethod`, pero **no** crea una `subscription` ni agenda cobros recurrentes. Tú controlas cuándo y cuánto cobrar creando payment intents futuros.
</Info>

### Incluir datos del cliente

Al crear una Checkout Session para setup, debes incluir información del cliente.

| Atributo   | Tipo     | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tax_id`   | `object` | **Requerido si no hay `email`.** Objeto que identifica al cliente a nivel fiscal o regulatorio. El `type` es uno de `cl_rut` (tax ID chileno, RUT) o `mx_rfc` (tax ID mexicano, RFC), y `value` es el identificador fiscal como string. Consulta el [objeto Customer](/es/reference/payments-api/checkout-sessions/checkout-session-object#customer-object). Si ya existe un `Customer` con el mismo `tax_id`, la solicitud devuelve un error `409 Conflict`. Para reutilizar un `Customer` existente, envía su `id` en `customer` en lugar de `customer_data`. |
| `name`     | `string` | Nombre completo del cliente.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `email`    | `string` | **Requerido si no hay `tax_id`.** Email usado para notificar al cliente sobre el registro y los cobros.                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `metadata` | `object` | Conjunto de pares clave-valor para almacenar información adicional.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |

***

## Redirige al cliente para completar el registro

A continuación, redirige al cliente al `redirect_url` de la respuesta. El cliente ve la página de checkout alojada por Fintoc, donde completa el registro.

Después de que el cliente complete el registro, Fintoc lo redirige automáticamente a tu `success_url` o `cancel_url`, según el resultado.

**Cliente**

```javascript theme={null}
window.location.assign(REDIRECT_URL_FROM_YOUR_BACKEND);
```

***

## Maneja los eventos posteriores a la sesión

Siempre usa [webhooks](/es/docs/resources/webhooks-walkthrough) para determinar el resultado final. Los clientes pueden cerrar la pestaña, perder conexión o nunca llegar a tu `success_url`.

### Eventos de Checkout Session

Cuando el registro se completa, Fintoc envía un evento `checkout_session.finished` con la información del `customer` y `payment_method`:

```json theme={null}
{
  "id": "evt_a4xK32BanKWYn",
  "object": "event",
  "type": "checkout_session.finished",
  "data": {
    "id": "cs_li5531onlFDi235",
    "object": "checkout_session",
    "mode": "live",
    "flow": "setup",
    "status": "finished",
    "currency": "CLP",
    "customer": {
      "id": "cus_NffrFeUfNV2Hib",
      "name": "Felipe Castro",
      "email": "jon@snow.com",
      "tax_id": {
        "type": "cl_rut",
        "value": "11.111.111-1"
      }
    },
    "payment_method": "pm_NffrFeUfNV2Hib",
    "metadata": {},
    "success_url": "https://merchant.com/success",
    "cancel_url": "https://merchant.com/cancel"
  }
}
```

### Eventos de Payment Method

Fintoc también envía un evento `payment_method.activated`. El campo `data` del evento contiene un `PaymentMethod` como este:

```json theme={null}
{
  "id": "pm_NffrFeUfNV2Hib",
  "object": "payment_method",
  "card": null, 
  "created_at": "2021-10-15T15:22:11.474Z",
  "customer": "cus_NffrFeUfNV2Hib",
  "mode": "live",
  "metadata": {},
  "pac": {
    "account_holder_id": "11.111.111-1",
    "account_number": "19831940978",
    "account_type": "checking_account",
    "institution": {
      "id": "cl_banco_falabella",
      "country": "cl",
      "name": "Banco Falabella"
    },
    "status": "active"
  },
  "type": "pac"
}
```

Guarda tanto el ID del `customer` como el ID del `payment_method`. Los necesitas para crear cargos más adelante.

### Resumen de eventos

Debes suscribirte a todos los siguientes eventos posteriores a la sesión:

| Evento                      | Descripción                                                      | Acción recomendada                                   |
| :-------------------------- | :--------------------------------------------------------------- | :--------------------------------------------------- |
| `checkout_session.finished` | Sesión completada exitosamente. Método registrado.               | Guarda `customer` + `payment_method`.                |
| `checkout_session.expired`  | La sesión expiró antes de que el cliente completara el registro. | Permite al cliente reintentar.                       |
| `payment_method.activated`  | El método de pago está activo y listo para cargos.               | Crea cargos contra este método cuando sea necesario. |
| `payment_method.canceled`   | El método de pago está cancelado y no disponible para cargos.    | Deja de crear cargos contra el método.               |

***

## Crear un cargo contra el método de pago guardado

Una vez que tienes un `payment_method` guardado, cóbralo creando un Payment Intent con los IDs del `payment_method` y `customer`:

**Servidor**

```curl theme={null}
curl --request POST "https://api.fintoc.com/v2/payment_intents" \
  --header "Authorization: YOUR_SECRET_API_KEY" \
  --header "Content-Type: application/json" \
  --data-raw '{
    "amount": 150000,
    "currency": "CLP",
    "customer": "cus_NffrFeUfNV2Hib",
    "payment_method": "pm_NffrFeUfNV2Hib",
    "metadata": {
      "order_id": "order_98765"
    }
  }'
```

```javascript Node theme={null}
const { Fintoc } = require('fintoc');

const fintoc = new Fintoc('YOUR_SECRET_API_KEY');

const paymentIntent = await fintoc.paymentIntents.create({
  amount: 150000,
  currency: 'CLP',
  customer: 'cus_NffrFeUfNV2Hib',
  payment_method: 'pm_NffrFeUfNV2Hib',
  metadata: {
    order_id: 'order_98765'
  }
});
```

```python theme={null}
from fintoc import Fintoc

client = Fintoc('YOUR_SECRET_API_KEY')

payment_intent = client.payment_intents.create(
    amount=150000,
    currency='CLP',
    customer='cus_NffrFeUfNV2Hib',
    payment_method='pm_NffrFeUfNV2Hib',
    metadata={
        'order_id': 'order_98765'
    }
)
```

| Parámetro        | Ejemplo                         | Descripción                                                                                                                                                                                                  |
| ---------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `amount`         | `150000`                        | **Requerido.** Un entero positivo que representa el monto a cobrar en la unidad menor de la moneda (por ejemplo, `150000` para `CLP 150000`, ya que CLP no tiene unidad menor, o `10000` para `MXN 100.00`). |
| `currency`       | `CLP`                           | **Requerido.** Código ISO 4217 de tres letras de la moneda. Uno de `CLP` o `MXN`.                                                                                                                            |
| `customer`       | `cus_NffrFeUfNV2Hib`            | **Requerido.** ID del `Customer` a cobrar.                                                                                                                                                                   |
| `payment_method` | `pm_NffrFeUfNV2Hib`             | **Requerido.** El ID del método de pago guardado.                                                                                                                                                            |
| `metadata`       | `{ "order_id": "order_98765" }` | Conjunto de pares clave-valor para almacenar información adicional.                                                                                                                                          |

Fintoc responde con el Payment Intent creado:

```json theme={null}
{
  "id": "pi_34i0T5AWRfIDMOJnhq9BgxXUiyt",
  "object": "payment_intent",
  "status": "created",
  "amount": 150000,
  "currency": "CLP",
  "customer": "cus_NffrFeUfNV2Hib",
  "payment_method": "pm_NffrFeUfNV2Hib",
  "metadata": {
    "order_id": "order_98765"
  }
}
```

### Maneja los eventos de pago

Suscríbete a los siguientes eventos para rastrear el resultado del pago:

| Evento                     | Descripción           | Acción recomendada                             |
| -------------------------- | --------------------- | ---------------------------------------------- |
| `payment_intent.succeeded` | El cargo fue exitoso. | Cumple la orden y confirma al cliente.         |
| `payment_intent.failed`    | El cargo falló.       | Reintenta el cargo o pide otro método de pago. |

***

## Prueba tu integración

Usando tu [Secret Key de modo de prueba](/es/docs/resources/test-mode), crea Checkout Sessions que simulan el flujo completo de setup y pago sin mover dinero.

### 1) Crea una Checkout Session de setup usando credenciales de prueba

Crea una Checkout Session con `flow: setup` usando tu Secret Key de modo de prueba. Completa el flujo de registro en la página alojada por Fintoc usando las siguientes credenciales:

**Credenciales de prueba:**

#### PAC:

* Usuario (RUT): `11.111.111-1`
* Contraseña: `jonsnow`

Selecciona la cuenta según el resultado final que quieras probar:

| Número de cuenta | Tipo de MFA                | Código correcto      |
| :--------------- | :------------------------- | :------------------- |
| 813990168        | Dispositivo de seguridad   | `000000`             |
| 422159212        | Aplicación móvil - Exitoso | `N/A`                |
| 5233137377       | Aplicación móvil - Fallido | `N/A`                |
| 170086177        | SMS                        | `0000`               |
| 746326042        | Tarjeta de coordenadas     | `['00', '00', '00']` |

#### Tarjeta:

| Número de tarjeta | Fecha de expiración    | CVV        | Nombre del titular | Código de challenge 3DS | Resultado final                      |
| ----------------- | :--------------------- | :--------- | :----------------- | :---------------------- | ------------------------------------ |
| 4111111111111111  | Cualquier fecha futura | Cualquiera | Cualquiera         | -                       | ✅ Exitoso                            |
| 4456524869770255  | Cualquier fecha futura | Cualquiera | Cualquiera         | 1234                    | ✅ Exitoso si el código es correcto   |
| 4574441215190335  | Cualquier fecha futura | Cualquiera | Cualquiera         | -                       | ❌ Fallido por credenciales inválidas |
| 4349003000047015  | Cualquier fecha futura | Cualquiera | Cualquiera         | -                       | ❌ Fallido por transacción rechazada  |

### 2) Verifica el método de pago guardado

Después de completar el registro de prueba, deberías recibir los eventos webhook `checkout_session.finished` y `payment_method.activated`. Verifica que:

* El ID del `payment_method` esté presente en el payload del evento.
* El ID del `customer` coincida con el cliente que registraste.

### 3) Crea un cargo de prueba contra el método guardado

Usando los IDs del `customer` y `payment_method` del paso 2, crea un Payment Intent contra el método guardado. Verifica que:

* Recibas el evento `payment_intent.succeeded`.
* El monto coincida con el que enviaste.
* El método de pago usado sea el PAC o tarjeta guardada.

<Info>
  El modo de prueba aún no soporta guardar un Payment Method en México.
</Info>

<br />
