Saltar al contenido
dte-sdk

createDte()

Construye un documento tributario electrónico inmutable y validado, con sus totales ya calculados. Es el primer paso del ciclo de vida de todo DTE.

Uso básico#

TypeScript
import { createDte } from 'dte-sdk'
 
const dte = createDte({
  type: 33,
  folio: 1024,
  issuedAt: '2026-10-28',
  issuer: {
    rut: '76.123.456-0',
    businessName: 'Arrow Software SpA',
    activity: 'Desarrollo de software',
    acteco: 620200,
    address: 'Av. Providencia 1234',
    commune: 'Providencia',
  },
  receiver: {
    rut: '77.654.321-7',
    businessName: 'Comercial Los Andes Ltda.',
    activity: 'Comercio al por menor',
    address: 'Huérfanos 1055',
    commune: 'Santiago',
  },
  items: [{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }],
})
 
dte.totals
// { net: 120000, exempt: 0, vatRate: 19, vat: 22800, total: 142800 }

Firma de tipo#

TypeScript
function createDte(input: CreateDteInput): Dte
 
type DteType = 33 | 34 | 39 | 41 | 46 | 52 | 56 | 61
 
interface CreateDteInput {
  type: DteType
  folio: number
  issuedAt?: string // 'YYYY-MM-DD', defaults to today in America/Santiago
  issuer: {
    rut: string
    businessName: string
    activity: string
    acteco: number | number[]
    address: string
    commune: string
    city?: string
  }
  receiver: {
    rut: string
    businessName: string
    activity?: string
    address?: string
    commune?: string
    city?: string
    email?: string
  }
  items: LineItem[] // 1..60 lines
  references?: Reference[] // required for 56 and 61
  paymentMethod?: 'cash' | 'credit' | 'free'
  dueDate?: string
}
 
interface LineItem {
  name: string
  description?: string
  quantity: number
  unitPrice: number
  unit?: string
  discountPercent?: number
  exempt?: boolean
}
 
interface Reference {
  type: DteType | 'SET'
  folio: number | string
  date: string
  code?: 1 | 2 | 3 // 1 = voids document, 2 = fixes text, 3 = fixes amounts
  reason?: string
}
 
// Dte = CreateDteInput with resolved defaults + `totals: Totals`, deeply readonly

Parámetros#

  • input.type (DteType) - El código del tipo de documento. Revisa Tipos de documento más abajo.
  • input.folio (number) - El número del documento, un entero positivo dentro de un rango de CAF que tengas para ese tipo. stampDte() lo verifica contra el CAF.
  • input.issuedAt (string, opcional) - Fecha de emisión en formato YYYY-MM-DD. Por defecto es la fecha de hoy en la zona horaria America/Santiago, no la del servidor.
  • input.issuer - Tu empresa, tal como está registrada en el SII:
    • rut - El RUT del emisor, con o sin puntos.
    • businessName - Razón social.
    • activity - Giro.
    • acteco (number | number[]) - Uno o más códigos de actividad económica.
    • address, commune - Dirección y comuna de origen. city es opcional.
  • input.receiver - El cliente. rut y businessName son obligatorios; activity, address, commune, city y email son opcionales.
  • input.items (LineItem[]) - Entre 1 y 60 líneas de detalle:
    • name - Lo que vendes. description agrega un texto más largo.
    • quantity, unitPrice - Cantidad y precio unitario neto en CLP (bruto en boletas, revisa calculateTotals()).
    • unit (opcional) - Unidad de medida, como 'UN' o 'KG'.
    • discountPercent (opcional) - Descuento de la línea, de 0 a 100.
    • exempt (opcional) - true cuando la línea no está afecta a IVA.
  • input.references (Reference[]) - Otros documentos a los que este hace referencia. Obligatorio en notas de débito (56) y notas de crédito (61).
    • type, folio, date - El documento referenciado. Usa 'SET' como tipo para referenciar un set de pruebas de certificación.
    • code - 1 anula el documento referenciado, 2 corrige texto, 3 corrige montos.
    • reason - Texto libre que explica la referencia.
  • input.paymentMethod (opcional) - 'cash' (contado), 'credit' (crédito) o 'free' (sin costo).
  • input.dueDate (opcional) - Fecha de vencimiento del pago en formato YYYY-MM-DD.

Valor de retorno#

Retorna un Dte: tu input con sus valores por defecto resueltos (issuedAt siempre viene definido) más un objeto totals, calculado con las mismas reglas que calculateTotals().

El documento es inmutable. Su tipo es profundamente readonly y el objeto está congelado, así que cada paso posterior (timbrar, firmar) retorna un objeto nuevo en vez de modificar este.

Errores#

createDte() lanza un DteError cuando el input no puede convertirse en un documento válido:

CódigoCuándo
MISSING_FIELDFalta un campo obligatorio o está vacío, incluidos items y, en los tipos 56 y 61, references
INVALID_RUTEl RUT del emisor o del receptor está mal formado o su dígito verificador Módulo 11 no corresponde
INVALID_AMOUNTUna cantidad no es un número positivo, un precio unitario es negativo o no es finito, o un descuento está fuera de 0–100

Los mensajes son genéricos a propósito: nunca incluyen RUTs ni montos. Decide según error.code, no según el mensaje.

TypeScript
import { createDte, DteError } from 'dte-sdk'
 
try {
  createDte(input)
} catch (error) {
  if (error instanceof DteError && error.code === 'INVALID_RUT') {
    // Ask the user to check the customer's RUT
  } else {
    throw error
  }
}

Ejemplos#

Líneas exentas#

Marca una línea con exempt: true y su monto va a totals.exempt en vez del neto afecto:

TypeScript
import { createDte } from 'dte-sdk'
 
// `issuer` and `receiver` as in Basic Usage
const dte = createDte({
  type: 33,
  folio: 1024,
  issuer,
  receiver,
  items: [
    { name: 'Licencia anual', quantity: 1, unitPrice: 120000 },
    { name: 'Curso de capacitación', quantity: 2, unitPrice: 45000, exempt: true },
  ],
})
 
dte.totals
// { net: 120000, exempt: 90000, vatRate: 19, vat: 22800, total: 232800 }

Nota de crédito con referencia#

Las notas de crédito y de débito deben apuntar al documento que modifican:

TypeScript
import { createDte } from 'dte-sdk'
 
const creditNote = createDte({
  type: 61,
  folio: 501,
  issuer,
  receiver,
  items: [{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }],
  references: [
    { type: 33, folio: 1024, date: '2026-10-28', code: 1, reason: 'Anula factura' },
  ],
})

Si omites references en un tipo 61, createDte() lanza MISSING_FIELD. Revisa Emitir una nota de crédito para ver el flujo completo.

Venta a crédito con fecha de vencimiento#

TypeScript
const dte = createDte({
  type: 33,
  folio: 1025,
  issuer,
  receiver,
  items: [{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }],
  paymentMethod: 'credit',
  dueDate: '2026-11-27',
})

Inmutabilidad#

TypeScript
dte.folio = 1026 // ✗ TypeScript error: 'folio' is a read-only property
 
// Build a new document instead
const next = createDte({ ...input, folio: 1026 })

Tipos de documento#

dte-sdk soporta ocho tipos de documento. DTE_TYPES asocia cada código con su nombre oficial:

CódigoDocumento
33Factura electrónica
34Factura no afecta o exenta electrónica
39Boleta electrónica
41Boleta exenta electrónica
46Factura de compra electrónica
52Guía de despacho electrónica
56Nota de débito electrónica
61Nota de crédito electrónica
TypeScript
import { DTE_TYPES } from 'dte-sdk'
 
DTE_TYPES[33] // 'Factura electrónica'
DTE_TYPES[61] // 'Nota de crédito electrónica'

Funciones relacionadas#