Documentation Index Fetch the complete documentation index at: https://mintlify.com/pipesanta/ubl-builder/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Tax calculations in UBL invoices involve a hierarchical structure:
Tax Scheme : The taxation system (e.g., IVA, INC, ICA)
Tax Category : The tax category with rate and exemptions
Tax Subtotal : The tax calculated for a category
Tax Total : The sum of all tax subtotals for a scheme
This guide covers how to properly configure and calculate taxes for Colombian and international invoices.
Tax Structure
Basic Tax Configuration
Create Tax Scheme
Define the taxation system: import { TaxScheme } from 'ubl-builder' ;
// IVA (VAT) - ID 01
const ivaScheme = new TaxScheme ({
id: '01' ,
name: 'IVA'
});
// INC (National Consumption Tax) - ID 04
const incScheme = new TaxScheme ({
id: '04' ,
name: 'INC'
});
// ICA (Industry and Commerce Tax) - ID 03
const icaScheme = new TaxScheme ({
id: '03' ,
name: 'ICA'
});
Colombian tax scheme IDs:
01: IVA (Value Added Tax)
02: IC (Consumption Tax)
03: ICA (Industry and Commerce Tax)
04: INC (National Consumption Tax)
05: ReteIVA (VAT Withholding)
06: ReteRenta (Income Withholding)
07: ReteICA (ICA Withholding)
Create Tax Category
Define the tax category with rate: import { TaxCategory } from 'ubl-builder' ;
const taxCategory = new TaxCategory ({
id: '01' , // Category ID
percent: '19' , // Tax rate
taxScheme: ivaScheme
});
// Access and modify
taxCategory . setPercent ( '19' );
const rate = taxCategory . getPercent (); // Returns '19'
const scheme = taxCategory . getTaxScheme (); // Returns TaxScheme
Create Tax Subtotal
Calculate tax for a specific category: import { TaxSubtotal } from 'ubl-builder' ;
const taxSubtotal = new TaxSubtotal ({
taxableAmount: '1000.00' , // Base amount
taxAmount: '190.00' , // 19% of 1000
percent: '19' ,
taxCategory: taxCategory
});
// Access amounts
const taxable = taxSubtotal . getTaxableAmount (); // '1000.00'
const tax = taxSubtotal . getTaxAmount (); // '190.00'
const percent = taxSubtotal . getPercent (); // '19'
Create Tax Total
Sum all subtotals for a tax scheme: import { TaxTotal } from 'ubl-builder' ;
const taxTotal = new TaxTotal ({
taxAmount: '190.00' , // Total tax for this scheme
taxSubtotals: [ taxSubtotal ]
});
// Access and modify
const total = taxTotal . getTaxAmount (); // '190.00'
taxTotal . setTaxAmount ( '200.00' );
Add to Invoice
Add tax totals to the invoice: // Add IVA tax total
invoice . addTaxTotal ( taxTotal );
// Add additional tax totals
invoice . addTaxTotal ({
taxAmount: '50.00' ,
taxSubtotals: [ /* INC subtotals */ ]
});
Colombian Tax Examples
IVA (VAT) - Standard Rate
import { TaxTotal , TaxSubtotal , TaxCategory , TaxScheme } from 'ubl-builder' ;
// Calculate 19% IVA on 1,000,000 COP
const ivaTotal = new TaxTotal ({
taxAmount: '190000.00' ,
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '190000.00' ,
percent: '19' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '19' ,
taxScheme: new TaxScheme ({
id: '01' ,
name: 'IVA'
})
})
})
]
});
invoice . addTaxTotal ( ivaTotal );
IVA - Multiple Rates
// Mixed rates: 19% and 5% IVA
const mixedIvaTotal = new TaxTotal ({
taxAmount: '240000.00' , // 190,000 + 50,000
taxSubtotals: [
// 19% on 1,000,000
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '190000.00' ,
percent: '19' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '19' ,
taxScheme: new TaxScheme ({ id: '01' , name: 'IVA' })
})
}),
// 5% on 1,000,000
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '50000.00' ,
percent: '5' ,
taxCategory: new TaxCategory ({
id: '02' ,
percent: '5' ,
taxScheme: new TaxScheme ({ id: '01' , name: 'IVA' })
})
})
]
});
invoice . addTaxTotal ( mixedIvaTotal );
INC (National Consumption Tax)
// 8% INC on luxury goods
const incTotal = new TaxTotal ({
taxAmount: '80000.00' ,
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '80000.00' ,
percent: '8' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '8' ,
taxScheme: new TaxScheme ({
id: '04' ,
name: 'INC'
})
})
})
]
});
invoice . addTaxTotal ( incTotal );
ICA (Industry and Commerce Tax)
// Variable ICA rate (e.g., 0.966% for services in Bogotá)
const icaTotal = new TaxTotal ({
taxAmount: '9660.00' ,
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '9660.00' ,
percent: '0.966' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '0.966' ,
taxScheme: new TaxScheme ({
id: '03' ,
name: 'ICA'
})
})
})
]
});
invoice . addTaxTotal ( icaTotal );
Zero-Rated (Exempt) Items
// 0% IVA for exempt goods
const exemptIvaTotal = new TaxTotal ({
taxAmount: '0.00' ,
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '500000.00' ,
taxAmount: '0.00' ,
percent: '0' ,
taxCategory: new TaxCategory ({
id: '04' , // Exempt category
percent: '0' ,
taxScheme: new TaxScheme ({ id: '01' , name: 'IVA' }),
taxExemptionReasonCode: 'E' ,
taxExemptionReason: 'Exempt goods per Article 424'
})
})
]
});
invoice . addTaxTotal ( exemptIvaTotal );
Multiple Tax Schemes
Combine different taxes on the same invoice:
// Product: 1,000,000 COP base
// IVA 19%: 190,000
// INC 8%: 80,000
// Total: 1,270,000
// Add IVA
invoice . addTaxTotal ({
taxAmount: '190000.00' ,
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '190000.00' ,
percent: '19' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '19' ,
taxScheme: new TaxScheme ({ id: '01' , name: 'IVA' })
})
})
]
});
// Add INC
invoice . addTaxTotal ({
taxAmount: '80000.00' ,
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '80000.00' ,
percent: '8' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '8' ,
taxScheme: new TaxScheme ({ id: '04' , name: 'INC' })
})
})
]
});
// Set monetary totals
import { LegalMonetaryTotal } from 'ubl-builder' ;
invoice . setLegalMonetaryTotal ({
lineExtensionAmount: '1000000.00' ,
taxExclusiveAmount: '1000000.00' ,
taxInclusiveAmount: '1270000.00' ,
payableAmount: '1270000.00'
});
Tax Calculation Helpers
Calculate Tax Amount
function calculateTax ( baseAmount : number , rate : number ) : string {
const taxAmount = baseAmount * ( rate / 100 );
return taxAmount . toFixed ( 2 );
}
const base = 1000000 ;
const ivaRate = 19 ;
const ivaAmount = calculateTax ( base , ivaRate ); // '190000.00'
Calculate Total with Tax
function calculateTotal ( baseAmount : number , taxRate : number ) : {
base : string ;
tax : string ;
total : string ;
} {
const tax = baseAmount * ( taxRate / 100 );
const total = baseAmount + tax ;
return {
base: baseAmount . toFixed ( 2 ),
tax: tax . toFixed ( 2 ),
total: total . toFixed ( 2 )
};
}
const result = calculateTotal ( 1000000 , 19 );
// { base: '1000000.00', tax: '190000.00', total: '1190000.00' }
Find Tax by Scheme ID
The Invoice class provides a helper to retrieve tax amounts:
// After adding tax totals to invoice
const ivaAmount = invoice . findTaxTotalById ( '01' ); // Returns '190000.00'
const incAmount = invoice . findTaxTotalById ( '04' ); // Returns '80000.00'
const icaAmount = invoice . findTaxTotalById ( '03' ); // Returns '0.00' if not set
// Get as number
const ivaNumber = invoice . findTaxTotalById ( '01' , false ); // Returns 190000
Invoice Line Taxes
Add tax information to individual invoice lines:
import { InvoiceLine , Item , Price , TaxTotal } from 'ubl-builder' ;
const line = new InvoiceLine ({
id: '1' ,
invoicedQuantity: '10' ,
lineExtensionAmount: '1000000.00' ,
item: new Item ({
description: 'Professional Services' ,
sellersItemIdentification: { id: 'SRV-001' }
}),
price: new Price ({
priceAmount: '100000.00' ,
baseQuantity: '1'
}),
taxTotals: [
new TaxTotal ({
taxAmount: '190000.00' ,
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '190000.00' ,
percent: '19' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '19' ,
taxScheme: new TaxScheme ({ id: '01' , name: 'IVA' })
})
})
]
})
]
});
invoice . addInvoiceLine ( line );
Withholding Taxes
For withholding tax (retenciones):
import { WithholdingTaxTotal } from 'ubl-builder' ;
// ReteIVA - 15% withholding on IVA
const reteIvaTotal = new WithholdingTaxTotal ({
taxAmount: '28500.00' , // 15% of 190,000 IVA
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '190000.00' ,
taxAmount: '28500.00' ,
percent: '15' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '15' ,
taxScheme: new TaxScheme ({
id: '05' ,
name: 'ReteIVA'
})
})
})
]
});
// Note: Withholding taxes reduce the payable amount
const payableAmount = 1190000 - 28500 ; // 1,161,500
Advanced Tax Configuration
Tiered Tax Rates
// Progressive tax rate based on amount tiers
const tieredTaxSubtotal = new TaxSubtotal ({
taxableAmount: '5000000.00' ,
taxAmount: '250000.00' ,
percent: '5' ,
tierRange: '0-10000000' ,
tierRatePercent: '5' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '5' ,
taxScheme: new TaxScheme ({ id: '01' , name: 'IVA' })
})
});
Per-Unit Tax
import { UdtMeasure } from 'ubl-builder' ;
// Tax per unit (e.g., per liter, per kilogram)
const perUnitTaxSubtotal = new TaxSubtotal ({
taxableAmount: '0.00' ,
taxAmount: '5000.00' , // 100 units × 50 per unit
baseUnitMeasure: new UdtMeasure ( '100' , { unitCode: 'LTR' }),
perUnitAmount: '50.00' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '0' ,
taxScheme: new TaxScheme ({ id: '02' , name: 'IC' })
})
});
Testing Tax Calculations
import { TaxTotal , TaxSubtotal } from 'ubl-builder' ;
// Create tax total
const taxTotal = new TaxTotal ({ taxAmount: '19.00' } as any );
// Test getter
expect ( taxTotal . getTaxAmount ()). toBe ( '19.00' );
// Test setter
taxTotal . setTaxAmount ( '20.00' );
expect ( taxTotal . getTaxAmount ()). toBe ( '20.00' );
// Test calculation
const subtotal1 = new TaxSubtotal ({ taxAmount: '10' } as any );
const subtotal2 = new TaxSubtotal ({ taxAmount: '2.5' } as any );
const total = new TaxTotal ({
taxAmount: '0' ,
taxSubtotals: [ subtotal1 , subtotal2 ]
} as any );
// Note: calculateTotalTaxAmount() has a known issue
// It concatenates strings instead of adding numbers
const calculated = total . calculateTotalTaxAmount ();
// Current behavior returns '0102.5' instead of '12.5'
The calculateTotalTaxAmount() method has a known issue where it concatenates strings instead of adding numbers. Always set taxAmount explicitly instead of relying on this method.
Complete Example
import {
Invoice ,
TaxTotal ,
TaxSubtotal ,
TaxCategory ,
TaxScheme ,
LegalMonetaryTotal
} from 'ubl-builder' ;
// Create invoice (simplified)
const invoice = new Invoice ( 'SETP990000001' , {
/* options */
} as any );
// Add IVA 19%
invoice . addTaxTotal ({
taxAmount: '190000.00' ,
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '190000.00' ,
percent: '19' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '19' ,
taxScheme: new TaxScheme ({
id: '01' ,
name: 'IVA'
})
})
})
]
});
// Add INC 8%
invoice . addTaxTotal ({
taxAmount: '80000.00' ,
taxSubtotals: [
new TaxSubtotal ({
taxableAmount: '1000000.00' ,
taxAmount: '80000.00' ,
percent: '8' ,
taxCategory: new TaxCategory ({
id: '01' ,
percent: '8' ,
taxScheme: new TaxScheme ({
id: '04' ,
name: 'INC'
})
})
})
]
});
// Set monetary totals
invoice . setLegalMonetaryTotal ({
lineExtensionAmount: '1000000.00' ,
taxExclusiveAmount: '1000000.00' ,
taxInclusiveAmount: '1270000.00' ,
payableAmount: '1270000.00'
});
// Retrieve tax amounts
const iva = invoice . findTaxTotalById ( '01' ); // '190000.00'
const inc = invoice . findTaxTotalById ( '04' ); // '80000.00'
const ica = invoice . findTaxTotalById ( '03' ); // '0.00'
Best Practices
Tax Calculation
Always calculate tax amounts before creating tax objects
Use proper decimal precision (2 decimals for COP)
Set taxAmount explicitly; don’t rely on calculateTotalTaxAmount()
Verify tax amounts match legal requirements
Include all applicable taxes for your jurisdiction
Tax Categories
Use correct tax scheme IDs (‘01’ for IVA, ‘04’ for INC, etc.)
Set appropriate tax category IDs for different rates
Include exemption reason codes when applicable
Document tax exemptions with reason text
Testing
Test calculations with known values
Verify tax totals sum correctly
Check rounding behavior
Test edge cases (zero rates, exempt items)
Validate against official tax tables
Next Steps
Creating Invoices Complete guide to invoice creation
DIAN Extensions Colombian e-invoicing compliance