Overview
DIAN (Dirección de Impuestos y Aduanas Nacionales) extensions are required for Colombian electronic invoicing. The UBL Builder library provides automatic generation and management of DIAN-specific extensions including:
Invoice control and authorization
Software provider information
Software security codes
QR codes for invoice verification
CUFE (Código Único de Factura Electrónica)
DIAN Extension Structure
DIAN extensions are added to the UBL document through the UBLExtensions element:
< ext:UBLExtensions >
< ext:UBLExtension >
< ext:ExtensionContent >
< sts:DianExtensions >
< sts:InvoiceControl > ... </ sts:InvoiceControl >
< sts:InvoiceSource > ... </ sts:InvoiceSource >
< sts:SoftwareProvider > ... </ sts:SoftwareProvider >
< sts:SoftwareSecurityCode > ... </ sts:SoftwareSecurityCode >
< sts:AuthorizationProvider > ... </ sts:AuthorizationProvider >
< sts:QRCode > ... </ sts:QRCode >
</ sts:DianExtensions >
</ ext:ExtensionContent >
</ ext:UBLExtension >
</ ext:UBLExtensions >
Automatic Extension Generation
Configure Invoice Options
Provide DIAN configuration when creating the invoice: import { Invoice } from 'ubl-builder' ;
const invoice = new Invoice ( 'SETP990000001' , {
timestamp: Date . now (),
enviroment: '2' , // '1' = production, '2' = testing
issuer: {
resolutionNumber: '18764003560527' ,
technicalKey: 'fc8eac425c29d8c3fc8eac420b26cf00668ea99812ab8' ,
prefix: 'SETP' ,
startRange: '990000000' ,
endRange: '995000000' ,
startDate: '2019-01-19' ,
endDate: '2030-01-19'
},
software: {
id: '0d2e2883-eb8e-4e48-9d89-9e1a87a9e413' ,
pin: '12345' ,
providerNit: '900123456'
}
});
Environment : ‘1’ for production invoices sent to DIAN, ‘2’ for testing
Resolution Number : DIAN authorization number for electronic invoicing
Technical Key : Unique key assigned by DIAN to the issuer
Prefix : Invoice prefix authorized by DIAN (e.g., SETP, SETT)
Range : Authorized invoice number range (from-to)
Software ID : UUID assigned by DIAN for your software
Pin : Software PIN provided by DIAN
Generate DIAN Extensions
Call calculateDianExtension() to generate the extension structure: // This automatically creates all DIAN extension components
invoice . calculateDianExtension ();
This method creates:
InvoiceControl : Authorization details and number range
InvoiceSource : Country identification (CO for Colombia)
SoftwareProvider : Technology provider NIT and software ID
SoftwareSecurityCode : SHA-384 hash of software ID + PIN + invoice number
AuthorizationProvider : DIAN NIT (800197268)
Finalize Document
Call finalizeDocument() to generate CUFE and QR code: // This calculates CUFE and QR code
invoice . finalizeDocument ();
// Retrieve the QR code
const qrCode = invoice . getQRCode ();
console . log ( 'QR Code:' , qrCode );
Always call finalizeDocument() after setting all invoice data and before generating XML. This ensures the CUFE and QR code include all invoice information.
DIAN Extension Components
Invoice Control
Contains authorization and numbering information:
import {
InvoiceControl ,
PeriodType ,
AuthorizedInvoices
} from 'ubl-builder' ;
const invoiceControl = new InvoiceControl ({
invoiceAuthorization: '18764003560527' ,
authorizationPeriod: new PeriodType ({
startDate: '2019-01-19' ,
endDate: '2030-01-19'
}),
authorizedInvoices: new AuthorizedInvoices ({
prefix: 'SETP' ,
from: '990000000' ,
to: '995000000'
})
});
Invoice Source
Identifies the country of origin:
import { InvoiceSource } from 'ubl-builder' ;
const invoiceSource = new InvoiceSource ({
identificationCode: {
content: 'CO' ,
attributes: {
listAgencyID: '6' ,
listAgencyName: 'United Nations Economic Commission for Europe' ,
listSchemeURI: 'urn:oasis:names:specification:ubl:codelist:gc:CountryIdentificationCode-2.1'
}
}
});
Software Provider
Identifies the technology provider and software:
import { SoftwareProvider , UdtIdentifier } from 'ubl-builder' ;
const softwareProvider = new SoftwareProvider ({
// Technology provider's NIT
providerID: new UdtIdentifier ( '900123456' , {
schemeAgencyID: '195' ,
schemeAgencyName: 'CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)' ,
schemeID: '9' , // NIT verification digit
schemeName: '31' // Document type: NIT
}),
// Software UUID assigned by DIAN
softwareID: new UdtIdentifier ( '0d2e2883-eb8e-4e48-9d89-9e1a87a9e413' , {
schemeAgencyID: '195' ,
schemeAgencyName: 'CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)'
})
});
Software Security Code
SHA-384 hash for software validation:
import { SHA384 } from 'ubl-builder' ;
import { UdtIdentifier } from 'ubl-builder' ;
// Calculate hash: softwareID + pin + invoiceNumber
const securityCodeInput =
options . software . id +
options . software . pin +
invoice . getID ();
const securityCodeHash = new SHA384 (). getHash (
securityCodeInput ,
'binary' ,
'hex'
);
const softwareSecurityCode = new UdtIdentifier ( securityCodeHash , {
schemeAgencyID: '195' ,
schemeAgencyName: 'CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)'
});
Authorization Provider
Always DIAN for Colombian invoices:
import { AuthorizationProvider , UdtIdentifier } from 'ubl-builder' ;
const authorizationProvider = new AuthorizationProvider ({
authorizationProviderID: new UdtIdentifier ( '800197268' , {
schemeAgencyID: '195' ,
schemeAgencyName: 'CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)' ,
schemeID: '4' , // Verification digit
schemeName: '31' // NIT
})
});
CUFE Calculation
The CUFE (Código Único de Factura Electrónica) is a unique identifier calculated using SHA-384:
// CUFE components (in order):
// 1. Invoice number (prefix + number)
// 2. Issue date
// 3. Issue time
// 4. Line extension amount (before taxes)
// 5. Tax code 01 (IVA)
// 6. IVA amount
// 7. Tax code 04 (INC)
// 8. INC amount
// 9. Tax code 03 (ICA)
// 10. ICA amount
// 11. Payable amount
// 12. Supplier NIT
// 13. Customer NIT
// 14. Technical key (or software PIN for contingency)
// 15. Environment (1 or 2)
const cufeComponents = [
'SETP990000001' ,
'2024-03-06' ,
'10:30:45-05:00' ,
'1000000.00' ,
'01' ,
'190000.00' ,
'04' ,
'0.00' ,
'03' ,
'0.00' ,
'1190000.00' ,
'900123456' ,
'800123456' ,
'fc8eac425c29d8c3fc8eac420b26cf00668ea99812ab8' ,
'2'
]. join ( '' );
const cufe = new SHA384 (). getHash ( cufeComponents , 'binary' , 'hex' );
// Set as invoice UUID
invoice . setUUID ( cufe , {
schemeName: 'CUFE-SHA384' ,
schemeID: '2' // Environment
});
For contingency invoices (type code ‘03’), the software PIN is used instead of the technical key in the CUFE calculation.
QR Code Generation
The QR code is a SHA-384 hash of the DIAN verification URL:
import { SHA384 } from 'ubl-builder' ;
// Get CUFE from invoice
const cufe = invoice . children . uuid . content ;
// Generate QR code URL
const qrUrl = `https://catalogovpfe.dian.gov.co/document/searchqr?documentkey= ${ cufe } ` ;
// Calculate QR code hash
const qrCode = new SHA384 (). getHash ( qrUrl , 'binary' , 'hex' );
// Set in DIAN extensions
invoice . children . UBLExtensions
. getDianUblExtension ()
. getExtensionContent ()
. getDianExtensionsContent ()
. setQRCode ( qrCode );
// Retrieve later
const retrievedQR = invoice . getQRCode ();
Manual Extension Creation
For advanced use cases, create extensions manually:
import {
UBLExtensions ,
UBLExtensionType ,
DianExtensions ,
DianExtensionsContent ,
InvoiceControl ,
InvoiceSource ,
SoftwareProvider ,
AuthorizationProvider ,
PeriodType ,
AuthorizedInvoices ,
UdtIdentifier
} from 'ubl-builder' ;
const ublExtensions = new UBLExtensions ();
ublExtensions . addUBLExtension (
new UBLExtensionType ({
extensionContent: new DianExtensions ({
dianExtensions: new DianExtensionsContent ({
invoiceControl: new InvoiceControl ({
invoiceAuthorization: '18764003560527' ,
authorizationPeriod: new PeriodType ({
startDate: '2019-01-19' ,
endDate: '2030-01-19'
}),
authorizedInvoices: new AuthorizedInvoices ({
prefix: 'SETP' ,
from: '990000000' ,
to: '995000000'
})
}),
invoiceSource: new InvoiceSource ({
identificationCode: {
content: 'CO' ,
attributes: {
listAgencyID: '6' ,
listAgencyName: 'United Nations Economic Commission for Europe' ,
listSchemeURI: 'urn:oasis:names:specification:ubl:codelist:gc:CountryIdentificationCode-2.1'
}
}
}),
softwareProvider: new SoftwareProvider ({
providerID: new UdtIdentifier ( '900123456' , {
schemeAgencyID: '195' ,
schemeAgencyName: 'CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)' ,
schemeID: '9' ,
schemeName: '31'
}),
softwareID: new UdtIdentifier ( '0d2e2883-eb8e-4e48-9d89-9e1a87a9e413' , {
schemeAgencyID: '195' ,
schemeAgencyName: 'CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)'
})
}),
softwareSecurityCode: new UdtIdentifier ( 'calculated_hash' , {
schemeAgencyID: '195' ,
schemeAgencyName: 'CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)'
}),
authorizationProvider: new AuthorizationProvider ({
authorizationProviderID: new UdtIdentifier ( '800197268' , {
schemeAgencyID: '195' ,
schemeAgencyName: 'CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)' ,
schemeID: '4' ,
schemeName: '31'
})
}),
QRCode: 'calculated_qr_hash'
})
})
})
);
invoice . setUBLExtensions ( ublExtensions );
Invoice Type Codes
DIAN defines specific invoice types:
01 : Standard invoice (Factura de venta)
02 : Export invoice (Factura de exportación)
03 : Contingency invoice (Factura de contingencia)
91 : Credit note (Nota crédito)
92 : Debit note (Nota débito)
// Standard invoice
invoice . setInvoiceTypeCode ( '01' );
// Contingency invoice (uses software PIN instead of technical key)
invoice . setInvoiceTypeCode ( '03' );
Testing Environments
Testing Environment
Production Environment
const invoice = new Invoice ( 'SETT990000001' , {
enviroment: '2' , // Testing
issuer: {
resolutionNumber: '18764003560527' ,
technicalKey: 'test_technical_key' ,
prefix: 'SETT' , // Test prefix
startRange: '990000000' ,
endRange: '995000000' ,
startDate: '2019-01-19' ,
endDate: '2030-01-19'
},
software: {
id: 'test-software-uuid' ,
pin: '12345' ,
providerNit: '900123456'
}
});
invoice . setProfileExecutionID ( '2' ); // Testing environment
const invoice = new Invoice ( 'SETP990000001' , {
enviroment: '1' , // Production
issuer: {
resolutionNumber: '18764003560527' ,
technicalKey: 'production_technical_key' ,
prefix: 'SETP' , // Production prefix
startRange: '990000000' ,
endRange: '995000000' ,
startDate: '2019-01-19' ,
endDate: '2030-01-19'
},
software: {
id: 'production-software-uuid' ,
pin: '54321' ,
providerNit: '900123456'
}
});
invoice . setProfileExecutionID ( '1' ); // Production environment
Use different prefixes and configurations for testing vs. production. Never send test invoices to the production environment.
Complete Example
import { Invoice } from 'ubl-builder' ;
// Create invoice with DIAN configuration
const invoice = new Invoice ( 'SETP990000001' , {
timestamp: Date . now (),
enviroment: '2' ,
issuer: {
resolutionNumber: '18764003560527' ,
technicalKey: 'fc8eac425c29d8c3fc8eac420b26cf00668ea99812ab8' ,
prefix: 'SETP' ,
startRange: '990000000' ,
endRange: '995000000' ,
startDate: '2019-01-19' ,
endDate: '2030-01-19'
},
software: {
id: '0d2e2883-eb8e-4e48-9d89-9e1a87a9e413' ,
pin: '12345' ,
providerNit: '900123456'
}
});
// Set basic properties
invoice . setDefaultProperties ();
invoice . setUBLVersionID ( 'UBL 2.1' );
invoice . setProfileID ( 'DIAN 2.1' );
invoice . setProfileExecutionID ( '2' );
invoice . setIssueDate ( '2024-03-06' );
invoice . setIssueTime ( '10:30:45-05:00' );
invoice . setInvoiceTypeCode ( '01' );
invoice . setDocumentCurrencyCode ( 'COP' );
// Add parties, lines, taxes, etc.
// ... (see other guides)
// Generate DIAN extensions
invoice . calculateDianExtension ();
// Finalize (calculates CUFE and QR code)
invoice . finalizeDocument ();
// Get QR code
const qrCode = invoice . getQRCode ();
console . log ( 'QR Code:' , qrCode );
// Generate XML
const xml = invoice . getXml ( true , false );
Best Practices
Configuration Management
Store DIAN credentials securely (environment variables, secrets manager)
Use different prefixes for test and production
Validate resolution number and date ranges
Keep software ID and PIN confidential
Rotate technical keys periodically
CUFE and QR Codes
Always call calculateDianExtension() before finalizeDocument()
Never modify invoice data after calling finalizeDocument()
Store CUFE with invoice for later reference
Include QR code in printed/PDF invoices
Test CUFE generation with known values
Compliance
Follow DIAN technical specifications v1.9 or later
Use correct invoice type codes
Include all required DIAN extensions
Test in DIAN testing environment before production
Keep authorization documents and resolution numbers current
Troubleshooting
CUFE Mismatch
If DIAN rejects the CUFE:
Verify all amounts have exactly 2 decimal places
Check tax amounts match tax totals exactly
Ensure supplier and customer NITs are correct
Verify technical key is correct
Confirm environment setting matches
Extension Validation Errors
If DIAN validation fails:
Ensure calculateDianExtension() was called
Verify software ID is a valid UUID
Check resolution number format
Confirm authorization dates are valid
Validate NIT format and verification digits
QR Code Issues
If QR code doesn’t verify:
Confirm finalizeDocument() was called
Check CUFE was calculated correctly
Verify QR code URL format
Test with DIAN’s QR code validator
Next Steps
Creating Invoices Complete guide to invoice creation
Tax Calculations Colombian tax configuration
DIAN Documentation Official DIAN resources (external)
API Reference Explore extension classes