> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.recurrente.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.recurrente.com/_mcp/server.

# Guardar y reutilizar métodos de pago

> Tokeniza una tarjeta con un checkout seguro y cóbrala después con montos variables

Usa este flujo cuando necesitas guardar la tarjeta de un cliente y cobrarla después sin que vuelva a ingresar sus datos. Es útil para cobros mensuales de monto variable, cargos por consumo, cargos adicionales a una suscripción o renovaciones administradas por tu sistema.

El cliente siempre ingresa la tarjeta en un checkout alojado por Recurrente. Tu sistema guarda únicamente el `payment_method_id` retornado por Recurrente y lo usa para crear cobros futuros.

> **Note**
>
> Antes de guardar una tarjeta, asegúrate de que el cliente acepte términos claros sobre cómo se harán los cobros futuros: frecuencia, cómo se calcula el monto, cuándo se cobra y cómo puede cancelar o actualizar su método de pago.

## Flujo general

1. Crea o identifica el cliente en Recurrente.
2. Crea un checkout con `mode: "setup"` para tokenizar la tarjeta sin cobrarla.
3. Envía el `checkout_url` al cliente.
4. Cuando el cliente completa el checkout, guarda el `payment_method.id`.
5. Usa `POST /api/one_time_payments` para cobrar ese método guardado cuando tengas el monto final.

## Paso 1: Crear o identificar el cliente

Si ya tienes un cliente en Recurrente, usa su `customer_id` al crear el checkout de tokenización. Si solo tienes el `user_id`, también puedes enviarlo.

```bash
curl -X POST https://app.recurrente.com/api/customers \
  -H "X-SECRET-KEY: tu_llave_secreta" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "cliente@example.com",
    "full_name": "Ana Lopez"
  }'
```

La respuesta incluye el `id` del cliente:

```json
{
  "id": "cus_abc123",
  "user_id": "us_123456",
  "email": "cliente@example.com",
  "name": "Ana Lopez"
}
```

## Paso 2: Crear un checkout de tokenización

Crea un checkout con `mode: "setup"`. Este checkout no cobra nada; solo guarda la tarjeta para usos futuros.

Al guardar una tarjeta nueva, Recurrente verifica la cuenta con una autorización de monto cero, sin capturar dinero. Una autorización aprobada con un token permanente genera `setup_intent.succeeded`; un rechazo o una verificación fallida genera `setup_intent.cancelled` y la tarjeta no queda habilitada para cobros. Guardar la tarjeta no garantiza que los cobros futuros sean aprobados ni sustituye la autenticación que pueda necesitar un pago posterior.

```bash
curl -X POST https://app.recurrente.com/api/checkouts \
  -H "X-SECRET-KEY: tu_llave_secreta" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "setup",
    "customer_id": "cus_abc123",
    "success_url": "https://tusitio.com/metodo-guardado",
    "cancel_url": "https://tusitio.com/metodo-cancelado",
    "metadata": {
      "billing_agreement_id": "ba_789"
    }
  }'
```

Recurrente responde con una URL alojada:

```json
{
  "id": "ch_eegw9j5zgqoae3ms",
  "checkout_url": "https://app.recurrente.com/checkout-session/ch_eegw9j5zgqoae3ms"
}
```

Redirige al cliente a `checkout_url` o envíasela por email, WhatsApp o dentro de tu app.

## Paso 3: Guardar el payment\_method\_id

Cuando el cliente completa el checkout, Recurrente emite `setup_intent.succeeded`. El método guardado viene dentro de `data.checkout.payment_method`.

```json
{
  "eventType": "setup_intent.succeeded",
  "eventId": "act_123",
  "data": {
    "event_type": "setup_intent.succeeded",
    "status": "succeeded",
    "checkout": {
      "id": "ch_eegw9j5zgqoae3ms",
      "status": "paid",
      "payment_method": {
        "id": "pay_m_7v5ie3pw",
        "type": "card",
        "card": {
          "last4": "4242",
          "network": "visa"
        }
      }
    },
    "customer": {
      "id": "cus_abc123",
      "email": "cliente@example.com"
    }
  }
}
```

Guarda `data.checkout.payment_method.id`. Ese es el token que usarás para cobros futuros.

> **Note**
>
> Si no recibes webhooks, consulta el checkout después de que el cliente vuelva a tu `success_url`: `GET /api/checkouts/{id}`. Cuando el checkout está completado, la respuesta incluye `payment_method.id`.

```bash
curl https://app.recurrente.com/api/checkouts/ch_eegw9j5zgqoae3ms \
  -H "X-SECRET-KEY: tu_llave_secreta"
```

```json
{
  "id": "ch_eegw9j5zgqoae3ms",
  "status": "paid",
  "payment_method": {
    "id": "pay_m_7v5ie3pw",
    "type": "card",
    "card": {
      "last4": "4242",
      "network": "visa"
    }
  }
}
```

## Paso 4: Cobrar después con un monto variable

Cuando tu sistema sabe el monto a cobrar, crea un pago único con el `payment_method_id` guardado. Usa una llave de idempotencia única por intento de cobro para evitar duplicados si necesitas reintentar la solicitud.

```bash
curl -X POST https://app.recurrente.com/api/one_time_payments \
  -H "X-SECRET-KEY: tu_llave_secreta" \
  -H "Idempotency-Key: invoice-2026-06-cus-abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_method_id": "pay_m_7v5ie3pw",
    "items": [
      {
        "name": "Consumo de junio",
        "amount_in_cents": 87500,
        "currency": "GTQ",
        "quantity": 1
      }
    ]
  }'
```

Respuesta exitosa:

```json
{
  "object": "one_time_payment",
  "id": "on_123456789",
  "status": "paid"
}
```

Si el banco rechaza el cobro, Recurrente responde con error y no debes reusar la misma `Idempotency-Key` para un nuevo intento de cobro. Crea un intento nuevo con una llave distinta cuando el cliente confirme que desea reintentar o actualice su método de pago.

## Cobros variables asociados a una suscripción

Si el cliente ya tiene una suscripción y quieres agregar cargos variables, tienes dos opciones.

Para cobrar inmediatamente el método guardado de la suscripción:

```bash
curl -X POST https://app.recurrente.com/api/one_time_payments \
  -H "X-SECRET-KEY: tu_llave_secreta" \
  -H "Idempotency-Key: su-nehndm7j-extra-junio" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription_id": "su_nehndm7j",
    "amount_in_cents": 5000,
    "description": "Cargo por consumo adicional",
    "mode": "now"
  }'
```

Para agregar el cargo al próximo ciclo de la suscripción:

```bash
curl -X POST https://app.recurrente.com/api/one_time_payments \
  -H "X-SECRET-KEY: tu_llave_secreta" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription_id": "su_nehndm7j",
    "amount_in_cents": 5000,
    "description": "Cargo por consumo adicional",
    "mode": "next_cycle"
  }'
```

`mode: "next_cycle"` crea un `invoice_item` pendiente. También admite montos negativos para créditos.

## Actualizar la tarjeta guardada

Cuando el cliente necesite cambiar tarjeta, crea otro checkout `mode: "setup"`. Al completarlo, guarda el nuevo `payment_method.id`.

Si el método pertenece a una suscripción, actualízala con:

```bash
curl -X PUT https://app.recurrente.com/api/subscriptions/su_nehndm7j \
  -H "X-SECRET-KEY: tu_llave_secreta" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_method_id": "pay_m_nueva123"
  }'
```

Si solo usas cobros variables con `POST /api/one_time_payments`, guarda el nuevo `payment_method_id` en tu sistema y úsalo para los siguientes cobros.

## Consideraciones

* `POST /api/one_time_payments` requiere que tu cuenta tenga cobros únicos habilitados.
* El `payment_method_id` debe pertenecer a un cliente de tu cuenta.
* Los cobros futuros pueden fallar aunque la tokenización haya sido exitosa. Maneja errores de banco y permite que el cliente actualice su tarjeta.
* Los webhooks reales solo se envían para eventos de producción. Para validar el flujo completo de tokenización, usa una llave LIVE; el checkout de `setup` no cobra un monto.
* Nunca recolectes ni almacenes números de tarjeta directamente. Usa siempre el checkout alojado de Recurrente.