- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8 - Actualizaciones de configuracion Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
281 lines
7.2 KiB
Markdown
281 lines
7.2 KiB
Markdown
---
|
|
id: "SAAS-004"
|
|
title: "Billing y Suscripciones"
|
|
type: "Module"
|
|
status: "Published"
|
|
priority: "P0"
|
|
module: "billing"
|
|
version: "1.0.0"
|
|
created_date: "2026-01-07"
|
|
updated_date: "2026-01-10"
|
|
---
|
|
|
|
# SAAS-004: Billing y Suscripciones
|
|
|
|
## Metadata
|
|
- **Codigo:** SAAS-004
|
|
- **Modulo:** Billing
|
|
- **Prioridad:** P0
|
|
- **Estado:** Completado
|
|
- **Fase:** 2 - Billing
|
|
|
|
## Descripcion
|
|
|
|
Sistema de facturacion completo con Stripe: suscripciones recurrentes, trials, upgrades/downgrades, facturas, y webhooks para sincronizacion.
|
|
|
|
## Objetivos
|
|
|
|
1. Integracion completa con Stripe
|
|
2. Suscripciones mensuales/anuales
|
|
3. Trial period (14 dias)
|
|
4. Upgrade/downgrade de plan
|
|
5. Facturas y recibos
|
|
|
|
## Alcance
|
|
|
|
### Incluido
|
|
- Stripe Checkout
|
|
- Suscripciones recurrentes
|
|
- Trial gratuito
|
|
- Cambio de plan (prorateo)
|
|
- Portal de cliente Stripe
|
|
- Webhooks de Stripe
|
|
- Historial de facturas
|
|
|
|
### Excluido
|
|
- Metered billing - fase posterior
|
|
- Multiples metodos de pago guardados
|
|
- Facturacion fiscal mexicana
|
|
|
|
## Modelo de Datos
|
|
|
|
### Tablas (schema: billing)
|
|
|
|
**subscriptions**
|
|
| Columna | Tipo | Descripcion |
|
|
|---------|------|-------------|
|
|
| id | UUID | PK |
|
|
| tenant_id | UUID | FK -> tenants.tenants (unique) |
|
|
| plan_id | UUID | FK -> plans.plans |
|
|
| stripe_subscription_id | VARCHAR | ID en Stripe |
|
|
| stripe_customer_id | VARCHAR | Customer ID Stripe |
|
|
| status | subscription_status | Estado (ver enums) |
|
|
| current_period_start | TIMESTAMP | Inicio periodo |
|
|
| current_period_end | TIMESTAMP | Fin periodo |
|
|
| trial_start | TIMESTAMP | Inicio trial |
|
|
| trial_end | TIMESTAMP | Fin trial |
|
|
| cancel_at | TIMESTAMP | Fecha programada cancelacion |
|
|
| canceled_at | TIMESTAMP | Fecha real cancelacion |
|
|
| cancel_reason | VARCHAR | Razon cancelacion |
|
|
| price_amount | DECIMAL | Precio del plan |
|
|
| currency | VARCHAR | Moneda (USD, MXN) |
|
|
| metadata | JSONB | Metadata adicional |
|
|
|
|
**invoices**
|
|
| Columna | Tipo | Descripcion |
|
|
|---------|------|-------------|
|
|
| id | UUID | PK |
|
|
| tenant_id | UUID | FK -> tenants.tenants |
|
|
| subscription_id | UUID | FK -> billing.subscriptions |
|
|
| stripe_invoice_id | VARCHAR | ID en Stripe |
|
|
| invoice_number | VARCHAR | Numero (INV-YYYYMM-XXXXXX) |
|
|
| subtotal | DECIMAL | Subtotal |
|
|
| tax | DECIMAL | Impuestos |
|
|
| discount | DECIMAL | Descuento aplicado |
|
|
| total | DECIMAL | Total |
|
|
| amount_paid | DECIMAL | Monto pagado |
|
|
| amount_due | DECIMAL | Monto pendiente |
|
|
| currency | VARCHAR | Moneda |
|
|
| status | invoice_status | draft, open, paid, void, uncollectible |
|
|
| invoice_date | DATE | Fecha factura |
|
|
| due_date | DATE | Fecha vencimiento |
|
|
| period_start | TIMESTAMP | Inicio periodo facturado |
|
|
| period_end | TIMESTAMP | Fin periodo facturado |
|
|
| paid_at | TIMESTAMP | Fecha de pago |
|
|
| invoice_pdf_url | VARCHAR | URL PDF factura |
|
|
| hosted_invoice_url | VARCHAR | URL Stripe hosted |
|
|
| customer_name | VARCHAR | Nombre cliente |
|
|
| customer_email | VARCHAR | Email cliente |
|
|
| billing_address | JSONB | Direccion facturacion |
|
|
|
|
**payment_methods**
|
|
| Columna | Tipo | Descripcion |
|
|
|---------|------|-------------|
|
|
| id | UUID | PK |
|
|
| tenant_id | UUID | FK -> tenants.tenants |
|
|
| type | payment_method_type | card, bank_transfer, oxxo |
|
|
| provider | VARCHAR | stripe, conekta, etc. |
|
|
| external_payment_method_id | VARCHAR | ID en proveedor |
|
|
| card_brand | VARCHAR | Visa, Mastercard, Amex |
|
|
| card_last4 | VARCHAR | Ultimos 4 digitos |
|
|
| card_exp_month | INTEGER | Mes expiracion |
|
|
| card_exp_year | INTEGER | Año expiracion |
|
|
| is_default | BOOLEAN | Metodo por defecto |
|
|
| created_at | TIMESTAMP | Fecha creacion |
|
|
|
|
## Enums de Billing
|
|
|
|
### tenants.subscription_status
|
|
|
|
Estado general del tenant respecto a su suscripcion (usado en tenant context):
|
|
|
|
| Valor | Descripcion |
|
|
|-------|-------------|
|
|
| trialing | En periodo de prueba |
|
|
| active | Suscripcion activa |
|
|
| past_due | Pago atrasado |
|
|
| cancelled | Cancelado |
|
|
| unpaid | Sin pago |
|
|
|
|
### billing.subscription_status
|
|
|
|
Estado interno del sistema de billing:
|
|
|
|
| Valor | Descripcion |
|
|
|-------|-------------|
|
|
| trial | En trial |
|
|
| active | Activo |
|
|
| past_due | Pago atrasado |
|
|
| cancelled | Cancelado |
|
|
| expired | Expirado |
|
|
|
|
**Nota:** El tenant usa `tenants.subscription_status` para el estado visible.
|
|
El modulo billing usa `billing.subscription_status` internamente.
|
|
|
|
## Integracion Stripe
|
|
|
|
### Productos y Precios
|
|
```typescript
|
|
// Configurados en Stripe Dashboard
|
|
const STRIPE_PRODUCTS = {
|
|
starter: {
|
|
monthly: 'price_xxx_monthly',
|
|
yearly: 'price_xxx_yearly'
|
|
},
|
|
pro: {
|
|
monthly: 'price_yyy_monthly',
|
|
yearly: 'price_yyy_yearly'
|
|
}
|
|
};
|
|
```
|
|
|
|
### Webhooks Manejados
|
|
- `customer.subscription.created`
|
|
- `customer.subscription.updated`
|
|
- `customer.subscription.deleted`
|
|
- `invoice.paid`
|
|
- `invoice.payment_failed`
|
|
- `customer.updated`
|
|
|
|
## Endpoints API
|
|
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /billing/plans | Planes disponibles |
|
|
| GET | /billing/subscription | Suscripcion actual |
|
|
| POST | /billing/checkout | Crear sesion checkout |
|
|
| POST | /billing/portal | URL portal de cliente |
|
|
| PUT | /billing/change-plan | Cambiar plan |
|
|
| POST | /billing/cancel | Cancelar suscripcion |
|
|
| POST | /billing/resume | Reanudar suscripcion |
|
|
| GET | /billing/invoices | Historial facturas |
|
|
| GET | /billing/invoices/:id/pdf | Descargar factura |
|
|
| POST | /billing/webhook | Webhook Stripe |
|
|
|
|
## Flujos
|
|
|
|
### Nueva Suscripcion
|
|
```
|
|
1. Usuario selecciona plan
|
|
2. Click "Suscribirse"
|
|
3. Backend crea Checkout Session
|
|
4. Usuario redirigido a Stripe Checkout
|
|
5. Usuario completa pago
|
|
6. Stripe envia webhook
|
|
7. Backend actualiza suscripcion
|
|
8. Usuario redirigido a app
|
|
```
|
|
|
|
### Upgrade de Plan
|
|
```
|
|
1. Usuario en plan Starter
|
|
2. Click "Upgrade a Pro"
|
|
3. Backend llama Stripe API
|
|
4. Stripe calcula prorateo
|
|
5. Se cobra diferencia
|
|
6. Plan actualizado inmediatamente
|
|
7. Features Pro desbloqueadas
|
|
```
|
|
|
|
### Trial Expirando
|
|
```
|
|
Dia -3: Email "Tu trial termina en 3 dias"
|
|
Dia -1: Email "Tu trial termina manana"
|
|
Dia 0: Email "Tu trial ha terminado"
|
|
Si no hay pago: downgrade a Free
|
|
```
|
|
|
|
## Estados de Suscripcion
|
|
|
|
```
|
|
trialing ──► active ──► past_due ──► cancelled
|
|
│
|
|
└──► paused
|
|
```
|
|
|
|
| Estado | Acceso | Descripcion |
|
|
|--------|--------|-------------|
|
|
| trialing | Completo | En periodo de prueba |
|
|
| active | Completo | Pagando |
|
|
| past_due | Limitado | Pago fallido (grace) |
|
|
| cancelled | Sin acceso | Cancelada |
|
|
| paused | Sin acceso | Pausada |
|
|
|
|
## Entregables
|
|
|
|
| Entregable | Estado | Archivo |
|
|
|------------|--------|---------|
|
|
| billing.module.ts | Completado | `modules/billing/` |
|
|
| stripe.service.ts | Completado | `services/` |
|
|
| billing.controller.ts | Completado | `controllers/` |
|
|
| DDL billing schema | Completado | `ddl/schemas/billing/` |
|
|
|
|
## Dependencias
|
|
|
|
### Depende de
|
|
- SAAS-001 (Auth)
|
|
- SAAS-002 (Tenants)
|
|
- SAAS-005 (Plans)
|
|
|
|
### Bloquea a
|
|
- Ninguno (pero habilita features por plan)
|
|
|
|
## Criterios de Aceptacion
|
|
|
|
- [x] Checkout funciona
|
|
- [x] Webhooks se procesan
|
|
- [x] Upgrade/downgrade funciona
|
|
- [x] Facturas se generan
|
|
- [x] Trial funciona
|
|
- [x] Cancelacion funciona
|
|
|
|
## Configuracion
|
|
|
|
```typescript
|
|
{
|
|
stripe: {
|
|
secretKey: process.env.STRIPE_SECRET_KEY,
|
|
webhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
|
|
portalReturnUrl: 'https://app.example.com/settings/billing'
|
|
},
|
|
trial: {
|
|
days: 14,
|
|
requiresCard: false
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
**Ultima actualizacion:** 2026-01-10
|