Skip to main content
Complyance is Officially Listed as a UAE Approved Accredited Service Provider
Create ZUGFeRD Invoice: Step-by-Step Guide

Create ZUGFeRD Invoice: Step-by-Step Guide

Swathy
Published on Jul 23, 2026
Create ZUGFeRD Invoice: Step-by-Step Guide

You send a PDF invoice. Your customer downloads it. Someone on their team types every line item into their accounting system manually. A digit gets transposed. The payment gets delayed.

A ZUGFeRD invoice solves this. It bundles a human-readable PDF with machine-readable XML into a single file. Your customer sees the invoice exactly as before. Their system extracts every data point automatically, with no manual entry and no transcription errors.

This guide walks you through how to create a ZUGFeRD invoice from scratch — profile selection through validation — in five concrete steps.

Key Takeaways:
- A ZUGFeRD invoice = PDF/A-3 container + embedded CII XML attachment.
- Six profiles exist — "EN 16931" covers the German e-invoicing mandate for most B2B cases.
- Creation paths: manual (open source), accounting software, or API.
- Validation is non-negotiable — invalid files get rejected and delay payments.
- The Complyance API handles the entire pipeline in a single API call.

Prerequisites: What You Need Before You Start

1. Pick the right profile

ZUGFeRD offers six profiles with varying levels of detail. For German e-invoicing compliance, you need at least the "EN 16931" profile.

2. Choose your creation method

You can generate ZUGFeRD invoices manually with open-source libraries, through accounting software with built-in export, or via a dedicated API.

3. Prepare your invoice data per EN 16931

The European standard EN 16931 defines every mandatory field a compliant e-invoice must contain.

Pro Tip: Map your existing invoice template fields to EN 16931 requirements before touching any code.
🖼️ Visual placeholder: Numbered steps infographic (1–5): Choose EN 16931 profile → Prepare invoice data per EN 16931 → Generate CII XML → Embed XML into PDF/A-3 as factur-x.xml → Validate (schema + Schematron + PDF/A-3).

How to Create a ZUGFeRD Invoice in 5 Steps

Step 1: Choose the Right ZUGFeRD Profile

ProfileWhat It IncludesBest For
MinimumBasic header data onlyInternal archival, supplier-side only
Basic WLExtended header data without line itemsInternal archival
BasicFull line-item detailStandard B2B invoices
EN 16931Complete EN 16931 implementationRecommended for German e-invoicing mandate
ExtendedAdditional fields beyond the standardIndustry-specific requirements
XRechnungXRechnung-profile XML embedded in PDF/A-3B2G invoicing with human-readable layer
Important: MINIMUM and BASIC WL are for internal use only. They do not satisfy the German e-invoicing mandate.

The bottom line: For German B2B compliance, choose EN 16931.

Step 2: Prepare Your Invoice Data (Mandatory Fields per EN 16931)

Invoice Header:

  • Invoice number (unique, sequential)
  • Invoice issue date
  • Payment terms and due date
  • Currency code (e.g., EUR)
  • Invoice type code (e.g., 380 for commercial invoice)

Seller Information:

  • Seller name and postal address
  • VAT identification number
  • Tax registration number or commercial register entry

Buyer Information:

  • Buyer name and postal address
  • Leitweg-ID (mandatory for German public sector recipients)

Line Items (per invoice line):

  • Line item number
  • Item description
  • Quantity and unit of measure
  • Net unit price
  • Tax category and tax rate
  • Line item net amount

Document Totals:

  • Total net amount
  • Total tax amount
  • Total gross amount (amount due)

Step 3: Generate the CII XML

XML
<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice
  xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
  xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
  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:2p1:en16931</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>

  <rsm:ExchangedDocument>
    <ram:ID>INV-2026-001234</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20260421</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>

  <rsm:SupplyChainTradeTransaction>
    <!-- Seller, Buyer, Line Items, Totals -->
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

Critical detail: The GuidelineSpecifiedDocumentContextParameter must exactly match your chosen profile.

Step 4: Embed the XML Into a PDF/A-3 Container

Three things must happen:

  1. Create or convert to PDF/A-3. Standard PDF or PDF/A-1 and PDF/A-2 will not work.
  2. Embed the XML with the correct filename. The CII XML must be attached as factur-x.xml.
  3. Set XMP metadata. The PDF metadata must declare the ZUGFeRD version and profile.
Pro Tip: PDF/A-3 compliance fails most often because of fonts. Every font used in the PDF must be fully embedded.

Step 5: Validate the Output

Validation LayerWhat Gets CheckedCommon Failures
Schema validationXML structure against the CII schemaMissing elements, wrong element order
Schematron rulesBusiness rules per EN 16931Tax calculation errors
PDF/A-3 complianceArchival standard of the PDF containerFonts not embedded

Recommended validation tools:

  • Complyance Validator
  • KoSIT Validator (open-source)
  • ZUGFeRD Community Validator at ferd-net.de
Non-negotiable: Never send a ZUGFeRD invoice without validating it first.

Method Comparison: Manual vs. Software vs. API

CriteriaManual (Open Source)Accounting SoftwareAPI (Complyance)
Setup effortHigh — requires XML expertiseMedium — one-time configurationMedium — developer integration
Ongoing effortHighLowVery low
ScalabilityNot scalableLimitedUnlimited
Error rateHighLowVery low
CostFreeFrom \~10 EUR/monthUsage-based
Best forSolo developers, testingSMBs with 10-500 invoices/monthBusinesses with 100+ invoices/month

Code Example: Create a ZUGFeRD Invoice With the Complyance API

PYTHON
import requests

API_KEY = "your_api_key"
BASE_URL = "https://api.complyance.io/v1"

invoice_data = {
    "profile": "EN16931",
    "invoice_number": "INV-2026-001234",
    "invoice_date": "2026-04-21",
    "currency": "EUR",
    "seller": {
        "name": "Muster GmbH",
        "address": {"street": "Musterstrasse 1", "city": "Berlin", "postal_code": "10115", "country": "DE"},
        "vat_id": "DE123456789"
    },
    "buyer": {
        "name": "Example Corp",
        "address": {"street": "Example Road 42", "city": "Munich", "postal_code": "80331", "country": "DE"},
        "vat_id": "DE987654321"
    },
    "line_items": [
        {"description": "IT Consulting - April 2026", "quantity": 40, "unit": "HUR", "unit_price": 150.00, "tax_rate": 19.0, "tax_category": "S"}
    ],
    "payment": {"means_code": "58", "iban": "DE89370400440532013000", "due_date": "2026-05-21"}
}

response = requests.post(
    f"{BASE_URL}/zugferd/create",
    json=invoice_data,
    headers={"Authorization": f"Bearer {API_KEY}"}
)

if response.status_code == 200:
    with open("invoice_INV-2026-001234.pdf", "wb") as f:
        f.write(response.content)
    print("ZUGFeRD invoice created successfully.")

Tools for ZUGFeRD Invoice Creation

Online platforms and APIs:

Accounting software with ZUGFeRD export:

  • lexoffice, sevdesk, DATEV, SAP (select modules)

Open-source libraries:

  • Mustang (Java), Factur-X (Python), ZUGFeRD-csharp (.NET)

Common Errors: Do's and Don'ts

DoDon't
Use PDF/A-3 as the container formatUse PDF/A-1, PDF/A-2, or standard PDF
Name the XML attachment factur-x.xmlUse arbitrary filenames
Fill every mandatory field per EN 16931Confuse optional fields with required ones
Calculate tax amounts programmaticallyRound taxes manually, then hard-code them
Validate before sendingAssume it will "probably work"
Set the profile identifier to match your actual profileCopy profile IDs from older ZUGFeRD versions
Fully embed all fonts in the PDFReference system fonts
Pro Tip: The single most frequent production error? Rounding discrepancies in tax calculations. Calculate each line item net amount first, sum those amounts, then calculate tax on the sum.

Next Steps

Creating a ZUGFeRD invoice is a structured, repeatable process. Choose your profile. Prepare your data. Generate the XML. Embed it in PDF/A-3. Validate. Done.

The real leverage comes from automation. If you send more than a handful of invoices per month, an API-based approach eliminates manual steps and scales without friction.

Share

Frequently Asked Questions

Five steps: choose the right profile, prepare your invoice data per EN 16931, generate the CII XML, embed the XML into a PDF/A-3 container, and validate the output.

The ZUGFeRD standard itself is open and free. Free options include Mustang (Java) and Factur-X (Python).

For occasional invoices, a free online tool works. For regular invoicing, accounting software with ZUGFeRD export (lexoffice, sevdesk, DATEV). For automated, high-volume processing, an API like Complyance.

Both comply with EN 16931. ZUGFeRD is hybrid — PDF plus embedded XML. XRechnung is pure XML. XRechnung is mandatory for German public sector.

For the German e-invoicing mandate, you need at least the EN 16931 profile.

Technically yes, but it is not straightforward. Generating ZUGFeRD invoices directly from your source system is faster, cheaper, and more reliable.

Yes. Without validation, you risk sending files that get rejected.

Use ZUGFeRD 2.3.3 or later.

About the Author

Swathy

Swathy

Content Marketer

I’m a Content Marketer at Complyance, focused on e-invoicing. Over the years, I’ve created a wide range of content, including blog posts, whitepapers, and product guides, which have supported Complyance’s growth across markets such as the UAE and EU regions. My goal is to deliver content that is comprehensive, clear, accurate, and easy to understand, no matter how complex the topic.

Related Posts

Complyance Logo

One API for Global E-invoicing