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

Lectura
30 min~5 min lectura
Objetivo de la lección

Concepto clave Implementar un flujo completo de suscripción con Stripe es como gestionar un gimnasio digital.

Puntos de control
  • Concepto clave
  • Cómo funciona en la práctica
  • Codigo en accion
  • Errores comunes

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.

Laboratorio de práctica

Antes de marcar esta lección como completa, escribí una evidencia breve para Implementación Profesional de Suscripciones y Facturación con Stripe: un ejemplo, una decisión, una captura, una mini demo o una nota que puedas reutilizar en portfolio.

Reflexión rápida

¿Qué cambiarías en tu forma de trabajar después de aplicar práctica: implementar un flujo completo de suscripción?

De lección a portfolio

Convertí esta lección en una prueba técnica visible.

Una app pequeña publicada, con README y decisiones explicadas, funciona mejor que una lista de tecnologías sueltas.

Paso 1

Creá una demo mínima que use el concepto de la lección.

Paso 2

Escribí un README corto con objetivo, stack, decisión técnica y mejora futura.

Paso 3

Publicá la demo y enlazala desde tu perfil profesional.

Newsletter Cursalo

Recibí rutas y cursos nuevos

Sumate para recibir recursos orientados a empleo y portfolio.

  • Rutas de empleo
  • Cursos prácticos
  • Portfolio y entrevistas

Sin spam. También podés entrar con tu cuenta para guardar progreso. Iniciá sesión

Práctica: Implementar un Flujo Completo de Susc... | CursaloFalar no WhatsApp