ZUGFeRD and Factur-X are standardized formats for electronic invoices that combine a PDF document with embedded XML data. They are designed to facilitate the exchange of structured invoice data between businesses and public administrations, ensuring compatibility and compliance with German and European regulations. This hybrid format streamlines the billing process and reduces manual errors by providing easy human readability and machine processability.

Generate PDF/A-3b

TX Text Control provides powerful PDF and document processing libraries to create these documents in the ISO standard PDF/A-3b format.

Learn More

This article shows how to create valid XRechnung and ZUGFeRD invoices with ASP.NET Core C#. The invoice is created with the help MailMerge component and the ZUGFeRD-csharp library.

Creating Valid XRechnung / ZUGFeRD Invoices with ASP.NET Core C#

ZUGFeRD and Factur-X

This article focuses on creating valid PDF/A-3b ZUGFeRD invoices from existing XML data. Whether you use ERP systems or other applications that already generate valid ZUGFeRD XML, or whether you generate the required XML directly from your business objects, at the end of the day you need to produce a valid PDF document with the XML attached.

TX Text Control provides the required functionality to create these documents programmatically. The following code snippet shows how to create a PDF/A-3b document with an embedded ZUGFeRD XML attachment:

using TXTextControl;
SaveSettings saveSettings = new SaveSettings();
var metaData = File.ReadAllText("metadata.xml");
// byte array from the ZUGFeRD XML file
var zugferdXML = File.ReadAllBytes("yourzugferd.xml");
// create a new embedded file
var zugferdInvoice = new EmbeddedFile(
"ZUGFeRD-invoice.xml",
zugferdXML,
metaData);
zugferdInvoice.Description = "ZUGFeRD-invoice";
zugferdInvoice.Relationship = "Alternative";
zugferdInvoice.MIMEType = "application/xml";
zugferdInvoice.LastModificationDate = DateTime.Now;
// set the embedded files
saveSettings.EmbeddedFiles = new EmbeddedFile[] { zugferdInvoice };
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
tx.Text = "Invoice";
// export the PDF
tx.Save("invoice.pdf", StreamType.AdobePDFA, saveSettings);
}
view raw test.cs hosted with ❤ by GitHub

In this code example, the visual version doesn't contain the actual invoice. In your application, the human-readable version would be generated from a template.

Adding XMP Metadata

The yourzugferd.xml file in the code above would be your pre-created ZUGFeRD XML. By adding XMP metadata, ZUGFeRD ensures that both the human-readable PDF and the machine-readable XML data are properly linked and accessible. A typical metadata XML for ZUGFeRD would look like this:

<rdf:Description xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field#"
xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"
xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
xmlns:pdfaType="http://www.aiim.org/pdfa/ns/type#"
rdf:about=""
>
<pdfaExtension:schemas>
<rdf:Bag>
<rdf:li rdf:parseType="Resource">
<pdfaSchema:schema>ZUGFeRD PDFA Extension Schema</pdfaSchema:schema>
<pdfaSchema:namespaceURI>urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#</pdfaSchema:namespaceURI>
<pdfaSchema:prefix>fx</pdfaSchema:prefix>
<pdfaSchema:property>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:name>DocumentFileName</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
<pdfaProperty:category>external</pdfaProperty:category>
<pdfaProperty:description>name of the embedded XML invoice file</pdfaProperty:description>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:name>DocumentType</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
<pdfaProperty:category>external</pdfaProperty:category>
<pdfaProperty:description>INVOICE</pdfaProperty:description>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:name>Version</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
<pdfaProperty:category>external</pdfaProperty:category>
<pdfaProperty:description>The actual version of the ZUGFeRD data</pdfaProperty:description>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:name>ConformanceLevel</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
<pdfaProperty:category>external</pdfaProperty:category>
<pdfaProperty:description>The conformance level of the ZUGFeRD data</pdfaProperty:description>
</rdf:li>
</rdf:Seq>
</pdfaSchema:property>
</rdf:li>
</rdf:Bag>
</pdfaExtension:schemas>
</rdf:Description>
<rdf:Description xmlns:fx="urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#"
fx:ConformanceLevel="EN 16931"
fx:DocumentFileName="zugferd-invoice.xml"
fx:DocumentType="INVOICE"
fx:Version="2p0"
rdf:about=""/>
view raw metadata.xml hosted with ❤ by GitHub

When opening in Adobe Acrobat Reader, the ZUGFeRD XML data is displayed in the attachments panel:

Creating ZUGFeRD documents with TX Text Control

The XMP metadata can be viewed in the document properties:

Creating ZUGFeRD documents with TX Text Control

Conclusion

Creating ZUGFeRD and Factur-X invoices is a common requirement for many businesses. TX Text Control provides the required functionality to create these documents programmatically. The PDF/A-3b format ensures that the document is compliant with the ISO standard for long-term archiving and the ZUGFeRD XML data is properly linked and accessible.