3 de junio de 2026
10 min de lectura
Suscripciones con Stripe: modelo de datos, eventos y casos de borde en proyectos SaaS
Cómo modelar el ciclo de vida completo de una suscripción con Stripe Billing: desde el trial hasta la cancelación y los reintentos de cobro.
Read in EnglishEl modelo de datos de Stripe Billing
Stripe Billing trabaja con cuatro objetos principales: Customer, Product, Price y Subscription. El Customer representa al usuario o empresa que paga. El Product describe qué se vende. El Price define el monto, la moneda y el intervalo de cobro. La Subscription conecta un Customer con uno o más Prices y gestiona el ciclo de vida del cobro.
Un error común es sincronizar solo el estado activo de la suscripción y asumir que todo lo demás es irrelevante. En la práctica, el sistema necesita reaccionar a transiciones de estado, a intentos de cobro fallidos, a periodos de gracia y a actualizaciones de plan. Todo eso llega por webhooks, no por polling.
Los eventos que no se pueden ignorar
Stripe emite decenas de tipos de eventos, pero para un SaaS con suscripciones hay cinco que son críticos: `customer.subscription.created`, `customer.subscription.updated`, `customer.subscription.deleted`, `invoice.payment_succeeded` e `invoice.payment_failed`. Cualquier otro evento puede ignorarse inicialmente; estos cinco no.
El evento `customer.subscription.updated` es especialmente importante porque cubre cambios de plan, cancelaciones programadas, reactivaciones y actualizaciones de periodo de prueba. Su payload incluye el estado anterior y el nuevo, lo que permite implementar lógica diferencial sin consultar la API de Stripe.
Manejo de pago fallido: actualizar estado y notificar al usuario.
case 'invoice.payment_failed': {
const invoice = event.data.object as Stripe.Invoice;
const subscriptionId = invoice.subscription as string;
await db.subscriptions.update({
where: { stripeSubscriptionId: subscriptionId },
data: {
status: 'past_due',
lastPaymentError: invoice.last_finalization_error?.message ?? null,
},
});
await notifications.send({
type: 'payment_failed',
userId: invoice.customer as string,
retryAt: invoice.next_payment_attempt
? new Date(invoice.next_payment_attempt * 1000)
: null,
});
break;
} Casos de borde en el ciclo de vida de una suscripción
El trial ending es uno de los casos más frecuentes: Stripe envía `customer.subscription.trial_will_end` tres días antes del fin del periodo de prueba. Ese evento es la oportunidad correcta para recordarle al usuario que actualice su método de pago antes de que se intente el primer cobro real.
Los upgrades y downgrades de plan tienen su propia lógica de prorratas. Por defecto, Stripe genera un crédito o cargo inmediato al cambiar de Price. Si el comportamiento esperado es diferente (por ejemplo, cambiar el plan al próximo ciclo sin prorratear), hay que configurar `proration_behavior` explícitamente al crear la suscripción o al actualizarla.
- Escucha `trial_will_end` para recordar el método de pago con anticipación.
- Maneja `subscription.updated` con lógica diferencial sobre el campo `status`.
- Configura `cancel_at_period_end` si quieres permitir cancelación al final del ciclo.
- Prueba el flujo de dunning con las tarjetas de prueba designadas de Stripe.
Sincronizar el estado de Stripe con tu base de datos
La base de datos del producto debe ser la fuente de verdad para el acceso y los features. Stripe es la fuente de verdad para el estado de pago. Esas dos cosas tienen que estar sincronizadas, pero no son lo mismo: un usuario puede tener acceso activo aunque Stripe esté en periodo de gracia, dependiendo de la política del negocio.
El patrón más limpio es guardar el `stripeSubscriptionId`, el `stripeCustomerId`, el `status` de Stripe y la `currentPeriodEnd` en la tabla de suscripciones del producto. Al recibir cualquier webhook relevante, se actualizan esos campos y se recalcula el acceso. Nunca se consulta la API de Stripe en tiempo de request para verificar si un usuario tiene acceso.
Más artículos
Volver a artículosPlataformas de pago en México: Stripe, Conekta, Mercado Pago y OpenPay
Comparativa técnica y comercial de las cuatro plataformas más usadas para aceptar pagos en proyectos digitales mexicanos.
3 de junio de 2026
7 min de lectura
Plataformas de envíos en México: Skydropx, EnviosPerros, Pakke y Enviame
Cómo elegir entre los principales agregadores de paquetería para ecommerce en México según volumen, operación y necesidades técnicas.
3 de junio de 2026
7 min de lectura
CMS headless en 2026: PayloadCMS, Strapi, Sanity y Directus
Qué CMS headless elegir según el tipo de proyecto, el control técnico que necesitas y cómo planeas modelar el contenido.
3 de junio de 2026
8 min de lectura