trading-platform/docs/02-definicion-modulos/OQI-005-payments-stripe/requerimientos/RF-PAY-001-suscripciones.md
rckrdmrd a7cca885f0 feat: Major platform documentation and architecture updates
Changes include:
- Updated architecture documentation
- Enhanced module definitions (OQI-001 to OQI-008)
- ML integration documentation updates
- Trading strategies documentation
- Orchestration and inventory updates
- Docker configuration updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:33:35 -06:00

315 lines
12 KiB
Markdown

---
id: "RF-PAY-001"
title: "Sistema de Planes y Suscripciones"
type: "Requirement"
status: "Done"
priority: "Alta"
epic: "OQI-005"
project: "trading-platform"
version: "1.0.0"
created_date: "2025-12-05"
updated_date: "2026-01-04"
---
# RF-PAY-001: Sistema de Planes y Suscripciones
**Version:** 1.0.0
**Fecha:** 2025-12-05
**Estado:** ✅ Implementado
**Prioridad:** P0 (Crítica)
**Story Points:** 8
**Épica:** [OQI-005](../_MAP.md)
---
## Descripción
El sistema debe permitir a los usuarios suscribirse a planes mensuales de pago recurrente integrados con Stripe Subscriptions, otorgando acceso diferenciado a funcionalidades premium según el nivel del plan.
---
## Objetivo de Negocio
- Generar ingresos recurrentes predecibles (MRR)
- Segmentar usuarios por valor (freemium → premium)
- Reducir churn con facturación automática
- Facilitar upgrades/downgrades entre planes
---
## Planes Disponibles
| Plan | Precio | Price ID Stripe | Características |
|------|--------|-----------------|-----------------|
| Free | $0/mes | - | Predicciones básicas (5/día), cursos introductorios |
| Basic | $19/mes | `price_1Sb3k64dPtEGmLmpeAdxvmIu` | Predicciones básicas ilimitadas, todos los cursos básicos |
| Pro | $49/mes | `price_1Sb3k64dPtEGmLmpm5n5bbJH` | Predicciones avanzadas, todos los cursos, indicadores técnicos |
| Premium | $99/mes | `price_1Sb3k74dPtEGmLmpHfLpUkvQ` | Todo incluido, soporte prioritario, análisis personalizados |
---
## Requisitos Funcionales
### RF-PAY-001.1: Creación de Suscripción
**DEBE:**
1. Crear Customer en Stripe si no existe
2. Adjuntar método de pago al Customer
3. Crear Subscription con el Price ID correspondiente
4. Guardar registro en tabla `billing.subscriptions`
5. Sincronizar estado inicial (`active`, `incomplete`, `trialing`)
### RF-PAY-001.2: Gestión de Método de Pago
**DEBE:**
1. Permitir agregar/actualizar tarjeta de crédito
2. Soportar Stripe Elements para PCI compliance
3. Guardar PaymentMethod como default del Customer
4. Mostrar últimos 4 dígitos y marca de tarjeta
### RF-PAY-001.3: Cambio de Plan (Upgrade/Downgrade)
**DEBE:**
1. Permitir cambiar de plan en cualquier momento
2. Proration automática de Stripe:
- **Upgrade:** Cobrar diferencia prorrateada inmediatamente
- **Downgrade:** Aplicar crédito para próximo ciclo
3. Actualizar `subscription.plan` en BD
4. Mantener `currentPeriodEnd` original
### RF-PAY-001.4: Cancelación de Suscripción
**DEBE:**
1. Permitir cancelar en cualquier momento
2. Mantener acceso hasta `currentPeriodEnd`
3. Marcar `cancelAtPeriodEnd = true`
4. Enviar email de confirmación de cancelación
5. No reembolsar período actual
### RF-PAY-001.5: Renovación Automática
**DEBE:**
1. Stripe intenta cobro automático en `currentPeriodEnd`
2. Si falla, reintentar según configuración Stripe (3 días)
3. Actualizar estado a `past_due` si falla
4. Enviar email de fallo de pago
5. Cancelar automáticamente si falla después de reintentos
### RF-PAY-001.6: Período de Prueba (Trial)
**DEBE:**
1. Ofrecer 7 días gratis en primer suscripción Pro/Premium
2. Crear suscripción con `trial_end` timestamp
3. No cobrar hasta que termine trial
4. Permitir cancelar durante trial sin cargo
5. Convertir a `active` automáticamente al finalizar trial
---
## Flujo de Creación de Suscripción
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Usuario │ │ Frontend │ │ Backend │ │ Stripe │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │ │
│ Selecciona plan │ │ │
│ "Pro" │ │ │
│──────────────────▶│ │ │
│ │ │ │
│ │ POST /payments/ │ │
│ │ subscriptions │ │
│ │ { plan: "pro", │ │
│ │ paymentMethodId }│ │
│ │──────────────────▶│ │
│ │ │ │
│ │ │ 1. Get/Create │
│ │ │ Customer │
│ │ │──────────────────▶│
│ │ │◀──────────────────│
│ │ │ customer_id │
│ │ │ │
│ │ │ 2. Attach │
│ │ │ PaymentMethod │
│ │ │──────────────────▶│
│ │ │◀──────────────────│
│ │ │ │
│ │ │ 3. Create │
│ │ │ Subscription │
│ │ │──────────────────▶│
│ │ │◀──────────────────│
│ │ │ subscription │
│ │ │ │
│ │ │ 4. Save to DB │
│ │ │ (subscriptions) │
│ │ │ │
│ │◀──────────────────│ │
│ │ { subscription, │ │
│ │ status: "active"}│ │
│ │ │ │
│◀──────────────────│ │ │
│ "Suscripción │ │ │
│ activada!" │ │ │
│ │ │ │
```
---
## Reglas de Negocio
### RN-001: Un Plan Activo por Usuario
- Un usuario solo puede tener **1 suscripción activa** a la vez
- Cambiar plan cancela la anterior y crea una nueva
- Free plan no genera registro en `subscriptions`
### RN-002: Acceso Según Plan
| Recurso | Free | Basic | Pro | Premium |
|---------|------|-------|-----|---------|
| Predicciones básicas | 5/día | ∞ | ∞ | ∞ |
| Predicciones avanzadas | ❌ | ❌ | ✅ | ✅ |
| Cursos básicos | 3 | ✅ | ✅ | ✅ |
| Cursos avanzados | ❌ | ❌ | ✅ | ✅ |
| Indicadores técnicos | ❌ | ❌ | ✅ | ✅ |
| Soporte prioritario | ❌ | ❌ | ❌ | ✅ |
| Análisis personalizados | ❌ | ❌ | ❌ | ✅ |
### RN-003: Cambio de Plan
**Upgrade (Free → Basic, Basic → Pro, etc.):**
- Aplicar inmediatamente
- Cobrar diferencia prorrateada
- Extender `currentPeriodEnd` proporcionalmente
**Downgrade (Premium → Pro, Pro → Basic, etc.):**
- Aplicar al finalizar período actual
- Generar crédito para próximo ciclo
- Notificar fecha de cambio efectivo
### RN-004: Cancelación y Reactivación
**Cancelación:**
- Mantener acceso hasta `currentPeriodEnd`
- Marcar `cancelAtPeriodEnd = true`
- No permitir reactivación automática después de `currentPeriodEnd`
**Reactivación:**
- Solo permitir si `cancelAtPeriodEnd = true` y antes de `currentPeriodEnd`
- Marcar `cancelAtPeriodEnd = false` en Stripe
---
## Estados de Suscripción
| Estado | Descripción | Acceso |
|--------|-------------|--------|
| `active` | Suscripción activa y al corriente | ✅ Completo |
| `trialing` | En período de prueba | ✅ Completo |
| `past_due` | Pago falló, en reintentos | ⚠️ Limitado |
| `canceled` | Cancelada por usuario o falta de pago | ❌ Free tier |
| `incomplete` | Pago inicial falló | ❌ Sin acceso |
| `incomplete_expired` | Pago falló y expiró (24h) | ❌ Sin acceso |
| `unpaid` | Todos los reintentos fallaron | ❌ Sin acceso |
---
## Manejo de Errores
| Error | Código | Mensaje Usuario | Acción |
|-------|--------|-----------------|--------|
| Tarjeta declinada | 402 | Tu tarjeta fue rechazada. Intenta con otra. | Solicitar nuevo método |
| Customer no existe | 404 | Error de configuración. Contacta soporte. | Crear Customer |
| Ya tiene suscripción | 409 | Ya tienes una suscripción activa. Cancela primero. | Redirigir a /settings |
| Plan inválido | 400 | El plan seleccionado no existe. | Mostrar planes válidos |
| Stripe API error | 502 | Error de procesamiento. Intenta más tarde. | Retry con backoff |
---
## Seguridad
### Validaciones
- Verificar que `userId` del token coincida con Customer
- No permitir modificar suscripciones de otros usuarios
- Validar Price ID contra lista permitida
- Verificar estado de Customer en Stripe antes de cambios
### Datos Sensibles
- **NUNCA** almacenar números de tarjeta completos
- Guardar solo `paymentMethod.last4` y `brand`
- Tokens `pm_xxx` son seguros para guardar
- Usar Stripe Elements para PCI compliance
---
## Configuración Requerida
```env
# Stripe Keys
STRIPE_SECRET_KEY=sk_test_51Sb3k64dPtEGmLmp...
STRIPE_PUBLISHABLE_KEY=pk_test_51Sb3k64dPtEGmLmp...
STRIPE_WEBHOOK_SECRET=whsec_...
# Price IDs (desde Stripe Dashboard)
STRIPE_PRICE_BASIC=price_1Sb3k64dPtEGmLmpeAdxvmIu
STRIPE_PRICE_PRO=price_1Sb3k64dPtEGmLmpm5n5bbJH
STRIPE_PRICE_PREMIUM=price_1Sb3k74dPtEGmLmpHfLpUkvQ
# Configuración de Trial
TRIAL_PERIOD_DAYS=7
```
---
## Webhooks Relacionados
| Evento | Acción |
|--------|--------|
| `customer.subscription.created` | Crear registro en BD |
| `customer.subscription.updated` | Sincronizar estado y plan |
| `customer.subscription.deleted` | Marcar como `canceled` |
| `customer.subscription.trial_will_end` | Enviar email recordatorio (3 días antes) |
| `invoice.payment_succeeded` | Crear registro en `payments` |
| `invoice.payment_failed` | Actualizar a `past_due`, enviar email |
---
## Métricas de Negocio
### KPIs a Rastrear
- **MRR (Monthly Recurring Revenue):** Suma de todas las suscripciones activas
- **Churn Rate:** (Cancelaciones del mes / Suscripciones inicio mes) * 100
- **ARPU (Average Revenue Per User):** MRR / Total usuarios suscritos
- **LTV (Lifetime Value):** ARPU / Churn Rate
- **Conversion Rate:** Trials → Paid
---
## Criterios de Aceptación
- [ ] Usuario puede suscribirse a Basic/Pro/Premium
- [ ] Usuario puede agregar/actualizar método de pago
- [ ] Usuario puede hacer upgrade inmediatamente
- [ ] Usuario puede hacer downgrade al final del período
- [ ] Usuario puede cancelar manteniendo acceso hasta period_end
- [ ] Usuario puede reactivar suscripción cancelada antes de expirar
- [ ] Trial de 7 días se aplica correctamente en primera suscripción
- [ ] Estados se sincronizan correctamente con webhooks
- [ ] Acceso a recursos se controla según plan activo
- [ ] Emails se envían en eventos clave (creación, cancelación, fallo)
---
## Especificación Técnica Relacionada
- [ET-PAY-001: Stripe Subscriptions](../especificaciones/ET-PAY-001-stripe-subscriptions.md)
## Historias de Usuario Relacionadas
- [US-PAY-001: Ver Planes Disponibles](../historias-usuario/US-PAY-001-ver-planes.md)
- [US-PAY-002: Suscribirse a Plan](../historias-usuario/US-PAY-002-suscribirse.md)
- [US-PAY-006: Agregar Método de Pago](../historias-usuario/US-PAY-006-agregar-metodo-pago.md)