Skip to main content

Overview

The Invoice class is the primary entry point for building UBL 2.1 compliant invoice XML documents. It provides a fluent API for setting invoice properties, adding line items, managing parties, taxes, and generating the final XML output with Colombian DIAN validation support.

Constructor

new Invoice(id: string, options: InvoiceOptions)
id
string
required
The unique identifier for the invoice (e.g., “SETP990000001”)
options
InvoiceOptions
required
Configuration object containing issuer, software, and environment settings
timestamp
number
Issue time in milliseconds for date/time fields. Defaults to Date.now()
enviroment
string
DIAN environment: "1" for production, "2" for testing. Defaults to "2"
issuer
object
required
Configuration of the invoice issuer
resolutionNumber
string
required
Resolution number from DIAN authorization
technicalKey
string
required
Issuer technical ID provided by DIAN
prefix
string
required
Assigned prefix for invoice numbering (e.g., “SETP”)
startRange
string
required
Authorized start number (e.g., “990000000”)
endRange
string
required
Authorized end number (e.g., “995000000”)
startDate
string
required
Authorization start date in yyyy-mm-dd format (e.g., “2019-01-19”)
endDate
string
required
Authorization end date in yyyy-mm-dd format (e.g., “2030-01-19”)
software
object
required
Software provider configuration
id
string
required
Software ID assigned by DIAN
pin
string
required
Software PIN for security code generation
providerNit
string
required
Technology provider’s NIT (tax identification number)

Example

import Invoice from 'ubl-builder/lib/ubl21/schemaDocuments/Invoice';

const invoice = new Invoice('SETP990000001', {
  timestamp: Date.now(),
  enviroment: '2', // Testing environment
  issuer: {
    resolutionNumber: '18760000001',
    technicalKey: '693ff6a2a553c82d409a927b6a46693fde08dfd0',
    prefix: 'SETP',
    startRange: '990000000',
    endRange: '995000000',
    startDate: '2019-01-19',
    endDate: '2030-01-19'
  },
  software: {
    id: '56f2ae4f-9f06-4f8d-a8b6-3c3b6f7c9f0d',
    pin: '12345',
    providerNit: '900373115'
  }
});

Core Methods

Document Properties

addProperty()

addProperty(key: string, value: string): Invoice
Adds an XML attribute to the root Invoice element.
key
string
required
Attribute name
value
string
required
Attribute value
invoice.addProperty('xmlns:custom', 'http://example.com/custom');

setDefaultProperties()

setDefaultProperties(): void
Sets all required XML namespace declarations for UBL 2.1 compliance. This includes namespaces for:
  • UBL Invoice schema
  • Common Aggregate Components (cac)
  • Common Basic Components (cbc)
  • XML Digital Signature (ds)
  • Extension Components (ext)
  • DIAN Structures (sts)
  • XAdES signatures
invoice.setDefaultProperties();

Basic Invoice Information

setUBLVersionID()

setUBLVersionID(value: string | UBLVersionID, attributes?: UBLVersionIDAttributes): Invoice
Sets the UBL version identifier (typically “UBL 2.1”).
invoice.setUBLVersionID('UBL 2.1');

setID()

setID(value: string | UdtIdentifier, attributes?: UdtIdentifierAttributes): Invoice
Sets the invoice document identifier.
invoice.setID('SETP990000001');

getID()

getID(raw?: boolean): string | UdtIdentifier
Retrieves the invoice ID.
raw
boolean
default:"true"
If true, returns the string value; if false, returns the UdtIdentifier object
const invoiceId = invoice.getID(); // Returns: "SETP990000001"
const idObject = invoice.getID(false); // Returns: UdtIdentifier instance

setProfileID()

setProfileID(value: string | UdtIdentifier, attributes?: UdtIdentifierAttributes): Invoice
Identifies the user-defined profile being used (e.g., “DIAN 2.1”).
invoice.setProfileID('DIAN 2.1');

setProfileExecutionID()

setProfileExecutionID(value: string | UdtIdentifier, attributes?: UdtIdentifierAttributes): Invoice
Sets the execution environment identifier.
invoice.setProfileExecutionID('2'); // Testing environment

setCustomizationID()

setCustomizationID(value: string | UdtIdentifier, attributes?: UdtIdentifierAttributes): Invoice
Identifies a user-defined customization of UBL.
invoice.setCustomizationID('CustomProfile1');

setUUID()

setUUID(value: string | UdtIdentifier, attributes?: UdtIdentifierAttributes): Invoice
Sets a universally unique identifier for the document. For Colombian invoices, this is typically the CUFE (Código Único de Factura Electrónica).
invoice.setUUID('693ff6a2a553c82d...', {
  schemeName: 'CUFE-SHA384',
  schemeID: '2'
});

setInvoiceTypeCode()

setInvoiceTypeCode(value: string | UdtCode, attributes?: UdtCodeAttributes): Invoice
Sets the type of invoice. Common codes:
  • "01": Standard invoice
  • "02": Export invoice
  • "03": Contingency invoice
invoice.setInvoiceTypeCode('01');

Dates and Times

setIssueDate()

setIssueDate(value: string): Invoice
Sets the invoice issue date in yyyy-mm-dd format.
invoice.setIssueDate('2024-03-15');

setIssueTime()

setIssueTime(value: string): Invoice
Sets the invoice issue time with timezone.
invoice.setIssueTime('14:30:00-05:00');

setDueDate()

setDueDate(value: string): Invoice
Sets the payment due date.
invoice.setDueDate('2024-04-15');

setTaxPointDate()

setTaxPointDate(value: string | UdtDate): Invoice
Sets the date when tax becomes applicable.
invoice.setTaxPointDate('2024-03-15');

Currency Settings

setDocumentCurrencyCode()

setDocumentCurrencyCode(value: string | UdtCode, attributes?: UdtCodeAttributes): Invoice
Sets the default currency for the entire invoice (e.g., “COP”, “USD”).
invoice.setDocumentCurrencyCode('COP');

setTaxCurrencyCode()

setTaxCurrencyCode(value: string | UdtCode, attributes?: UdtCodeAttributes): Invoice
Sets the currency used for tax amounts.
invoice.setTaxCurrencyCode('COP');

setPricingCurrencyCode()

setPricingCurrencyCode(value: string | UdtCode, attributes?: UdtCodeAttributes): Invoice
Sets the currency used for prices.
invoice.setPricingCurrencyCode('USD');

setPaymentCurrencyCode()

setPaymentCurrencyCode(value: string | UdtCode, attributes?: UdtCodeAttributes): Invoice
Sets the currency used for payment.
invoice.setPaymentCurrencyCode('COP');

setPaymentAlternativeCurrencyCode()

setPaymentAlternativeCurrencyCode(value: string | UdtCode, attributes?: UdtCodeAttributes): Invoice
Sets an alternative payment currency.
invoice.setPaymentAlternativeCurrencyCode('USD');

Notes and References

addNote()

addNote(value: string, attributes?: UdtTextAttributes): Invoice
Adds a free-form text note to the invoice. Can be called multiple times.
invoice.addNote('Payment due within 30 days');
invoice.addNote('Special handling required');

setCopyIndicator()

setCopyIndicator(value: boolean): Invoice
Indicates whether this document is a copy.
invoice.setCopyIndicator(false);

setBuyerReference()

setBuyerReference(value: string | UdtText, attributes?: UdtTextAttributes): Invoice
Sets a reference provided by the buyer for internal routing.
invoice.setBuyerReference('PO-2024-001');

setAccountingCost()

setAccountingCost(value: string | UdtText, attributes?: UdtTextAttributes): Invoice
Sets the buyer’s accounting code as text.
invoice.setAccountingCost('DEPT-001-2024');

setAccountingCostCode()

setAccountingCostCode(value: string | UdtCode, attributes?: UdtCodeAttributes): Invoice
Sets the buyer’s accounting code.
invoice.setAccountingCostCode('ACC001');

setLineCountNumeric()

setLineCountNumeric(value: string | UdtNumeric, attributes?: UdtNumericAttributes): Invoice
Sets the number of line items. Automatically set by finalizeDocument().
invoice.setLineCountNumeric('5');

Periods and References

addInvoicePeriod()

addInvoicePeriod(): PeriodType
addInvoicePeriod(value: PeriodType | PeriodTypeParams): Invoice
Adds a period to which the invoice applies. When called without arguments, returns a new PeriodType instance for chaining.
invoice.addInvoicePeriod({
  startDate: '2024-01-01',
  endDate: '2024-01-31'
});

// Or use fluent API
invoice.addInvoicePeriod()
  .setStartDate('2024-01-01')
  .setEndDate('2024-01-31');

clearInvoicePeriods()

clearInvoicePeriods(): void
Removes all invoice periods.
invoice.clearInvoicePeriods();

setOrderReference()

setOrderReference(value: OrderReference | OrderReferenceParams): Invoice
Sets a reference to the purchase order associated with this invoice.
invoice.setOrderReference({
  id: 'PO-2024-001',
  issueDate: '2024-01-15'
});

addBillingReference()

addBillingReference(value: BillingReference | BillingReferenceParams): Invoice
Adds a reference to a billing document.
invoice.addBillingReference({
  invoiceDocumentReference: {
    id: 'INV-2024-001',
    issueDate: '2024-01-01'
  }
});

addDespatchDocumentReference()

addDespatchDocumentReference(input: DespatchDocumentReference | DespatchDocumentReferenceParams): Invoice
Adds a reference to a Despatch Advice document.
invoice.addDespatchDocumentReference({
  id: 'DESP-2024-001'
});

addReceiptDocumentReference()

addReceiptDocumentReference(input: ReceiptDocumentReference | ReceiptDocumentReferenceParams): Invoice
Adds a reference to a Receipt Advice document.
invoice.addReceiptDocumentReference({
  id: 'RCPT-2024-001'
});

addStatementDocumentReference()

addStatementDocumentReference(input: StatementDocumentReference | StatementDocumentReferenceParams): Invoice
Adds a reference to a Statement document.
invoice.addStatementDocumentReference({
  id: 'STMT-2024-001'
});

addOriginatorDocumentReference()

addOriginatorDocumentReference(input: OriginatorDocumentReference | OriginatorDocumentReferenceParams): Invoice
Adds a reference to an originator document.
invoice.addOriginatorDocumentReference({
  id: 'ORIG-2024-001'
});

addContractDocumentReference()

addContractDocumentReference(input: ContractDocumentReference | ContractDocumentReferenceParams): Invoice
Adds a reference to a contract.
invoice.addContractDocumentReference({
  id: 'CONTRACT-2024-001'
});

addAdditionalDocumentReference()

addAdditionalDocumentReference(input: AdditionalDocumentReference | AdditionalDocumentReferenceParams): Invoice
Adds a reference to an additional document.
invoice.addAdditionalDocumentReference({
  id: 'ATTACH-001',
  documentType: 'Supporting documentation'
});

addProjectReference()

addProjectReference(input: ProjectReference | ProjectReferenceParams): Invoice
Adds a reference to a project.
invoice.addProjectReference({
  id: 'PROJECT-2024-001'
});

Parties

setAccountingSupplierParty()

setAccountingSupplierParty(value: AccountingSupplierParty): Invoice
Sets the accounting supplier party (seller/issuer of the invoice).
invoice.setAccountingSupplierParty(new AccountingSupplierParty({
  party: {
    partyIdentification: [{ id: '900123456' }],
    partyName: [{ name: 'Acme Corporation' }]
  }
}));

setAccountingCustomerParty()

setAccountingCustomerParty(value: AccountingCustomerParty): Invoice
Sets the accounting customer party (buyer).
invoice.setAccountingCustomerParty(new AccountingCustomerParty({
  party: {
    partyIdentification: [{ id: '900654321' }],
    partyName: [{ name: 'Customer Inc.' }]
  }
}));

setTaxRepresentativeParty()

setTaxRepresentativeParty(input: TaxRepresentativeParty | PartyParams): Invoice
Sets the tax representative party.
invoice.setTaxRepresentativeParty({
  partyIdentification: [{ id: '900111222' }],
  partyName: [{ name: 'Tax Representative Ltd.' }]
});

addSignature()

addSignature(value: Signature | SignatureParams): Invoice
Adds a signature to the invoice.
invoice.addSignature({
  id: 'SIG-001',
  signatoryParty: {
    partyIdentification: [{ id: '900123456' }]
  }
});

Delivery and Payment

addDelivery()

addDelivery(value: Delivery | DeliveryTypeParams): Invoice
Adds delivery information.
invoice.addDelivery({
  actualDeliveryDate: '2024-03-20',
  deliveryLocation: {
    address: {
      streetName: '123 Main St',
      cityName: 'Bogotá',
      country: { identificationCode: 'CO' }
    }
  }
});

setDeliveryTerms()

setDeliveryTerms(value: DeliveryTerms | DeliveryTermsParams): Invoice
Sets the delivery terms.
invoice.setDeliveryTerms({
  specialTerms: 'FOB Destination'
});

addPaymentMeans()

addPaymentMeans(value: PaymentMeans | PaymentMeansParams): Invoice
Adds payment method information.
invoice.addPaymentMeans({
  paymentMeansCode: '10', // Cash
  paymentDueDate: '2024-04-15'
});

addPrepaidPayment()

addPrepaidPayment(value: PrepaidPayment | PaymentTypeParams): Invoice
Adds a prepaid payment.
invoice.addPrepaidPayment({
  paidAmount: { amount: '500.00', currencyID: 'COP' },
  paidDate: '2024-01-15'
});

setPaymentExchangeRate()

setPaymentExchangeRate(value: PaymentExchangeRate | ExchangeRateParams): Invoice
Sets the exchange rate between document currency and payment currency.
invoice.setPaymentExchangeRate({
  sourceCurrencyCode: 'USD',
  targetCurrencyCode: 'COP',
  calculationRate: '3850.00'
});

Financial Totals

addAllowanceCharge()

addAllowanceCharge(value: AllowanceCharge): Invoice
Adds a document-level allowance (discount) or charge.
invoice.addAllowanceCharge(new AllowanceCharge({
  chargeIndicator: false, // false = allowance/discount
  amount: { amount: '100.00', currencyID: 'COP' },
  allowanceChargeReason: 'Volume discount'
}));

addTaxTotal()

addTaxTotal(value: TaxTotal | TaxTotalTypeParams): Invoice
Adds tax total information for a specific tax type.
invoice.addTaxTotal({
  taxAmount: { amount: '190.00', currencyID: 'COP' },
  taxSubtotals: [{
    taxableAmount: { amount: '1000.00', currencyID: 'COP' },
    taxAmount: { amount: '190.00', currencyID: 'COP' },
    taxCategory: {
      percent: '19',
      taxScheme: { id: '01', name: 'IVA' }
    }
  }]
});

setLegalMonetaryTotal()

setLegalMonetaryTotal(value: LegalMonetaryTotal | MonetaryTotalParams): Invoice
Sets the monetary totals for the invoice.
invoice.setLegalMonetaryTotal({
  lineExtensionAmount: { amount: '1000.00', currencyID: 'COP' },
  taxExclusiveAmount: { amount: '1000.00', currencyID: 'COP' },
  taxInclusiveAmount: { amount: '1190.00', currencyID: 'COP' },
  payableAmount: { amount: '1190.00', currencyID: 'COP' }
});

Invoice Lines

addInvoiceLine()

addInvoiceLine(value: InvoiceLine | InvoiceLineParams): Invoice
Adds a line item to the invoice.
invoice.addInvoiceLine({
  invoicedQuantity: { quantity: '10', unitCode: 'EA' },
  lineExtensionAmount: { amount: '1000.00', currencyID: 'COP' },
  item: {
    description: 'Professional services',
    name: 'Consulting'
  },
  price: {
    priceAmount: { amount: '100.00', currencyID: 'COP' }
  }
});

Extensions

setUBLExtensions()

setUBLExtensions(value: UBLExtensions): Invoice
Sets UBL extensions for the invoice. Used for DIAN-specific extensions in Colombian invoices.
const extensions = new UBLExtensions();
// Configure extensions...
invoice.setUBLExtensions(extensions);

Colombian DIAN-Specific Methods

calculateDianExtension()

calculateDianExtension(): void
Calculates and sets the DIAN extension content including:
  • Invoice control information (authorization, ranges)
  • Software provider details
  • Software security code (hashed)
  • Authorization provider (DIAN)
This method uses the issuer and software options provided in the constructor.
invoice.calculateDianExtension();

applyCufeCode()

applyCufeCode(): void
Calculates and applies the CUFE (Código Único de Factura Electrónica) using SHA-384 hashing according to DIAN specifications. The CUFE is composed of:
  • Invoice number
  • Issue date and time
  • Gross amount
  • Tax codes and amounts (IVA, INC, ICA)
  • Total payable
  • Supplier and customer NITs
  • Technical key
  • Environment
invoice.applyCufeCode();
This method is automatically called by finalizeDocument().

applyQRCode()

applyQRCode(): void
Generates and applies the QR code for DIAN validation portal. The QR code is a SHA-384 hash of the validation URL containing the CUFE.
invoice.applyQRCode();
This method is automatically called by finalizeDocument() and requires the CUFE to be set first.

getQRCode()

getQRCode(): string | null
Retrieves the generated QR code hash.
const qrCode = invoice.getQRCode();

findTaxTotalById()

findTaxTotalById(taxId: string, asString?: boolean): string | number
Finds and returns the tax amount for a specific tax type.
taxId
string
required
Tax scheme ID (e.g., “01” for IVA, “04” for INC, “03” for ICA)
asString
boolean
default:"true"
If true, returns formatted string; if false, returns number
const ivaAmount = invoice.findTaxTotalById('01'); // Returns: "190.00"
const ivaNumber = invoice.findTaxTotalById('01', false); // Returns: 190.00

finalizeDocument()

finalizeDocument(): Invoice
Finalizes the invoice document by:
  1. Setting the line count based on number of invoice lines
  2. Assigning sequential IDs to each invoice line
  3. Calculating and setting the CUFE code
  4. Generating and setting the QR code
This method should be called after all invoice data has been added and before generating XML.
invoice.finalizeDocument();
Always call finalizeDocument() before calling getXml() to ensure all required Colombian DIAN validations are applied.

XML Generation

getXml()

getXml(pretty?: boolean, headless?: boolean): string
Generates the final UBL 2.1 XML document.
pretty
boolean
default:"false"
If true, formats the XML with indentation and line breaks
headless
boolean
default:"false"
If true, omits the XML declaration header
// Generate compact XML with header
const xml = invoice.getXml();

// Generate formatted XML
const prettyXml = invoice.getXml(true);

// Generate XML without declaration
const bodyXml = invoice.getXml(false, true);

Complete Example

import Invoice from 'ubl-builder/lib/ubl21/schemaDocuments/Invoice';
import { AccountingSupplierParty, AccountingCustomerParty } from 'ubl-builder/lib/ubl21/CommonAggregateComponents';

// Create invoice instance
const invoice = new Invoice('SETP990000001', {
  timestamp: Date.now(),
  enviroment: '2',
  issuer: {
    resolutionNumber: '18760000001',
    technicalKey: '693ff6a2a553c82d409a927b6a46693fde08dfd0',
    prefix: 'SETP',
    startRange: '990000000',
    endRange: '995000000',
    startDate: '2019-01-19',
    endDate: '2030-01-19'
  },
  software: {
    id: '56f2ae4f-9f06-4f8d-a8b6-3c3b6f7c9f0d',
    pin: '12345',
    providerNit: '900373115'
  }
});

// Set default properties and basic info
invoice
  .setDefaultProperties()
  .setUBLVersionID('UBL 2.1')
  .setProfileID('DIAN 2.1')
  .setProfileExecutionID('2')
  .setID('SETP990000001')
  .setIssueDate('2024-03-15')
  .setIssueTime('14:30:00-05:00')
  .setInvoiceTypeCode('01')
  .setDocumentCurrencyCode('COP')
  .addNote('Payment due within 30 days');

// Set supplier (seller)
invoice.setAccountingSupplierParty(new AccountingSupplierParty({
  party: {
    partyIdentification: [{ id: '900123456' }],
    partyName: [{ name: 'Acme Corporation' }],
    postalAddress: {
      cityName: 'Bogotá',
      countrySubentity: 'Cundinamarca',
      country: { identificationCode: 'CO' }
    },
    partyTaxScheme: [{
      companyID: '900123456',
      taxScheme: { id: '01', name: 'IVA' }
    }]
  }
}));

// Set customer (buyer)
invoice.setAccountingCustomerParty(new AccountingCustomerParty({
  party: {
    partyIdentification: [{ id: '900654321' }],
    partyName: [{ name: 'Customer Inc.' }],
    partyTaxScheme: [{
      companyID: '900654321',
      taxScheme: { id: '01', name: 'IVA' }
    }]
  }
}));

// Add invoice line
invoice.addInvoiceLine({
  invoicedQuantity: { quantity: '10', unitCode: 'EA' },
  lineExtensionAmount: { amount: '1000.00', currencyID: 'COP' },
  item: {
    description: 'Professional consulting services',
    name: 'Consulting'
  },
  price: {
    priceAmount: { amount: '100.00', currencyID: 'COP' }
  },
  taxTotals: [{
    taxAmount: { amount: '190.00', currencyID: 'COP' },
    taxSubtotals: [{
      taxableAmount: { amount: '1000.00', currencyID: 'COP' },
      taxAmount: { amount: '190.00', currencyID: 'COP' },
      taxCategory: {
        percent: '19',
        taxScheme: { id: '01', name: 'IVA' }
      }
    }]
  }]
});

// Add tax totals
invoice.addTaxTotal({
  taxAmount: { amount: '190.00', currencyID: 'COP' },
  taxSubtotals: [{
    taxableAmount: { amount: '1000.00', currencyID: 'COP' },
    taxAmount: { amount: '190.00', currencyID: 'COP' },
    taxCategory: {
      percent: '19',
      taxScheme: { id: '01', name: 'IVA' }
    }
  }]
});

// Set monetary totals
invoice.setLegalMonetaryTotal({
  lineExtensionAmount: { amount: '1000.00', currencyID: 'COP' },
  taxExclusiveAmount: { amount: '1000.00', currencyID: 'COP' },
  taxInclusiveAmount: { amount: '1190.00', currencyID: 'COP' },
  payableAmount: { amount: '1190.00', currencyID: 'COP' }
});

// Calculate DIAN extensions and finalize
invoice.calculateDianExtension();
invoice.finalizeDocument();

// Generate XML
const xml = invoice.getXml(true);
console.log(xml);

Type Definitions

InvoiceOptions

type InvoiceOptions = {
  timestamp?: number;
  enviroment?: string;
  issuer: {
    resolutionNumber: string;
    technicalKey: string;
    prefix: string;
    startRange: string;
    endRange: string;
    startDate: string;
    endDate: string;
  };
  software: {
    id: string;
    pin: string;
    providerNit: string;
  };
};

Method Chaining

Most methods return the Invoice instance, enabling fluent method chaining:
invoice
  .setID('SETP990000001')
  .setIssueDate('2024-03-15')
  .setIssueTime('14:30:00-05:00')
  .setInvoiceTypeCode('01')
  .setDocumentCurrencyCode('COP')
  .addNote('Payment terms: Net 30');

Best Practices

Order of Operations: Always follow this sequence when building invoices:
  1. Create Invoice instance with options
  2. Set default properties and basic information
  3. Configure parties (supplier, customer)
  4. Add invoice lines with tax information
  5. Add document-level allowances/charges if needed
  6. Add tax totals
  7. Set legal monetary total
  8. Call calculateDianExtension() for Colombian invoices
  9. Call finalizeDocument() to calculate CUFE and QR code
  10. Generate XML with getXml()
CUFE Calculation: The CUFE must be calculated after all monetary amounts and tax information have been set, as it depends on these values. Always call finalizeDocument() before generating XML for Colombian DIAN invoices.
Tax Totals: Ensure that tax totals at the document level match the sum of tax amounts from all invoice lines. The findTaxTotalById() method helps verify tax amounts by tax type.

Build docs developers (and LLMs) love