Diseñar la Arquitectura del Proyecto

Lectura
25 min~5 min lectura

Concepto clave

Diseñar la arquitectura de un sistema de suscripciones con Stripe es como planificar la red eléctrica de una ciudad. No solo necesitas que la energía llegue a cada casa (pagos procesados), sino que también debes manejar cortes (fallos de pago), mantenimiento (actualizaciones) y medidores inteligentes (webhooks para notificaciones). La arquitectura define cómo se organizan los componentes: tu backend, Stripe, tu base de datos y los clientes, asegurando que los pagos recurrentes, facturas y eventos se manejen de forma confiable y escalable.

En el mundo real, piensa en Netflix: cada mes, cobran a millones de usuarios, generan facturas, manejan cancelaciones y notifican a su sistema si un pago falla para pausar el acceso. Con Stripe, tu arquitectura debe integrar las Billing APIs para gestionar suscripciones y facturas, y los webhooks para escuchar eventos como pagos exitosos o fallidos, creando un ciclo completo que automatiza la lógica de negocio.

Cómo funciona en la práctica

Imagina que estás construyendo una plataforma SaaS como Zoom. Sigue estos pasos para diseñar la arquitectura:

  1. Configuración inicial: Crea una cuenta en Stripe, obtén las claves API (secreta y pública) y configura webhooks en el dashboard de Stripe para apuntar a tu endpoint backend.
  2. Flujo de suscripción:
    • Frontend: Usa Stripe Elements o Checkout para capturar detalles de pago del cliente.
    • Backend: Crea un cliente en Stripe, configura un plan de precios y genera una suscripción usando la API.
    • Base de datos: Almacena el ID de suscripción de Stripe y el estado (activa, cancelada) vinculado al usuario.
  3. Manejo de eventos: Configura un endpoint en tu backend (ej., /webhooks/stripe) que reciba eventos de Stripe vía webhooks. Valida la firma del webhook para seguridad y procesa eventos como invoice.paid o customer.subscription.deleted para actualizar tu base de datos.
  4. Facturación: Usa las Billing APIs para generar facturas personalizadas o descargar facturas existentes, sincronizando con tu sistema de contabilidad.

Código en acción

Aquí tienes un ejemplo funcional en Node.js usando la librería stripe. Primero, configura el cliente de Stripe:

// Configuración inicial en backend
const stripe = require('stripe')('sk_test_tu_clave_secreta');

// Crear una suscripción para un cliente
async function createSubscription(customerId, priceId) {
  try {
    const subscription = await stripe.subscriptions.create({
      customer: customerId,
      items: [
        { price: priceId },
      ],
      payment_behavior: 'default_incomplete',
      expand: ['latest_invoice.payment_intent'],
    });
    return subscription;
  } catch (error) {
    console.error('Error creando suscripción:', error);
    throw error;
  }
}

Ahora, maneja un webhook para eventos de factura. Antes, podrías procesar sin validar, lo que es inseguro. Después, con validación de firma:

// Manejo de webhooks con validación
const endpointSecret = 'whsec_tu_secreto_webhook';

app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {
  const sig = request.headers['stripe-signature'];
  let event;

  try {
    event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret);
  } catch (err) {
    return response.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Procesar el evento
  switch (event.type) {
    case 'invoice.paid':
      const invoice = event.data.object;
      console.log(`Factura ${invoice.id} pagada para ${invoice.customer}`);
      // Actualizar base de datos: marcar usuario como activo
      break;
    case 'invoice.payment_failed':
      console.log('Pago fallido, notificar al usuario');
      break;
    default:
      console.log(`Evento no manejado: ${event.type}`);
  }

  response.json({received: true});
});

Errores comunes

  • No validar webhooks: Exponer tu backend a eventos falsos. Siempre usa stripe.webhooks.constructEvent para verificar la firma.
  • Almacenar datos sensibles: Guardar números de tarjeta en tu base de datos. En su lugar, usa tokens de Stripe o PaymentMethods.
  • Ignorar estados de suscripción: No actualizar tu base de datos cuando Stripe notifica cambios vía webhooks, llevando a inconsistencias.
  • Mal manejo de errores de pago: No reintentar pagos fallidos o no notificar a usuarios, causando cancelaciones innecesarias.
  • Falta de logging: No registrar eventos de webhooks, dificultando el debug en producción.

Checklist de dominio

  1. Configurar webhooks en Stripe y validar firmas en el backend.
  2. Integrar Stripe Checkout o Elements para capturar pagos de forma segura.
  3. Usar las Billing APIs para crear suscripciones, planes y facturas.
  4. Sincronizar estados de suscripción entre Stripe y tu base de datos.
  5. Manejar eventos comunes como invoice.paid y customer.subscription.updated.
  6. Implementar lógica para reintentos de pago fallidos.
  7. Probar en modo de prueba (test mode) antes de ir a producción.

Diseña un endpoint de webhooks para manejar suscripciones

En este ejercicio, crearás un endpoint backend que procese webhooks de Stripe para actualizar el estado de suscripciones en tu base de datos. Sigue estos pasos:

  1. Configura un proyecto básico: Crea una nueva carpeta para el proyecto, inicializa un proyecto Node.js con npm init -y, e instala las dependencias: npm install stripe express.
  2. Configura Stripe: Obtén una clave secreta de prueba desde el dashboard de Stripe y configúrala en tu código. Crea un archivo index.js y configura Express para manejar solicitudes POST en /webhook.
  3. Implementa validación de webhooks: Usa stripe.webhooks.constructEvent para validar la firma del webhook. Define un secreto de endpoint (puedes simularlo con un string para pruebas).
  4. Procesa eventos clave: Maneja al menos dos eventos: invoice.paid y customer.subscription.deleted. Para cada evento, registra un mensaje en consola simulando una actualización en base de datos (ej., 'Suscripción activada' o 'Suscripción cancelada').
  5. Prueba con Stripe CLI: Instala Stripe CLI y ejecuta stripe listen --forward-to localhost:3000/webhook para enviar eventos de prueba a tu endpoint. Dispara eventos desde el dashboard de Stripe o usa comandos CLI para verificar que tu endpoint responde correctamente.

Entrega: Un archivo index.js funcional que muestre el manejo de webhooks con validación y logging.

Pistas
  • Usa express.raw({type: 'application/json'}) en el middleware para manejar el cuerpo crudo del webhook.
  • Simula una base de datos con un objeto JavaScript en memoria para almacenar estados de suscripción.
  • Prueba con eventos de prueba de Stripe; no necesitas una cuenta real para esto.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.