Quiz Final: Evaluación del Proyecto Integrador

Quiz
20 min~4 min lectura

Quiz Interactivo

Pon a prueba tus conocimientos

Concepto clave

En un sistema de suscripciones profesional, el ciclo de vida completo del cliente se gestiona a través de tres componentes principales: suscripciones para pagos recurrentes, Billing APIs para facturación automatizada, y webhooks para sincronización en tiempo real. Imagina esto como un servicio de gimnasio: la suscripción es la membresía mensual, las facturas son los recibos que envías cada mes, y los webhooks son las notificaciones automáticas cuando alguien se da de baja o cambia de plan.

La arquitectura debe ser resiliente: los webhooks garantizan que tu base de datos refleje siempre el estado real en Stripe, evitando discrepancias. Un error común es tratar Stripe solo como pasarela de pago, cuando en realidad es un sistema de gestión de relaciones con clientes (CRM) financiero. La clave está en diseñar tu backend para manejar eventos asíncronos, no solo solicitudes síncronas.

Cómo funciona en la práctica

Veamos el flujo completo desde que un usuario se suscribe hasta su primer pago fallido:

  1. El cliente selecciona un plan en tu frontend y proporciona datos de pago.
  2. Tu backend crea un Customer en Stripe, luego una Subscription asociada a ese cliente.
  3. Stripe genera automáticamente la primera factura (Invoice) e intenta el pago.
  4. Si el pago es exitoso, Stripe envía un webhook invoice.paid a tu endpoint.
  5. Tu backend procesa el webhook, actualiza el estado del usuario en tu base de datos y envía acceso al servicio.
  6. Si el pago falla, Stripe envía invoice.payment_failed y tu sistema puede notificar al cliente o suspender el servicio temporalmente.

Código en acción

Creación de una suscripción con manejo de errores básico:

// Antes: Sin manejo de errores robusto
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

async function createSubscription(customerId, priceId) {
  const subscription = await stripe.subscriptions.create({
    customer: customerId,
    items: [{ price: priceId }],
    payment_behavior: 'default_incomplete',
    expand: ['latest_invoice.payment_intent']
  });
  return subscription;
}
// Después: Con validación y manejo de errores
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

async function createSubscription(customerId, priceId) {
  try {
    // Validar que el cliente existe
    const customer = await stripe.customers.retrieve(customerId);
    if (customer.deleted) {
      throw new Error('Cliente eliminado en Stripe');
    }
    
    // Crear suscripción con metadata para tracking
    const subscription = await stripe.subscriptions.create({
      customer: customerId,
      items: [{ price: priceId }],
      payment_behavior: 'default_incomplete',
      metadata: {
        internal_user_id: 'user_123',
        created_via: 'web_checkout'
      },
      expand: ['latest_invoice.payment_intent']
    });
    
    // Registrar en tu base de datos
    await db.subscriptions.create({
      stripe_subscription_id: subscription.id,
      status: subscription.status,
      current_period_end: new Date(subscription.current_period_end * 1000)
    });
    
    return {
      subscriptionId: subscription.id,
      clientSecret: subscription.latest_invoice.payment_intent.client_secret,
      status: subscription.status
    };
  } catch (error) {
    console.error('Error creando suscripción:', error);
    // Enviar a servicio de monitoreo
    await monitoring.logError('stripe_subscription_error', error);
    throw error;
  }
}

Errores comunes

  • No verificar firmas de webhooks: Cualquiera puede enviar peticiones a tu endpoint. Siempre valida la firma con stripe.webhooks.constructEvent().
  • Ignorar eventos duplicados: Stripe puede enviar el mismo webhook múltiples veces. Implementa idempotencia almacenando IDs de eventos procesados.
  • No manejar pagos fallidos: El 10-15% de los pagos recurrentes fallan mensualmente. Configura reintentos automáticos y notificaciones proactivas.
  • Depender solo del estado en tu base de datos: El estado real está en Stripe. Sincroniza regularmente o usa webhooks para mantener consistencia.
  • No probar flujos de cancelación: Los usuarios cancelarán. Asegúrate de manejar customer.subscription.deleted correctamente.

Checklist de dominio

  • ✓ Puedo crear un cliente, suscripción y factura en una sola transacción atómica
  • ✓ Mi endpoint de webhooks valida firmas y maneja eventos duplicados
  • ✓ Implementé lógica para pagos fallidos con reintentos configurados
  • ✓ Sé cómo actualizar/cancelar suscripciones mediante API
  • ✓ Uso metadata para asociar objetos de Stripe con mis registros internos
  • ✓ Configuré eventos esenciales: invoice.paid, invoice.payment_failed, customer.subscription.deleted
  • ✓ Probé el flujo completo con modos de prueba de Stripe

Implementar endpoint de webhooks con manejo de eventos críticos

Construye un endpoint de webhooks que procese 3 eventos esenciales y mantenga sincronizada tu base de datos. Sigue estos pasos:

  1. Crea una ruta POST /api/stripe/webhook en tu backend
  2. Implementa verificación de firma usando la clave secreta de webhooks de Stripe
  3. Procesa estos eventos:
    • invoice.paid: Actualiza el estado de la suscripción a activa y registra la fecha de pago
    • invoice.payment_failed: Marca la suscripción como "payment_failed" y notifica al usuario
    • customer.subscription.deleted: Cancela el acceso al servicio y archiva los datos
  4. Implementa idempotencia: almacena IDs de eventos procesados para evitar duplicados
  5. Agrega logging detallado para debugging en producción
  6. Prueba con la CLI de Stripe: stripe listen --forward-to localhost:3000/api/stripe/webhook
Pistas
  • Usa stripe.webhooks.constructEvent() para verificar la firma
  • Los eventos tienen propiedad 'type' y 'data.object' con los detalles
  • Guarda event.id en tu base de datos antes de procesar para idempotencia

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.