# 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) ```sql SELECT plan_code, plan_name, max_users, features, subscription_status FROM billing.get_tenant_plan(tenant_id); ``` ### can_add_user(tenant_id) ```sql SELECT billing.can_add_user(tenant_id); -- Returns: true/false ``` ### has_feature(tenant_id, feature) ```sql 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 ```json { "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