# Creating ZUGFeRD Compliant PDF Invoices in C#

> ZUGFeRD / Factur-X documents can be created and extracted using TX Text Control X19. This article shows how to create a valid ZUGFeRD compliant invoice PDF document from scratch.

- **Author:** Bjoern Meyer
- **Published:** 2021-02-03
- **Modified:** 2025-11-16
- **Description:** ZUGFeRD / Factur-X documents can be created and extracted using TX Text Control X19. This article shows how to create a valid ZUGFeRD compliant invoice PDF document from scratch.
- **4 min read** (772 words)
- **Tags:**
  - ASP.NET
  - DS Server
  - Electronic Invoice
  - PDF
  - Windows Forms
  - WPF
  - Zugferd
- **Web URL:** https://www.textcontrol.com/blog/2021/02/03/creating-zugferd-compliant-pdf-invoices-in-csharp/
- **LLMs URL:** https://www.textcontrol.com/blog/2021/02/03/creating-zugferd-compliant-pdf-invoices-in-csharp/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2021/02/03/creating-zugferd-compliant-pdf-invoices-in-csharp/llms-full.txt
- **GitHub Repository:** https://github.com/TextControl/TextControl.WindowsForms.Zugferd

---

The [ZUGFeRD](https://www.ferd-net.de/) / Factur-X standard is a hybrid electronic invoice format that consists of two parts:

- A PDF visual, human-readable representation of the invoice.
- An XML file that contains invoice data in a structured form that can be processed automatically.

TX Text Control X19 supports the embedding of attachments in PDF/A-3b documents and also the extraction of an attachment. This sample shows 3 steps of the creation process using TX Text Control:

- Creating the required ZUGFeRD XML.
- Creating the visual representation.
- Export both to a valid PDF/A-3b document.

### Embedding Existing XML

In case, you already have a valid XML representation created by a third-party tool or an ERP system, you can easily embed this XML to a PDF document using the Save method by specifying an EmbeddedFile in the *SaveSettings*.

```
string xmlZugferd = ""; // your XML
string metaData = ""; // required RDF meta data

TXTextControl.SaveSettings saveSettings = new TXTextControl.SaveSettings();

// create a new embedded file
var zugferdInvoice = new TXTextControl.EmbeddedFile(
  "ZUGFeRD-invoice.xml",
  Encoding.UTF8.GetBytes(xmlZugferd),
  metaData);

zugferdInvoice.Description = "ZUGFeRD-invoice";
zugferdInvoice.Relationship = "Alternative";
zugferdInvoice.MIMEType = "application/xml";
zugferdInvoice.LastModificationDate = DateTime.Now;

// set the embedded files
saveSettings.EmbeddedFiles = new TXTextControl.EmbeddedFile[] {
  new TXTextControl.EmbeddedFile(
     "ZUGFeRD-invoice.xml",
     Encoding.UTF8.GetBytes(xmlZugferd),
     metadata) };

// export the PDF
textControl1.Save("test.pdf", TXTextControl.StreamType.AdobePDFA, saveSettings);
```

### Create ZUGFeRD XML

For demo purposes, we implemented the helper class *TXTextControl.DocumentServer.PDF.Zugferd.Invoice* that creates a valid ZUGFeRD XML. The method *CreateSampleInvoice* returns the required XML that is embedded into the created PDF document.

```
private Invoice CreateSampleInvoice() {
   // new zugferd invoice
   Invoice invoice = new Invoice("A12345", DateTime.Now, CurrencyCode.USD);

   invoice.Type = InvoiceType.Invoice;
   invoice.Profile = Profile.Comfort;

   // buyer
   invoice.Buyer = new TradeParty {
      ID = "TX_1",
      Name = "Text Control GmbH",
      ContactName = "Peter Paulsen",
      City = "Bremen",
      Postcode = "28217",
      Country = CountryCode.DE,
      Street = "Überseetor 18"
   };

   // seller
   invoice.Seller = new TradeParty {
      ID = "TX_2",
      Name = "Text Control, LLC",
      ContactName = "Jack Jackson",
      City = "Charlotte, NC",
      Postcode = "28210",
      Country = CountryCode.US,
      Street = "6926 Shannon Willow Rd, Suite 400",
   };

   // add tax id's
   invoice.Seller.SpecifiedTaxRegistrations.Add(
      new TaxID() { ID = "US12367623", Scheme = TaxScheme.VA });

   // add products
   List<LineItem> lineItems = new List<LineItem>();

   lineItems.Add(new LineItem() {
      Price = 200,
      ProductID = "A123",
      Name = "Product A",
      Quantity = 5,
      Total = 1000,
      UnitCode = QuantityCodes.C62
   });

   // add line items to invoice
   foreach (LineItem item in lineItems)
      invoice.LineItems.Add(item);

   // set the total amount
   invoice.TotalAmount = 1000;

   return invoice;
}
```

In the sample application, a very simple template is used to create the visual representation of the invoice:

![ZUGFeRD Template](https://s1-www.textcontrol.com/assets/dist/blog/2021/02/03/a/assets/template.webp "ZUGFeRD Template")

The following code loads the template into a TextControl and uses MailMerge to merge the sample data into the document. The *CreateXml* method of the *Invoice* class returns the valid ZUGFeRD XML. Together with the required meta data, the XML is embedded and exported to a valid PDF/A-3b document.

```
TXTextControl.DocumentServer.MailMerge mm = new TXTextControl.DocumentServer.MailMerge();
mm.TextComponent = textControl1;

textControl1.Load("invoice.tx", TXTextControl.StreamType.InternalUnicodeFormat);

Invoice invoice = CreateSampleInvoice();

// merge data into template
mm.MergeJsonData(JsonConvert.SerializeObject(invoice));

// create the XML
string xmlZugferd = invoice.CreateXml();

// get the required meta data
string metaData = MetaData.GetMetaData();

TXTextControl.SaveSettings saveSettings = new TXTextControl.SaveSettings();

// create a new embedded file
var zugferdInvoice = new TXTextControl.EmbeddedFile(
  "ZUGFeRD-invoice.xml",
  Encoding.UTF8.GetBytes(xmlZugferd),
  metaData);

zugferdInvoice.Description = "ZUGFeRD-invoice";
zugferdInvoice.Relationship = "Alternative";
zugferdInvoice.MIMEType = "application/xml";
zugferdInvoice.LastModificationDate = DateTime.Now;

// set the embedded files
saveSettings.EmbeddedFiles = new TXTextControl.EmbeddedFile[] {
  new TXTextControl.EmbeddedFile(
     "ZUGFeRD-invoice.xml",
     Encoding.UTF8.GetBytes(xmlZugferd),
     metaData) };

// export the PDF
textControl1.Save("test.pdf", TXTextControl.StreamType.AdobePDFA, saveSettings);
```

### The ZUGFeRD XML

The XML document that is embedded in the PDF is listed below:

```
<?xml version="1.0" encoding="utf-8"?>
<rsm:CrossIndustryInvoice xmlns:a="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:10" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:comfort</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>A12345</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20210203</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:IncludedSupplyChainTradeLineItem>
      <ram:AssociatedDocumentLineDocument>
        <ram:LineID>1</ram:LineID>
      </ram:AssociatedDocumentLineDocument>
      <ram:SpecifiedTradeProduct>
        <ram:Name>Product A</ram:Name>
      </ram:SpecifiedTradeProduct>
      <ram:SpecifiedLineTradeAgreement>
        <ram:NetPriceProductTradePrice>
          <ram:ChargeAmount>200</ram:ChargeAmount>
        </ram:NetPriceProductTradePrice>
      </ram:SpecifiedLineTradeAgreement>
      <ram:SpecifiedLineTradeDelivery>
        <ram:BilledQuantity unitCode="C62">5</ram:BilledQuantity>
      </ram:SpecifiedLineTradeDelivery>
      <ram:SpecifiedLineTradeSettlement>
        <ram:ApplicableTradeTax>
          <ram:TypeCode>VAT</ram:TypeCode>
          <ram:CategoryCode>S</ram:CategoryCode>
          <ram:RateApplicablePercent>19</ram:RateApplicablePercent>
        </ram:ApplicableTradeTax>
        <ram:SpecifiedTradeSettlementLineMonetarySummation>
          <ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
        </ram:SpecifiedTradeSettlementLineMonetarySummation>
      </ram:SpecifiedLineTradeSettlement>
    </ram:IncludedSupplyChainTradeLineItem>
    <ram:ApplicableHeaderTradeAgreement>
      <ram:SellerTradeParty>
        <ram:Name>Text Control, LLC</ram:Name>
        <ram:PostalTradeAddress>
          <ram:PostcodeCode>28210</ram:PostcodeCode>
          <ram:LineOne>Jack Jackson</ram:LineOne>
          <ram:LineTwo>6926 Shannon Willow Rd, Suite 400</ram:LineTwo>
          <ram:CityName>Charlotte, NC</ram:CityName>
          <ram:CountryID>US</ram:CountryID>
        </ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration>
          <ram:ID schemeID="VA">US12367623</ram:ID>
        </ram:SpecifiedTaxRegistration>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:Name>Text Control GmbH</ram:Name>
        <ram:PostalTradeAddress>
          <ram:PostcodeCode>28217</ram:PostcodeCode>
          <ram:LineOne>Peter Paulsen</ram:LineOne>
          <ram:LineTwo>Überseetor 18</ram:LineTwo>
          <ram:CityName>Bremen</ram:CityName>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
      </ram:BuyerTradeParty>
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeDelivery>
      <ram:ActualDeliverySupplyChainEvent>
        <ram:OccurrenceDateTime>
          <udt:DateTimeString format="102">20210203</udt:DateTimeString>
        </ram:OccurrenceDateTime>
      </ram:ActualDeliverySupplyChainEvent>
    </ram:ApplicableHeaderTradeDelivery>
    <ram:ApplicableHeaderTradeSettlement>
      <ram:InvoiceCurrencyCode>USD</ram:InvoiceCurrencyCode>
      <ram:ApplicableTradeTax>
        <ram:CalculatedAmount>190.00</ram:CalculatedAmount>
        <ram:TypeCode>VAT</ram:TypeCode>
        <ram:BasisAmount>1000.00</ram:BasisAmount>
        <ram:CategoryCode>S</ram:CategoryCode>
        <ram:RateApplicablePercent>19</ram:RateApplicablePercent>
      </ram:ApplicableTradeTax>
      <ram:SpecifiedTradePaymentTerms>
        <ram:DueDateDateTime>
          <udt:DateTimeString format="102">20210305</udt:DateTimeString>
        </ram:DueDateDateTime>
      </ram:SpecifiedTradePaymentTerms>
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
        <ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>
        <ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>
        <ram:TaxBasisTotalAmount>1000.00</ram:TaxBasisTotalAmount>
        <ram:TaxTotalAmount currencyID="USD">190.00</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>1190.00</ram:GrandTotalAmount>
        <ram:DuePayableAmount>1190.00</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
```

### In Acrobat Reader

When the resulting PDF document is opened in Acrobat Reader, you can check the PDF/A-3b conformance using the *Standards* tab:

![ZUGFeRD Template](https://s1-www.textcontrol.com/assets/dist/blog/2021/02/03/a/assets/adobe1.webp "ZUGFeRD Template")

Additionally, you can verify the attachments:

![ZUGFeRD Template](https://s1-www.textcontrol.com/assets/dist/blog/2021/02/03/a/assets/adobe2.webp "ZUGFeRD Template")

### Validating the Conformance

After validating the ZUGFeRD document using validation services such as the *ZF/FX Validation* (https://www.zugferd-community.net/de/dashboard/validation), you can see that the created document passes all tests:

![ZUGFeRD Template](https://s1-www.textcontrol.com/assets/dist/blog/2021/02/03/a/assets/valid.webp "ZUGFeRD Template")

You can download the sample project from our GitHub repository that contains the ZUGFeRD helper classes to create a valid XML document from scratch.

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [Electronic Invoicing will Become Mandatory in Germany in 2025](https://www.textcontrol.com/blog/2024/04/10/electronic-invoicing-will-become-mandatory-in-germany-in-2025/llms.txt)
- [Extract Text and Data from PDF Documents in C#](https://www.textcontrol.com/blog/2022/06/16/extract-text-and-data-from-pdf-documents-in-csharp/llms.txt)
- [Creating PDF Files using TX Text Control .NET in C#](https://www.textcontrol.com/blog/2022/05/24/creating-pdf-files-using-tx-text-control-dotnet/llms.txt)
- [Generating Interactive PDF Forms by Injecting JavaScript](https://www.textcontrol.com/blog/2022/03/31/generating-interactive-pdf-forms-by-injecting-javascript/llms.txt)
- [Form Field Handling in PDF Documents](https://www.textcontrol.com/blog/2022/01/03/form-field-handling-in-pdf-documents/llms.txt)
- [X19 Sneak Peek: Validating ZUGFeRD / Factur-X Invoices with TX Text Control](https://www.textcontrol.com/blog/2020/11/10/x19-sneak-peek-validating-zugferd-factur-x-invoices-with-tx-text-control/llms.txt)
- [X19 Sneak Peek: Processing AcroForm Fields in Adobe PDF Documents](https://www.textcontrol.com/blog/2020/10/29/sneak-peek-processing-acroform-fields-from-adobe-pdf-documents/llms.txt)
- [Create and Modify Adobe PDF Documents within your .NET Application](https://www.textcontrol.com/blog/2019/05/27/create-and-modify-adobe-pdf-documents/llms.txt)
- [How to create Adobe PDF files in .NET](https://www.textcontrol.com/blog/2018/08/11/how-to-create-pdf-files-in-net/llms.txt)
- [TXTextControl.Markdown.Core 34.1.0-beta: Work with Full Documents, Selection, and SubTextParts](https://www.textcontrol.com/blog/2026/04/14/txtextcontrol-markdown-core-34-1-0-beta-work-with-full-documents-selection-and-subtextparts/llms.txt)
- [TX Spell .NET 11.0 SP1 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2026/04/08/tx-spell-net-11-0-sp1-is-now-available/llms.txt)
- [Why Structured E-Invoices Still Need Tamper Protection using C# and .NET](https://www.textcontrol.com/blog/2026/03/24/why-structured-e-invoices-still-need-tamper-protection-using-csharp-and-dotnet/llms.txt)
- [TX Text Control 34.0 SP2 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2026/02/18/tx-text-control-34-0-sp2-is-now-available/llms.txt)
- [TX Text Control 34.0 SP1 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2025/12/03/tx-text-control-34-0-sp1-is-now-available/llms.txt)
- [Introducing TX Text Control 34.0: Your Next Leap in Document Processing](https://www.textcontrol.com/blog/2025/11/10/introducing-tx-text-control-34-0-your-next-leap-in-document-processing/llms.txt)
- [Extending DS Server with Custom Digital Signature APIs](https://www.textcontrol.com/blog/2025/10/09/extending-ds-server-with-custom-digital-signature-apis/llms.txt)
- [Sneak Peek: TX Text Control 34.0 Coming November 2025](https://www.textcontrol.com/blog/2025/10/02/sneak-peek-tx-text-control-34-0-coming-november-2025/llms.txt)
- [TX Text Control 33.0 SP3 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2025/08/14/tx-text-control-33-0-sp3-is-now-available/llms.txt)
- [TX Text Control 33.0 SP2 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2025/06/18/tx-text-control-33-0-sp2-is-now-available/llms.txt)
- [Document Lifecycle Optimization: Leveraging TX Text Control's Internal Format](https://www.textcontrol.com/blog/2025/05/16/document-lifecycle-optimization-leveraging-tx-text-controls-internal-format/llms.txt)
- [Expert Implementation Services for Legacy System Modernization](https://www.textcontrol.com/blog/2025/05/07/expert-implementation-services-for-legacy-system-modernization/llms.txt)
- [Service Pack Releases: What's New in TX Text Control 33.0 SP1 and 32.0 SP5](https://www.textcontrol.com/blog/2025/05/07/service-pack-releases-whats-new-in-tx-text-control-33-0-sp1-and-32-0-sp5/llms.txt)
- [Top 5 Real-World Applications for TX Text Control Document Processing Libraries](https://www.textcontrol.com/blog/2025/04/01/top-5-real-world-applications-for-tx-text-control-document-processing-libraries/llms.txt)
- [DWX Developer Week Moves to Mannheim - And Text Control Is on Board!](https://www.textcontrol.com/blog/2025/03/19/dwx-developer-week-moves-to-mannheim-and-tx-text-control-is-on-board/llms.txt)
- [The Wait is Over: TX Text Control for Linux is Officially Here](https://www.textcontrol.com/blog/2025/03/12/the-wait-is-over-tx-text-control-for-linux-is-officially-here/llms.txt)
