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

dty-fy

v0.4.0

Published

Librería completa para gestionar Documentos Tributarios Electrónicos (DTE) del SII de Chile. Soporta Facturas, Boletas, Notas de Crédito/Débito, Guías de Despacho y documentos de Exportación.

Readme

dty-fy

npm version License: EULA Node TypeScript

Libreria completa para gestionar Documentos Tributarios Electronicos (DTE) ante el Servicio de Impuestos Internos (SII) de Chile.

Soporta los 12 tipos de DTE: facturas, boletas, notas de credito/debito, guias de despacho y documentos de exportacion.


Tabla de Contenidos


Instalacion

npm install dty-fy

Requisitos

  • Node.js 18+
  • Certificado digital (.pfx/.p12) de una CA acreditada por el SII
  • Archivos CAF (Codigo de Autorizacion de Folios) entregados por el SII

Formatos de Modulo

La libreria distribuye tanto ESM como CommonJS:

// ESM (recomendado)
import { DteBuilder, SiiClient } from 'dty-fy';

// CommonJS
const { DteBuilder, SiiClient } = require('dty-fy');

Inicio Rapido

import { SiiClient, DteBuilder, CafManager, CertificateLoader } from 'dty-fy';

// 1. Cargar certificado digital
const cert = await CertificateLoader.fromPfx('./certificado.pfx', 'password');

// 2. Cargar folios autorizados (CAF)
const cafManager = new CafManager();
await cafManager.loadCaf('./caf-factura-33.xml');

// 3. Configurar cliente SII
const sii = new SiiClient({
  environment: 'certification',
  certificate: cert,
  rutSender: '11111111-1',
  rutCompany: '76543210-3',
  fechaResolucion: '2024-01-15',
  numeroResolucion: 0,
});

// 4. Construir una Factura Electronica (TipoDTE 33)
const factura = new DteBuilder()
  .tipo(33)
  .folio(cafManager.nextFolio(33))
  .emisor({
    rut: '76543210-3',
    razonSocial: 'Mi Empresa SpA',
    giro: 'Desarrollo de Software',
    acteco: 620200,
    direccion: 'Av. Providencia 1234',
    comuna: 'Providencia',
  })
  .receptor({
    rut: '87654321-4',
    razonSocial: 'Cliente Ejemplo Ltda',
    giro: 'Comercio',
    direccion: 'Los Leones 999',
    comuna: 'Providencia',
  })
  .addDetalle({ nombre: 'Servicio de desarrollo', cantidad: 1, precioUnitario: 500000 })
  .addDetalle({ nombre: 'Hosting anual', cantidad: 12, unidad: 'mes', precioUnitario: 15000 })
  .formaPago('credito')
  .build();

// 5. Firmar, timbrar y enviar al SII
const result = await sii.emitir(factura, cafManager);

if (result.success) {
  console.log(`DTE enviado! TrackID: ${result.trackId}`);
  console.log(`Folio: ${result.folio}`);

  const estado = await sii.consultarEstadoEnvio(result.trackId!);
  console.log(`Estado: ${estado.status} - ${estado.glosa}`);
} else {
  console.error(`Error: ${result.error}`);
}

Arquitectura

┌─────────────────────────────────────────────────────────┐
│                     SiiClient                           │
│  (orquestador: autenticacion, firma, envio, consulta)  │
└──────┬───────────────────────────────────────┬─────────┘
       │                                       │
       ▼                                       ▼
┌──────────────┐  ┌──────────┐  ┌──────────────────────┐
│  DteBuilder  │  │ XmlSigner│  │  CertificateLoader    │
│  (fluido)    │  │(XMLDSig) │  │  (.pfx, .pem, base64) │
└──────┬───────┘  └──────────┘  └──────────────────────┘
       │              │                    │
       ▼              ▼                    ▼
┌──────────┐  ┌──────────────┐  ┌──────────────────────┐
│ CafManager│  │ TED Generator│  │  SII Auth & Sender   │
│ (folios)  │  │(Timbre Elec)│  │  (seed, token, POST)  │
└──────────┘  └──────────────┘  └──────────────────────┘

Certificados Digitales

El certificado digital se obtiene a traves de una Autoridad Certificadora (CA) acreditada por el SII, no directamente desde el SII. La CA entrega un archivo .pfx (o .p12) que contiene la llave privada y el certificado X.509, protegido por una contrasena.

Metodos de Carga

import { CertificateLoader } from 'dty-fy';

// Desde archivo .pfx (el mas comun)
const cert = await CertificateLoader.fromPfx('./cert.pfx', 'password');

// Desde Buffer (base de datos, S3, cloud storage)
const cert = CertificateLoader.fromPfxBuffer(buffer, 'password');

// Desde string base64 (variables de entorno, serverless, CI/CD)
const cert = CertificateLoader.fromPfxBase64(process.env.CERT_PFX_B64!, process.env.CERT_PASSWORD!);

// Desde archivos PEM separados
const cert = await CertificateLoader.fromPem('./cert.pem', './key.pem');

// Desde strings PEM en memoria
const cert = CertificateLoader.fromPemStrings(certPem, keyPem);

Utilidades del Certificado

import {
  isCertificateValid,
  daysUntilCertExpiry,
  getRutFromCertificate,
  getCertificateSummary,
} from 'dty-fy';

const cert = await CertificateLoader.fromPfx('./cert.pfx', 'pass');

isCertificateValid(cert);                // boolean — esta vigente?
daysUntilCertExpiry(cert);               // number | null — dias restantes
getRutFromCertificate(cert);             // string | null — RUT embebido por la CA
getCertificateSummary(cert);             // string — resumen legible

Gestion de CAF

CafManager administra la carga, el parseo y la asignacion de folios desde los archivos CAF (Codigo de Autorizacion de Folios) entregados por el SII.

import { CafManager } from 'dty-fy';

const caf = new CafManager();

// Cargar desde archivo XML
await caf.loadCaf('./caf-33.xml');

// Cargar desde string XML
caf.addCaf(xmlString);

// Cargar datos CAF pre-parseados directamente
caf.addCafData(cafData);

// Obtener siguiente folio disponible (marca automaticamente como usado)
const folio = caf.nextFolio(33);

// Consultar folios restantes
const remaining = caf.remainingFolios(33);

// Obtener datos CAF para un folio especifico
const cafData = caf.getCaf(33, folio);

// Verificar y marcar uso manualmente
caf.isFolioUsed(33, folio);       // boolean
caf.markFolioUsed(33, folio);     // void

// Listar todos los CAF cargados para un tipo de DTE
const cafs = caf.getCafsForType(33);

// Reiniciar todo el estado
caf.clearAll();

Constructor de DTE

DteBuilder proporciona una API fluida (builder pattern) para construir documentos DTE. Todos los metodos son encadenables.

Metodos

| Metodo | Parametros | Descripcion | |--------|-----------|-------------| | tipo | code: TipoDteCode | Establecer tipo de DTE (33, 39, 61, etc.) | | folio | n: number | Establecer numero de folio | | fechaEmision | date: string \| Date | Fecha de emision (default: hoy) | | fechaVencimiento | date: string \| Date | Fecha de vencimiento (facturas credito) | | formaPago | tipo: 'contado' \| 'credito' \| 'gratis' | Establecer forma de pago | | montoBruto | bruto: boolean | Activar montos brutos (requerido para boletas) | | emisor | data: EmisorInput | Datos del emisor | | receptor | data: ReceptorInput | Datos del receptor | | indTraslado | code: number | Establecer indicador de traslado (obligatorio para DTE 52) | | tpoImpresion | code: number | Establecer tipo de impresión (opcional) | | transporte | data: TransporteInput | Establecer datos logísticos del transporte terrestre (DTE 52) | | addDetalle | data: DetalleInput | Agregar linea de detalle | | addReferencia | data: ReferenciaInput | Agregar referencia a otro documento (requerido para NC/ND) | | addDescuento | data: DescuentoRecargoInput | Agregar descuento o recargo global | | build | — | Validar y retornar DteDocument |

Tipos de Entrada

interface EmisorInput {
  rut: string;
  razonSocial: string;
  giro: string;
  acteco: number;
  direccion: string;
  comuna: string;
  ciudad?: string;
  telefono?: string;
  correo?: string;
  sucursal?: string;
}

interface ReceptorInput {
  rut: string;
  razonSocial?: string;
  giro?: string;
  direccion?: string;
  comuna?: string;
  ciudad?: string;
  contacto?: string;
  correo?: string;
}

interface DetalleInput {
  nombre: string;
  descripcion?: string;
  cantidad?: number;        // default: 1
  unidad?: string;          // default: 'unidad'
  precioUnitario: number;
  montoItem?: number;
  descuentoPct?: number;
  descuentoMonto?: number;
  exento?: boolean;
  codigos?: Array<{ tipo: string; valor: string }>;
}

interface ReferenciaInput {
  tipoDocRef: number;
  folioRef: number;
  fechaRef: string;
  codigoRef?: number;       // 1=anula, 2=corrige texto, 3=corrige montos
  razon?: string;
}

interface DescuentoRecargoInput {
  tipo: 'descuento' | 'recargo';
  glosa?: string;
  tipoValor: 'porcentaje' | 'monto';
  valor: number;
}

interface ChoferInput {
  rut?: string;
  nombre?: string;
}

interface TransporteInput {
  patente?: string;
  patenteCarro?: string;
  rutTrans?: string;
  chofer?: ChoferInput;
  fchSalida?: string | Date;
  hraSalida?: string;
  fchLlegada?: string | Date;
  dirDest?: string;
  cmnaDest?: string;
  ciudadDest?: string;
}

Ejemplos

Factura con descuento global:

const factura = new DteBuilder()
  .tipo(33)
  .folio(1)
  .emisor(emisorData)
  .receptor(receptorData)
  .addDetalle({ nombre: 'Producto A', cantidad: 10, precioUnitario: 5000 })
  .addDetalle({ nombre: 'Producto B', cantidad: 5, precioUnitario: 8000 })
  .addDescuento({ tipo: 'descuento', tipoValor: 'porcentaje', valor: 10, glosa: 'Volumen' })
  .build();
// IVA se calcula sobre el neto posterior al descuento

Nota de Credito referenciando una factura:

const notaCredito = new DteBuilder()
  .tipo(61)
  .folio(cafManager.nextFolio(61))
  .emisor(emisorData)
  .receptor(receptorData)
  .addDetalle({ nombre: 'Servicio web', cantidad: 1, precioUnitario: 500000 })
  .addReferencia({
    tipoDocRef: 33,
    folioRef: 123,
    fechaRef: '2024-03-15',
    codigoRef: 1,
    razon: 'Anulacion por devolucion',
  })
  .build();

Boleta Electronica con montos brutos:

const boleta = new DteBuilder()
  .tipo(39)
  .folio(cafManager.nextFolio(39))
  .emisor({ rut: '76543210-3', razonSocial: 'Mi Tienda', giro: 'Venta al detalle', acteco: 471100, direccion: 'Calle 1', comuna: 'Santiago' })
  .receptor({ rut: '66666666-6', razonSocial: 'Consumidor Final' })
  .montoBruto(true)
  .addDetalle({ nombre: 'Cafe Latte', cantidad: 2, precioUnitario: 3500 })
  .addDetalle({ nombre: 'Croissant', cantidad: 1, precioUnitario: 2500 })
  .build();
// Los montos de boleta incluyen IVA (MntBruto=true)

Guía de Despacho (DTE 52) con datos de transporte:

const guiaDespacho = new DteBuilder()
  .tipo(52)
  .folio(cafManager.nextFolio(52))
  .emisor(emisorData)
  .receptor(receptorData)
  .indTraslado(5) // 5 = Traslados internos (obligatorio para DTE 52)
  .transporte({
    patente: 'AA1122',
    patenteCarro: 'BB3344',
    rutTrans: '77777777-7',
    chofer: {
      rut: '11111111-1',
      nombre: 'Juan Pérez'
    },
    dirDest: 'Av. Vitacura 5000',
    cmnaDest: 'Vitacura',
    ciudadDest: 'Santiago'
  })
  .addDetalle({ nombre: 'Pallets de madera', cantidad: 50, precioUnitario: 3500 })
  .build();

Cliente SII

SiiClient orquesta el ciclo de vida completo del DTE: autenticacion, generacion de TED, firma XML, construccion del sobre de envio y envio al SII.

Constructor

import { SiiClient } from 'dty-fy';

const sii = new SiiClient({
  environment: 'certification' | 'production',
  certificate: certificateData,
  rutSender: string,      // RUT de la persona/sistema que envia
  rutCompany: string,     // RUT de la empresa (emisor)
  fechaResolucion?: string, // YYYY-MM-DD (default: vacio)
  numeroResolucion?: number, // 0 para certificacion (default: 0)
});

Metodos

| Metodo | Firma | Descripcion | |--------|-------|-------------| | authenticate | (): Promise<string> | Obtener y cachear token de sesion SII (auto-llamado por emitir) | | emitir | (doc: DteDocument, caf: CafManager): Promise<EmitirResult> | Flujo completo: TED -> firma -> sobre -> envio | | consultarEstadoEnvio | (trackId: string): Promise<EstadoEnvio> | Consultar estado de envio por TrackID | | consultarEstadoDte | (tipoDte, folio, fechaEmision, montoTotal, rutReceptor): Promise<EstadoDte> | Consultar estado de un DTE especifico |

Resultado de Emision

interface EmitirResult {
  success: boolean;
  trackId?: string;     // TrackID del SII (en exito)
  folio: number;
  tipoDte: TipoDteCode;
  xml: string;          // XML del sobre firmado
  error?: string;       // Mensaje de error (en fallo)
}

Resultados de Estado

interface EstadoEnvio {
  status: string;       // 'SOK' | 'CRT' | 'EPR' | 'RSC' | 'RFR' | 'RCT' | 'RPS'
  glosa: string;        // Descripcion legible
  trackId: string;
  numDtes?: number;
  informados?: number;
  aceptados?: number;
  rechazados?: number;
  reparos?: number;
}

interface EstadoDte {
  status: string;       // 'DOK' | 'RCH' | 'RPR' | 'DNK'
  glosa: string;
  tipoDte: number;
  folio: number;
  fechaEmision?: string;
  rutEmisor?: string;
  rutReceptor?: string;
  montoTotal?: number;
  errorCode?: string;
}

Funciones Utiles

Validacion y Formateo de RUT

import { validateRut, formatRut, formatRutPretty, cleanRut, calculateDv } from 'dty-fy';

validateRut('11111111-1');      // true
validateRut('11111111-2');      // false
formatRut('111111111');         // '11111111-1'
formatRutPretty('111111111');   // '11.111.111-1'
cleanRut('11.111.111-1');       // '11111111-1'
calculateDv('11111111');        // '1'

Calculos de Impuestos

import { calculateIva, calculateNetoFromBruto, calculateTotals, calculateMontoItem } from 'dty-fy';

calculateIva(100000);              // 19000 (IVA 19%)
calculateIva(100000, 10);          // 10000 (tasa personalizada)
calculateNetoFromBruto(119000);    // 100000
calculateMontoItem(10, 5000);      // 50000
calculateMontoItem(10, 5000, 10);  // 45000 (10% descuento)

Construccion XML (Bajo Nivel)

import { buildDocumentoXml, buildEnvioDteXml, buildEnvioBoletaXml } from 'dty-fy';

const docXml: string = buildDocumentoXml(dteDocument);
const envelope: string = buildEnvioDteXml([signedDocXml], caratula);
const boletaEnvelope: string = buildEnvioBoletaXml([signedBoletaXml], caratula);

Parseo XML

import { parseSiiResponse, parseUploadResponse } from 'dty-fy';

const result = parseSiiResponse(siiXmlResponse);        // { estado, seed?, token?, glosa? }
const upload = parseUploadResponse(siiHtmlResponse);    // { success, trackId?, error? }

Fechas

import { formatDate, formatTimestamp } from 'dty-fy';

formatDate();                          // '2024-01-15'
formatDate(new Date('2024-06-01'));    // '2024-06-01'
formatTimestamp();                     // '2024-01-15T14:30:00'

Constantes y Tipos

Codigos de Tipo de DTE

import { TipoDTE, TIPO_DTE_DESCRIPTIONS, VALID_DTE_CODES } from 'dty-fy';

TipoDTE.FacturaElectronica           // 33
TipoDTE.FacturaExenta               // 34
TipoDTE.BoletaElectronica           // 39
TipoDTE.BoletaExenta               // 41
TipoDTE.LiquidacionFactura          // 43
TipoDTE.FacturaCompra               // 46
TipoDTE.GuiaDespacho                // 52
TipoDTE.NotaDebito                  // 56
TipoDTE.NotaCredito                 // 61
TipoDTE.FacturaExportacion          // 110
TipoDTE.NotaDebitoExportacion       // 111
TipoDTE.NotaCreditoExportacion      // 112

TIPO_DTE_DESCRIPTIONS[33];           // 'Factura Electronica'
VALID_DTE_CODES;                     // Set { 33, 34, 39, 41, 43, 46, 52, 56, 61, 110, 111, 112 }

Conjuntos por Tipo

import { BOLETA_TYPES, EXPORT_TYPES, EXENTO_TYPES } from 'dty-fy';

BOLETA_TYPES  // Set { 39, 41 }
EXPORT_TYPES  // Set { 110, 111, 112 }
EXENTO_TYPES  // Set { 34, 41 }

Constantes del Sistema

import { IVA_RATE, RUT_SII, SII_URLS, SII_NAMESPACES } from 'dty-fy';

IVA_RATE                    // 19
RUT_SII                     // '60803000-K'
SII_URLS.certification      // { host, getSeed, getToken, upload, ... }
SII_NAMESPACES              // { DTE, DS, C14N, SHA1, RSA_SHA1, ... }

Codigos de Estado

import { ESTADO_ENVIO, ESTADO_DTE } from 'dty-fy';

ESTADO_ENVIO.SOK  // '0' — Aceptado OK
ESTADO_ENVIO.CRT  // '?' — En proceso
ESTADO_DTE.DOK    // '0' — DTE Aceptado OK
ESTADO_DTE.RCH    // '1' — DTE Rechazado

Tipos Principales

import type {
  DteDocument,      // Estructura completa del documento DTE
  TipoDteCode,      // 33 | 34 | 39 | 41 | 43 | 46 | 52 | 56 | 61 | 110 | 111 | 112
  SiiEnvironment,   // 'certification' | 'production'
  SiiConfig,        // Objeto de configuracion del cliente
  EmitirResult,     // Resultado de emision
  EstadoEnvio,      // Estado del envio batch
  EstadoDte,        // Estado del DTE individual
  CafeData,         // Datos de CAF parseados
  CertificateData,  // Datos del certificado parseados
} from 'chile-dte';

Manejo de Errores

La libreria define una jerarquia de clases de error para un manejo granular:

import {
  SiiError,          // Error base para todas las fallas SII/DTE
  SiiAuthError,      // Falla de autenticacion (seed/token)
  SiiSendError,      // Falla de envio (puede incluir trackId)
  SiiValidationError,// Falla de validacion local (puede incluir field)
  CertificateError,  // Falla de carga/parseo de certificado
  CafError,          // Falla de CAF/asignacion de folio (puede incluir tipoDte)
} from 'dty-fy';

try {
  const result = await sii.emitir(factura, cafManager);
  if (!result.success) {
    console.error(`Emision fallida: ${result.error}`);
  }
} catch (error) {
  if (error instanceof SiiAuthError) {
    // Error de autenticacion (ej. certificado vencido)
  } else if (error instanceof SiiValidationError) {
    // Error de validacion (revisar error.field)
  } else if (error instanceof CafError) {
    // Error de CAF (ej. sin folios disponibles)
  }
}

Ambientes

| Ambiente | Host SII | Uso | |----------|----------|-----| | certification | maullin.sii.cl | Pruebas y certificacion | | production | palena.sii.cl | Produccion |

const sii = new SiiClient({
  environment: 'certification',  // o 'production'
  // ...
});

Licencia

EULA (End User License Agreement) — Copyright (c) 2026 bm0x.

Ver el archivo LICENSE para los terminos completos.