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.5.1

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.

Downloads

56

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

CafParser y CafManager administran la ingesta, validación criptográfica y asignación de folios desde los archivos CAF (Código de Autorización de Folios) entregados por el SII.

Parseo y Validación Criptográfica (CafParser)

CafParser valida que el CAF coincida con el RUT emisor, tipo de DTE, rango de folios ($D \le F \le H$) y verifica la firma digital <FRMA> del SII sobre <DA>:

import { CafParser } from 'dty-fy';

// Parsear desde string XML o Buffer (ej. subido vía API o leído de S3/GCS)
const cafData = CafParser.fromXml(xmlBuffer, {
  expectedRut: '76543210-3',       // Valida RUT emisor
  expectedTipoDte: 33,              // Valida TipoDTE
  targetFolio: 15,                  // Valida que el folio esté en el rango autorizado
  verifySignature: true,            // Verifica firma <FRMA> con clave pública SII
  siiPublicKey: process.env.SII_CAF_PUBKEY,
});

// O parsear directamente desde archivo en disco
const cafData = await CafParser.fromFile('./caf-33.xml');

Asignación y Ciclo de Vida de Folios (CafManager)

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 (lanza CafFolioExhaustedError si se agotan)
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) | | tipoDespacho | code: number | Establecer tipo de despacho (para DTE 52: 1, 2 o 3) | | 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();

Timbre Electronico y Codigo PDF417

El Timbre Electrónico DTE (TED) y su representación bidimensional PDF417 constituyen la firma gráfica y mecanismo de verificación offline exigido por el SII (Resolución Ex. SII N° 11 de 2003).

Generación de Código PDF417 (renderPdf417)

Genera el código de barras PDF417 conforme al estándar del SII: nivel de corrección de error ECL 5 y ancho de 10 a 14 columnas.

import { renderPdf417 } from 'dty-fy';

// Renderizar SVG vectorial (ideal para facturas en PDF, impresión térmica o web)
const svg = await renderPdf417(tedXml, {
  format: 'svg',
  columns: 12,                  // 10 a 14 (default: 12)
  errorCorrectionLevel: 5,      // Estándar SII: nivel 5 (default: 5)
  scale: 2,
});

// Renderizar PNG en Buffer (ideal para canvas o guardado directo a archivo)
const pngBuffer = await renderPdf417(tedXml, {
  format: 'png',
  columns: 12,
  errorCorrectionLevel: 5,
  scale: 3,
});

Generación y Firma de TED

import { generateTed, buildTedXml, signTed, verifyTed } from 'dty-fy';

// Generar estructura TED a partir del documento y datos CAF
const ted = generateTed(documento, cafData);

// Construir XML del TED
const tedXml = buildTedXml(ted);

// O firmar y verificar manualmente con clave privada CAF y codificación ISO-8859-1
const signedTed = signTed(rawTedXml, cafData.privateKey);
const isValid = verifyTed(signedTed, cafData.publicKey);

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 (gestión automática de TTL y concurrencia) | | emitir | (doc: DteDocument, caf: CafManager): Promise<EmitirResult> | Flujo completo individual: TED -> firma DTE -> sobre -> envio | | emitirBatch | (docs: DteDocument[], caf: CafManager): Promise<{ trackId?: string; results: EmitirResult[] }> | Emisión en lote dentro de un único sobre (hasta 2000 DTEs) | | consultarEstadoEnvio | (trackId: string): Promise<EstadoEnvio> | Consultar estado de envio por TrackID (inmediato) | | pollEnvio | (trackId: string, options?: Partial<PollTrackIdOptions>): Promise<EstadoEnvio> | Sondeo automático de TrackID con backoff exponencial y jitter | | consultarEstadoDte | (tipoDte, folio, fechaEmision, montoTotal, rutReceptor): Promise<EstadoDte> | Consultar estado de un DTE especifico |

Sondeo de Envío con Backoff (pollEnvio)

El SII procesa los envíos de forma asíncrona. pollEnvio realiza consultas periódicas con retroceso exponencial (exponential backoff) y fluctuación (jitter) hasta obtener un estado terminal (EPR, RCT, RFL, RFR, RSC):

const estado = await sii.pollEnvio(result.trackId!, {
  maxAttempts: 10,
  initialDelayMs: 3000,
  backoffFactor: 1.5,
  maxDelayMs: 60000,
  onAttempt: (attempt, delayMs) => {
    console.log(`Intento ${attempt}: esperando ${delayMs}ms...`);
  },
});

console.log(`Estado final: ${estado.status} - ${estado.glosa}`);

Gestión de Tokens de Sesión (TokenManager)

TokenManager encapsula la obtención y renovación de tokens con el SII:

  • TTL de 50 minutos (los tokens del SII expiran tras 60 minutos de inactividad).
  • Deduplicación concurrente: múltiples solicitudes simultáneas comparten la misma promesa de autenticación para evitar saturar el endpoint de semillas.
import { TokenManager } from 'dty-fy';

const tokenManager = new TokenManager(cert, 'certification', 50);
const token = await tokenManager.getToken(); // Reutiliza el token activo o renueva si caducó

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 y Zona Horaria

Todas las fechas y marcas de tiempo operan de manera determinista bajo la zona horaria chilena (America/Santiago, GMT-3 / GMT-4 según horario de verano):

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

CHILE_TIMEZONE;                        // 'America/Santiago'
formatDate();                          // '2024-01-15' (fecha actual en Chile)
formatDate(new Date('2024-06-01'));    // '2024-06-01'
formatTimestamp();                     // '2024-01-15T14:30:00' (timestamp ISO local sin offset)

Manejo de Codificación ISO-8859-1 (Latin-1)

El SII rechaza documentos que contengan caracteres fuera del repertorio ISO-8859-1. La librería provee sanitización y validación a nivel de bytes:

import { sanitizeToLatin1, isLatin1, toLatin1Buffer } from 'dty-fy';

isLatin1('Factura Nº 123');            // true
isLatin1('Producto \u2014 test');       // false (contiene em-dash)

sanitizeToLatin1('Cotización — $500'); // 'Cotizacion - $500' (translitera caracteres incompatibles)
const buf: Buffer = toLatin1Buffer('Texto legal'); // Buffer en codificación latin1

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 / carátula recibida
ESTADO_ENVIO.EPR  // 'EPR' — Envío Procesado
ESTADO_ENVIO.RFL  // 'RFL' — Rechazado por Firma/Línea
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
  CafData,                // Datos de CAF parseados
  CertificateData,        // Datos del certificado parseados
  PollTrackIdOptions,     // Opciones para sondeo de TrackID
  Pdf417RenderOptions,    // Opciones para renderizado de código de barras
} from 'dty-fy';

Manejo de Errores

La librería define una jerarquía estricta de errores con propiedades tipadas para capturar fallos específicos de negocio, CAF y comunicación con el SII:

Excepciones Tipadas de Dominio

| Clase de Error | Cuándo se lanza | Propiedades clave | |----------------|-----------------|-------------------| | DteSchemaValidationError | Violación de reglas de esquema/negocio (ej. DTE 61 sin CodRef 1, 2 o 3; DTE 52 sin IndTraslado) | field, value | | CafFolioExhaustedError | Se agotan los folios autorizados en el rango del CAF | tipoDte, requestedFolio, availableRange | | CafInvalidSignatureError | La firma <FRMA> sobre <DA> en el CAF no coincide o el CAF fue alterado | tipoDte, folioRange | | SiiTokenExpiredError | La sesión del token ha expirado o el SII retorna código de rechazo de sesión | token | | SiiWafBlockedError | El cortafuegos/WAF del SII bloquea la petición (HTML de error, HTTP 403/503) | url, statusCode | | SiiRejectedStatusError | El envío o documento fue formalmente rechazado por el SII (RSC, RFR, RCT, RFL) | status, glosa, trackId, detalles |

import {
  SiiError,
  DteSchemaValidationError,
  CafFolioExhaustedError,
  CafInvalidSignatureError,
  SiiTokenExpiredError,
  SiiWafBlockedError,
  SiiRejectedStatusError,
} from 'dty-fy';

try {
  const result = await sii.emitir(factura, cafManager);
} catch (error) {
  if (error instanceof CafFolioExhaustedError) {
    console.error(`Folios agotados para tipo ${error.tipoDte}: rango ${error.availableRange.desde}-${error.availableRange.hasta}`);
  } else if (error instanceof DteSchemaValidationError) {
    console.error(`Validación fallida en campo ${error.field}: valor '${error.value}'`);
  } else if (error instanceof SiiWafBlockedError) {
    console.error(`Petición bloqueada por WAF en ${error.url} (HTTP ${error.statusCode})`);
  } else if (error instanceof SiiRejectedStatusError) {
    console.error(`Rechazado por SII [${error.status}]: ${error.glosa} (TrackID: ${error.trackId})`);
  } else if (error instanceof SiiError) {
    console.error(`Error general SII: ${error.message}`);
  }
}

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.