sat-fy
v0.2.0
Published
Librería profesional para orquestar documentos fiscales (CFDI 4.0), descarga masiva, timbrado vía PAC y catálogos del SAT México
Maintainers
Readme
sat-fy es el motor fiscal base y estrictamente tipado diseñado como módulo principal para operar de forma nativa dentro de Onirion-Dev ERP.
Desarrollado para simplificar y abstraer completamente la integración del ecosistema fiscal mexicano (CFDI 4.0, Descarga Masiva, conectividad con PACs), liberando a Onirion-Dev de lidiar con criptografía compleja de OpenSSL, implementaciones arcaicas de SOAP o reglas de sellado manuales.
🌟 Características
- 🔒 Criptografía Nivel Bancario: Lee, descifra y valida archivos
.cery.key(e.firma y CSD) sin dependencias nativas bloqueantes, utilizandonode:cryptoynode-forge. - 🏗️ CFDI 4.0 Builder: Interfaz fluida para la creación de comprobantes, aplicando auto-cálculos de impuestos y sumatorias de manera segura.
- ✍️ Firma Automática (Cadena Original): Generación del Sello Digital SAT e inyección automática en el comprobante mediante RSA-SHA256.
- 🚀 Integración PAC Universal: Adaptadores estandarizados para que el ERP pueda timbrar y cancelar de forma transparente con proveedores como SW Sapien, Facturapi, SolucionFACT, entre otros.
- 📦 Descarga Masiva (API v1.5): Solicitud, validación (polling) asíncrona y extracción ZIP de hasta 200,000 CFDI emitidos/recibidos directamente de los WebServices del SAT.
- ⚡ Validación Pública SAT: Consulta en tiempo real el WebService de ConsultaQR para corroborar el estado fiscal (
Vigente,Cancelado) de un comprobante. - 📚 Catálogos 100% Tipados: Interfaces completas para catálogos locales y estrategias Lazy para listados masivos (ClaveProdServ, Código Postal).
📖 Tabla de Contenidos
⚙️ Instalación
Requiere Node.js 20.0.0 o superior.
npm install sat-fyNota: La librería expone nativamente módulos ESM y CommonJS (CJS) garantizando su compatibilidad en cualquier configuración.
💻 Uso y Ejemplos Básicos
1. Manejo de Credenciales
sat-fy provee utilerías seguras para cargar Certificados de Sello Digital (CSD) y la e.firma (FIEL).
import { loadCsd, loadEfirma } from 'sat-fy';
// 1. CSD (Certificado de Sello Digital) - Usado para sellar CFDI
const csd = await loadCsd(
'./keys/CSD_Pruebas.cer',
'./keys/CSD_Pruebas.key',
'PasswordCSD123'
);
console.log('Certificado No:', csd.noCertificado);
// 2. e.firma (FIEL) - Usada para Descarga Masiva o Cancelaciones directas
const efirma = await loadEfirma(
'./keys/FIEL.cer',
'./keys/FIEL.key',
'PasswordFIEL123'
);2. Creación y Sellado de Factura (CFDI 4.0)
Diseñado bajo el patrón Builder, simplifica drásticamente el modelado de una factura válida.
import { CfdiBuilder, CfdiSello, CfdiSerializer } from 'sat-fy';
// Configuración y construcción del comprobante
const cfdi = new CfdiBuilder()
.setSerie('F')
.setFolio('1050')
.setFecha(new Date()) // sat-fy se encarga de formatear la zona horaria (Mexico City)
.setFormaPago('03') // Transferencia
.setMetodoPago('PUE') // Pago en una sola exhibición
.setMoneda('MXN')
.setLugarExpedicion('64000')
.setTipoDeComprobante('I')
.setEmisor({
rfc: 'EKU9003173C9',
nombre: 'EMPRESA KEMPER DE PRUEBA SA DE CV',
regimenFiscal: '601',
})
.setReceptor({
rfc: 'XAXX010101000',
nombre: 'PUBLICO EN GENERAL',
usoCfdi: 'S01',
domicilioFiscalReceptor: '64000',
regimenFiscalReceptor: '616',
})
.addConcepto({
claveProdServ: '43231500', // Software
cantidad: 1,
claveUnidad: 'E48',
descripcion: 'Licencia Anual de Software',
valorUnitario: 5000,
objetoImp: '02', // Sí objeto de impuesto
impuestos: [
{ tipo: 'traslado', base: 5000, impuesto: '002', tipoFactor: 'Tasa', tasaOCuota: 0.160000 }
]
})
.build();
// Sellado Digital RSA-SHA256
const sello = new CfdiSello({
cerPath: './keys/CSD_Pruebas.cer',
keyPath: './keys/CSD_Pruebas.key',
password: 'PasswordCSD123'
});
const xmlSellado = await sello.sign(cfdi);
// Tu XML es ahora válido y cuenta con la Cadena Original y el nodo Sello inyectado.3. Timbrado con un PAC
Utiliza la interfaz unificada de sat-fy/pac para evitar anclar el código de tu proyecto a un PAC específico.
import { createPacClient } from 'sat-fy';
const pacClient = createPacClient({
provider: 'sw-sapien', // Soportados: 'sw-sapien', 'facturapi', 'solucionfact'
token: 'TOKEN_BEARER_PROPORCIONADO_POR_EL_PAC',
modo: 'sandbox' // Cambiar a 'produccion' en vivo
});
try {
const result = await pacClient.timbrar(xmlSellado);
console.log(`¡Timbrado Exitoso! UUID: ${result.uuid}`);
console.log(result.xml); // XML final con el nodo TimbreFiscalDigital
} catch (error) {
console.error('Fallo el timbrado:', error.message);
}4. Descarga Masiva del SAT
Descarga miles de comprobantes a la vez (emitidos o recibidos) de manera programática, sin intervención humana.
import { SatDescargaMasiva, SatAuth } from 'sat-fy';
const orquestador = new SatDescargaMasiva({
auth: new SatAuth({ cerPath, keyPath, password }) // Debe ser e.firma
});
// 1. Solicitamos la orden de descarga (Ej. recibidos de Octubre)
const { idSolicitud } = await orquestador.solicitar({
fechaInicial: new Date('2023-10-01T00:00:00Z'),
fechaFinal: new Date('2023-10-31T23:59:59Z'),
rfcSolicitante: 'TU_RFC_AQUI',
}, 'recibidos');
console.log(`Solicitud SAT Registrada: ${idSolicitud}`);
// 2. Realizamos polling al SAT (Auto-reintentos hasta que se acepte o procese)
const idsPaquetes = await orquestador.verificarHastaListo(idSolicitud, {
intervaloMs: 30000, // Verificar cada 30 segundos
onProgress: (estado, intento) => console.log(`Intento ${intento}: Estatus SAT -> ${estado}`)
});
// 3. Descargamos, extraemos los ZIPs y parseamos el resultado en memoria
const facturasDescargadas = await orquestador.descargarPaquetes(idsPaquetes);
for (const cfdi of facturasDescargadas) {
console.log(`UUID: ${cfdi.uuid} | Total: $${cfdi.total} | Emisor: ${cfdi.rfcEmisor}`);
}5. Verificación de Estatus (ConsultaQR)
Valida la legitimidad de un UUID contra los servidores públicos del SAT.
import { SatValidador } from 'sat-fy';
const validador = new SatValidador();
const estatus = await validador.consultarEstado({
rfcEmisor: 'EKU9003173C9',
rfcReceptor: 'XAXX010101000',
total: '5800.00',
uuid: '550E8400-E29B-41D4-A716-446655440000',
});
console.log(estatus.estado); // "Vigente" o "Cancelado"
console.log(estatus.esCancelable); // "Cancelable sin aceptación"📁 Arquitectura de Catálogos
sat-fy provee IntelliSense avanzado gracias a la tipificación estricta de catálogos como:
Formas de Pago(Ej: '01', '03')Métodos de Pago(PUE, PPD)Régimen Fiscal,Impuestos,Uso de CFDI, entre otros.
⚠️ AVISO PARA CATÁLOGOS MASIVOS El catálogo de
Claves de Producto o Servicio(ClaveProdServ) y el deCódigos Postalescontemplan más de 60,000 registros. Para preservar un peso ultra ligero en la librería (< 1MB),sat-fyNO inyecta estos catálogos directamente. La librería provee las interfaces y tipos exactos, esperando que en un entorno productivo alimentes esta validación a través de tu propia Base de Datos (PostgreSQL, MongoDB) para optimizar memoria RAM en Node.js.
🛡️ Manejo de Errores
La librería define errores estructurados (SatAuthError, SatValidacionError, SatTimbradoError, SatDescargaError) que incluyen metadata útil y rastreable:
import { SatDescargaError } from 'sat-fy';
try {
await orquestador.descargarPaquetes([...]);
} catch (error) {
if (error instanceof SatDescargaError) {
console.error('El SAT rechazó el proceso SOAP:', error.soapResponse);
}
}🤝 Contribución
Si encuentras algún problema, deseas agregar un nuevo PAC al estándar o mejorar alguna funcionalidad:
- Realiza un Fork del proyecto.
- Crea tu Feature Branch (
git checkout -b feature/NuevoPAC). - Asegúrate de ejecutar el linter y los tests:
npm run lint npm run test - Haz commit y push de tus cambios.
- Abre un Pull Request.
Este proyecto está adherido al Código de Conducta de Contribuyentes.
📄 Licencia
Este proyecto se distribuye bajo la licencia MIT. Eres completamente libre de usarlo en entornos personales, educativos y comerciales sin restricción.
El logo del SAT y marcas registradas son propiedad de la Secretaría de Hacienda y Crédito Público (SHCP) de los Estados Unidos Mexicanos. Este proyecto es una iniciativa open-source no afiliada a dicha entidad gubernamental.
