Concepto clave
Las suscripciones en Stripe representan un modelo de negocio donde los clientes pagan de forma recurrente por acceso continuo a un producto o servicio. A diferencia de los pagos únicos, las suscripciones gestionan automáticamente la facturación periódica, renovaciones y cancelaciones. En el núcleo están los objetos Subscription que vinculan un cliente con un plan de precios y controlan el ciclo de facturación.
Imagina una suscripción como un contrato de alquiler: el cliente (inquilino) se compromete a pagar mensualmente por usar tu servicio (propiedad), y Stripe actúa como el agente que gestiona automáticamente los cobros, envía recordatorios y maneja las renovaciones. Los webhooks son notificaciones en tiempo real que Stripe envía a tu servidor cuando ocurren eventos importantes como pagos exitosos, fallidos o cancelaciones, permitiéndote sincronizar tu base de datos y activar lógica de negocio.
Cómo funciona en la práctica
El flujo típico para implementar suscripciones incluye: 1) Crear un producto y precio recurrente en el Dashboard de Stripe o mediante API, 2) Configurar un cliente con método de pago, 3) Crear la suscripción vinculando cliente y precio, 4) Escuchar webhooks para actualizar el estado en tu sistema.
Paso a paso: Primero, defines tu producto y configuración de precios. Luego, cuando un usuario se registra en tu plataforma, creas un objeto Customer en Stripe y adjuntas un PaymentMethod. Después, inicias la suscripción con el customer ID y price ID. Stripe manejará automáticamente el primer pago y los recurrentes según la frecuencia configurada. Paralelamente, configuras un endpoint en tu backend para recibir webhooks como invoice.paid o customer.subscription.updated para mantener tu base de datos actualizada.
Codigo en accion
Ejemplo de creación de una suscripción usando la API de Stripe en Node.js:
// Configuración inicial
const stripe = require('stripe')('sk_test_...');
// Crear un cliente y suscripción
async function createSubscription(customerEmail, priceId) {
try {
// 1. Crear cliente
const customer = await stripe.customers.create({
email: customerEmail,
payment_method: 'pm_card_visa', // En producción, usaría un PaymentMethod ID real
});
// 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'],
});
console.log('Suscripción creada:', subscription.id);
return subscription;
} catch (error) {
console.error('Error:', error);
}
}
// Llamar la función
createSubscription('[email protected]', 'price_abc123');Ejemplo de manejo de webhooks para actualizar estado de usuario:
// Endpoint para webhooks
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, 'whsec_...');
} catch (err) {
return res.status(400).send(`Webhook Error: ${err.message}`);
}
// Manejar eventos específicos
switch (event.type) {
case 'invoice.paid':
const invoice = event.data.object;
// Actualizar base de datos: usuario activo hasta next_payment
updateUserStatus(invoice.customer, 'active', invoice.period_end);
break;
case 'invoice.payment_failed':
const failedInvoice = event.data.object;
// Notificar al usuario y posiblemente degradar acceso
handlePaymentFailure(failedInvoice.customer);
break;
case 'customer.subscription.deleted':
const subscription = event.data.object;
// Cancelar acceso del usuario
cancelUserAccess(subscription.customer);
break;
default:
console.log(`Evento no manejado: ${event.type}`);
}
res.json({received: true});
});Errores comunes
- No validar webhooks: Aceptar eventos sin verificar la firma de Stripe expone a ataques. Siempre usa
stripe.webhooks.constructEventpara validar. - Ignorar estados de suscripción: Stripe tiene estados como
active,past_due,canceled. No sincronizarlos con tu base de datos causa inconsistencias. - Manejo incorrecto de fallos de pago: No implementar lógica para reintentos o notificaciones cuando un pago recurrente falla, llevando a cancelaciones no deseadas.
- No expandir objetos en respuestas: La API devuelve IDs por defecto; usa parámetro
expandpara obtener detalles completos de objetos relacionados como invoices. - Configurar precios incorrectamente: Definir intervalos (mensual/anual) o cantidades erróneas en precios, causando cobros inesperados.
Checklist de dominio
- Puedo crear y gestionar productos y precios recurrentes mediante API
- Sé configurar clientes con métodos de pago y crear suscripciones
- Implemento webhooks para manejar eventos clave como pagos exitosos o fallidos
- Entiendo y sincronizo los estados de suscripción (active, past_due, canceled)
- Manejo correctamente fallos de pago con reintentos y notificaciones
- Uso la Billing API para generar y enviar facturas personalizadas
- Puedo cancelar o pausar suscripciones programáticamente
Implementa un sistema de suscripciones con manejo de webhooks
En este ejercicio, crearás un backend básico que implemente suscripciones recurrentes usando Stripe y maneje eventos mediante webhooks. Sigue estos pasos:
- Configura un proyecto Node.js con Express y la librería Stripe.
- Crea un endpoint POST
/create-subscriptionque acepte email de cliente y price ID, y devuelva un subscription ID. - Implementa un endpoint POST
/webhookque valide eventos Stripe y actualice un objeto simulado de usuario en memoria. - Agrega lógica para manejar al menos tres eventos:
invoice.paid,invoice.payment_failed, ycustomer.subscription.deleted. - Prueba tu implementación usando las claves de prueba de Stripe y herramientas como Stripe CLI para simular eventos.
Entrega: Código fuente con comentarios explicando cada sección clave.
Pistas- Usa
stripe.webhooks.constructEventpara validar webhooks y evitar falsificaciones. - Considera usar un objeto en memoria como
let users = {}para simular la base de datos y rastrear estados. - Prueba con price IDs de prueba como 'price_1' para simular suscripciones sin cobros reales.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.