Configurar Métodos de Pago y Facturación Automática

Video
30 min~4 min lectura

Reproductor de video

Concepto clave

La configuración de métodos de pago y facturación automática en Stripe es el motor financiero que mantiene tu negocio de suscripciones funcionando sin intervención manual. Imagina esto como un sistema de suscripción a un gimnasio: el cliente proporciona su tarjeta una vez, y cada mes se le cobra automáticamente mientras mantenga su membresía activa. Stripe actúa como el cajero automatizado que procesa esos pagos y genera recibos.

En términos técnicos, esto involucra tres componentes principales: PaymentMethods (tarjetas, bancos digitales), Subscriptions (planes recurrentes) y Invoices (facturas generadas automáticamente). La magia ocurre cuando Stripe combina estos elementos: cuando una suscripción se renueva, Stripe crea una factura, intenta cobrar usando el método de pago guardado, y si tiene éxito, marca la factura como pagada y envía un recibo.

Cómo funciona en la práctica

Vamos a seguir el flujo completo de un cliente que se suscribe a tu servicio:

  1. El cliente ingresa su información de pago en tu frontend (usando Stripe Elements o Checkout)
  2. Tu backend recibe un PaymentMethod ID seguro de Stripe
  3. Creas un Customer en Stripe y adjuntas el PaymentMethod
  4. Creas una Subscription para ese cliente con un plan específico
  5. Stripe genera automáticamente la primera factura y la paga
  6. Cada ciclo de facturación, Stripe repite el proceso: genera factura → intenta pago → envía webhook

El punto crítico aquí es que una vez configurado, el sistema funciona automáticamente. Tu única responsibilidad es manejar los fallos de pago a través de webhooks.

Código en acción

Primero, veamos cómo crear un cliente con método de pago y suscripción:

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

async function createSubscription(customerEmail, paymentMethodId, priceId) {
  // 1. Crear cliente
  const customer = await stripe.customers.create({
    email: customerEmail,
    payment_method: paymentMethodId,
    invoice_settings: {
      default_payment_method: paymentMethodId
    }
  });
  
  // 2. Crear suscripción
  const subscription = await stripe.subscriptions.create({
    customer: customer.id,
    items: [{
      price: priceId
    }],
    payment_behavior: 'default_incomplete',
    expand: ['latest_invoice.payment_intent']
  });
  
  return {
    clientSecret: subscription.latest_invoice.payment_intent.client_secret,
    subscriptionId: subscription.id
  };
}

Ahora, veamos cómo manejar la renovación automática con webhooks:

// Webhook handler para invoice.payment_succeeded
app.post('/webhook', async (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;
  
  try {
    event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET
    );
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }
  
  // Manejar el evento de factura pagada
  if (event.type === 'invoice.payment_succeeded') {
    const invoice = event.data.object;
    
    // Aquí actualizas tu base de datos
    await updateUserSubscription(invoice.customer, {
      status: 'active',
      current_period_end: new Date(invoice.period_end * 1000),
      invoiceUrl: invoice.hosted_invoice_url
    });
    
    // Opcional: enviar email de confirmación
    await sendInvoiceEmail(invoice.customer_email, invoice.hosted_invoice_url);
  }
  
  res.json({received: true});
});

Errores comunes

  • No configurar payment_behavior correctamente: Si usas 'default_incomplete' en suscripciones, asegúrate de confirmar el PaymentIntent en el frontend. La alternativa 'allow_incomplete' maneja esto automáticamente pero requiere lógica de reintento.
  • Olvidar los webhooks en producción: Los eventos como invoice.payment_succeeded solo llegan vía webhooks. Sin ellos, tu base de datos no se actualiza tras pagos automáticos.
  • No manejar fallos de pago: Stripe intentará cobrar varias veces, pero necesitas escuchar invoice.payment_failed para notificar al usuario o degradar su servicio.
  • Usar precios en lugar de productos: Los precios definen el costo y ciclo, pero los productos definen qué estás vendiendo. Crea productos primero, luego precios asociados.
  • Ignorar el campo default_payment_method: Sin esto, las facturas futuras no sabrán qué método de pago usar. Siempre configúralo al crear el cliente.

Checklist de dominio

  1. Puedo crear un cliente con método de pago por defecto configurado
  2. Sé diferenciar entre PaymentMethod, PaymentIntent y SetupIntent
  3. He implementado webhooks para invoice.payment_succeeded y invoice.payment_failed
  4. Puedo listar todas las suscripciones de un cliente y su estado actual
  5. Entiendo cómo Stripe reintenta pagos fallidos automáticamente
  6. Sé dó encontrar las facturas generadas automáticamente en el Dashboard
  7. Puedo actualizar/cancelar una suscripción y predecir su próxima factura

Implementa un sistema completo de suscripción con renovación automática

En este ejercicio, crearás un endpoint backend que maneje suscripciones recurrentes con facturación automática.

  1. Crea un endpoint POST /api/subscribe que reciba:
    • email del cliente
    • paymentMethodId (simulado o real desde Stripe.js)
    • priceId (usa 'price_1' para mensual o 'price_2' para anual)
  2. Implementa la lógica para:
    • Crear un cliente en Stripe con el método de pago como predeterminado
    • Crear una suscripción que se renueve automáticamente
    • Devolver el clientSecret para confirmar el pago inicial
  3. Crea un webhook handler en /webhook que:
    • Verifique la firma de Stripe
    • Actualice tu base de datos (simulada) cuando una factura se pague exitosamente
    • Envie un email simulado (console.log) con el enlace a la factura
  4. Prueba el flujo completo:
    • Suscribe un cliente
    • Simula un webhook de invoice.payment_succeeded usando stripe CLI
    • Verifica que tu base de datos se actualizó

Requisitos técnicos: Usa Node.js con Express, el SDK de Stripe, y variables de entorno para las claves.

Pistas
  • Recuerda que el payment_behavior: 'default_incomplete' requiere confirmación del PaymentIntent en el frontend
  • Usa stripe.webhooks.constructEvent() para verificar webhooks, no confíes en el body crudo
  • Para pruebas, genera eventos con 'stripe trigger invoice.payment_succeeded' en la CLI

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.