erp-core/docs/04-modelado/domain-models/billing-domain.md

18 KiB

Modelo de Dominio: Billing (MGN-015)

Módulo: MGN-015 - Billing y Suscripciones SaaS Fecha: 2025-12-06 Estado: Implementado


Diagrama de Entidades

┌─────────────────────────────────────────────────────────────────────────────┐
│                           BILLING DOMAIN                                     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌──────────────────────┐         ┌──────────────────────┐                  │
│  │ subscription_plans   │         │      tenants         │                  │
│  │ (Global)             │         │   (from auth)        │                  │
│  ├──────────────────────┤         ├──────────────────────┤                  │
│  │ id                   │         │ id                   │                  │
│  │ code                 │◄────────│                      │                  │
│  │ name                 │         └──────────┬───────────┘                  │
│  │ price_monthly        │                    │                              │
│  │ price_yearly         │                    │ 1                            │
│  │ max_users            │                    │                              │
│  │ max_companies        │                    ▼                              │
│  │ features (JSONB)     │         ┌──────────────────────┐                  │
│  └──────────┬───────────┘         │   subscriptions      │                  │
│             │                     ├──────────────────────┤                  │
│             │ 1                   │ id                   │                  │
│             │                     │ tenant_id            │──┐               │
│             ▼                     │ plan_id              │  │               │
│  ┌──────────────────────┐         │ status               │  │               │
│  │    subscriptions     │◄────────│ billing_cycle        │  │               │
│  │                      │         │ current_period_start │  │               │
│  └──────────────────────┘         │ current_period_end   │  │               │
│                                   │ stripe_subscription_id│  │               │
│                                   └──────────┬───────────┘  │               │
│                                              │              │               │
│                                              │ 1            │               │
│                                              ▼              │               │
│                                   ┌──────────────────────┐  │               │
│                                   │ subscription_history │  │               │
│                                   ├──────────────────────┤  │               │
│                                   │ id                   │  │               │
│                                   │ subscription_id      │  │               │
│                                   │ event_type           │  │               │
│                                   │ previous_plan_id     │  │               │
│                                   │ new_plan_id          │  │               │
│                                   │ metadata (JSONB)     │  │               │
│                                   └──────────────────────┘  │               │
│                                                             │               │
│  ┌──────────────────────┐         ┌──────────────────────┐  │               │
│  │   tenant_owners      │         │   payment_methods    │  │               │
│  ├──────────────────────┤         ├──────────────────────┤  │               │
│  │ id                   │         │ id                   │  │               │
│  │ tenant_id            │◄────────│ tenant_id            │◄─┤               │
│  │ user_id              │         │ type                 │  │               │
│  │ ownership_type       │         │ card_last_four       │  │               │
│  │ billing_email        │         │ card_brand           │  │               │
│  └──────────────────────┘         │ is_default           │  │               │
│                                   │ stripe_payment_method_id│ │              │
│                                   └──────────────────────┘  │               │
│                                                             │               │
│  ┌──────────────────────┐         ┌──────────────────────┐  │               │
│  │      invoices        │         │      payments        │  │               │
│  ├──────────────────────┤         ├──────────────────────┤  │               │
│  │ id                   │◄────────│ id                   │  │               │
│  │ tenant_id            │◄────────│ tenant_id            │◄─┤               │
│  │ subscription_id      │         │ invoice_id           │  │               │
│  │ invoice_number       │         │ payment_method_id    │  │               │
│  │ status               │         │ amount               │  │               │
│  │ subtotal             │         │ status               │  │               │
│  │ tax_amount           │         │ paid_at              │  │               │
│  │ total                │         │ stripe_payment_intent_id│ │              │
│  │ cfdi_uuid            │         └──────────────────────┘  │               │
│  └──────────┬───────────┘                                   │               │
│             │                                               │               │
│             │ 1..*                                          │               │
│             ▼                                               │               │
│  ┌──────────────────────┐                                   │               │
│  │   invoice_lines      │                                   │               │
│  ├──────────────────────┤                                   │               │
│  │ id                   │                                   │               │
│  │ invoice_id           │                                   │               │
│  │ description          │                                   │               │
│  │ quantity             │                                   │               │
│  │ unit_price           │                                   │               │
│  │ amount               │                                   │               │
│  └──────────────────────┘                                   │               │
│                                                             │               │
│  ┌──────────────────────┐         ┌──────────────────────┐  │               │
│  │       coupons        │         │  coupon_redemptions  │  │               │
│  │      (Global)        │         ├──────────────────────┤  │               │
│  ├──────────────────────┤         │ id                   │  │               │
│  │ id                   │◄────────│ coupon_id            │  │               │
│  │ code                 │         │ tenant_id            │◄─┤               │
│  │ discount_type        │         │ subscription_id      │  │               │
│  │ discount_value       │         │ redeemed_at          │  │               │
│  │ max_redemptions      │         └──────────────────────┘  │               │
│  │ valid_from           │                                   │               │
│  │ valid_until          │                                   │               │
│  └──────────────────────┘                                   │               │
│                                                             │               │
│  ┌──────────────────────┐                                   │               │
│  │    usage_records     │                                   │               │
│  ├──────────────────────┤                                   │               │
│  │ id                   │                                   │               │
│  │ tenant_id            │◄──────────────────────────────────┘               │
│  │ subscription_id      │                                                   │
│  │ metric_type          │                                                   │
│  │ quantity             │                                                   │
│  │ billing_period       │                                                   │
│  └──────────────────────┘                                                   │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Entidades

1. subscription_plans (Planes de Suscripción)

Propósito: Define los planes disponibles para los tenants. Alcance: Global (no tiene tenant_id)

Atributo Tipo Descripción
id UUID Identificador único
code VARCHAR(50) Código único (free, basic, professional, enterprise)
name VARCHAR(100) Nombre del plan
price_monthly DECIMAL Precio mensual
price_yearly DECIMAL Precio anual
max_users INTEGER Límite de usuarios (NULL = ilimitado)
max_companies INTEGER Límite de empresas
max_storage_gb INTEGER Límite de almacenamiento
features JSONB Features habilitadas
trial_days INTEGER Días de prueba
is_default BOOLEAN Plan por defecto

2. subscriptions (Suscripciones)

Propósito: Suscripción activa de cada tenant. Restricción: Solo 1 suscripción por tenant.

Atributo Tipo Descripción
id UUID Identificador único
tenant_id UUID FK a auth.tenants
plan_id UUID FK a subscription_plans
status ENUM trialing, active, past_due, paused, cancelled, suspended, expired
billing_cycle ENUM monthly, quarterly, semi_annual, annual
current_period_start TIMESTAMP Inicio del período actual
current_period_end TIMESTAMP Fin del período actual
stripe_subscription_id VARCHAR ID de Stripe

3. tenant_owners (Propietarios)

Propósito: Usuarios que pueden gestionar billing del tenant.

Atributo Tipo Descripción
tenant_id UUID FK a auth.tenants
user_id UUID FK a auth.users
ownership_type VARCHAR owner, billing_admin
billing_email VARCHAR Email de facturación

4. payment_methods (Métodos de Pago)

Propósito: Métodos de pago registrados por tenant.

Atributo Tipo Descripción
tenant_id UUID FK a auth.tenants
type ENUM card, bank_transfer, paypal, oxxo, spei
card_last_four VARCHAR(4) Últimos 4 dígitos
card_brand VARCHAR visa, mastercard, amex
is_default BOOLEAN Método por defecto
stripe_payment_method_id VARCHAR ID de Stripe

5. invoices (Facturas)

Propósito: Facturas de suscripción.

Atributo Tipo Descripción
tenant_id UUID FK a auth.tenants
invoice_number VARCHAR Número de factura
status ENUM draft, open, paid, void, uncollectible
subtotal DECIMAL Subtotal
tax_amount DECIMAL Impuestos
total DECIMAL Total
cfdi_uuid VARCHAR UUID del CFDI (México)

6. payments (Pagos)

Propósito: Pagos recibidos.

Atributo Tipo Descripción
tenant_id UUID FK a auth.tenants
invoice_id UUID FK a invoices
amount DECIMAL Monto pagado
status ENUM pending, processing, succeeded, failed, cancelled, refunded
stripe_payment_intent_id VARCHAR ID de Stripe

7. coupons (Cupones)

Propósito: Cupones de descuento. Alcance: Global

Atributo Tipo Descripción
code VARCHAR Código del cupón
discount_type VARCHAR percent, fixed
discount_value DECIMAL Valor del descuento
max_redemptions INTEGER Máximo de usos
valid_from TIMESTAMP Válido desde
valid_until TIMESTAMP Válido hasta

8. usage_records (Registros de Uso)

Propósito: Tracking de uso para billing por consumo.

Atributo Tipo Descripción
tenant_id UUID FK a auth.tenants
metric_type VARCHAR users, storage_gb, api_calls
quantity DECIMAL Cantidad consumida
billing_period DATE Período de facturación

Estados de Suscripción

                    ┌─────────┐
                    │ trialing│
                    └────┬────┘
                         │ (trial ends)
                         ▼
    ┌─────────┐    ┌─────────┐    ┌─────────┐
    │ paused  │◄───│ active  │───►│past_due │
    └────┬────┘    └────┬────┘    └────┬────┘
         │              │              │
         │              │              │ (payment fails)
         │              ▼              ▼
         │        ┌─────────┐    ┌─────────┐
         └───────►│cancelled│    │suspended│
                  └─────────┘    └────┬────┘
                                      │
                                      ▼
                                ┌─────────┐
                                │ expired │
                                └─────────┘

Funciones de Negocio

get_tenant_plan(tenant_id)

SELECT plan_code, plan_name, max_users, features, subscription_status
FROM billing.get_tenant_plan(tenant_id);

can_add_user(tenant_id)

SELECT billing.can_add_user(tenant_id);
-- Returns: true/false

has_feature(tenant_id, feature)

SELECT billing.has_feature(tenant_id, 'crm');
-- Returns: true/false

Integración con Stripe

Campo Propósito
stripe_customer_id ID del customer en Stripe
stripe_subscription_id ID de la suscripción en Stripe
stripe_payment_method_id ID del método de pago
stripe_payment_intent_id ID del payment intent
stripe_invoice_id ID de la factura en Stripe

Features JSONB Structure

{
  "inventory": true,
  "sales": true,
  "financial": true,
  "purchase": true,
  "crm": false,
  "projects": false,
  "reports_basic": true,
  "reports_advanced": false,
  "api_access": false,
  "white_label": false,
  "priority_support": false
}

Generado por: Requirements-Analyst Fecha: 2025-12-06