Las suscripciones recurrentes son el modelo de monetización preferido para apps y SaaS porque generan ingresos predecibles y mejoran el lifetime value del cliente. Pero implementar un sistema de billing recurrente bien hecho es más complejo de lo que parece. En esta guía compartimos los patrones de arquitectura que usamos en Soamee para construir sistemas de suscripción robustos en producción.
Por qué la implementación importa más de lo que crees
La diferencia entre un sistema de suscripciones mediocre y uno excelente puede representar un 20-30% de tu MRR. Un buen dunning (gestión de pagos fallidos) puede recuperar el 40-60% de las transacciones que fallan inicialmente. Un trial bien diseñado puede convertir al 80-95% de los usuarios que lo inician. Y unas prorratas correctas evitan disputas con clientes y pérdidas por cobros incorrectos.
Hemos visto startups perder miles de euros al mes por implementaciones naive: reintentos de pago que se hacen todos a la misma hora saturando la cola, prorratas que no tienen en cuenta los días reales del mes, trials que expiran sin notificar al usuario, y cancelaciones que no liberan correctamente los permisos del plan.
Arquitectura de un sistema de suscripciones
Componentes principales
Un sistema de suscripciones completo tiene estos componentes:
- Subscription Engine: gestiona el estado de las suscripciones (active, trialing, past_due, canceled, paused).
- Billing Engine: calcula los importes a cobrar, prorratas y genera facturas.
- Payment Processor: ejecuta los cobros (Stripe, Redsys, RevenueCat).
- Dunning System: gestiona reintentos de pagos fallidos y comunicación al usuario.
- Entitlement System: controla qué funcionalidades tiene disponibles cada usuario según su plan.
- Analytics: métricas de MRR, churn, LTV, conversión de trial.
Patrón de estados
El ciclo de vida de una suscripción sigue esta máquina de estados:
[trialing] → [active] → [past_due] → [canceled]
↓ ↓ ↓
[canceled] [paused] [active] (si se recupera el pago)
Cada transición de estado debe:
- Actualizar los permisos del usuario (entitlements).
- Enviar la comunicación adecuada (email, push notification).
- Registrar el evento para analytics.
- Ejecutar la lógica de billing (cobrar, dejar de cobrar, prorratear).
Opción 1: Stripe Billing
Stripe Billing es nuestra recomendación por defecto para suscripciones web. Gestiona la complejidad del billing recurrente y te permite centrarte en tu producto.
Integración básica
La integración mínima con Stripe Billing implica:
- Crear productos y planes en Stripe (via API o dashboard).
- Checkout Session para que el usuario se suscriba con un flujo de pago hosted o embebido.
- Webhooks para sincronizar el estado de la suscripción con tu base de datos.
- Customer Portal para que el usuario gestione su suscripción (cambiar plan, cancelar, actualizar pago).
Los webhooks críticos que debes manejar:
customer.subscription.created: nueva suscripción creada.customer.subscription.updated: cambio de plan, estado o período.customer.subscription.deleted: suscripción cancelada definitivamente.invoice.paid: pago exitoso, activar/renovar acceso.invoice.payment_failed: pago fallido, iniciar dunning.customer.subscription.trial_will_end: trial a punto de terminar (3 días antes).
Gestión de trials
Stripe soporta trials nativamente. Configuraciones que recomendamos:
- Trial sin tarjeta: más volumen de trials pero menor conversión. Útil para productos con efecto red donde necesitas masa crítica.
- Trial con tarjeta: menor volumen pero mayor conversión (el usuario ya tiene intención de pago). Nuestra recomendación por defecto.
- Duración: 7-14 días es el estándar. GolfyApp usa 7 días con resultados de conversión del 95%.
La clave de la conversión durante el trial es la activación. Si el usuario experimenta el valor core del producto durante el trial, convertirá. Nuestra estrategia:
- Día 0: email de bienvenida con guía de inicio rápido.
- Día 1-2: si no ha usado la feature principal, email con tutorial específico.
- Día 5 (trial de 7): recordatorio de que el trial termina en 2 días + resumen del valor obtenido.
- Día 6: último recordatorio con oferta especial si convierte hoy.
Prorratas
Stripe calcula prorratas automáticamente cuando un usuario cambia de plan a mitad del ciclo. Hay tres estrategias:
create_prorations(default): cobra/abona la diferencia proporcional. Si el usuario pasa de Plan Basic (10 EUR/mes) a Plan Pro (30 EUR/mes) a mitad de mes, se le cobra 10 EUR adicionales por los 15 días restantes.none: no prorratear. El nuevo plan entra en vigor en el próximo ciclo.always_invoice: generar factura inmediata por la diferencia.
Dunning
Stripe tiene Smart Retries que usa ML para decidir cuándo reintentar un pago fallido. Complementamos con:
- Email automático al usuario cuando un pago falla con link para actualizar método de pago.
- 3 reintentos en los siguientes 7 días con horarios variables.
- Si después de 3 intentos sigue fallando, marcar como
past_duey notificar que el servicio se suspenderá en 3 días. - Después de 10 días sin pago, cancelar la suscripción.
Esta configuración nos permite recuperar el 50-60% de los pagos fallidos.
Opción 2: RevenueCat para apps móviles
Si tu app vive en iOS y/o Android, las suscripciones in-app tienen sus propias reglas. Apple y Google gestionan los cobros, pero necesitas un backend que unifique el estado.
Por qué RevenueCat
- Un SDK, dos stores: abstrae las diferencias entre App Store Connect y Google Play Billing.
- Server-side validation: valida receipts automáticamente sin que tu backend toque las APIs de Apple/Google.
- Webhooks unificados: un único endpoint recibe eventos de ambas stores.
- Analytics: métricas de suscripción unificadas (MRR, churn, trial conversion) entre iOS y Android.
- Experiments: A/B testing de pricing y paywalls sin publicar nueva versión.
Integración con RevenueCat
- SDK en la app: configurar el SDK de RevenueCat (Swift, Kotlin, React Native, Flutter).
- Productos en las stores: crear productos de suscripción en App Store Connect y Google Play Console.
- Mapeo en RevenueCat: configurar los “Entitlements” que mapean productos a permisos.
- Webhooks a tu backend: sincronizar el estado de suscripción con tu base de datos.
- Paywalls: diseñar las pantallas de compra con los componentes de RevenueCat o custom.
Particularidades de las stores
Hay diferencias importantes entre Apple y Google:
- Comisiones: ambas cobran 30% el primer año, 15% a partir del segundo (Small Business Program: 15% desde el inicio si facturas menos de 1M USD/año).
- Grace periods: Apple da 6-16 días de gracia por pago fallido. Google da 3-30 días configurables.
- Cancelación: en iOS, el acceso continúa hasta fin del período pagado. En Android, puedes revocar inmediatamente o al final.
- Precio: Apple requiere precios de su catálogo predefinido. Google permite precios libres.
- Family sharing: Apple soporta compartir suscripciones en familia. Google también pero con diferencias.
El caso PEMAV
En PEMAV implementamos RevenueCat para gestionar suscripciones en iOS y Android con un único backend. Los aprendizajes clave:
- La sincronización entre el estado de la store y tu backend puede tener delays de hasta minutos. Diseña para eventual consistency.
- Los usuarios que cambian de dispositivo (de Android a iOS o viceversa) necesitan un mecanismo de “restore purchases” robusto.
- Las ofertas introductoras (primer mes gratis, 3 meses al 50%) son muy efectivas en las stores y RevenueCat las gestiona bien.
Opción 3: Billing custom sobre Redsys
Si por requisitos de comisiones o regulatorios necesitas usar Redsys para suscripciones, debes construir la lógica de billing tú mismo. Redsys solo proporciona la tokenización y el cobro; el resto es tu responsabilidad.
Arquitectura con Redsys
- Primera transacción: CIT (Cardholder Initiated) con 3D Secure que devuelve un token COF.
- Cobros recurrentes: MIT (Merchant Initiated) con el token almacenado, sin intervención del usuario.
- Tu billing engine: un servicio que ejecuta cobros según la lógica de tu plan:
- Cron job o scheduler que identifica suscripciones a renovar cada día.
- Lógica de reintentos con backoff exponencial para pagos fallidos.
- Cálculo de prorratas cuando el usuario cambia de plan.
- Generación de facturas con datos fiscales correctos.
Cuándo tiene sentido
Solo recomendamos billing custom sobre Redsys cuando:
- Procesas volúmenes muy altos en España y la diferencia de comisiones justifica el desarrollo.
- Tienes requisitos regulatorios que exigen procesamiento bancario local.
- Tu modelo de billing es tan específico que ni Stripe Billing ni ninguna plataforma lo soporta nativamente.
En todos los demás casos, Stripe Billing ahorra meses de desarrollo y mantenimiento.
Patrones de diseño para suscripciones
Feature flags por plan
El patrón que usamos para controlar acceso a funcionalidades:
Plan → [Feature Flags] → Entitlements
Ejemplo:
- Plan Free: max_projects=3, api_calls=1000/mes, no_export
- Plan Pro: max_projects=unlimited, api_calls=50000/mes, export_csv
- Plan Enterprise: everything + sso + audit_logs + api_unlimited
Los feature flags se cargan al inicio de sesión y se cachean. Cuando el plan cambia (via webhook), se invalida el cache y se recargan los entitlements.
Metering para usage-based billing
Si tu pricing tiene componente de uso, necesitas un sistema de metering:
- Registrar uso: cada acción metered (llamada API, mensaje, GB) se registra en un contador.
- Agregar por período: al final del período de billing, se calcula el total.
- Reportar a Stripe: Stripe Usage Records API permite reportar uso y lo factura automáticamente.
El truco es que el metering debe ser eventual consistent pero no perder eventos. Usamos Redis para contadores en tiempo real y PostgreSQL como source of truth con reconciliación periódica.
Cancelación con retención
El flujo de cancelación es una oportunidad de retención:
- Encuesta de motivos: por qué cancela (precio, no usa, alternativa, etc.).
- Oferta contextual: basada en el motivo:
- Si es precio → ofrecer descuento o plan inferior.
- Si es falta de uso → ofrecer pausa temporal (1-3 meses).
- Si es alternativa → mostrar funcionalidades únicas que quizás no conoce.
- Confirmación: si insiste en cancelar, confirmar y preguntar si quiere acceso hasta fin de período.
En GolfyApp, este flujo de retención reduce la cancelación voluntaria en un 30%.
Métricas que debes trackear
Un sistema de suscripciones sin analytics es como conducir sin velocímetro. Las métricas mínimas:
- MRR (Monthly Recurring Revenue): ingresos recurrentes normalizados al mes.
- Churn rate: porcentaje de suscriptores que cancelan por mes (voluntario + involuntario).
- Trial conversion rate: porcentaje de trials que convierten a pago.
- Expansion MRR: ingresos adicionales de upgrades y add-ons.
- Net Revenue Retention: mide si los clientes existentes gastan más o menos con el tiempo (target: >100%).
- LTV: valor total que genera un cliente durante su vida (MRR / churn rate).
- Dunning recovery rate: porcentaje de pagos fallidos que se recuperan.
Implementación paso a paso
Semana 1-2: Fundamentos
- Definir planes y pricing.
- Crear productos en Stripe / configurar RevenueCat.
- Implementar checkout / paywall.
- Configurar webhooks básicos (created, updated, deleted).
- Implementar entitlement system (feature flags por plan).
Semana 3: Trial y conversión
- Configurar trial (duración, con/sin tarjeta).
- Implementar emails automáticos durante el trial.
- Configurar Customer Portal / pantalla de gestión de suscripción.
- Implementar flujo de upgrade/downgrade con prorratas.
Semana 4: Dunning y retención
- Configurar Smart Retries en Stripe.
- Implementar emails de pago fallido con link de actualización.
- Implementar flujo de cancelación con retención.
- Configurar analytics de suscripción.
Semana 5+: Optimización
- A/B testing de pricing y paywalls.
- Optimización de comunicación durante trial.
- Análisis de cohortes y churn por segmento.
- Implementación de metering si aplica.
Errores comunes que evitar
- No manejar el webhook
invoice.payment_failed: sin dunning, pierdes el 20-40% de los renovaciones por pagos fallidos. - Prorratas incorrectas: no calcular correctamente los días del período actual genera disputas.
- Race conditions en webhooks: Stripe puede enviar webhooks fuera de orden. Tu sistema debe ser idempotente.
- No cachear entitlements: consultar el plan en cada request es un cuello de botella. Cachea y invalida via webhook.
- Trial sin activación: un trial donde el usuario no experimenta el valor core tiene 0% de conversión.
- Cancelación inmediata sin acceso: si cancelas y cortas acceso inmediatamente, el usuario siente que perdió dinero (pagó el período pero no puede usarlo).
Conclusión
Implementar suscripciones recurrentes correctamente requiere pensar en el ciclo de vida completo: desde la adquisición (trial) hasta la retención (dunning, cancelación con ofertas) pasando por la expansión (upgrades, add-ons). La tecnología existe (Stripe Billing, RevenueCat) para no reinventar la rueda, pero la lógica de negocio que construyes encima marca la diferencia entre un negocio que crece y uno que pierde clientes por goteo.
Si necesitas implementar un sistema de suscripciones en tu app o plataforma, contacta con nuestro equipo. Hemos construido sistemas de billing en producción con tasas de conversión del 95% y recovery rates del 60%.