Ciclo de Vida de la Suscripción
Estados
draft → confirmed → trialing → active ↔ past_due → canceled
↕
paused
| Estado | Descripción |
|---|---|
| draft | Borrador. Puede editarse libremente antes de ser confirmada |
| confirmed | Confirmada, esperando activación |
| trialing | En período de prueba gratuito |
| active | Activa, generando cobros recurrentes |
| past_due | Con pago atrasado |
| paused | Pausada temporalmente (sin cobros) |
| canceled | Cancelada (estado terminal) |
Creación de una Suscripción
Para crear una suscripción, informe:
| Campo | Obligatorio | Descripción |
|---|---|---|
| Cuenta de cobro | Sí | La cuenta del cliente que será cobrada |
| Plan | No | Plan preconfigurado (o ítems sueltos) |
| Ciclo de cobro | Sí | monthly, quarterly, semiannual o annual |
| Método de cobro | Sí | charge_automatically, manual_charge o manual_invoice |
| Período de prueba | No | 0 a 90 días de prueba gratuita |
| Código de descuento | No | Descuento a aplicar |
| Ítems | No | Productos, precios y cantidades (si no usa plan) |
| Empresa | No | Empresa emisora (para multi-empresa) |
Flujo de Creación
- La suscripción se crea con estado
draft - Los ítems se crean a partir de los ítems proporcionados o de los ítems del plan
- El uso del código de descuento se incrementa (si fue proporcionado)
- Se emite un evento
subscription.db.created
Confirmación y Activación
Confirmar (draft → confirmed)
Confirma la suscripción, opcionalmente creando la primera factura.
Activar (draft/confirmed → trialing/active)
- Si tiene período de prueba: el estado cambia a
trialing, contrialStartytrialEnddefinidos - Si no tiene prueba: el estado cambia directamente a
active - Define las fechas del período de cobro (
currentPeriodStart,currentPeriodEnd)
Vista previa de la Activación
Antes de activar, es posible visualizar:
- Fecha de inicio, si habrá prueba, duración de la prueba
- Fechas del período de cobro
- Fecha de la primera factura
- Totales de setup y recurrentes
Renovación
La renovación es automática mediante un worker diario (00:00 UTC):
- Busca suscripciones activas con
currentPeriodEnd ≤ ahora - Si
cancelAtPeriodEnd = true: cancela la suscripción - De lo contrario: avanza al siguiente período de cobro
- Usa lock optimista para prevenir renovaciones duplicadas
Cálculo de los Períodos
| Ciclo | Duración |
|---|---|
monthly | +1 mes |
quarterly | +3 meses |
semiannual | +6 meses |
annual | +1 año |
Cancelación
Cancelar al Fin del Período (cancelAtPeriodEnd: true)
- Define la flag
cancelAtPeriodEnd - La suscripción continúa activa hasta el fin del período actual
- En la renovación, el estado cambia a
canceled - Puede revertirse antes de la fecha de cancelación
Cancelar Inmediatamente (cancelAtPeriodEnd: false)
- El estado cambia a
canceledinmediatamente - La fecha de cancelación se registra
- El motivo de la cancelación se almacena
Revertir a Confirmado
Las suscripciones activas pueden revertirse a confirmed para permitir la edición antes de reactivar. Útil para corregir errores antes de la próxima renovación.
Eliminación
Solo las suscripciones en draft, confirmed o canceled pueden eliminarse, y únicamente si no existen facturas con pagos.
Cálculo del MRR
El MRR (Monthly Recurring Revenue) se calcula normalizando el valor total a mensual:
| Ciclo | Fórmula |
|---|---|
monthly | Total de los ítems |
quarterly | Total ÷ 3 |
semiannual | Total ÷ 6 |
annual | Total ÷ 12 |
Eventos Emitidos
| Evento | Cuándo |
|---|---|
subscription.db.created | Suscripción creada |
subscription.confirmed | Confirmada |
subscription.activated | Activada |
subscription.renewed | Renovada |
subscription.paused | Pausada |
subscription.resumed | Reanudada |
subscription.canceled | Cancelada |
subscription.pending_cancellation | Marcada para cancelar al fin del período |
subscription.plan_changed | Plan modificado |
subscription_status_changed | Cualquier cambio de estado |