Saltar al contenido

Lección 9 de 25 · Lectura y práctica

Práctica: Implementar un Flujo Completo de Suscripción

Concepto claveImplementar un flujo completo de suscripción con Stripe es como gestionar un gimnasio digital. En lugar de fichas de entrada, usas tokens de pago; en lugar de recibos mensuales, generas facturas automáticas; y en.

Del concepto a la práctica

Taller de esta lección

Un flujo completo se valida como una secuencia de estados: selección, cliente, suscripción, factura, pago y acceso. Cada paso debe dejar una referencia para poder diagnosticar dónde se detuvo el proceso.

Ejemplo resuelto

Para el plan equipo, el usuario selecciona price_team_3000; el backend crea cus_22, luego sub_22 y recibe invoice_22. Tras invoice.paid, guarda acceso=activo y fecha de renovación, sin inventar una fecha si no viene en la respuesta.

La página de éxito es una señal de interfaz, no una concesión de acceso. Verifica que la sesión y el customer correspondan al usuario autenticado mediante una relación creada por el servidor. Al recibir invoice.paid, comprueba que la factura corresponde al plan admitido y reconcilia la suscripción vigente antes de actualizar el acceso. Facturas de cero o marcadas pagadas fuera de Stripe pueden tener invoice.paid sin un nuevo cargo de tarjeta; registra esa diferencia.

Pruébalo

  1. Dibuja las seis etapas.

  2. Asigna un identificador a cada objeto.

  3. Simula pago correcto y pago pendiente.

  4. Compara el acceso otorgado en ambos casos.

Error frecuente: usar la respuesta del navegador como autoridad final. Corrección: valida en el backend y usa el evento de facturación para sincronizar el estado.

Comprueba tu resultado

La ruta correcta debe terminar con acceso activo solo después de invoice.paid. La ruta pendiente debe conservar factura y suscripción identificadas, pero marcar acceso como pendiente según la regla documentada.

Proveedor de pago que envía un webhook verificado al servidor; registro idempotente antes de conceder acceso.
CursaloMapa de práctica
Confirmar el pago en el servidor

El servidor concede acceso a partir de un evento verificado del proveedor y un registro persistente. La pantalla de éxito del navegador es una notificación, no una prueba suficiente de pago. La idempotencia evita duplicar la operación cuando el evento llega más de una vez.

Ver la infografía en tamaño completo ↗
Fuentes para profundizar

Concepto clave

Implementar un flujo completo de suscripción con Stripe es como gestionar un gimnasio digital. En lugar de fichas de entrada, usas tokens de pago; en lugar de recibos mensuales, generas facturas automáticas; y en lugar de un recepcionista, tienes webhooks que notifican eventos como renovaciones o cancelaciones. El flujo completo abarca desde que el usuario selecciona un plan hasta que recibe su primera factura y se gestionan sus pagos recurrentes.

La arquitectura se basa en tres pilares: Customer (cliente con método de pago), Subscription (suscripción a un plan con ciclo de facturación) y Invoice (factura generada automáticamente). Los webhooks actún como el sistema nervioso, enviando eventos en tiempo real (ej: invoice.paid) para que tu backend sincronice el estado. Es crucial entender que Stripe maneja la lógica de cobro, pero tu aplicación debe gestionar la lógica de negocio (ej: activar acceso al servicio).

Cómo funciona en la práctica

Imagina que implementas suscripciones para una plataforma de cursos online. El flujo paso a paso es:

  1. Frontend: El usuario selecciona un plan (ej: "Premium - $29/mes") y completa un formulario de pago con Stripe Elements, obteniendo un paymentMethodId.
  2. Backend: Recibes el paymentMethodId y creas un Customer en Stripe asociándolo. Luego, creas una Subscription para ese cliente al plan deseado.
  3. Stripe: Genera automáticamente la primera factura (invoice) e intenta cobrarla. Si es exitoso, envía un evento invoice.paid vía webhook.
  4. Backend: Tu endpoint de webhook recibe invoice.paid, verifica la firma, identifica la suscripción y activa el acceso al curso en tu base de datos.
  5. Ciclo recurrente: Cada mes, Stripe genera una nueva factura, la cobra y notifica con webhooks. Tu backend actualiza el estado según corresponda (ej: si falla el pago, suspende el acceso).

La clave es que tu backend nunca asume el estado; siempre lo sincroniza desde los webhooks. Por ejemplo, no marques una suscripción como "activa" tras crearla; espera a invoice.paid.

Codigo en accion

Aquí un ejemplo en Node.js con la librería stripe. Primero, crea un cliente y una suscripción:

// Configuración inicial
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

// Endpoint para crear suscripción
app.post('/api/subscribe', async (req, res) => {
  try {
    const { paymentMethodId, planId } = req.body;
    
    // 1. Crear cliente
    const customer = await stripe.customers.create({
      payment_method: paymentMethodId,
      invoice_settings: {
        default_payment_method: paymentMethodId
      }
    });
    
    // 2. Crear suscripción
    const subscription = await stripe.subscriptions.create({
      customer: customer.id,
      items: [{ plan: planId }],
      expand: ['latest_invoice.payment_intent']
    });
    
    res.json({ subscriptionId: subscription.id, status: subscription.status });
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});

Luego, procesa webhooks para manejar eventos. Antes de implementar, así se veía un manejo básico:

// ANTES: Sin verificación de firma (vulnerable)
app.post('/webhook', (req, res) => {
  const event = req.body;
  if (event.type === 'invoice.paid') {
    // Activar acceso
  }
  res.sendStatus(200);
});

Después de refactorizar, con verificación segura:

// DESPUÉS: Con verificación de firma (recomendado)
app.post('/webhook', async (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;
  
  try {
    event = stripe.webhooks.constructEvent(
      req.rawBody,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET
    );
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }
  
  switch (event.type) {
    case 'invoice.paid':
      const invoice = event.data.object;
      await activateUserAccess(invoice.subscription);
      break;
    case 'invoice.payment_failed':
      const failedInvoice = event.data.object;
      await suspendUserAccess(failedInvoice.subscription);
      break;
    case 'customer.subscription.deleted':
      const subscription = event.data.object;
      await cancelUserAccess(subscription.id);
      break;
  }
  
  res.json({ received: true });
});

Errores comunes

  • No verificar firmas de webhooks: Expones tu backend a eventos falsificados. Siempre usa stripe.webhooks.constructEvent con el secreto.
  • Asumir el estado de la suscripción: No confíes en el status devuelto al crear la suscripción; síncroniza desde webhooks para evitar inconsistencias.
  • Olvidar expandir recursos: Al crear suscripciones, usa expand para acceder a datos anidados (ej: latest_invoice.payment_intent) sin llamadas adicionales.
  • Manejar mal los fallos de pago: No solo escuches invoice.paid; configura retry logic con invoice.payment_failed y notifica al usuario.
  • No probar webhooks localmente: Usa el CLI de Stripe para reenviar eventos a tu entorno local y simular flujos completos.

Checklist de dominio

  1. Puedo crear un Customer con un método de pago por defecto usando la API de Stripe.
  2. Sé crear una Subscription asociada a un plan y cliente, manejando la respuesta con expand.
  3. He implementado un endpoint de webhook que verifica firmas y procesa invoice.paid, invoice.payment_failed y customer.subscription.deleted.
  4. Puedo listar y actualizar suscripciones (ej: cambiar plan, cancelar) mediante la API.
  5. Entiendo cómo las facturas se generan automáticamente y cómo acceder a su historial.
  6. He probado el flujo completo localmente usando stripe listen y stripe trigger.
  7. Sé integrar este flujo con mi base de datos para mantener consistencia entre Stripe y mi estado de negocio.

Implementa un sistema de suscripciones para una SaaS

En este ejercicio, crearás un backend básico que maneje suscripciones recurrentes para una plataforma SaaS ficticia. Sigue estos pasos:

  1. Configuración inicial: Crea un proyecto Node.js, instala la librería stripe y configura las variables de entorno con tu STRIPE_SECRET_KEY y STRIPE_WEBHOOK_SECRET (usa claves de prueba).
  2. Endpoint de suscripción: Implementa un endpoint POST /subscribe que reciba paymentMethodId y planId. Dentro:
    • Crea un Customer en Stripe con el paymentMethodId como método por defecto.
    • Crea una Subscription para ese cliente al plan especificado, expandiendo latest_invoice.payment_intent.
    • Devuelve el subscriptionId y status en JSON.
  3. Webhook handler: Crea un endpoint POST /webhook que:
    • Verifique la firma del evento usando stripe.webhooks.constructEvent.
    • Procese tres eventos: invoice.paid (registra en consola "Acceso activado para suscripción X"), invoice.payment_failed (registra "Pago fallado para suscripción X"), y customer.subscription.deleted (registra "Suscripción X cancelada").
    • Use el campo subscription del objeto invoice para identificar la suscripción.
  4. Prueba integral: Usa la CLI de Stripe para probar:
    • Ejecuta stripe listen --forward-to localhost:3000/webhook para capturar eventos.
    • En otra terminal, usa stripe trigger invoice.paid para simular un pago exitoso y verifica que tu endpoint registre el mensaje correcto.
  5. Extensión opcional: Añade un endpoint GET /subscription/:id que, usando la API de Stripe, recupere los detalles de una suscripción y muestre su status, plan y fecha de próxima factura.
Pistas
  • Usa el método stripe.customers.create con invoice_settings para establecer el payment method por defecto.
  • Recuerda que req.rawBody puede ser necesario para webhooks; en Express, usa body-parser con verify para preservar el cuerpo crudo.
  • Al expandir latest_invoice.payment_intent, accedes al client_secret para manejar pagos que requieren autenticación adicional.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con Implementación Profesional de Suscripciones y Facturación con Stripe

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.