- Update vision, architecture and technical documentation - Update module definitions (PMC-001 to PMC-008) - Update requirements documentation - Add CONTEXT-MAP.yml and ENVIRONMENT-INVENTORY.yml - Add orchestration guidelines and references 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
738 lines
20 KiB
Markdown
738 lines
20 KiB
Markdown
---
|
|
id: "PMC-009-PAYMENTS"
|
|
title: "PMC-009: Modulo de Payments"
|
|
type: "Module Definition"
|
|
epic: "PMC-009"
|
|
status: "Draft"
|
|
project: "platform_marketing_content"
|
|
version: "1.0.0"
|
|
created_date: "2026-01-04"
|
|
updated_date: "2026-01-04"
|
|
---
|
|
# PMC-009: Modulo de Payments
|
|
|
|
**Version:** 1.0.0
|
|
**Fecha:** 2026-01-04
|
|
**Estado:** Definicion
|
|
**Prioridad:** Alta
|
|
|
|
---
|
|
|
|
## Descripcion General
|
|
|
|
El modulo de Payments proporciona la integracion completa con Stripe para gestionar suscripciones, pagos y facturacion del sistema SaaS. Incluye checkout flow con Stripe Elements, gestion de planes de suscripcion, facturacion automatica y sistema de creditos de generacion.
|
|
|
|
### Objetivos
|
|
|
|
1. Integrar Stripe como pasarela de pagos principal
|
|
2. Gestionar planes de suscripcion (Free, Pro, Enterprise, Internal)
|
|
3. Implementar checkout flow con Stripe Elements
|
|
4. Automatizar facturacion y cobros recurrentes
|
|
5. Gestionar creditos de generacion por tenant
|
|
6. Procesar webhooks de Stripe para sincronizar estados
|
|
|
|
---
|
|
|
|
## Planes de Suscripcion
|
|
|
|
```yaml
|
|
Planes Disponibles:
|
|
free:
|
|
nombre: "Free"
|
|
precio: $0/mes
|
|
limites:
|
|
generaciones_mes: 50
|
|
storage_gb: 1
|
|
usuarios_max: 1
|
|
modelos_custom: 0
|
|
features:
|
|
- Generacion basica de imagenes
|
|
- 1 proyecto activo
|
|
- Soporte por email
|
|
|
|
pro:
|
|
nombre: "Pro"
|
|
precio: $79/mes
|
|
stripe_price_id: pmc_pro
|
|
limites:
|
|
generaciones_mes: 500
|
|
storage_gb: 25
|
|
usuarios_max: 5
|
|
modelos_custom: 3
|
|
features:
|
|
- Todo de Free
|
|
- Modelos personalizados
|
|
- API access
|
|
- Integraciones n8n
|
|
- Soporte prioritario
|
|
|
|
enterprise:
|
|
nombre: "Enterprise"
|
|
precio: $249/mes
|
|
stripe_price_id: pmc_enterprise
|
|
limites:
|
|
generaciones_mes: unlimited
|
|
storage_gb: 100
|
|
usuarios_max: unlimited
|
|
modelos_custom: unlimited
|
|
features:
|
|
- Todo de Pro
|
|
- Generaciones ilimitadas
|
|
- Usuarios ilimitados
|
|
- SSO/SAML
|
|
- SLA garantizado
|
|
- Soporte dedicado
|
|
|
|
internal:
|
|
nombre: "Internal"
|
|
precio: $0/mes
|
|
limites:
|
|
generaciones_mes: unlimited
|
|
storage_gb: unlimited
|
|
usuarios_max: unlimited
|
|
modelos_custom: unlimited
|
|
features:
|
|
- Acceso completo sin restricciones
|
|
- Solo para uso interno de la organizacion
|
|
```
|
|
|
|
---
|
|
|
|
## Productos Stripe Propuestos
|
|
|
|
```yaml
|
|
Productos Stripe:
|
|
pmc_pro:
|
|
type: subscription
|
|
nombre: "PMC Pro Plan"
|
|
precio: $79/mes
|
|
billing_interval: monthly
|
|
descripcion: "500 generaciones, 25GB storage, 5 usuarios"
|
|
metadata:
|
|
plan_code: pro
|
|
generations: 500
|
|
storage_gb: 25
|
|
users_max: 5
|
|
|
|
pmc_enterprise:
|
|
type: subscription
|
|
nombre: "PMC Enterprise Plan"
|
|
precio: $249/mes
|
|
billing_interval: monthly
|
|
descripcion: "Generaciones ilimitadas, recursos ilimitados"
|
|
metadata:
|
|
plan_code: enterprise
|
|
generations: unlimited
|
|
storage_gb: 100
|
|
users_max: unlimited
|
|
|
|
pmc_generations_100:
|
|
type: one_time
|
|
nombre: "Pack 100 Generaciones Extra"
|
|
precio: $19
|
|
descripcion: "100 creditos de generacion adicionales"
|
|
metadata:
|
|
product_type: credits
|
|
credits_amount: 100
|
|
```
|
|
|
|
---
|
|
|
|
## Entidades del Dominio
|
|
|
|
### Subscription
|
|
|
|
```yaml
|
|
Entidad: Subscription
|
|
Descripcion: Suscripcion activa de un tenant a un plan
|
|
Atributos:
|
|
- id: UUID (PK)
|
|
- tenant_id: UUID (FK a Tenant)
|
|
- user_id: UUID (FK a User, quien suscribio)
|
|
- plan_id: UUID (FK a Plan)
|
|
- stripe_subscription_id: string (sub_xxx)
|
|
- stripe_customer_id: string (cus_xxx)
|
|
- status: enum [active, past_due, canceled, incomplete, trialing, paused]
|
|
- current_period_start: timestamp
|
|
- current_period_end: timestamp
|
|
- cancel_at_period_end: boolean
|
|
- canceled_at: timestamp
|
|
- trial_start: timestamp
|
|
- trial_end: timestamp
|
|
- metadata: JSONB
|
|
- created_at: timestamp
|
|
- updated_at: timestamp
|
|
|
|
Relaciones:
|
|
- N:1 con Tenant
|
|
- N:1 con User
|
|
- N:1 con Plan
|
|
- 1:N con Invoice
|
|
```
|
|
|
|
### Invoice
|
|
|
|
```yaml
|
|
Entidad: Invoice
|
|
Descripcion: Factura generada por Stripe
|
|
Atributos:
|
|
- id: UUID (PK)
|
|
- tenant_id: UUID (FK)
|
|
- subscription_id: UUID (FK a Subscription)
|
|
- stripe_invoice_id: string (in_xxx)
|
|
- stripe_invoice_number: string
|
|
- amount_due: decimal
|
|
- amount_paid: decimal
|
|
- currency: string (usd, eur)
|
|
- status: enum [draft, open, paid, void, uncollectible]
|
|
- invoice_pdf_url: string
|
|
- hosted_invoice_url: string
|
|
- paid_at: timestamp
|
|
- due_date: timestamp
|
|
- period_start: timestamp
|
|
- period_end: timestamp
|
|
- created_at: timestamp
|
|
- updated_at: timestamp
|
|
|
|
Relaciones:
|
|
- N:1 con Tenant
|
|
- N:1 con Subscription
|
|
```
|
|
|
|
### PaymentMethod
|
|
|
|
```yaml
|
|
Entidad: PaymentMethod
|
|
Descripcion: Metodo de pago registrado del cliente
|
|
Atributos:
|
|
- id: UUID (PK)
|
|
- tenant_id: UUID (FK)
|
|
- user_id: UUID (FK)
|
|
- stripe_payment_method_id: string (pm_xxx)
|
|
- type: enum [card, sepa_debit, us_bank_account]
|
|
- card_brand: string (visa, mastercard, amex)
|
|
- card_last4: string
|
|
- card_exp_month: integer
|
|
- card_exp_year: integer
|
|
- is_default: boolean
|
|
- billing_details: JSONB (name, email, address)
|
|
- created_at: timestamp
|
|
- updated_at: timestamp
|
|
|
|
Relaciones:
|
|
- N:1 con Tenant
|
|
- N:1 con User
|
|
```
|
|
|
|
### GenerationCredit
|
|
|
|
```yaml
|
|
Entidad: GenerationCredit
|
|
Descripcion: Balance de creditos de generacion por tenant
|
|
Atributos:
|
|
- id: UUID (PK)
|
|
- tenant_id: UUID (FK, unico)
|
|
- credits_included: integer (del plan)
|
|
- credits_remaining: integer (del periodo actual)
|
|
- credits_used: integer (del periodo actual)
|
|
- credits_extra: integer (comprados, no expiran)
|
|
- resets_at: timestamp (inicio proximo periodo)
|
|
- last_reset_at: timestamp
|
|
- created_at: timestamp
|
|
- updated_at: timestamp
|
|
|
|
Relaciones:
|
|
- 1:1 con Tenant
|
|
|
|
Notas:
|
|
- credits_remaining se resetea cada periodo de facturacion
|
|
- credits_extra no se resetean, son acumulables
|
|
- Al consumir, primero se usan credits_remaining, luego credits_extra
|
|
```
|
|
|
|
### CreditTransaction
|
|
|
|
```yaml
|
|
Entidad: CreditTransaction
|
|
Descripcion: Historial de movimientos de creditos
|
|
Atributos:
|
|
- id: UUID (PK)
|
|
- tenant_id: UUID (FK)
|
|
- type: enum [subscription_reset, purchase, usage, adjustment, refund]
|
|
- amount: integer (positivo o negativo)
|
|
- balance_after: integer
|
|
- description: string
|
|
- reference_type: string (generation_job, invoice, manual)
|
|
- reference_id: UUID
|
|
- created_at: timestamp
|
|
|
|
Relaciones:
|
|
- N:1 con Tenant
|
|
```
|
|
|
|
---
|
|
|
|
## Funcionalidades
|
|
|
|
### F-009.1: Seleccionar Plan y Suscribirse
|
|
|
|
| ID | Funcionalidad | Descripcion | Prioridad |
|
|
|----|---------------|-------------|-----------|
|
|
| F-009.1.1 | Ver planes disponibles | Mostrar comparativa de planes | Alta |
|
|
| F-009.1.2 | Seleccionar plan | Elegir plan deseado | Alta |
|
|
| F-009.1.3 | Crear customer Stripe | Registrar cliente en Stripe | Alta |
|
|
| F-009.1.4 | Iniciar trial | Periodo de prueba de 14 dias | Media |
|
|
|
|
### F-009.2: Checkout con Stripe Elements
|
|
|
|
| ID | Funcionalidad | Descripcion | Prioridad |
|
|
|----|---------------|-------------|-----------|
|
|
| F-009.2.1 | Crear checkout session | Generar sesion de pago Stripe | Alta |
|
|
| F-009.2.2 | Stripe Elements UI | Formulario de pago embebido | Alta |
|
|
| F-009.2.3 | Confirmar pago | Procesar transaccion | Alta |
|
|
| F-009.2.4 | Manejar errores | Reintentos y mensajes claros | Alta |
|
|
|
|
### F-009.3: Gestionar Suscripcion
|
|
|
|
| ID | Funcionalidad | Descripcion | Prioridad |
|
|
|----|---------------|-------------|-----------|
|
|
| F-009.3.1 | Ver suscripcion actual | Detalles del plan activo | Alta |
|
|
| F-009.3.2 | Upgrade de plan | Cambiar a plan superior | Alta |
|
|
| F-009.3.3 | Downgrade de plan | Cambiar a plan inferior | Media |
|
|
| F-009.3.4 | Cancelar suscripcion | Finalizar al terminar periodo | Media |
|
|
| F-009.3.5 | Reactivar suscripcion | Revertir cancelacion pendiente | Media |
|
|
|
|
### F-009.4: Ver Facturas e Historial
|
|
|
|
| ID | Funcionalidad | Descripcion | Prioridad |
|
|
|----|---------------|-------------|-----------|
|
|
| F-009.4.1 | Listar facturas | Historial de pagos | Alta |
|
|
| F-009.4.2 | Descargar factura PDF | Obtener comprobante | Alta |
|
|
| F-009.4.3 | Ver detalle de factura | Items, impuestos, totales | Media |
|
|
|
|
### F-009.5: Comprar Creditos Adicionales
|
|
|
|
| ID | Funcionalidad | Descripcion | Prioridad |
|
|
|----|---------------|-------------|-----------|
|
|
| F-009.5.1 | Ver packs disponibles | Mostrar opciones de creditos | Media |
|
|
| F-009.5.2 | Comprar pack | Checkout one-time | Media |
|
|
| F-009.5.3 | Acreditar creditos | Sumar a credits_extra | Media |
|
|
|
|
### F-009.6: Webhooks de Stripe
|
|
|
|
| ID | Funcionalidad | Descripcion | Prioridad |
|
|
|----|---------------|-------------|-----------|
|
|
| F-009.6.1 | invoice.paid | Actualizar estado de factura | Alta |
|
|
| F-009.6.2 | invoice.payment_failed | Notificar y manejar fallo | Alta |
|
|
| F-009.6.3 | customer.subscription.updated | Sincronizar cambios de suscripcion | Alta |
|
|
| F-009.6.4 | customer.subscription.deleted | Manejar cancelacion | Alta |
|
|
| F-009.6.5 | checkout.session.completed | Confirmar compra one-time | Alta |
|
|
|
|
---
|
|
|
|
## API Endpoints
|
|
|
|
```yaml
|
|
Base: /api/v1/billing
|
|
|
|
# Checkout y Suscripcion
|
|
POST /billing/checkout:
|
|
Descripcion: Crear sesion de checkout Stripe
|
|
Body: { plan_code: "pro", success_url: string, cancel_url: string }
|
|
Response: { checkout_url: string, session_id: string }
|
|
Permisos: tenant_admin
|
|
|
|
GET /billing/subscription:
|
|
Descripcion: Ver suscripcion actual del tenant
|
|
Response: { subscription, plan, usage }
|
|
Permisos: authenticated
|
|
|
|
POST /billing/subscription/upgrade:
|
|
Descripcion: Upgrade inmediato a plan superior
|
|
Body: { new_plan_code: string }
|
|
Response: { subscription, proration_amount }
|
|
Permisos: tenant_admin
|
|
|
|
POST /billing/subscription/downgrade:
|
|
Descripcion: Downgrade al final del periodo
|
|
Body: { new_plan_code: string }
|
|
Response: { subscription, effective_date }
|
|
Permisos: tenant_admin
|
|
|
|
POST /billing/subscription/cancel:
|
|
Descripcion: Cancelar suscripcion al final del periodo
|
|
Body: { reason?: string, feedback?: string }
|
|
Response: { subscription, cancel_at }
|
|
Permisos: tenant_admin
|
|
|
|
POST /billing/subscription/reactivate:
|
|
Descripcion: Revertir cancelacion pendiente
|
|
Response: { subscription }
|
|
Permisos: tenant_admin
|
|
|
|
# Metodos de Pago
|
|
GET /billing/payment-methods:
|
|
Descripcion: Listar metodos de pago
|
|
Response: { payment_methods: [] }
|
|
Permisos: tenant_admin
|
|
|
|
POST /billing/payment-methods:
|
|
Descripcion: Agregar metodo de pago
|
|
Body: { payment_method_id: string }
|
|
Response: { payment_method }
|
|
Permisos: tenant_admin
|
|
|
|
DELETE /billing/payment-methods/:id:
|
|
Descripcion: Eliminar metodo de pago
|
|
Response: 204 No Content
|
|
Permisos: tenant_admin
|
|
|
|
PATCH /billing/payment-methods/:id/default:
|
|
Descripcion: Establecer como metodo predeterminado
|
|
Response: { payment_method }
|
|
Permisos: tenant_admin
|
|
|
|
# Facturas
|
|
GET /billing/invoices:
|
|
Descripcion: Listar facturas del tenant
|
|
Query: ?status=paid&page=1&limit=20
|
|
Response: { invoices: [], pagination }
|
|
Permisos: tenant_admin
|
|
|
|
GET /billing/invoices/:id:
|
|
Descripcion: Detalle de factura
|
|
Response: { invoice }
|
|
Permisos: tenant_admin
|
|
|
|
GET /billing/invoices/:id/pdf:
|
|
Descripcion: Descargar PDF de factura
|
|
Response: Redirect a URL de Stripe
|
|
Permisos: tenant_admin
|
|
|
|
# Creditos
|
|
GET /billing/credits:
|
|
Descripcion: Ver balance de creditos
|
|
Response: { credits_remaining, credits_extra, credits_used, resets_at }
|
|
Permisos: authenticated
|
|
|
|
POST /billing/credits/purchase:
|
|
Descripcion: Comprar pack de creditos
|
|
Body: { pack_code: "pmc_generations_100" }
|
|
Response: { checkout_url, session_id }
|
|
Permisos: tenant_admin
|
|
|
|
GET /billing/credits/transactions:
|
|
Descripcion: Historial de movimientos de creditos
|
|
Query: ?type=usage&page=1&limit=50
|
|
Response: { transactions: [], pagination }
|
|
Permisos: tenant_admin
|
|
|
|
# Webhooks (endpoint publico)
|
|
POST /billing/webhooks:
|
|
Descripcion: Endpoint para webhooks de Stripe
|
|
Headers: Stripe-Signature
|
|
Response: 200 OK
|
|
Notas: Verificar firma con STRIPE_WEBHOOK_SECRET
|
|
```
|
|
|
|
---
|
|
|
|
## Reglas de Negocio
|
|
|
|
```yaml
|
|
RN-009.1:
|
|
Descripcion: Solo tenant_admin puede cambiar plan
|
|
Validacion: Verificar rol del usuario
|
|
Accion: 403 Forbidden si no es admin
|
|
|
|
RN-009.2:
|
|
Descripcion: Downgrade aplica al final del periodo
|
|
Validacion: No cambio inmediato, schedule para renewal
|
|
Accion: Stripe schedule subscription update
|
|
|
|
RN-009.3:
|
|
Descripcion: Creditos del plan no usados no se transfieren
|
|
Validacion: credits_remaining se resetea cada periodo
|
|
Excepcion: credits_extra (comprados) son permanentes
|
|
|
|
RN-009.4:
|
|
Descripcion: Cancelacion permite usar hasta fin del periodo
|
|
Validacion: cancel_at_period_end = true
|
|
Accion: Acceso continua hasta current_period_end
|
|
|
|
RN-009.5:
|
|
Descripcion: Plan Free no requiere metodo de pago
|
|
Validacion: Permitir suscripcion sin checkout
|
|
Accion: Crear subscription con trial infinito o sin cobro
|
|
|
|
RN-009.6:
|
|
Descripcion: Upgrade es inmediato con prorrateo
|
|
Validacion: Cobrar diferencia proporcional
|
|
Accion: Stripe proration automatico
|
|
|
|
RN-009.7:
|
|
Descripcion: Pago fallido da 3 reintentos
|
|
Validacion: Stripe Smart Retries habilitado
|
|
Accion: Notificar usuario, suspender tras fallos
|
|
|
|
RN-009.8:
|
|
Descripcion: Creditos se consumen en orden
|
|
Validacion: Primero credits_remaining, luego credits_extra
|
|
Accion: Logica en GenerationService
|
|
|
|
RN-009.9:
|
|
Descripcion: Plan Internal solo asignable por super_admin
|
|
Validacion: Verificar rol super_admin
|
|
Accion: No disponible en checkout publico
|
|
```
|
|
|
|
---
|
|
|
|
## Dependencias
|
|
|
|
```yaml
|
|
Dependencias de Modulos:
|
|
- PMC-001 Tenants:
|
|
uso: Asociacion tenant-plan, limites por tenant
|
|
datos: tenant_id, plan_id, limits JSONB
|
|
|
|
- PMC-007 Admin:
|
|
uso: Permisos de billing, gestion de planes
|
|
datos: admin.billing permission
|
|
|
|
- PMC-004 Generation:
|
|
uso: Consumo de creditos por generacion
|
|
integracion: Decrementar credits al generar
|
|
|
|
Dependencias del Catalogo:
|
|
- @CATALOG_PAYMENTS:
|
|
path: shared/catalog/payments/
|
|
uso: Patron base de integracion Stripe
|
|
incluye:
|
|
- Stripe SDK wrapper
|
|
- Webhook handling
|
|
- Customer management
|
|
- Subscription lifecycle
|
|
adaptar:
|
|
- Crear productos/precios PMC en Stripe
|
|
- Implementar sistema de creditos
|
|
- Integrar con planes de PMC-001
|
|
docs: shared/catalog/payments/README.md
|
|
|
|
- @CATALOG_NOTIFY:
|
|
path: shared/catalog/notifications/
|
|
uso: Notificaciones de pago
|
|
incluye:
|
|
- Email de confirmacion de pago
|
|
- Alerta de pago fallido
|
|
- Recordatorio de vencimiento
|
|
docs: shared/catalog/notifications/README.md
|
|
|
|
Servicios Externos:
|
|
- Stripe:
|
|
tipo: Payment Gateway
|
|
productos:
|
|
- Subscriptions API
|
|
- Checkout Sessions
|
|
- Payment Intents
|
|
- Webhooks
|
|
- Customer Portal
|
|
sdk: stripe (npm)
|
|
version: "^14.0.0"
|
|
|
|
Referencia de Implementacion:
|
|
- Payment service: projects/gamilit/apps/backend/src/modules/payments/
|
|
- Stripe integration: projects/gamilit/apps/backend/src/modules/payments/services/stripe.service.ts
|
|
- Webhook handler: projects/gamilit/apps/backend/src/modules/payments/controllers/webhooks.controller.ts
|
|
```
|
|
|
|
---
|
|
|
|
## Configuracion
|
|
|
|
```yaml
|
|
Variables de Entorno:
|
|
STRIPE_SECRET_KEY:
|
|
descripcion: API key secreta de Stripe
|
|
formato: sk_live_xxx o sk_test_xxx
|
|
requerido: true
|
|
|
|
STRIPE_PUBLISHABLE_KEY:
|
|
descripcion: API key publica para frontend
|
|
formato: pk_live_xxx o pk_test_xxx
|
|
requerido: true
|
|
|
|
STRIPE_WEBHOOK_SECRET:
|
|
descripcion: Secret para verificar webhooks
|
|
formato: whsec_xxx
|
|
requerido: true
|
|
|
|
STRIPE_PRICE_PRO:
|
|
descripcion: Price ID del plan Pro
|
|
formato: price_xxx
|
|
requerido: true
|
|
|
|
STRIPE_PRICE_ENTERPRISE:
|
|
descripcion: Price ID del plan Enterprise
|
|
formato: price_xxx
|
|
requerido: true
|
|
|
|
STRIPE_PRICE_CREDITS_100:
|
|
descripcion: Price ID del pack de 100 creditos
|
|
formato: price_xxx
|
|
requerido: true
|
|
|
|
STRIPE_TRIAL_DAYS:
|
|
descripcion: Dias de prueba para nuevas suscripciones
|
|
default: 14
|
|
requerido: false
|
|
|
|
BILLING_CURRENCY:
|
|
descripcion: Moneda por defecto
|
|
default: "usd"
|
|
requerido: false
|
|
```
|
|
|
|
---
|
|
|
|
## Flujos de Usuario
|
|
|
|
### Suscribirse a Plan Pro
|
|
|
|
```
|
|
1. Usuario navega a Settings → Billing → Plans
|
|
2. Ve comparativa de planes (Free, Pro, Enterprise)
|
|
3. Selecciona "Upgrade to Pro"
|
|
4. Sistema crea Checkout Session en Stripe
|
|
5. Redirect a Stripe Checkout
|
|
6. Usuario ingresa datos de pago (Stripe Elements)
|
|
7. Stripe procesa pago
|
|
8. Webhook invoice.paid recibido
|
|
9. Sistema actualiza subscription y credits
|
|
10. Redirect a success_url con confirmacion
|
|
```
|
|
|
|
### Cancelar Suscripcion
|
|
|
|
```
|
|
1. Admin navega a Settings → Billing → Subscription
|
|
2. Click en "Cancel Subscription"
|
|
3. Modal de confirmacion con fecha de fin
|
|
4. Opcionalmente ingresa razon/feedback
|
|
5. Sistema llama Stripe cancel at period end
|
|
6. Suscripcion marcada cancel_at_period_end = true
|
|
7. Usuario puede seguir usando hasta current_period_end
|
|
8. Al vencer, subscription status = canceled
|
|
```
|
|
|
|
### Comprar Creditos Extra
|
|
|
|
```
|
|
1. Usuario ve que credits_remaining esta bajo
|
|
2. Navega a Settings → Billing → Credits
|
|
3. Ve packs disponibles (100 creditos por $19)
|
|
4. Click en "Buy Credits"
|
|
5. Checkout Session para one-time payment
|
|
6. Stripe procesa pago
|
|
7. Webhook checkout.session.completed
|
|
8. Sistema suma credits_extra += 100
|
|
9. Redirect con confirmacion
|
|
```
|
|
|
|
---
|
|
|
|
## Webhooks de Stripe
|
|
|
|
```yaml
|
|
Eventos a Procesar:
|
|
invoice.paid:
|
|
accion:
|
|
- Actualizar Invoice status = paid
|
|
- Si es primera factura, activar subscription
|
|
- Reset credits_remaining del periodo
|
|
|
|
invoice.payment_failed:
|
|
accion:
|
|
- Actualizar Invoice status segun attempt
|
|
- Notificar usuario por email
|
|
- Tras 3 fallos, marcar subscription past_due
|
|
|
|
customer.subscription.created:
|
|
accion:
|
|
- Crear registro Subscription local
|
|
- Crear GenerationCredit para tenant
|
|
- Actualizar tenant.plan_id
|
|
|
|
customer.subscription.updated:
|
|
accion:
|
|
- Sincronizar status, period dates
|
|
- Si cambio de plan, actualizar limits
|
|
- Recalcular credits si aplica
|
|
|
|
customer.subscription.deleted:
|
|
accion:
|
|
- Marcar subscription status = canceled
|
|
- Cambiar tenant a plan Free
|
|
- Notificar admin del tenant
|
|
|
|
checkout.session.completed:
|
|
accion:
|
|
- Si mode = subscription, ya manejado por invoice.paid
|
|
- Si mode = payment (creditos), acreditar credits_extra
|
|
- Crear CreditTransaction
|
|
|
|
customer.created:
|
|
accion:
|
|
- Actualizar tenant con stripe_customer_id
|
|
|
|
payment_method.attached:
|
|
accion:
|
|
- Crear/actualizar PaymentMethod local
|
|
```
|
|
|
|
---
|
|
|
|
## Criterios de Aceptacion
|
|
|
|
- [ ] Checkout con Stripe Elements funciona end-to-end
|
|
- [ ] Suscripcion se crea correctamente tras pago
|
|
- [ ] Upgrade inmediato con prorrateo funciona
|
|
- [ ] Downgrade se programa para fin de periodo
|
|
- [ ] Cancelacion permite uso hasta vencimiento
|
|
- [ ] Facturas se sincronizan via webhooks
|
|
- [ ] PDFs de facturas descargables
|
|
- [ ] Sistema de creditos funciona correctamente
|
|
- [ ] Compra de creditos extra funciona
|
|
- [ ] Webhooks procesan todos los eventos clave
|
|
- [ ] Notificaciones de pago se envian
|
|
- [ ] Solo tenant_admin puede gestionar billing
|
|
|
|
---
|
|
|
|
## Consideraciones de Seguridad
|
|
|
|
```yaml
|
|
Seguridad:
|
|
- API keys de Stripe solo en backend (nunca en frontend)
|
|
- Webhook signature verification obligatorio
|
|
- PCI compliance delegado a Stripe (no almacenar tarjetas)
|
|
- Audit log de todas las transacciones
|
|
- Rate limiting en endpoints de billing
|
|
- Validar que usuario pertenece al tenant
|
|
```
|
|
|
|
---
|
|
|
|
## Referencias
|
|
|
|
- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
|
|
- [@CATALOG_PAYMENTS](../../../shared/catalog/payments/)
|
|
- [PMC-001-TENANTS.md](./PMC-001-TENANTS.md)
|
|
- [PMC-007-ADMIN.md](./PMC-007-ADMIN.md)
|
|
- [Stripe Docs](https://stripe.com/docs)
|
|
|
|
---
|
|
|
|
**Documento generado por:** Requirements-Analyst
|
|
**Fecha:** 2026-01-04
|