npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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

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 .cer y .key (e.firma y CSD) sin dependencias nativas bloqueantes, utilizando node:crypto y node-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-fy

Nota: 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 de Códigos Postales contemplan más de 60,000 registros. Para preservar un peso ultra ligero en la librería (< 1MB), sat-fy NO 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:

  1. Realiza un Fork del proyecto.
  2. Crea tu Feature Branch (git checkout -b feature/NuevoPAC).
  3. Asegúrate de ejecutar el linter y los tests:
    npm run lint
    npm run test
  4. Haz commit y push de tus cambios.
  5. 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.