ML Engine Updates: - Updated BTCUSD with Polygon API data (2024-2025): 215,699 new records - Re-trained all ML models: Attention (R²: 0.223), Base, Metamodel (87.3% confidence) - Backtest results: +176.71R profit with aggressive_filter strategy Documentation Consolidation: - Created docs/99-analisis/_MAP.md index with 13 new analysis documents - Consolidated inventories: removed duplicates from orchestration/inventarios/ - Updated ML_INVENTORY.yml with BTCUSD metrics and training results - Added execution reports: FASE11-BTCUSD, correction issues, alignment validation Architecture & Integration: - Updated all module documentation with NEXUS v3.4 frontmatter - Fixed _MAP.md indexes across all folders - Updated orchestration plans and traces Files: 229 changed, 5064 insertions(+), 1872 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
460 lines
16 KiB
Markdown
460 lines
16 KiB
Markdown
---
|
|
id: "RF-PAY-004"
|
|
title: "Sistema de Facturacion Automatica"
|
|
type: "Requirement"
|
|
status: "Done"
|
|
priority: "Alta"
|
|
epic: "OQI-005"
|
|
project: "trading-platform"
|
|
version: "1.0.0"
|
|
created_date: "2025-12-05"
|
|
updated_date: "2026-01-04"
|
|
---
|
|
|
|
# RF-PAY-004: Sistema de Facturación Automática
|
|
|
|
**Version:** 1.0.0
|
|
**Fecha:** 2025-12-05
|
|
**Estado:** 📋 Planificado
|
|
**Prioridad:** P1 (Alta)
|
|
**Story Points:** 5
|
|
**Épica:** [OQI-005](../_MAP.md)
|
|
|
|
---
|
|
|
|
## Descripción
|
|
|
|
El sistema debe generar, almacenar y entregar facturas electrónicas automáticas para todos los pagos procesados, cumpliendo con requisitos fiscales de LATAM y permitiendo a usuarios descargar comprobantes en formato PDF.
|
|
|
|
---
|
|
|
|
## Objetivo de Negocio
|
|
|
|
- Cumplir con obligaciones fiscales en cada país
|
|
- Reducir consultas de soporte por comprobantes
|
|
- Facilitar deducción de impuestos para empresas
|
|
- Mejorar profesionalismo y confianza de la plataforma
|
|
- Automatizar envío de facturas por email
|
|
|
|
---
|
|
|
|
## Tipos de Facturas
|
|
|
|
| Tipo | Descripción | Ejemplo |
|
|
|------|-------------|---------|
|
|
| **Recibo de Pago** | Compra única (curso) | Invoice #INV-2025-001234 |
|
|
| **Factura de Suscripción** | Cobro mensual recurrente | Invoice #SUB-2025-001234 |
|
|
| **Nota de Crédito** | Reembolso parcial/total | Credit Note #CN-2025-001234 |
|
|
|
|
---
|
|
|
|
## Requisitos Funcionales
|
|
|
|
### RF-PAY-004.1: Generación Automática de Facturas
|
|
|
|
**DEBE:**
|
|
1. Generar factura inmediatamente después de pago exitoso
|
|
2. Asignar número de factura único secuencial
|
|
3. Incluir todos los datos fiscales requeridos
|
|
4. Generar PDF con diseño profesional
|
|
5. Almacenar PDF en S3/storage persistente
|
|
|
|
**Trigger:**
|
|
- Webhook `invoice.payment_succeeded` de Stripe
|
|
- Webhook `payment_intent.succeeded` para pagos únicos
|
|
|
|
### RF-PAY-004.2: Contenido de Factura
|
|
|
|
**DEBE incluir:**
|
|
|
|
**Información del Emisor:**
|
|
- Razón Social: "Trading Platform Inc."
|
|
- RFC/Tax ID: XX-XXXXXXX-XX
|
|
- Dirección fiscal completa
|
|
- Email de contacto: billing@trading.com
|
|
|
|
**Información del Cliente:**
|
|
- Nombre completo
|
|
- Email
|
|
- País/Región
|
|
- RFC/Tax ID (si lo proporcionó)
|
|
- Dirección de facturación (si la proporcionó)
|
|
|
|
**Detalles de la Transacción:**
|
|
- Número de factura único
|
|
- Fecha de emisión
|
|
- Descripción del producto/servicio
|
|
- Cantidad
|
|
- Precio unitario
|
|
- Subtotal
|
|
- Impuestos (IVA/VAT si aplica)
|
|
- Total
|
|
- Método de pago (últimos 4 dígitos de tarjeta)
|
|
|
|
**Footer:**
|
|
- "Powered by Stripe"
|
|
- Políticas de reembolso
|
|
- Contacto de soporte
|
|
|
|
### RF-PAY-004.3: Numeración de Facturas
|
|
|
|
**DEBE:**
|
|
1. Formato: `{PREFIX}-{YEAR}-{SEQUENCE}`
|
|
- `INV-2025-000001` (pago único)
|
|
- `SUB-2025-000001` (suscripción)
|
|
- `CN-2025-000001` (nota de crédito)
|
|
2. Secuencia separada por tipo
|
|
3. Reiniciar secuencia cada año
|
|
4. Incremento atómico para evitar duplicados
|
|
|
|
**Implementación:**
|
|
```typescript
|
|
async function generateInvoiceNumber(type: InvoiceType): Promise<string> {
|
|
const year = new Date().getFullYear();
|
|
const prefix = type === 'subscription' ? 'SUB' :
|
|
type === 'credit_note' ? 'CN' : 'INV';
|
|
|
|
const sequence = await db.invoiceSequence.increment({
|
|
where: { prefix, year },
|
|
field: 'current',
|
|
});
|
|
|
|
return `${prefix}-${year}-${sequence.toString().padStart(6, '0')}`;
|
|
}
|
|
// Ejemplo: INV-2025-000042
|
|
```
|
|
|
|
### RF-PAY-004.4: Generación de PDF
|
|
|
|
**DEBE:**
|
|
1. Usar librería de generación de PDF (puppeteer, pdfkit, react-pdf)
|
|
2. Aplicar diseño responsive (A4)
|
|
3. Incluir logo de Trading Platform
|
|
4. Soportar múltiples idiomas (ES, EN)
|
|
5. Tamaño máximo: 1 MB
|
|
|
|
**Diseño:**
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ │
|
|
│ [Logo Trading Platform] FACTURA / INVOICE │
|
|
│ │
|
|
│ Trading Platform Inc. #INV-2025-000042 │
|
|
│ 1234 Tech Street Fecha: 05/12/2025 │
|
|
│ San Francisco, CA 94105 │
|
|
│ RFC: XX-XXXXXXX-XX │
|
|
│ │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ FACTURADO A: │
|
|
│ Juan Pérez │
|
|
│ juan.perez@example.com │
|
|
│ México │
|
|
│ │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ DESCRIPCIÓN CANT. PRECIO TOTAL │
|
|
│ ───────────────────────────────────────────────── │
|
|
│ Suscripción Pro 1 $49.00 $49.00 │
|
|
│ (01/01/2025 - 31/01/2025) │
|
|
│ │
|
|
│ SUBTOTAL: $49.00│
|
|
│ IVA (16%): $7.84│
|
|
│ ───────────────│
|
|
│ TOTAL: $56.84│
|
|
│ │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ MÉTODO DE PAGO: │
|
|
│ Visa •••• 4242 │
|
|
│ │
|
|
│ Powered by Stripe | ID: pi_3Abc123... │
|
|
│ │
|
|
│ Dudas: support@trading.com │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### RF-PAY-004.5: Almacenamiento de Facturas
|
|
|
|
**DEBE:**
|
|
1. Guardar PDF en S3 bucket: `invoices/{year}/{month}/{invoiceId}.pdf`
|
|
2. Registrar metadata en tabla `billing.invoices`
|
|
3. Generar URL firmada con expiración de 24h para descarga
|
|
4. Mantener facturas por mínimo **7 años** (requisito fiscal)
|
|
|
|
**Modelo de datos:**
|
|
```typescript
|
|
@Entity({ name: 'invoices', schema: 'billing' })
|
|
class Invoice {
|
|
id: string; // UUID
|
|
userId: string; // FK a users
|
|
invoiceNumber: string; // INV-2025-000042 (UNIQUE)
|
|
type: InvoiceType; // payment | subscription | credit_note
|
|
status: InvoiceStatus; // draft | issued | paid | void
|
|
paymentId?: string; // FK a payments
|
|
subscriptionId?: string; // FK a subscriptions
|
|
stripeInvoiceId?: string; // Stripe Invoice ID
|
|
pdfUrl: string; // S3 URL
|
|
amount: Decimal; // Monto total
|
|
currency: string; // USD
|
|
taxAmount?: Decimal; // IVA/VAT
|
|
issuedAt: Date; // Fecha de emisión
|
|
dueAt?: Date; // Fecha de vencimiento
|
|
paidAt?: Date; // Fecha de pago
|
|
customerName: string;
|
|
customerEmail: string;
|
|
customerTaxId?: string; // RFC/CUIT/RUT
|
|
metadata?: object;
|
|
createdAt: Date;
|
|
updatedAt: Date;
|
|
}
|
|
```
|
|
|
|
### RF-PAY-004.6: Envío Automático por Email
|
|
|
|
**DEBE:**
|
|
1. Enviar email inmediatamente después de generar factura
|
|
2. Adjuntar PDF de la factura
|
|
3. Incluir link de descarga (URL firmada)
|
|
4. Asunto personalizado por idioma
|
|
5. Tracking de apertura y descarga
|
|
|
|
**Template de Email:**
|
|
```
|
|
Asunto: Tu factura de Trading Platform - #INV-2025-000042
|
|
|
|
Hola Juan,
|
|
|
|
Gracias por tu pago de $49.00 USD.
|
|
|
|
Tu factura está adjunta a este email. También puedes descargarla desde:
|
|
[Descargar Factura] (válido por 24 horas)
|
|
|
|
Detalles de la compra:
|
|
- Producto: Suscripción Pro
|
|
- Período: 01/01/2025 - 31/01/2025
|
|
- Total: $49.00 USD
|
|
|
|
¿Preguntas? Escríbenos a support@trading.com
|
|
|
|
Saludos,
|
|
El equipo de Trading Platform
|
|
```
|
|
|
|
### RF-PAY-004.7: Actualización de Datos Fiscales
|
|
|
|
**DEBE:**
|
|
1. Permitir al usuario agregar/editar:
|
|
- Nombre fiscal (puede diferir de nombre de usuario)
|
|
- RFC/Tax ID
|
|
- Dirección fiscal completa
|
|
- Régimen fiscal (si aplica)
|
|
2. Validar formato de RFC según país
|
|
3. Aplicar datos fiscales a **futuras** facturas (no retroactivo)
|
|
4. Mostrar advertencia si falta información fiscal
|
|
|
|
### RF-PAY-004.8: Notas de Crédito (Reembolsos)
|
|
|
|
**DEBE:**
|
|
1. Generar nota de crédito automáticamente al procesar reembolso
|
|
2. Referenciar factura original
|
|
3. Formato: `CN-2025-000001`
|
|
4. Incluir monto original y monto reembolsado
|
|
5. Enviar por email junto con confirmación de reembolso
|
|
|
|
---
|
|
|
|
## Flujo de Generación de Factura
|
|
|
|
```
|
|
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
│ Stripe │ │ Backend │ │ S3/Store │ │ Usuario │
|
|
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
|
│ │ │ │
|
|
│ Webhook: invoice. │ │ │
|
|
│ payment_succeeded │ │ │
|
|
│──────────────────▶│ │ │
|
|
│ │ │ │
|
|
│ │ 1. Fetch payment │ │
|
|
│ │ & user data │ │
|
|
│ │ │ │
|
|
│ │ 2. Generate │ │
|
|
│ │ invoice number │ │
|
|
│ │ (INV-2025-042) │ │
|
|
│ │ │ │
|
|
│ │ 3. Render PDF │ │
|
|
│ │ from template │ │
|
|
│ │ │ │
|
|
│ │ │ 4. Upload PDF │
|
|
│ │──────────────────▶│ │
|
|
│ │◀──────────────────│ │
|
|
│ │ { url } │ │
|
|
│ │ │ │
|
|
│ │ 5. Save invoice │ │
|
|
│ │ to DB │ │
|
|
│ │ │ │
|
|
│ │ 6. Send email │ │
|
|
│ │ with PDF │ │
|
|
│ │──────────────────────────────────────▶│
|
|
│ │ │ │
|
|
│ │ │ │
|
|
```
|
|
|
|
---
|
|
|
|
## Reglas de Negocio
|
|
|
|
### RN-001: Generación Obligatoria
|
|
|
|
**SIEMPRE** generar factura para:
|
|
- Compra de curso > $0
|
|
- Cobro de suscripción mensual
|
|
- Recarga de wallet > $10
|
|
- Reembolso (nota de crédito)
|
|
|
|
**NO generar** para:
|
|
- Pagos fallidos
|
|
- Suscripciones en trial (hasta que se cobre)
|
|
- Créditos promocionales gratuitos
|
|
|
|
### RN-002: Impuestos (IVA/VAT)
|
|
|
|
| País | IVA | Nota |
|
|
|------|-----|------|
|
|
| México | 16% | Solo si cliente tiene RFC |
|
|
| Colombia | 19% | Siempre aplicar |
|
|
| Argentina | 21% | Siempre aplicar |
|
|
| Chile | 19% | Siempre aplicar |
|
|
| USA | 0% | No hay VAT federal |
|
|
| EU | Variable | Según país del cliente |
|
|
|
|
**Stripe Tax** puede calcular automáticamente si se habilita.
|
|
|
|
### RN-003: Idioma de Factura
|
|
|
|
- Detectar idioma según `user.preferredLanguage`
|
|
- Fallback a inglés si no hay traducción
|
|
- Soportar: ES, EN, PT (futuro)
|
|
|
|
### RN-004: Modificación de Facturas
|
|
|
|
- Facturas emitidas **NO** se pueden editar
|
|
- Si hay error, emitir nota de crédito y nueva factura
|
|
- Mantener trazabilidad completa
|
|
|
|
---
|
|
|
|
## Cumplimiento Fiscal
|
|
|
|
### México (SAT)
|
|
|
|
- Usar CFDI 4.0 para facturación formal (futuro)
|
|
- Por ahora, factura simplificada es suficiente
|
|
- Incluir RFC en formato: AAAA######XXX
|
|
|
|
### Colombia (DIAN)
|
|
|
|
- Incluir NIT del cliente
|
|
- IVA del 19% obligatorio
|
|
- Resolución de facturación (futuro)
|
|
|
|
### Argentina (AFIP)
|
|
|
|
- Incluir CUIT del cliente
|
|
- IVA del 21%
|
|
- Factura electrónica (futuro)
|
|
|
|
---
|
|
|
|
## Seguridad
|
|
|
|
### Acceso a Facturas
|
|
|
|
- Solo el usuario propietario puede descargar su factura
|
|
- URLs firmadas con expiración de 24h
|
|
- Logs de acceso a facturas
|
|
|
|
### Datos Sensibles
|
|
|
|
- **NO** incluir número completo de tarjeta (solo last4)
|
|
- Encriptar Tax IDs en BD
|
|
- Cumplir GDPR/CCPA en retención de datos
|
|
|
|
---
|
|
|
|
## Configuración Requerida
|
|
|
|
```env
|
|
# Storage
|
|
AWS_S3_BUCKET=trading-invoices
|
|
AWS_S3_REGION=us-east-1
|
|
INVOICE_PDF_RETENTION_YEARS=7
|
|
|
|
# Facturación
|
|
COMPANY_LEGAL_NAME="Trading Platform Inc."
|
|
COMPANY_TAX_ID=XX-XXXXXXX-XX
|
|
COMPANY_ADDRESS="1234 Tech Street, San Francisco, CA 94105"
|
|
COMPANY_EMAIL=billing@trading.com
|
|
|
|
# Email
|
|
INVOICE_FROM_EMAIL=billing@trading.com
|
|
INVOICE_REPLY_TO=support@trading.com
|
|
```
|
|
|
|
---
|
|
|
|
## Webhooks Relacionados
|
|
|
|
| Evento | Acción |
|
|
|--------|--------|
|
|
| `invoice.payment_succeeded` | Generar factura de suscripción |
|
|
| `payment_intent.succeeded` | Generar factura de pago único |
|
|
| `charge.refunded` | Generar nota de crédito |
|
|
|
|
---
|
|
|
|
## Manejo de Errores
|
|
|
|
| Error | Código | Acción |
|
|
|-------|--------|--------|
|
|
| Fallo en generación de PDF | 500 | Retry 3 veces, alertar dev |
|
|
| Fallo en upload a S3 | 500 | Guardar PDF temporalmente, retry |
|
|
| Email bounce | 400 | Guardar factura, notificar usuario en app |
|
|
| Datos fiscales incompletos | 400 | Generar con datos disponibles |
|
|
|
|
---
|
|
|
|
## Métricas de Negocio
|
|
|
|
- Total de facturas emitidas/mes
|
|
- Tasa de descarga de facturas
|
|
- Tiempo promedio de generación de PDF
|
|
- Facturas con datos fiscales completos vs incompletos
|
|
|
|
---
|
|
|
|
## Criterios de Aceptación
|
|
|
|
- [ ] Factura se genera automáticamente después de pago exitoso
|
|
- [ ] PDF incluye todos los datos fiscales requeridos
|
|
- [ ] Número de factura es único y secuencial
|
|
- [ ] PDF se almacena en S3 correctamente
|
|
- [ ] Email con factura se envía inmediatamente
|
|
- [ ] Usuario puede descargar factura desde dashboard
|
|
- [ ] URL de descarga expira después de 24h
|
|
- [ ] Nota de crédito se genera para reembolsos
|
|
- [ ] Usuario puede actualizar datos fiscales en perfil
|
|
- [ ] Impuestos se calculan correctamente según país
|
|
|
|
---
|
|
|
|
## Especificación Técnica Relacionada
|
|
|
|
- [ET-PAY-004: Invoice Generation](../especificaciones/ET-PAY-004-invoices.md)
|
|
|
|
## Historias de Usuario Relacionadas
|
|
|
|
- [US-PAY-007: Ver Facturas](../historias-usuario/US-PAY-007-ver-facturas.md)
|
|
- [US-PAY-002: Suscribirse a Plan](../historias-usuario/US-PAY-002-suscribirse.md)
|