Full Invoice Example
import {
Invoice,
InvoiceLine,
Item,
Price,
TaxTotal,
TaxSubtotal,
TaxCategory,
TaxScheme,
ClassifiedTaxCategory,
LegalMonetaryTotal,
AccountingSupplierParty,
AccountingCustomerParty,
Party,
PartyTaxScheme,
PartyLegalEntity,
PartyName,
PostalAddress,
Country,
Contact,
SellersItemIdentification,
Delivery,
DeliveryLocation,
Address,
PaymentMeans,
PaymentTerms,
} from 'ubl-builder';
const invoiceOptions = {
enviroment: '1', // Production environment
issuer: {
prefix: 'INV',
resolutionNumber: '321654987',
startDate: '2024-01-01',
endDate: '2025-12-31',
startRange: '1000',
endRange: '10000',
technicalKey: 'tech-key-prod-123',
},
software: {
id: 'soft-prod-123',
pin: 'prod-pin-987654321',
providerNit: '900123456-1',
},
};
const invoice = new Invoice('INV-2026-001', invoiceOptions);
// Basic invoice properties
invoice.setDefaultProperties();
invoice.setID('INV-2026-001');
invoice.setUBLVersionID('UBL 2.1');
invoice.setIssueDate('2026-03-06');
invoice.setIssueTime('14:30:00-05:00');
invoice.setInvoiceTypeCode('01'); // Standard invoice
invoice.setDocumentCurrencyCode('USD');
invoice.setDueDate('2026-04-05'); // 30 days payment term
invoice.addNote('Payment due within 30 days of invoice date');
invoice.addNote('Bank transfer preferred', { languageID: 'en' });
// Invoice period
invoice.addInvoicePeriod({
startDate: '2026-02-01',
endDate: '2026-02-28',
});
// Create supplier party (seller)
const supplierTaxScheme = new PartyTaxScheme({
registrationName: 'Acme Corporation Inc',
companyID: '900123456',
taxScheme: new TaxScheme({
id: '01',
name: 'VAT',
}),
});
const supplierLegalEntity = new PartyLegalEntity({
registrationName: 'Acme Corporation Inc',
companyID: '900123456-1',
});
const supplierAddress = new PostalAddress({
streetName: '123 Business Street',
cityName: 'New York',
postalZone: '10001',
countrySubentity: 'NY',
country: new Country({
identificationCode: 'US',
name: 'United States',
}),
});
const supplierContact = new Contact({
name: 'John Smith',
telephone: '+1-555-0100',
electronicMail: '[email protected]',
});
const supplierParty = new Party({
partyNames: [new PartyName({ name: 'Acme Corporation' })],
postalAddress: supplierAddress,
partyTaxSchemes: [supplierTaxScheme],
partyLegalEntities: [supplierLegalEntity],
contact: supplierContact,
} as any);
const accountingSupplierParty = new AccountingSupplierParty({
party: supplierParty,
});
invoice.setAccountingSupplierParty(accountingSupplierParty);
// Create customer party (buyer)
const customerTaxScheme = new PartyTaxScheme({
registrationName: 'Global Tech Solutions LLC',
companyID: '800987654',
taxScheme: new TaxScheme({
id: '01',
name: 'VAT',
}),
});
const customerLegalEntity = new PartyLegalEntity({
registrationName: 'Global Tech Solutions LLC',
companyID: '800987654-3',
});
const customerAddress = new PostalAddress({
streetName: '456 Tech Avenue',
cityName: 'San Francisco',
postalZone: '94105',
countrySubentity: 'CA',
country: new Country({
identificationCode: 'US',
name: 'United States',
}),
});
const customerContact = new Contact({
name: 'Jane Doe',
telephone: '+1-555-0200',
electronicMail: '[email protected]',
});
const customerParty = new Party({
partyNames: [new PartyName({ name: 'Global Tech Solutions' })],
postalAddress: customerAddress,
partyTaxSchemes: [customerTaxScheme],
partyLegalEntities: [customerLegalEntity],
contact: customerContact,
} as any);
const accountingCustomerParty = new AccountingCustomerParty({
party: customerParty,
});
invoice.setAccountingCustomerParty(accountingCustomerParty);
// Delivery information
const deliveryAddress = new Address({
streetName: '456 Tech Avenue',
cityName: 'San Francisco',
postalZone: '94105',
countrySubentity: 'CA',
country: new Country({
identificationCode: 'US',
name: 'United States',
}),
});
const deliveryLocation = new DeliveryLocation({
address: deliveryAddress,
});
const delivery = new Delivery({
actualDeliveryDate: '2026-02-28',
deliveryLocation: deliveryLocation,
});
invoice.addDelivery(delivery);
// Payment means
const paymentMeans = new PaymentMeans({
paymentMeansCode: '31', // Wire transfer
paymentID: 'INV-2026-001',
});
invoice.addPaymentMeans(paymentMeans);
// Tax configuration
const taxScheme = new TaxScheme({
id: '01',
name: 'VAT',
});
const classifiedTaxCategory = new ClassifiedTaxCategory({
id: 'S',
percent: '10.00',
taxScheme: taxScheme,
});
// Invoice Line 1: Professional Services
const item1 = new Item({
name: 'Software Development Services',
descriptions: ['Full-stack development for Q1 2026', 'Includes frontend and backend work'],
sellersItemIdentification: new SellersItemIdentification({
id: 'SERV-DEV-001',
}),
classifiedTaxCategory: classifiedTaxCategory,
} as any);
const price1 = new Price({
priceAmount: '5000.00',
});
const invoiceLine1 = new InvoiceLine({
id: '1',
invoicedQuantity: '160',
lineExtensionAmount: '8000.00',
item: item1,
price: price1,
} as any);
invoice.addInvoiceLine(invoiceLine1);
// Invoice Line 2: Hardware
const item2 = new Item({
name: 'Enterprise Server',
descriptions: ['Dell PowerEdge R750', '2x Intel Xeon processors, 128GB RAM'],
sellersItemIdentification: new SellersItemIdentification({
id: 'HW-SRV-750',
}),
classifiedTaxCategory: classifiedTaxCategory,
} as any);
const price2 = new Price({
priceAmount: '12000.00',
});
const invoiceLine2 = new InvoiceLine({
id: '2',
invoicedQuantity: '1',
lineExtensionAmount: '12000.00',
item: item2,
price: price2,
} as any);
invoice.addInvoiceLine(invoiceLine2);
// Invoice Line 3: Software Licenses
const item3 = new Item({
name: 'Annual Software License',
descriptions: ['Enterprise tier subscription', 'Includes 24/7 support'],
sellersItemIdentification: new SellersItemIdentification({
id: 'LIC-ENT-001',
}),
classifiedTaxCategory: classifiedTaxCategory,
} as any);
const price3 = new Price({
priceAmount: '2400.00',
});
const invoiceLine3 = new InvoiceLine({
id: '3',
invoicedQuantity: '5',
lineExtensionAmount: '12000.00',
item: item3,
price: price3,
} as any);
invoice.addInvoiceLine(invoiceLine3);
// Calculate totals
const lineExtensionAmount = 8000.00 + 12000.00 + 12000.00; // 32000.00
const taxRate = 0.10; // 10%
const taxAmount = (lineExtensionAmount * taxRate).toFixed(2); // 3200.00
const payableAmount = (lineExtensionAmount + parseFloat(taxAmount)).toFixed(2); // 35200.00
// Tax category for totals
const taxCategory = new TaxCategory({
id: 'S',
percent: '10.00',
taxScheme: taxScheme,
});
// Tax subtotal
const taxSubtotal = new TaxSubtotal({
taxableAmount: lineExtensionAmount.toFixed(2),
taxAmount: taxAmount,
taxCategory: taxCategory,
});
// Tax total
const taxTotal = new TaxTotal({
taxAmount: taxAmount,
taxSubtotals: [taxSubtotal],
});
invoice.addTaxTotal(taxTotal);
// Legal monetary total
const legalMonetaryTotal = new LegalMonetaryTotal({
lineExtensionAmount: lineExtensionAmount.toFixed(2),
taxExclusiveAmount: lineExtensionAmount.toFixed(2),
taxInclusiveAmount: payableAmount,
payableAmount: payableAmount,
});
invoice.setLegalMonetaryTotal(legalMonetaryTotal);
// Set line count
invoice.setLineCountNumeric('3');
// Generate XML
const xml = invoice.getXml(true);
console.log(xml);
// Save to file
import * as fs from 'fs';
fs.writeFileSync('invoice-INV-2026-001.xml', xml);
console.log('Invoice saved to invoice-INV-2026-001.xml');
Invoice Structure Overview
A complete UBL 2.1 invoice includes the following major components:- Header
- Parties
- Delivery
- Payment
- Lines
- Totals
Basic invoice identification and metadata:
- Invoice ID and issue date/time
- Invoice type code
- Currency code
- Due date
- Notes and references
- Invoice period
Supplier and customer information:
- Party names and identifiers
- Tax registration details
- Legal entity information
- Postal addresses
- Contact information
Delivery details:
- Delivery date
- Delivery location and address
- Delivery terms
- Shipment information
Payment information:
- Payment means (wire transfer, card, etc.)
- Payment terms
- Due date
- Payment account details
Individual invoice lines:
- Line ID and quantity
- Item description
- Price and line extension amount
- Tax category per line
Financial summaries:
- Tax totals with subtotals by rate
- Line extension amount (subtotal)
- Tax exclusive/inclusive amounts
- Payable amount
Key Components Explained
Party Information
Both supplier and customer parties require:const party = new Party({
partyNames: [new PartyName({ name: 'Company Name' })],
postalAddress: postalAddress,
partyTaxSchemes: [taxScheme],
partyLegalEntities: [legalEntity],
contact: contact,
});
Delivery Details
Specify where and when goods/services were delivered:const delivery = new Delivery({
actualDeliveryDate: '2026-02-28',
deliveryLocation: new DeliveryLocation({
address: deliveryAddress,
}),
});
Payment Means
Indicate how payment should be made:const paymentMeans = new PaymentMeans({
paymentMeansCode: '31', // Wire transfer
paymentID: 'INV-2026-001',
});
30- Credit transfer31- Debit transfer48- Bank card49- Direct debit54- Credit card
Invoice Lines
Each line represents an item or service:const invoiceLine = new InvoiceLine({
id: '1', // Line number
invoicedQuantity: '2', // Quantity
lineExtensionAmount: '2000.00', // Total for this line
item: item, // Item details
price: price, // Unit price
});
Invoice Line Amount Calculation:
lineExtensionAmount = invoicedQuantity × price.priceAmountAlways ensure this calculation is correct, as validation may fail if amounts don’t match.Generated XML Structure
The complete invoice generates a UBL 2.1 XML document with this structure:<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" ...>
<!-- Header Information -->
<cbc:UBLVersionID>UBL 2.1</cbc:UBLVersionID>
<cbc:ID>INV-2026-001</cbc:ID>
<cbc:IssueDate>2026-03-06</cbc:IssueDate>
<cbc:IssueTime>14:30:00-05:00</cbc:IssueTime>
<cbc:DueDate>2026-04-05</cbc:DueDate>
<cbc:InvoiceTypeCode>01</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>USD</cbc:DocumentCurrencyCode>
<!-- Invoice Period -->
<cac:InvoicePeriod>
<cbc:StartDate>2026-02-01</cbc:StartDate>
<cbc:EndDate>2026-02-28</cbc:EndDate>
</cac:InvoicePeriod>
<!-- Supplier Party -->
<cac:AccountingSupplierParty>
<cac:Party>...</cac:Party>
</cac:AccountingSupplierParty>
<!-- Customer Party -->
<cac:AccountingCustomerParty>
<cac:Party>...</cac:Party>
</cac:AccountingCustomerParty>
<!-- Delivery -->
<cac:Delivery>...</cac:Delivery>
<!-- Payment Means -->
<cac:PaymentMeans>...</cac:PaymentMeans>
<!-- Tax Total -->
<cac:TaxTotal>...</cac:TaxTotal>
<!-- Legal Monetary Total -->
<cac:LegalMonetaryTotal>...</cac:LegalMonetaryTotal>
<!-- Invoice Lines -->
<cac:InvoiceLine>...</cac:InvoiceLine>
<cac:InvoiceLine>...</cac:InvoiceLine>
<cac:InvoiceLine>...</cac:InvoiceLine>
</Invoice>
Financial Summary
For this example invoice:| Description | Amount |
|---|---|
| Line 1: Software Development (160 hrs × $5,000) | $8,000.00 |
| Line 2: Enterprise Server (1 × $12,000) | $12,000.00 |
| Line 3: Software Licenses (5 × $2,400) | $12,000.00 |
| Subtotal | $32,000.00 |
| Tax (10%) | $3,200.00 |
| Total Payable | $35,200.00 |
Best Practices for Production Invoices:
- Always validate party tax IDs and legal entity information
- Include complete contact information for both parties
- Specify delivery dates and locations for goods
- Add clear payment terms and due dates
- Use consistent currency codes throughout
- Include detailed item descriptions
- Ensure all amounts are calculated correctly
- Add meaningful notes for payment instructions
Next Steps
- Start with simpler examples: Basic Invoice
- Learn about tax calculations: Invoice with Tax
- Explore the complete API: API Reference
- Review UBL 2.1 standard: OASIS UBL Documentation