Concepto clave
Una suscripción en Stripe es un modelo de negocio donde los clientes pagan de forma recurrente por acceso continuo a un producto o servicio. Piensa en Netflix: pagas mensualmente para ver series ilimitadas. En Stripe, esto se implementa combinando tres elementos fundamentales: Customer (el cliente), Price (el precio del plan) y Subscription (la suscripción que vincula ambos).
La magia está en la automatización: una vez creada, Stripe se encarga de cobrar periódicamente, generar facturas y notificar cambios mediante webhooks. Esto libera al desarrollador de gestionar manualmente renovaciones, recordatorios o fallos de pago. Es como contratar un jardinero que viene cada semana sin que tengas que recordárselo; solo configuras la frecuencia y él actúa.
Cómo funciona en la práctica
Para crear una suscripción, sigue estos pasos en orden lógico:
- Configura el precio: Define un objeto Price en el Dashboard de Stripe o mediante API. Especifica monto, moneda e intervalo (mensual, anual).
- Crea o identifica al cliente: Necesitas un Customer, que puede existir o crearse al momento con su método de pago.
- Inicia la suscripción: Usa la API para crear una Subscription, pasando el customer y el price. Stripe realiza el primer pago inmediatamente.
- Gestiona eventos: Configura webhooks para escuchar eventos como payment_failed o subscription_updated, y actúa en tu backend.
Ejemplo real: una SaaS de gestión de proyectos ofrece un plan "Pro" a $29/mes. Al registrarse, el usuario introduce su tarjeta; tu backend crea un Customer con ese método, luego una Subscription al price "pro_monthly", y el usuario accede al servicio. Cada mes, Stripe cobra automáticamente y envía un invoice.
Código en acción
Aquí un ejemplo funcional en Node.js con la librería stripe. Asegúrate de tener instalado stripe (npm install stripe) y configurada tu clave secreta.
const stripe = require('stripe')('sk_test_tu_clave_secreta');
// Antes: crear un customer y un price por separado (ineficiente si se repite)
async function crearSuscripcionAntes(customerId, priceId) {
// Lógica dispersa
const subscription = await stripe.subscriptions.create({
customer: customerId,
items: [{ price: priceId }],
});
return subscription;
}
// Después: función optimizada que maneja todo en un flujo
export async function crearSuscripcion(email, paymentMethodId, priceId) {
try {
// 1. Crear customer con método de pago
const customer = await stripe.customers.create({
email: email,
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 }],
expand: ['latest_invoice.payment_intent'], // Trae datos adicionales
});
// 3. Retornar estado para el frontend
return {
status: subscription.status,
clientSecret: subscription.latest_invoice.payment_intent.client_secret,
subscriptionId: subscription.id,
};
} catch (error) {
console.error('Error creando suscripción:', error);
throw new Error('No se pudo crear la suscripción');
}
}
// Uso práctico
// crearSuscripcion('[email protected]', 'pm_card_visa', 'price_abc123');En Python, el enfoque es similar:
import stripe
stripe.api_key = "sk_test_tu_clave_secreta"
def crear_suscripcion(email, payment_method_id, price_id):
# Crear cliente
customer = stripe.Customer.create(
email=email,
payment_method=payment_method_id,
invoice_settings={
'default_payment_method': payment_method_id
}
)
# Crear suscripción
subscription = stripe.Subscription.create(
customer=customer.id,
items=[{'price': price_id}],
expand=['latest_invoice.payment_intent']
)
return {
'status': subscription.status,
'client_secret': subscription.latest_invoice.payment_intent.client_secret,
'subscription_id': subscription.id
}Errores comunes
- No expandir invoice.payment_intent: Si no usas expand, perderás el client_secret necesario para confirmar pagos en el frontend. Siempre incluye expand: ['latest_invoice.payment_intent'] para flujos de 3D Secure.
- Olvidar configurar default_payment_method: Al crear un Customer, debes establecer invoice_settings.default_payment_method con el payment_method_id. Sin esto, los cobros recurrentes pueden fallar.
- Manejo inadecuado de webhooks: No verificar firmas de webhooks permite ataques. Usa stripe.webhooks.constructEvent en Node.js o similar en otros lenguajes para autenticar eventos.
- Ignorar estados de suscripción: Stripe devuelve status como active, past_due, o canceled. No asumas que active significa pago exitoso; verifica latest_invoice.paid.
- Precios no recurrentes: Asegúrate de que el Price tenga recurring definido. Un price de una sola vez no funciona en suscripciones.
Checklist de dominio
- Puedo crear un Price recurrente via API o Dashboard y explicar sus parámetros (interval, amount).
- Sé crear un Customer con un método de pago y configurar default_payment_method para facturas.
- Implemento una función que crea una Subscription, maneja errores y retorna datos para el frontend.
- Configuro webhooks para escuchar invoice.payment_failed y actualizar el estado del usuario en mi base de datos.
- Verifico el estado de una suscripción (status, current_period_end) y sé cancelarla o pausarla mediante API.
- Comprendo la diferencia entre trial_period_days (prueba gratis) y billing_cycle_anchor (control de fechas de cobro).
- Uso expand para acceder a datos anidados como payment_intent sin hacer llamadas adicionales.
Implementa un endpoint de suscripción con manejo de errores
En este ejercicio, crearás un endpoint de backend que permita suscribir usuarios a un plan. Usarás Node.js o Python, y simularás un entorno real con Stripe en modo test.
- Prepara tu entorno: Instala la librería Stripe (npm install stripe o pip install stripe) y configura tu clave secreta de test (encuéntrala en el Dashboard de Stripe).
- Crea un Price de prueba: Ve al Dashboard de Stripe > Products > Add Product. Crea un producto "Plan Básico" con un Price recurrente mensual de $10. Anota el price_id (ej: price_abc123).
- Desarrolla el endpoint: En tu código, crea una función o ruta (ej: POST /api/subscribe) que:
- Acepte email, paymentMethodId (simulado con pm_card_visa) y priceId.
- Cree un Customer con el email y paymentMethodId, configurando default_payment_method.
- Cree una Subscription usando ese customer y priceId, expandiendo latest_invoice.payment_intent.
- Maneje errores con try-catch: si falla, retorna un mensaje claro (ej: "Pago rechazado").
- Retorne un JSON con status, subscriptionId, y clientSecret.
- Prueba el flujo: Usa cURL o Postman para enviar una petición a tu endpoint con datos de prueba. Verifica que la suscripción aparezca en el Dashboard de Stripe como active.
- Agrega validación: Añade una validación básica (ej: verificar que el email tenga formato válido) antes de llamar a Stripe.
- Usa pm_card_visa como paymentMethodId para pruebas; es una tarjeta de prueba que siempre funciona.
- Recuerda que expand es un array: ['latest_invoice.payment_intent']. Sin esto, client_secret será undefined.
- En el Dashboard de Stripe, ve a Developers > Webhooks para ver eventos en tiempo real y depurar.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.