Opciones de facturación para suscripciones

Al crear un producto o checkout con charge_type: "recurring", tres campos trabajan juntos para controlar cuándo y cuánto se cobra la primera vez:

CampoQué controla
billing_cycle_anchor_dayDía del mes (1–31) al que se anclan los cobros recurrentes
proration_behaviorSi el primer cobro se prorratea (create_prorations) o no (none)
defer_to_billing_daySi el primer cobro se difiere hasta el día de anclaje

billing_cycle_anchor_day por sí solo no cambia el primer cobro: únicamente surte efecto cuando se combina con proration_behavior: create_prorations o defer_to_billing_day: true.

Qué pasa en cada combinación

Un cliente se suscribe el 10 de abril a un plan mensual de GTQ 300, con billing_cycle_anchor_day: 15:

ConfiguraciónPrimer cobro (10 de abril)Siguiente cobro
Ninguno (proration_behavior: none, defer_to_billing_day: false)GTQ 30010 de mayo
proration_behavior: create_prorationsGTQ 50 (5 días: 10→15 de abril)15 de abril (GTQ 300)
defer_to_billing_day: trueGTQ 0 (solo se guarda la tarjeta)15 de abril (GTQ 300)

A partir del segundo cobro, los cobros ocurren el día 15 de cada mes.

Si una suscripción tiene período de prueba gratuito (free_trial_interval), tanto el prorrateo como el diferimiento se ignoran. El trial toma precedencia.

Ejemplo 1: Cobro proporcional desde el primer día

Cobra solo los días restantes hasta el día de cobro. El siguiente cobro será el monto completo el día de anclaje.

$curl -X POST https://app.recurrente.com/api/checkouts \
> -H "X-PUBLIC-KEY: tu_llave_publica" \
> -H "X-SECRET-KEY: tu_llave_privada" \
> -H "Content-Type: application/json" \
> -d '{
> "items": [
> {
> "name": "Membresía Mensual",
> "currency": "GTQ",
> "amount_in_cents": 30000,
> "charge_type": "recurring",
> "billing_interval": "month",
> "billing_interval_count": 1,
> "billing_cycle_anchor_day": 15,
> "proration_behavior": "create_prorations"
> }
> ],
> "success_url": "https://tusitio.com/gracias",
> "cancel_url": "https://tusitio.com/cancelado"
> }'

En el checkout, el cliente verá el monto mensual completo menos un ítem de crédito por los días no usados. La diferencia es el monto prorrateado que se cobra hoy.

Ejemplo 2: Diferir el primer cobro hasta el día de cobro

No cobra nada al crear la suscripción. Solo tokeniza la tarjeta (vía SetupIntent); el primer cobro completo ocurre automáticamente en la próxima fecha de anclaje.

$curl -X POST https://app.recurrente.com/api/checkouts \
> -H "X-PUBLIC-KEY: tu_llave_publica" \
> -H "X-SECRET-KEY: tu_llave_privada" \
> -H "Content-Type: application/json" \
> -d '{
> "items": [
> {
> "name": "Membresía Mensual",
> "currency": "GTQ",
> "amount_in_cents": 30000,
> "charge_type": "recurring",
> "billing_interval": "month",
> "billing_interval_count": 1,
> "billing_cycle_anchor_day": 15,
> "defer_to_billing_day": true
> }
> ],
> "success_url": "https://tusitio.com/gracias",
> "cancel_url": "https://tusitio.com/cancelado"
> }'

Cuando el cliente completa el checkout, recibirás un webhook setup_intent.succeeded (no payment_intent.succeeded) porque no hubo cobro. El webhook subscription.create llega al mismo tiempo con la suscripción ya activa. El primer cobro real dispara payment_intent.succeeded el día de anclaje.

proration_behavior: create_prorations y defer_to_billing_day: true son mutuamente excluyentes: si ambos están activos, el prorrateo toma precedencia y el primer cobro se hace hoy con el monto prorrateado.

Cómo leer la próxima fecha de cobro

Después de crear una suscripción, la respuesta de GET /api/subscriptions/{id} incluye current_period_end, que es la fecha del siguiente cobro automático:

1{
2 "id": "su_nehndm7j",
3 "status": "active",
4 "current_period_start": "2050-04-10T15:00:00Z",
5 "current_period_end": "2050-04-15T15:00:00Z",
6 "next_payment_attempt_at": null
7}
  • Si usaste proration_behavior: create_prorations, current_period_end apunta a la próxima fecha de anclaje (cuando se hará el primer cobro completo).
  • Si usaste defer_to_billing_day: true, current_period_end apunta al día de anclaje (cuando se hará el primer cobro).
  • Sin ninguno, current_period_end es created_at + billing_interval.

Consideraciones

  • Solo funciona con intervalos mensuales. Los campos billing_cycle_anchor_day, proration_behavior y defer_to_billing_day aplican únicamente cuando billing_interval es month.
  • Si el mes tiene menos días que billing_cycle_anchor_day, el cobro se hace el último día del mes. Por ejemplo, billing_cycle_anchor_day: 31 cobra el 28 en febrero.
  • Cambiar el precio de una suscripción activa no es posible vía API (PUT /api/products/{id} no permite editar precios con suscripciones activas).