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#
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#
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 readonlyPará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 formatoYYYY-MM-DD. Por defecto es la fecha de hoy en la zona horariaAmerica/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.cityes opcional.
input.receiver- El cliente.rutybusinessNameson obligatorios;activity,address,commune,cityyemailson opcionales.input.items(LineItem[]) - Entre 1 y 60 líneas de detalle:name- Lo que vendes.descriptionagrega un texto más largo.quantity,unitPrice- Cantidad y precio unitario neto en CLP (bruto en boletas, revisacalculateTotals()).unit(opcional) - Unidad de medida, como'UN'o'KG'.discountPercent(opcional) - Descuento de la línea, de 0 a 100.exempt(opcional) -truecuando 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-1anula el documento referenciado,2corrige texto,3corrige 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 formatoYYYY-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ódigo | Cuándo |
|---|---|
MISSING_FIELD | Falta un campo obligatorio o está vacío, incluidos items y, en los tipos 56 y 61, references |
INVALID_RUT | El RUT del emisor o del receptor está mal formado o su dígito verificador Módulo 11 no corresponde |
INVALID_AMOUNT | Una 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.
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:
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:
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#
const dte = createDte({
type: 33,
folio: 1025,
issuer,
receiver,
items: [{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }],
paymentMethod: 'credit',
dueDate: '2026-11-27',
})Inmutabilidad#
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ódigo | Documento |
|---|---|
33 | Factura electrónica |
34 | Factura no afecta o exenta electrónica |
39 | Boleta electrónica |
41 | Boleta exenta electrónica |
46 | Factura de compra electrónica |
52 | Guía de despacho electrónica |
56 | Nota de débito electrónica |
61 | Nota de crédito electrónica |
import { DTE_TYPES } from 'dte-sdk'
DTE_TYPES[33] // 'Factura electrónica'
DTE_TYPES[61] // 'Nota de crédito electrónica'Funciones relacionadas#
calculateTotals()- Las reglas detrás dedte.totalsstampDte()- Siguiente paso: agregar el timbre electrónicotoXml()- Previsualizar el documento como XML