TAREA-001: Estandarización de épicas al formato SIMCO 4.0.1 Cambios aplicados a las 12 épicas: - Frontmatter: simco_version="4.0.1", story_points, updated_at=2026-01-17 - Metadata: Agregado **Story Points:** N - Nueva sección "## Historias de Usuario" antes de Entregables - Cada HU: Como/Quiero/Para, Story Points, Criterios [CA-XXX-N], Tareas [MCH-TT-XXX-NN] - Tabla resumen de Story Points al final de cada épica Épicas estandarizadas: - MCH-016: Entregas a Domicilio (5 HUs, 34 SP) - MCH-017: Notificaciones (6 HUs, 34 SP) - MCH-018: Planes y Suscripciones (6 HUs, 21 SP) - MCH-019: Tienda de Tokens (6 HUs, 21 SP) - MCH-020: Pagos de Suscripción (6 HUs, 34 SP) - MCH-021: Dashboard Web (6 HUs, 21 SP) - MCH-022: Modo Offline (6 HUs, 21 SP) - MCH-023: Programa de Referidos (6 HUs, 21 SP) - MCH-024: CoDi y SPEI (5 HUs, 21 SP) - MCH-025: Widgets y Atajos (6 HUs, 21 SP) - MCH-026: Multi-idioma LATAM (7 HUs, 34 SP) - MCH-027: Integración SAT (8 HUs, 55 SP) Rango de IDs utilizados: MCH-US-150 a MCH-US-269 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
405 lines
12 KiB
Markdown
405 lines
12 KiB
Markdown
---
|
|
id: EPIC-MCH-018
|
|
type: Epic
|
|
title: "MCH-018: Planes y Suscripciones"
|
|
code: MCH-018
|
|
status: Completado
|
|
phase: 5
|
|
priority: P0
|
|
story_points: 21
|
|
created_at: 2026-01-06
|
|
updated_at: 2026-01-17
|
|
simco_version: "4.0.1"
|
|
dependencies:
|
|
blocks: []
|
|
depends_on: []
|
|
---
|
|
|
|
# MCH-018: Planes y Suscripciones
|
|
|
|
## Metadata
|
|
- **Codigo:** MCH-018
|
|
- **Fase:** 5 - Monetizacion
|
|
- **Prioridad:** P0
|
|
- **Estado:** Completado
|
|
- **Story Points:** 21
|
|
- **Fecha inicio:** 2026-01-06
|
|
- **Fecha fin:** 2026-01-07
|
|
|
|
## Descripcion
|
|
|
|
Sistema de planes de suscripcion para monetizar MiChangarrito: dos planes principales (Changarrito y Tiendita), facturacion mensual, y gestion de ciclos de pago.
|
|
|
|
## Objetivos
|
|
|
|
1. Definir planes disponibles
|
|
2. Proceso de suscripcion
|
|
3. Facturacion recurrente
|
|
4. Gestion de ciclo de vida
|
|
5. Upgrade/downgrade de plan
|
|
|
|
## Alcance
|
|
|
|
### Incluido
|
|
- Plan Changarrito ($99/mes)
|
|
- Plan Tiendita ($199/mes)
|
|
- Trial de 14 dias
|
|
- Facturacion via Stripe
|
|
- Cancelacion y pausas
|
|
- Historial de facturacion
|
|
|
|
### Excluido
|
|
- Planes anuales (fase posterior)
|
|
- Planes enterprise personalizados
|
|
- Facturacion fiscal mexicana (MCH-027)
|
|
|
|
## Planes
|
|
|
|
### Plan Changarrito - $99/mes
|
|
```
|
|
✓ App movil completa
|
|
✓ Punto de venta basico
|
|
✓ Hasta 500 productos
|
|
✓ 1 usuario
|
|
✓ 500 tokens IA/mes
|
|
✓ Soporte por WhatsApp
|
|
✗ WhatsApp Business propio
|
|
✗ Predicciones de inventario
|
|
```
|
|
|
|
### Plan Tiendita - $199/mes
|
|
```
|
|
✓ Todo de Changarrito
|
|
✓ Productos ilimitados
|
|
✓ Hasta 5 usuarios
|
|
✓ 2,000 tokens IA/mes
|
|
✓ WhatsApp Business propio
|
|
✓ Predicciones de inventario
|
|
✓ Reportes avanzados
|
|
✓ Entregas a domicilio
|
|
✓ Soporte prioritario
|
|
```
|
|
|
|
## Modelo de Datos
|
|
|
|
### Tablas (schema: subscriptions)
|
|
|
|
**plans**
|
|
- id, name, code, price
|
|
- currency, interval (month/year)
|
|
- features (JSONB), token_quota
|
|
- max_products, max_users
|
|
- stripe_price_id, status
|
|
|
|
**subscriptions**
|
|
- id, tenant_id, plan_id
|
|
- status (trialing/active/past_due/cancelled)
|
|
- stripe_subscription_id
|
|
- current_period_start, current_period_end
|
|
- trial_end, cancelled_at
|
|
|
|
**invoices**
|
|
- id, subscription_id, amount
|
|
- status, stripe_invoice_id
|
|
- paid_at, pdf_url
|
|
|
|
## Endpoints API
|
|
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /subscriptions/plans | Listar planes |
|
|
| GET | /subscriptions/current | Suscripcion actual |
|
|
| POST | /subscriptions/subscribe | Suscribirse |
|
|
| POST | /subscriptions/cancel | Cancelar |
|
|
| POST | /subscriptions/resume | Reanudar |
|
|
| PUT | /subscriptions/change-plan | Cambiar plan |
|
|
| GET | /subscriptions/invoices | Historial facturas |
|
|
| POST | /subscriptions/webhook | Webhook Stripe |
|
|
|
|
## Flujos
|
|
|
|
### Nueva Suscripcion
|
|
```
|
|
1. Usuario selecciona plan
|
|
2. Ingresa metodo de pago (Stripe)
|
|
3. Se crea suscripcion con trial
|
|
4. Usuario tiene acceso inmediato
|
|
5. Al terminar trial, se cobra automaticamente
|
|
```
|
|
|
|
### Cancelacion
|
|
```
|
|
1. Usuario solicita cancelar
|
|
2. Confirmacion requerida
|
|
3. Suscripcion marcada para cancelar
|
|
4. Acceso hasta fin del periodo
|
|
5. Datos preservados 30 dias
|
|
```
|
|
|
|
### Upgrade
|
|
```
|
|
1. Usuario en Changarrito
|
|
2. Solicita upgrade a Tiendita
|
|
3. Se calcula prorateo
|
|
4. Pago de diferencia
|
|
5. Features activadas inmediatamente
|
|
```
|
|
|
|
## Estados de Suscripcion
|
|
|
|
```
|
|
trialing ──► active ──► past_due ──► cancelled
|
|
│ │
|
|
└───────────┴──► paused
|
|
```
|
|
|
|
| Estado | Descripcion | Acceso |
|
|
|--------|-------------|--------|
|
|
| trialing | En periodo de prueba | Completo |
|
|
| active | Pagando normalmente | Completo |
|
|
| past_due | Pago fallido (grace period) | Limitado |
|
|
| cancelled | Cancelada | Sin acceso |
|
|
| paused | Pausada temporalmente | Sin acceso |
|
|
|
|
## Integracion Stripe
|
|
|
|
### Subscription Billing
|
|
```typescript
|
|
const subscription = await stripe.subscriptions.create({
|
|
customer: customer.stripe_id,
|
|
items: [{ price: plan.stripe_price_id }],
|
|
trial_period_days: 14,
|
|
payment_behavior: 'default_incomplete',
|
|
expand: ['latest_invoice.payment_intent']
|
|
});
|
|
```
|
|
|
|
### Webhooks Manejados
|
|
- `customer.subscription.created`
|
|
- `customer.subscription.updated`
|
|
- `customer.subscription.deleted`
|
|
- `invoice.payment_succeeded`
|
|
- `invoice.payment_failed`
|
|
|
|
## Historias de Usuario
|
|
|
|
### MCH-US-170: Catalogo de Planes de Suscripcion
|
|
**Story Points:** 3
|
|
|
|
**Como** visitante o usuario registrado
|
|
**Quiero** ver el catalogo de planes disponibles con sus caracteristicas y precios
|
|
**Para** tomar una decision informada sobre cual plan contratar
|
|
|
|
#### Criterios de Aceptacion
|
|
- [CA-170-1] Se muestran los planes Changarrito ($99/mes) y Tiendita ($199/mes)
|
|
- [CA-170-2] Cada plan muestra claramente sus caracteristicas incluidas y excluidas
|
|
- [CA-170-3] Se indica el periodo de prueba gratuito de 14 dias
|
|
- [CA-170-4] Existe boton de CTA para iniciar suscripcion en cada plan
|
|
- [CA-170-5] La comparativa entre planes es clara y visual
|
|
|
|
#### Tareas
|
|
| ID | Tarea | Estimacion |
|
|
|----|-------|------------|
|
|
| MCH-TT-170-01 | Crear componente PlanCard con features | 2h |
|
|
| MCH-TT-170-02 | Implementar pagina Plans.tsx con comparativa | 3h |
|
|
| MCH-TT-170-03 | Integrar endpoint GET /subscriptions/plans | 1h |
|
|
| MCH-TT-170-04 | Agregar tests unitarios de componentes | 2h |
|
|
|
|
---
|
|
|
|
### MCH-US-171: Proceso de Suscripcion con Trial
|
|
**Story Points:** 5
|
|
|
|
**Como** usuario nuevo
|
|
**Quiero** suscribirme a un plan con un periodo de prueba gratuito
|
|
**Para** probar el sistema antes de comprometerme con el pago
|
|
|
|
#### Criterios de Aceptacion
|
|
- [CA-171-1] El usuario puede seleccionar un plan y registrar metodo de pago via Stripe
|
|
- [CA-171-2] Se crea suscripcion en estado "trialing" con 14 dias de trial
|
|
- [CA-171-3] El usuario tiene acceso completo a features del plan durante el trial
|
|
- [CA-171-4] Se notifica por email la activacion del trial y fecha de primer cobro
|
|
- [CA-171-5] El tenant se configura con los limites del plan seleccionado
|
|
|
|
#### Tareas
|
|
| ID | Tarea | Estimacion |
|
|
|----|-------|------------|
|
|
| MCH-TT-171-01 | Implementar flujo de checkout con Stripe Elements | 4h |
|
|
| MCH-TT-171-02 | Crear endpoint POST /subscriptions/subscribe | 3h |
|
|
| MCH-TT-171-03 | Configurar trial_period_days en Stripe | 1h |
|
|
| MCH-TT-171-04 | Implementar notificaciones email de trial | 2h |
|
|
| MCH-TT-171-05 | Tests de integracion del flujo completo | 2h |
|
|
|
|
---
|
|
|
|
### MCH-US-172: Facturacion Recurrente Automatica
|
|
**Story Points:** 5
|
|
|
|
**Como** suscriptor activo
|
|
**Quiero** que mi pago mensual se procese automaticamente
|
|
**Para** mantener mi suscripcion activa sin intervencion manual
|
|
|
|
#### Criterios de Aceptacion
|
|
- [CA-172-1] Stripe cobra automaticamente al terminar el trial o periodo actual
|
|
- [CA-172-2] Se genera invoice y se almacena en tabla invoices
|
|
- [CA-172-3] El webhook invoice.payment_succeeded actualiza estado a "active"
|
|
- [CA-172-4] El webhook invoice.payment_failed marca como "past_due" con grace period
|
|
- [CA-172-5] Se envia email de confirmacion de pago con link al recibo
|
|
|
|
#### Tareas
|
|
| ID | Tarea | Estimacion |
|
|
|----|-------|------------|
|
|
| MCH-TT-172-01 | Implementar handler webhook invoice.payment_succeeded | 2h |
|
|
| MCH-TT-172-02 | Implementar handler webhook invoice.payment_failed | 2h |
|
|
| MCH-TT-172-03 | Crear servicio de sincronizacion de invoices | 3h |
|
|
| MCH-TT-172-04 | Implementar emails transaccionales de facturacion | 2h |
|
|
| MCH-TT-172-05 | Configurar retry policy para pagos fallidos | 1h |
|
|
|
|
---
|
|
|
|
### MCH-US-173: Upgrade y Downgrade de Plan
|
|
**Story Points:** 3
|
|
|
|
**Como** suscriptor del plan Changarrito
|
|
**Quiero** poder cambiar a plan Tiendita (o viceversa)
|
|
**Para** ajustar mi suscripcion a las necesidades de mi negocio
|
|
|
|
#### Criterios de Aceptacion
|
|
- [CA-173-1] El usuario puede solicitar cambio de plan desde su dashboard
|
|
- [CA-173-2] Se calcula y muestra el prorateo antes de confirmar
|
|
- [CA-173-3] En upgrade: se cobra diferencia y activan features inmediatamente
|
|
- [CA-173-4] En downgrade: se ajusta al siguiente ciclo de facturacion
|
|
- [CA-173-5] Los limites del tenant se actualizan segun nuevo plan
|
|
|
|
#### Tareas
|
|
| ID | Tarea | Estimacion |
|
|
|----|-------|------------|
|
|
| MCH-TT-173-01 | Implementar endpoint PUT /subscriptions/change-plan | 3h |
|
|
| MCH-TT-173-02 | Calcular prorateo con Stripe proration_behavior | 2h |
|
|
| MCH-TT-173-03 | Crear UI de cambio de plan con preview de costos | 2h |
|
|
| MCH-TT-173-04 | Actualizar limites de tenant post-cambio | 1h |
|
|
|
|
---
|
|
|
|
### MCH-US-174: Cancelacion y Pausas de Suscripcion
|
|
**Story Points:** 3
|
|
|
|
**Como** suscriptor
|
|
**Quiero** poder cancelar o pausar mi suscripcion
|
|
**Para** gestionar el ciclo de vida segun mis circunstancias
|
|
|
|
#### Criterios de Aceptacion
|
|
- [CA-174-1] El usuario puede solicitar cancelacion con confirmacion requerida
|
|
- [CA-174-2] La cancelacion es efectiva al final del periodo pagado
|
|
- [CA-174-3] Los datos se preservan 30 dias despues de cancelar
|
|
- [CA-174-4] El usuario puede reanudar suscripcion cancelada antes de perder datos
|
|
- [CA-174-5] Se puede pausar temporalmente con estado "paused"
|
|
|
|
#### Tareas
|
|
| ID | Tarea | Estimacion |
|
|
|----|-------|------------|
|
|
| MCH-TT-174-01 | Implementar endpoint POST /subscriptions/cancel | 2h |
|
|
| MCH-TT-174-02 | Implementar endpoint POST /subscriptions/resume | 2h |
|
|
| MCH-TT-174-03 | Crear UI de cancelacion con encuesta de salida | 2h |
|
|
| MCH-TT-174-04 | Implementar job de limpieza de datos post-30 dias | 2h |
|
|
| MCH-TT-174-05 | Manejar webhook customer.subscription.deleted | 1h |
|
|
|
|
---
|
|
|
|
### MCH-US-175: Historial de Facturacion
|
|
**Story Points:** 2
|
|
|
|
**Como** suscriptor
|
|
**Quiero** ver mi historial de facturas y descargar recibos
|
|
**Para** tener control de mis gastos y documentacion fiscal
|
|
|
|
#### Criterios de Aceptacion
|
|
- [CA-175-1] Se muestra lista de invoices con fecha, monto y estado
|
|
- [CA-175-2] Cada invoice tiene link para descargar PDF desde Stripe
|
|
- [CA-175-3] Se pueden filtrar invoices por rango de fechas
|
|
- [CA-175-4] Se muestra informacion de la suscripcion actual y proximo cobro
|
|
- [CA-175-5] El historial es accesible desde pagina Billing.tsx
|
|
|
|
#### Tareas
|
|
| ID | Tarea | Estimacion |
|
|
|----|-------|------------|
|
|
| MCH-TT-175-01 | Implementar endpoint GET /subscriptions/invoices | 2h |
|
|
| MCH-TT-175-02 | Crear pagina Billing.tsx con historial | 3h |
|
|
| MCH-TT-175-03 | Integrar descarga de PDF via Stripe invoice URL | 1h |
|
|
| MCH-TT-175-04 | Agregar filtros y paginacion al historial | 2h |
|
|
|
|
---
|
|
|
|
### Resumen de Historias de Usuario
|
|
|
|
| ID | Historia | Story Points | Estado |
|
|
|----|----------|--------------|--------|
|
|
| MCH-US-170 | Catalogo de Planes de Suscripcion | 3 | Completado |
|
|
| MCH-US-171 | Proceso de Suscripcion con Trial | 5 | Completado |
|
|
| MCH-US-172 | Facturacion Recurrente Automatica | 5 | Completado |
|
|
| MCH-US-173 | Upgrade y Downgrade de Plan | 3 | En Progreso |
|
|
| MCH-US-174 | Cancelacion y Pausas de Suscripcion | 3 | Completado |
|
|
| MCH-US-175 | Historial de Facturacion | 2 | Pendiente |
|
|
| **TOTAL** | | **21** | |
|
|
|
|
## Entregables
|
|
|
|
| Entregable | Estado | Archivo |
|
|
|------------|--------|---------|
|
|
| DDL subscriptions | Completado | `10-subscriptions.sql` |
|
|
| subscriptions.module | Completado | `modules/subscriptions/` |
|
|
| Stripe integration | Completado | `providers/stripe.provider.ts` |
|
|
| Plans UI | Pendiente | `pages/Plans.tsx` |
|
|
| Billing UI | Pendiente | `pages/Billing.tsx` |
|
|
|
|
## Dependencias
|
|
|
|
### Depende de
|
|
- MCH-005 (Stripe integration base)
|
|
- MCH-002 (Auth)
|
|
|
|
### Bloquea a
|
|
- MCH-019 (Tokens)
|
|
- MCH-020 (Pagos online)
|
|
|
|
## Criterios de Aceptacion
|
|
|
|
- [x] Planes se muestran correctamente
|
|
- [x] Suscripcion se crea en Stripe
|
|
- [x] Trial de 14 dias funciona
|
|
- [x] Cobro recurrente funciona
|
|
- [x] Cancelacion funciona
|
|
- [ ] Upgrade/downgrade funciona
|
|
|
|
## Configuracion
|
|
|
|
```typescript
|
|
// plans seed
|
|
[
|
|
{
|
|
name: 'Changarrito',
|
|
code: 'changarrito',
|
|
price: 99,
|
|
currency: 'MXN',
|
|
token_quota: 500,
|
|
max_products: 500,
|
|
max_users: 1,
|
|
stripe_price_id: 'price_xxx'
|
|
},
|
|
{
|
|
name: 'Tiendita',
|
|
code: 'tiendita',
|
|
price: 199,
|
|
currency: 'MXN',
|
|
token_quota: 2000,
|
|
max_products: null, // unlimited
|
|
max_users: 5,
|
|
stripe_price_id: 'price_yyy'
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
**Ultima actualizacion:** 2026-01-17
|