# ANALISIS MODULO RT-010: FACTURACION CFDI 4.0 **Fecha:** 2025-12-18 **Fase:** 2 - Analisis por Modulo **Modulo:** RT-010 Facturacion **Herencia:** 60% **Story Points:** 35 **Prioridad:** P0 --- ## 1. DESCRIPCION GENERAL ### 1.1 Proposito Generacion de comprobantes fiscales digitales (CFDI 4.0) para ventas en POS y e-commerce, con timbrado en tiempo real y portal de autofactura. ### 1.2 Funcionalidades Principales | Funcionalidad | Descripcion | Criticidad | |---------------|-------------|------------| | Facturacion POS | Al cerrar venta | Critica | | Publico general | RFC generico | Alta | | Autofactura | Portal publico | Alta | | Notas de credito | Por devolucion | Alta | | Cancelacion | Dentro de plazo | Media | | Reportes | Fiscales | Media | --- ## 2. HERENCIA DEL CORE ### 2.1 Componentes Heredados (60%) | Componente Core | % Uso | Accion | |-----------------|-------|--------| | financial.invoices | 80% | EXTENDER | | financial.invoice_lines | 80% | EXTENDER | | financial.payments | 100% | HEREDAR | | core.partners | 100% | HEREDAR | ### 2.2 Servicios a Heredar ```typescript import { InvoicesService } from '@erp-core/financial'; import { PaymentsService } from '@erp-core/financial'; import { PartnersService } from '@erp-core/core'; ``` ### 2.3 Servicios a Extender ```typescript class CFDIInvoiceService extends InvoicesService { // Generacion CFDI async generateCFDI(posOrderId: string): Promise; async timbrar(cfdi: CFDI): Promise; // Cancelacion async cancelCFDI(invoiceId: string, motivo: string): Promise; } ``` --- ## 3. COMPONENTES NUEVOS ### 3.1 Estructura CFDI 4.0 ```typescript interface CFDI40 { // Comprobante version: '4.0'; serie: string; folio: string; fecha: Date; formaPago: string; // 01 Efectivo, 04 Tarjeta, etc. metodoPago: 'PUE' | 'PPD'; // Pago en una exhibicion / Parcialidades tipoDeComprobante: 'I' | 'E' | 'T' | 'N' | 'P'; // Ingreso, Egreso, Traslado, Nomina, Pago lugarExpedicion: string; // CP // Emisor emisor: { rfc: string; nombre: string; regimenFiscal: string; // 601, 612, etc. }; // Receptor receptor: { rfc: string; nombre: string; domicilioFiscalReceptor: string; // CP regimenFiscalReceptor: string; usoCFDI: string; // G03 Gastos en general, etc. }; // Conceptos conceptos: CFDIConcepto[]; // Impuestos impuestos: { totalImpuestosTrasladados: number; totalImpuestosRetenidos: number; traslados: CFDITraslado[]; retenciones?: CFDIRetencion[]; }; // Totales subTotal: number; descuento?: number; total: number; // Timbre (despues de timbrar) timbreFiscalDigital?: { version: '1.1'; uuid: string; fechaTimbrado: Date; rfcProvCertif: string; selloCFD: string; selloSAT: string; noCertificadoSAT: string; }; } interface CFDIConcepto { claveProdServ: string; // Clave SAT (ej: 01010101) noIdentificacion?: string; // SKU cantidad: number; claveUnidad: string; // E48, H87, etc. unidad?: string; // Descripcion unidad descripcion: string; valorUnitario: number; importe: number; descuento?: number; objetoImp: '01' | '02' | '03'; // No objeto, Si objeto, Si objeto no desglosado impuestos?: { traslados: CFDITraslado[]; retenciones?: CFDIRetencion[]; }; } interface CFDITraslado { base: number; impuesto: '002'; // IVA tipoFactor: 'Tasa' | 'Cuota' | 'Exento'; tasaOCuota: number; // 0.160000 importe: number; } ``` ### 3.2 Servicios Backend | Servicio | Metodos Principales | |----------|-------------------| | CFDIService | generate(), timbrar(), cancel(), validate() | | CFDIBuilderService | fromPOSOrder(), fromEcommerceOrder() | | PACService | timbrar(), consultar(), cancelar() | | XMLService | buildXML(), parseXML(), validate() | | PDFService | generatePDF() | | AutoFacturaService | validateTicket(), generateFromTicket() | ### 3.3 Controladores ```typescript @Controller('cfdi') export class CFDIController { // Generacion desde POS @Post('pos/:orderId') generateFromPOS(@Param('orderId') orderId: string, @Body() dto: CFDIRequestDto): Promise; // Generacion desde E-commerce @Post('ecommerce/:orderId') generateFromEcommerce(@Param('orderId') orderId: string): Promise; // Factura publico general @Post('public/:orderId') generatePublicInvoice(@Param('orderId') orderId: string): Promise; // Consulta @Get(':id') getCFDI(@Param('id') id: string): Promise; @Get(':id/xml') getXML(@Param('id') id: string): Promise; @Get(':id/pdf') getPDF(@Param('id') id: string): Promise; // Cancelacion @Post(':id/cancel') cancel(@Param('id') id: string, @Body() dto: CancelDto): Promise; // Notas de credito @Post('credit-note') createCreditNote(@Body() dto: CreditNoteDto): Promise; // Reportes @Get('report/monthly') getMonthlyReport(@Query() filters: ReportFilters): Promise; } // API Publica - Autofactura @Controller('autofactura') export class AutofacturaController { @Get('validate/:ticketNumber') validateTicket(@Param('ticketNumber') ticketNumber: string): Promise; @Post('generate') generate(@Body() dto: AutofacturaDto): Promise; @Get('download/:uuid') download(@Param('uuid') uuid: string): Promise<{ xml: string; pdf: Buffer }>; } ``` --- ## 4. INTEGRACION PAC ### 4.1 Proveedores Soportados ```typescript interface PACProvider { name: string; timbrar(xml: string): Promise; consultar(uuid: string): Promise; cancelar(uuid: string, motivo: string): Promise; } // Implementaciones class FinkokPAC implements PACProvider { private readonly wsdlUrl = 'https://demo-facturacion.finkok.com/servicios/soap/stamp.wsdl'; // ... } class FacturamaPAC implements PACProvider { private readonly apiUrl = 'https://api.facturama.mx/3/cfdis'; // ... } class SWsapienPAC implements PACProvider { private readonly apiUrl = 'https://services.test.sw.com.mx/cfdi40/issue'; // ... } ``` ### 4.2 Configuracion ```yaml cfdi_config: pac: primary: "finkok" backup: "facturama" timeout: 10000 # 10 segundos retries: 3 emisor: rfc: "XAXX010101000" # Configurable por tenant nombre: "EMPRESA DEMO SA DE CV" regimen: "601" cp: "06600" certificados: cer_path: "/certs/{tenant}/cer.cer" key_path: "/certs/{tenant}/key.key" key_password: "${CFDI_KEY_PASSWORD}" almacenamiento: xml_path: "/storage/cfdi/{tenant}/{year}/{month}/" retention_years: 5 ``` --- ## 5. FLUJOS DE NEGOCIO ### 5.1 Facturacion en POS ``` 1. Cliente solicita factura al cerrar venta ↓ 2. Capturar datos fiscales: - RFC - Nombre o Razon Social - Regimen Fiscal - Uso CFDI - CP Domicilio Fiscal ↓ 3. Validar RFC contra lista SAT (opcional) ↓ 4. Construir XML CFDI 4.0 ↓ 5. Firmar con certificado ↓ 6. Enviar a PAC para timbrado ↓ 7. Si exito: a. Guardar XML timbrado b. Generar PDF c. Enviar por email d. Imprimir (opcional) ↓ 8. Si fallo: a. Reintentar con PAC backup b. Si falla: marcar para reintento posterior ``` ### 5.2 Autofactura ``` 1. Cliente accede al portal publico ↓ 2. Ingresa numero de ticket ↓ 3. Sistema valida: - Ticket existe - No esta facturado - Dentro de plazo (30 dias) ↓ 4. Muestra detalle de compra ↓ 5. Cliente ingresa datos fiscales ↓ 6. Genera y timbra CFDI ↓ 7. Descarga XML y PDF ``` ### 5.3 Cancelacion ``` 1. Solicitar cancelacion ↓ 2. Validar: - Dentro de plazo (30 dias) - No tiene pagos aplicados ↓ 3. Seleccionar motivo: - 01: Con documento relacionado (sustitucion) - 02: Sin documento relacionado - 03: No se llevo a cabo - 04: Error en datos ↓ 4. Enviar solicitud a PAC ↓ 5. Si requiere aceptacion receptor: - Esperar aceptacion ↓ 6. Confirmar cancelacion ``` --- ## 6. TABLAS DDL ### 6.1 Tablas Nuevas ```sql -- Configuracion CFDI por tenant CREATE TABLE retail.cfdi_config ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id) UNIQUE, emisor_rfc VARCHAR(13) NOT NULL, emisor_nombre VARCHAR(255) NOT NULL, emisor_regimen VARCHAR(3) NOT NULL, emisor_cp VARCHAR(5) NOT NULL, pac_provider VARCHAR(20) NOT NULL DEFAULT 'finkok', pac_user VARCHAR(100), pac_password_encrypted TEXT, cer_path TEXT, key_path TEXT, key_password_encrypted TEXT, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ ); -- CFDIs emitidos CREATE TABLE retail.cfdis ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), tenant_id UUID NOT NULL REFERENCES auth.tenants(id), -- Relacion origen source_type VARCHAR(20) NOT NULL, -- pos_order, ecommerce_order source_id UUID NOT NULL, -- Datos comprobante serie VARCHAR(10), folio VARCHAR(20), uuid VARCHAR(36), -- UUID del SAT fecha_emision TIMESTAMPTZ NOT NULL, tipo_comprobante CHAR(1) NOT NULL, -- I, E, T, N, P forma_pago VARCHAR(2), metodo_pago VARCHAR(3), -- Receptor receptor_rfc VARCHAR(13) NOT NULL, receptor_nombre VARCHAR(255) NOT NULL, receptor_regimen VARCHAR(3), receptor_cp VARCHAR(5), uso_cfdi VARCHAR(4), -- Totales subtotal DECIMAL(12,2) NOT NULL, descuento DECIMAL(12,2) DEFAULT 0, total_impuestos DECIMAL(12,2) NOT NULL, total DECIMAL(12,2) NOT NULL, -- Estado status VARCHAR(20) NOT NULL DEFAULT 'vigente', -- vigente, cancelado cancel_date TIMESTAMPTZ, cancel_reason VARCHAR(2), -- Archivos xml_content TEXT, xml_path TEXT, pdf_path TEXT, -- Timbre fecha_timbrado TIMESTAMPTZ, rfc_pac VARCHAR(13), sello_cfd TEXT, sello_sat TEXT, no_certificado_sat VARCHAR(20), created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ, UNIQUE(tenant_id, uuid) ); -- Indices CREATE INDEX idx_cfdis_source ON retail.cfdis(source_type, source_id); CREATE INDEX idx_cfdis_uuid ON retail.cfdis(uuid); CREATE INDEX idx_cfdis_fecha ON retail.cfdis(fecha_emision); CREATE INDEX idx_cfdis_receptor ON retail.cfdis(receptor_rfc); ``` --- ## 7. DEPENDENCIAS ### 7.1 Dependencias de Core | Modulo | Estado | Requerido Para | |--------|--------|---------------| | MGN-010 Financial | 70% | Facturas base | ### 7.2 Dependencias de Retail | Modulo | Tipo | |--------|------| | RT-001 Fundamentos | Prerequisito | | RT-002 POS | Origen de facturas | | RT-009 E-commerce | Origen de facturas | ### 7.3 Dependencias Externas | Servicio | Proposito | |----------|-----------| | PAC (Finkok, Facturama) | Timbrado | | SAT | Validacion RFC (opcional) | --- ## 8. CRITERIOS DE ACEPTACION ### 8.1 Funcionales - [ ] Generar factura desde POS - [ ] Generar factura publico general - [ ] Timbrar en < 5 segundos - [ ] Retry automatico con PAC backup - [ ] Generar PDF - [ ] Enviar por email - [ ] Portal de autofactura - [ ] Cancelar CFDI - [ ] Generar nota de credito - [ ] Almacenar XMLs 5 anos ### 8.2 Compliance - [ ] CFDI 4.0 valido - [ ] Catalogo SAT actualizado - [ ] Certificados vigentes - [ ] Timbre valido --- ## 9. ESTIMACION DETALLADA | Componente | SP Backend | SP Frontend | Total | |------------|-----------|-------------|-------| | Entities + Migrations | 3 | - | 3 | | CFDIService | 5 | - | 5 | | CFDIBuilderService | 5 | - | 5 | | PACService | 5 | - | 5 | | XMLService | 3 | - | 3 | | PDFService | 2 | - | 2 | | AutofacturaService | 3 | - | 3 | | Controllers | 3 | - | 3 | | Autofactura Portal | - | 4 | 4 | | Config UI | - | 2 | 2 | | **TOTAL** | **29** | **6** | **35** | --- ## 10. CATALOGOS SAT REQUERIDOS | Catalogo | Uso | |----------|-----| | c_FormaPago | 01 Efectivo, 04 Tarjeta, etc. | | c_MetodoPago | PUE, PPD | | c_UsoCFDI | G01, G03, etc. | | c_RegimenFiscal | 601, 612, etc. | | c_ClaveProdServ | Claves de productos | | c_ClaveUnidad | E48, H87, etc. | | c_TipoDeComprobante | I, E, T, N, P | | c_Impuesto | 002 IVA | | c_TasaOCuota | 0.160000, 0.000000 | | c_Moneda | MXN, USD | --- **Estado:** ANALISIS COMPLETO **Bloqueado por:** RT-001, RT-002 o RT-009