---
title: "Crear un checkout"
method: POST
path: "/checkouts"
tags: ["checkouts"]
---

# Crear un checkout

`POST /checkouts`

Crea una nueva sesión de checkout. Cada elemento del arreglo `items` puede declararse de dos maneras:

- **Con un producto existente** (recomendado): incluye `product_id` (o `price_id` si el producto tiene varios precios) y opcionalmente `quantity`. No envíes `name`, `amount_in_cents`, etc.; el producto ya tiene esa configuración.
- **Con detalles inline**: incluye `name`, `amount_in_cents`, `currency` y los demás campos del cobro. Recurrente creará un producto invisible bajo la cuenta y lo asociará al checkout.

Cuando usas `items`, no envíes `amount_in_cents` en la raíz del payload. El total del checkout se calcula sumando los ítems y debe alcanzar el mínimo de cobro: 500 para GTQ (Q5) o 100 para USD ($1). Un ítem individual, como envío, puede ser menor al mínimo si el total del checkout sí lo cumple.

Ejemplo mínimo con un producto ya creado:

```json
{
  "items": [
    { "product_id": "prod_1234567", "quantity": 1 }
  ],
  "success_url": "https://tusitio.com/exito",
  "cancel_url": "https://tusitio.com/cancelar"
}
```

### Cuotas en Checkout

En un checkout hospedado, tu integración controla qué opciones de cuotas se muestran con `available_installments`; el comprador escoge entre esas opciones al pagar. No envíes `installments` al crear un checkout para seleccionar la cantidad final de cuotas.

Para que un checkout muestre cuotas necesitas:

- Moneda `GTQ` (las cuotas no aplican en USD).
- Un cobro único (`charge_type: "one_time"`).
- Pagos con tarjeta habilitados en la cuenta, y una cuenta empresarial (las cuentas personales no pueden ofrecer cuotas).
- **No** hace falta que la cuenta esté verificada, ni habilitar nada con el adquirente.

Mientras la cuenta no complete su verificación sí aplica su tope de procesamiento sin verificación (Q500 en GTQ, $50 en USD, acumulado). Si el total del checkout pasa ese tope, `POST /checkouts` responde `422` con `code: amount_exceeds_unverified_limit` y no crea el checkout, porque el comprador se habría topado con el bloqueo de cuenta no verificada en la página de pago. Completa la verificación de la cuenta para quitar el tope.

Si quieres que el checkout solo permita una cantidad específica de cuotas, muestra únicamente esa opción y desactiva el pago con tarjeta de contado:

```json
{
  "items": [
    {
      "name": "Pago en 6 cuotas",
      "amount_in_cents": 15000,
      "currency": "GTQ",
      "charge_type": "one_time",
      "quantity": 1,
      "payment_method_types": [],
      "available_installments": [6]
    }
  ]
}
```

Para que el comprador elija entre varias opciones, envía una lista como `available_installments: [3, 6, 12]`. Para ocultar cuotas, envía `available_installments: []`.

El parámetro `installments` aplica solo en endpoints de cobro directo que lo incluyan, como `POST /terminal_session_commands`, donde tu sistema escoge la cantidad de cuotas. Las cuotas dependen de la moneda, la cuenta, el banco/emisor y la tarjeta del comprador; si la tarjeta no soporta la opción elegida, el cobro puede fallar con `unsupported_installments`.

## Headers

- `X-SECRET-KEY` string, required

## Request body

- object
  - `items` CheckoutsPostRequestBodyContentApplicationJsonSchemaItemsItems[] — Lista de productos/servicios a incluir en el checkout. Cada item puede usar `product_id` / `price_id` (producto existente) **o** los campos inline (`name`, `amount_in_cents`, `currency`, …). Los dos modos son excluyentes para un mismo item.
    - `product_id` string — ID de un producto existente en tu cuenta (lo obtienes al crear el producto o desde `GET /products`). Cuando lo envías, **no es necesario** incluir `name`, `amount_in_cents`, `currency` ni los demás campos inline — el checkout usa el primer precio del producto. Si el producto tiene múltiples precios, usa `price_id` para elegir uno específico.
    - `price_id` string — ID de un precio específico (lo obtienes en `prices[].id` al crear u obtener un producto). Úsalo cuando un mismo producto tenga varios precios y quieras elegir cuál cobrar. Tiene precedencia sobre `product_id` si envías ambos.
    - `quantity` integer — (Opcional) Cantidad. Si no incluyes una, el default es 1. El valor mínimo es 1 y el valor máximo es 9. Aplica tanto si usas `product_id`/`price_id` como si envías detalles inline.
    - `metadata` union
      - string
      - number, double
      - boolean
    - `name` string — (Solo modo inline) El nombre del producto. Ignorado si envías `product_id` o `price_id`.
    - `currency` 'GTQ' | 'USD' — (Solo modo inline) La moneda a cobrar.
    - `amount_in_cents` integer — (Solo modo inline) Monto a cobrar en centavos. El total del checkout debe ser al menos 500 para GTQ (Q5) o 100 para USD ($1); un ítem individual puede ser menor si el total cumple el mínimo.
    - `phone_requirement` 'none' | 'optional' | 'required' — (Solo modo inline, opcional) Requerimiento de teléfono para el formulario de checkout.
    - `address_requirement` 'none' | 'optional' | 'required' — (Solo modo inline, opcional) Requerimiento de dirección para el formulario de checkout.
    - `billing_info_requirement` 'none' | 'optional' | 'required' — (Solo modo inline, opcional) Requerimiento de información fiscal (NIT) para el formulario de checkout.
    - `image_url` string — (Solo modo inline, opcional) URL de la imagen del producto.
    - `charge_type` 'one_time' | 'recurring' — (Solo modo inline) Tipo de cargo.
    - `billing_interval` 'day' | 'week' | 'month' | 'year' — (Solo modo inline, para suscripciones) Intervalo de facturación.
    - `billing_interval_count` integer — (Solo modo inline, para suscripciones) Cada cuántos intervalos se cobra.
    - `periods_before_automatic_cancellation` integer — (Solo modo inline, opcional, para suscripciones) Número de períodos antes de cancelar automáticamente.
    - `free_trial_interval` 'week' | 'month' | 'year' — (Solo modo inline, opcional, para suscripciones) Intervalo del período de prueba gratuito.
    - `free_trial_interval_count` integer — (Solo modo inline, opcional, para suscripciones) Duración del período de prueba gratuito.
    - `proration_behavior` 'none' | 'create_prorations' — (Solo modo inline, opcional, para suscripciones mensuales) Controla el primer cobro cuando la suscripción se crea un día distinto al `billing_cycle_anchor_day`. `create_prorations` cobra solo los días restantes hasta el día de cobro (como ítem de crédito en el checkout); `none` cobra el monto completo. Ignorado si hay período de prueba gratuito.
    - `billing_cycle_anchor_day` integer — (Solo modo inline, opcional, para suscripciones mensuales) Día del mes (1–31) en que ocurrirán los cobros recurrentes. Combínalo con `proration_behavior` o `defer_to_billing_day` para controlar la fecha del primer cobro. Si el mes tiene menos días, se cobra el último día.
    - `defer_to_billing_day` boolean — (Solo modo inline, opcional, para suscripciones mensuales) Si es `true`, difiere el primer cobro hasta la próxima ocurrencia de `billing_cycle_anchor_day` (solo se guarda el método de pago al crear). Alternativa a `proration_behavior: create_prorations` cuando no quieres cobrar nada hasta el día de cobro.
    - `has_dynamic_pricing` boolean — (Solo modo inline, opcional) Indica si el producto debe usar precio dinámico. El precio se convierte en el 'monto a recibir' neto por el comercio. Disponible solo para pagos únicos.
    - `payment_method_types` CheckoutsPostRequestBodyContentApplicationJsonSchemaItemsItemsPaymentMethodTypesItems[] — (Solo modo inline, opcional) Métodos de pago habilitados para este ítem: `card` (tarjeta, pago de contado), `bank_transfer` (transferencia bancaria), `stablecoins` (dólares digitales), `balance` (Balance Recurrente). Al enviarlo, el ítem usa su propia configuración en vez de heredar la de la cuenta; los valores no reconocidos se ignoran. Las cuotas son un eje aparte (`available_installments`): `card` controla el pago de contado con tarjeta, no las cuotas. Para que el comprador solo pueda pagar en cuotas, omite `card` y envía `available_installments`.
    - `available_installments` CheckoutsPostRequestBodyContentApplicationJsonSchemaItemsItemsAvailableInstallmentsItems[] — (Solo modo inline, opcional) Opciones de cuotas (en meses) que se mostrarán en el checkout, independientes de `payment_method_types`. Solo aplica a `GTQ` y requiere que la cuenta tenga pagos con tarjeta habilitados. Usa `[]` para ocultar cuotas, o una lista como `[3]` para mostrar solo esa opción. Si envías `product_id` o `price_id`, este campo no sobreescribe el producto existente; configura las cuotas en el producto con `POST /products` o `PATCH /products`.
  - `mode` 'setup' — (Opcional) Modo del checkout. Envía `setup` para tokenizar una tarjeta sin cobrarla.
  - `success_url` string, uri — (Opcional) URL a dónde dirigir al comprador después de un pago exitoso
  - `cancel_url` string, uri — (Opcional) URL a dónde dirigir al comprador cuando abandona el checkout
  - `user_id` string — (Opcional) ID del usuario a quien pertenece el checkout. Prepopula los campos de información de usuario (nombre, email y teléfono del cliente si existe en tu cuenta).
  - `customer_id` string — (Opcional) ID del cliente en tu cuenta. Prepopula los campos de información de usuario (nombre, email y teléfono guardado del cliente). Si envías `customer_id` y `user_id`, se usa `customer_id`.
  - `metadata` union
    - string
    - number, double
    - boolean
  - `expires_at` string, date-time — (Opcional) Fecha en la que quieres que el checkout expire, en formato ISO 8601
  - `discount_code` string — (Opcional) Código de descuento/cupón a aplicar al checkout
  - `transfer_setups` CheckoutsPostRequestBodyContentApplicationJsonSchemaTransferSetupsItems[] — (Opcional, solo LIVE) Transferencias automáticas de fondos a otras cuentas de Recurrente. No está disponible en Sandbox. En pagos únicos envía `amount_in_cents`: un monto fijo que se transfiere una vez, cuando el cobro se completa. En suscripciones envía `amount_percent`: un porcentaje del total de cada factura, que se transfiere en cada cobro exitoso mientras la suscripción esté activa. Úsalo para dividir el pago: enrutar fondos a una cuenta conectada, o quedarte con una comisión cuando el checkout se crea en el contexto de una cuenta conectada mediante `X-ACCOUNT-ID`.
    - `amount_in_cents` integer — Monto fijo en centavos a transferir (solo pagos únicos). La suma de todas las transferencias no puede exceder el monto neto disponible después de fees, FEL e IVA.
    - `amount_percent` number, double — Porcentaje del total de cada factura a transferir (solo suscripciones), entre 0 y 100 con hasta 2 decimales. Al crear el checkout se valida que el porcentaje quepa en el monto neto disponible después de fees, FEL e IVA.
    - `recipient_id` string — ID de la cuenta de Recurrente que recibe los fondos (típicamente una cuenta conectada). No es una cuenta bancaria: los fondos se acreditan al balance de Recurrente de esa cuenta. Si se omite, se usa tu propia cuenta.
    - `purpose` 'fund_split' | 'platform_commission' — Usa `platform_commission` solo para una comisión que fluye desde la cuenta conectada indicada por `X-ACCOUNT-ID` hacia tu plataforma.

## Response `201`

Checkout creado exitosamente

- CheckoutsCreateCheckoutResponse201
  - `id` string, required — ID único del checkout
  - `status` 'unpaid' | 'paid' | 'payment_in_progress' | 'expired', required — Estado del checkout
  - `total_in_cents` integer — Monto total en centavos (después de descuentos)
  - `subtotal_in_cents` integer — Monto subtotal en centavos (antes de descuentos)
  - `discount` CheckoutsPostResponsesContentApplicationJsonSchemaDiscount — Descuento aplicado al checkout (null si no hay descuento)
    - `amount_in_cents` integer — Monto del descuento en centavos
    - `coupon` Coupon
      - `id` string — ID único del cupón
      - `name` string — Nombre o código del cupón
      - `discount_mode` 'code' | 'bank' | 'custom_bins' — Tipo de descuento
      - `display_name` string, nullable — Nombre visible para el cliente (usado en modo custom_bins)
      - `amount_off_in_cents` integer, nullable — Descuento fijo en centavos
      - `percent_off` number, double, nullable — Porcentaje de descuento
      - `automatically_applies` boolean — Si el descuento se aplica automáticamente en checkouts de tienda
      - `max_redemptions` integer, nullable — Número máximo de usos
      - `times_redeemed` integer — Número de veces que se ha redimido el descuento
      - `currency` string, nullable — Moneda del descuento fijo
      - `duration` 'once' | 'forever' — Duración del descuento para suscripciones
      - `expires_at` string, date-time, nullable — Fecha de expiración
      - `status` string — Estado del cupón
  - `currency` 'GTQ' | 'USD' — Moneda del checkout
  - `payment_method_types` CheckoutsPostResponsesContentApplicationJsonSchemaPaymentMethodTypesItems[] — Métodos de pago que se le ofrecerán al comprador en este checkout, ya resueltos según la configuración del producto/cuenta, la moneda y el tipo de cobro: `card` (tarjeta, pago de contado), `bank_transfer` (transferencia bancaria), `stablecoins` (dólares digitales), `balance` (Balance Recurrente). Las cuotas se exponen por separado en `available_installments`; `card` indica pago de contado, así que un checkout puede ofrecer cuotas (`available_installments` no vacío) sin incluir `card`.
  - `available_installments` integer[] — Opciones de cuotas (en meses) disponibles en este checkout, independientes de `payment_method_types`. Vacío si no se ofrecen cuotas.
  - `live_mode` boolean — Si el checkout está en modo producción (true) o prueba (false)
  - `success_url` string — URL de redirección en caso de pago exitoso
  - `cancel_url` string — URL de redirección en caso de cancelación
  - `expires_at` string, date-time — Fecha de expiración del checkout
  - `created_at` string, date-time — Fecha de creación
  - `metadata` union
    - string
    - number, double
    - boolean
  - `items` CheckoutItem[], required — Colección completa de filas mutables del checkout. No incluye descuentos, envío, fees ni prorrateos derivados.
    - `id` string, required — ID estable de esta fila del checkout. Úsalo para modificarla o eliminarla.
    - `price_id` string, required — ID del precio asociado. Puede repetirse en varias filas.
    - `quantity` integer, required — Cantidad absoluta de esta fila.
    - `metadata` union, required
      - string
      - number, double
      - boolean
  - `custom_fields` CheckoutCustomFieldValue[] — Valores recolectados de los campos personalizados. Si el checkout tiene múltiples productos, cada producto contribuye sus propias entradas — la `key` puede repetirse entre productos. Usa `field_id` como identificador canónico al reconciliar valores.
    - `field_id` string — Identificador canónico del campo (estable y único por producto). Úsalo para reconciliar valores; en checkouts con múltiples productos, dos entradas pueden tener la misma `key` pero distinto `field_id`.
    - `key` string — Identificador legible definido por el comerciante. Puede repetirse entre productos en el mismo checkout.
    - `type` 'text' | 'numeric' | 'dropdown'
    - `value` string
  - `transfer_setups` TransferSetup[] — Configuraciones de transferencia asociadas
    - `id` string — ID de la configuración de transferencia
    - `status` 'pending' | 'completed' | 'cancelled' | 'reversed' — En pagos únicos: `pending` mientras el cobro no se completa y `completed` cuando la transferencia se ejecutó. En suscripciones la configuración queda `pending` mientras la suscripción está activa. `cancelled` si el checkout, la suscripción o un reembolso canceló el setup antes de ejecutarlo; `reversed` si un reembolso devolvió una transferencia ya completada.
    - `amount_in_cents` integer, nullable — Monto fijo en centavos a transferir (pagos únicos). No puede exceder el monto neto disponible después de fees, FEL e IVA.
    - `amount_percent` number, double, nullable — Porcentaje del total de cada factura a transferir (suscripciones).
    - `currency` string — Moneda
    - `recipient_id` string — ID de la cuenta de Recurrente que recibe los fondos (no es una cuenta bancaria).
    - `purpose` 'fund_split' | 'platform_commission' — Semántica comercial de la transferencia. Usa `platform_commission` únicamente cuando el checkout pertenece a una cuenta conectada y los fondos regresan a su plataforma; ese valor habilita la reconciliación y facturación diaria de la comisión.
  - `latest_intent` CheckoutsPostResponsesContentApplicationJsonSchemaLatestIntent — Último intent unificado asociado. Su `id` usa el prefijo `in_…`.
    - `id` string
    - `type` string
    - `created_at` string, date-time
    - `data` CheckoutsPostResponsesContentApplicationJsonSchemaLatestIntentData
      - `auth_code` string, nullable
  - `payment` CheckoutsPostResponsesContentApplicationJsonSchemaPayment — Información del pago (si está pagado)
    - `id` string — ID del pago
    - `paymentable` CheckoutsPostResponsesContentApplicationJsonSchemaPaymentPaymentable
      - `type` string — Tipo de elemento pagable
      - `id` string — ID del elemento pagable
      - `tax_name` string, nullable — Nombre fiscal del comprador
      - `tax_id` string, nullable — ID fiscal del comprador
      - `address` Address
        - `address_line_1` string, nullable — Línea de dirección 1
        - `address_line_2` string, nullable — Línea de dirección 2
        - `city` string, nullable — Ciudad
        - `region` string, nullable — Región o departamento
        - `country` string, nullable — País
        - `zip_code` string, nullable — Código postal
      - `phone_number` string, nullable — Número de teléfono del comprador
  - `payment_method` CheckoutsPostResponsesContentApplicationJsonSchemaPaymentMethod — Método de pago utilizado
    - `id` string — ID del método de pago
    - `type` string — Tipo de método de pago
    - `card` CheckoutsPostResponsesContentApplicationJsonSchemaPaymentMethodCard
      - `last4` string — Últimos 4 dígitos de la tarjeta
      - `expiration_month` integer — Mes de expiración
      - `expiration_year` integer — Año de expiración
      - `network` string — Red de la tarjeta
      - `issuer_name` string, nullable — Nombre del banco emisor
    - `address` Address
      - `address_line_1` string, nullable — Línea de dirección 1
      - `address_line_2` string, nullable — Línea de dirección 2
      - `city` string, nullable — Ciudad
      - `region` string, nullable — Región o departamento
      - `country` string, nullable — País
      - `zip_code` string, nullable — Código postal
    - `phone_number` string, nullable — Número de teléfono asociado al método de pago
  - `checkout_url` string — URL del checkout donde el usuario puede pagar

## Other responses

- `400` — Error de validación
- `422` — El total supera lo que la cuenta puede procesar sin verificarse (`amount_exceeds_unverified_limit`). No se crea el checkout: nadie podría pagarlo mientras la cuenta siga sin verificar.

---

[API](https://skmtc.dev/recurrente/apis/referencia-api.md) · [All operations](https://skmtc.dev/recurrente/apis/referencia-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/recurrente/referencia-api/revisions/f494a078482c/schema)
