How to create compliant e-invoices with ColdFusion and ColdBox
Akitogo Team, 26 Nov 2025
Legal Requirements for E-Invoicing
Starting January 1, 2025, all B2B transactions in Germany require the ability to receive electronic invoices in structured formats. From 2027 onwards, businesses must also be able to send e-invoices. Similar requirements exist across the European Union under the EN 16931 standard.
Who is affected?
- All businesses operating in Germany conducting B2B transactions
- Companies invoicing public sector entities (B2G) - already mandatory
- Businesses trading with partners in EU countries requiring Factur-X/ZUGFeRD
- Small businesses and freelancers are included (with some transitional periods)
The ZUGFeRD standard (and its French counterpart Factur-X) embeds machine-readable XML data into PDF invoices. This hybrid approach ensures invoices are both human-readable (PDF) and machine-processable (XML) in a single file.
Getting Started with cbZUGFeRD
The cbZUGFeRD module wraps the Mustang Project Java library, providing a CFML API for generating ZUGFeRD-compliant invoices. Installation via CommandBox:
box install cbzugferd
How to use
// Get the factory singleton
var factory = getInstance('MustangFactory@cbzugferd');
// or iject as property
// Create your invoice
var invoice = factory.createInvoice();
// Set up sender (your company)
var sender = factory.createTradeParty(
"Your Company GmbH",
"Main Street 1",
"12345",
"Berlin",
"DE"
);
sender.addVATID("DE123456789");
// Add bank details
var bankDetails = factory.createBankDetails(
"DE89370400440532013000",
"COBADEFFXXX"
);
sender.addBankDetails(bankDetails);
// Create recipient
var recipient = factory.createTradeParty(
"Customer Inc",
"Customer Road 5",
"54321",
"Munich",
"DE"
);
// Configure invoice
invoice.setNumber("INV-2024-001")
.setIssueDate(now())
.setDueDate(dateAdd("d", 30, now()))
.setSender(sender)
.setRecipient(recipient);
// Add line items
var product = factory.createProduct(
"Consulting Services",
"Professional IT Consulting",
"HUR", // Hours
19 // VAT percentage
);
var item = factory.createItem(product, 150.00, 8); // 8 hours at 150 EUR
invoice.addItem(item);
Regulatory Compliance
German law requires certain information on invoices. The Mustang library supports regulatory notes with the correct subject codes for validation:
// Add required regulatory information
invoice.addRegulatoryNote("Geschäftsführer: Max Mustermann");
invoice.addRegulatoryNote("Handelsregister: Amtsgericht Berlin HRB 12345");
Generating the PDF with Embedded Fonts
For PDF/A compliance, fonts must be properly embedded. Use cfdocument with the fontdirectory attribute pointing to a folder containing TTF fonts:
// Create PDF with embedded fonts for PDF/A compliance
cfdocument(
format="PDF"
fontembed="true"
fontdirectory="/System/Library/Fonts/Supplemental/"
type="modern"
name="pdfContent"
) {
writeOutput('<html><head>');
writeOutput('<style>body { font-family: Arial, sans-serif; }</style>');
writeOutput('</head><body>');
writeOutput('<h1>Invoice</h1>...');
writeOutput('</body></html>');
}
fileWrite("/path/to/invoice.pdf", pdfContent);
Note: On macOS, TTF fonts are located in /System/Library/Fonts/Supplemental/. On Linux servers, use /usr/share/fonts/truetype/. On Windows, use C:/Windows/Fonts/.
Note: If you want to skip the font embedding, the ignorePDFAErrors() method allows processing of regular PDFs.
Generating the Final PDF
Once your invoice data is prepared, it takes your existing PDF and embeds the XML invoice data:
// Create exporter and embed ZUGFeRD data
var exporter = factory.createExporterFromA1()
.ignorePDFAErrors() // remove if font is embedded properly
.load("/path/to/your/invoice.pdf")
.setProducer("Your Application")
.setCreator("cbZUGFeRD");
exporter.setTransaction(invoice);
exporter.export("/path/to/zugferd-invoice.pdf");
Validation
Validate your generated invoices before sending them to customers. Here are a few online validators you can try: