> ## Documentation Index
> Fetch the complete documentation index at: https://docs.invopop.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Chargebee in Germany

> Generate ZUGFeRD and XRechnung e-invoices from Chargebee for German customers

Germany supports two structured e-invoicing formats: **ZUGFeRD** and **XRechnung**. Both are valid and supported by Invopop, but they serve different purposes and have different requirements.

* **ZUGFeRD** is the most common choice for B2B invoicing. It has fewer validation constraints, which is why we always recommend embedding the XML inside a PDF — your customer receives a standard-looking PDF that also contains a machine-readable file. No per-customer setup is required.
* **XRechnung** is primarily used for B2G invoicing (invoicing public authorities). It has stricter validations and more required fields, but if your customers require it, Invopop fully supports it.

This guide assumes you have already connected the Chargebee app and completed the general setup — see the [Chargebee overview](/guides/chargebee) first if you haven't.

**Required apps:** [UN/CEFACT CII](/apps/uncefact-cii)

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/WJcWJqBiA-Q" title="Chargebee + Invopop | E-invoicing in Germany" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen loading="lazy" />

## Using Chargebee's email delivery

For Invopop to update the invoice in Chargebee and trigger Chargebee's own email delivery to your customer, you will need a **Full Access API key**. Beyond that, the following conditions must be met in Chargebee — if any of these are not in place, Chargebee will not forward the generated PDF (or XML, in the case of XRechnung) to your customer:

1. The `SEND_EINVOICE_NOTIFICATION` feature flag must be enabled on your Chargebee site. Contact your Chargebee representative to enable this.
2. The `cf_invopop_include` custom field must be present and set to `true` on each customer you want to process.
3. Invoice and credit note email notifications must be enabled on your Chargebee site.

## Workflows

<Tabs>
  <Tab title="ZUGFeRD (B2B)">
    <Card title="Chargebee ZUGFeRD" icon="code-branch" iconType="duotone" href="https://console.invopop.com/redirect/workflows/new?template=chargebee-cb-zugferd" cta="Add to my workspace">
      Syncs with Chargebee, downloads the Chargebee PDF, generates a ZUGFeRD XML, and embeds both into a single hybrid PDF.
    </Card>

    The ZUGFeRD workflow downloads the existing Chargebee PDF, generates the ZUGFeRD-compliant XML, and embeds the XML into the PDF to produce a single hybrid document. Chargebee then picks up the result and sends it to your customer. No per-customer configuration is required beyond having a valid German supplier set up in Invopop.

    ```json Example Chargebee ZUGFeRD workflow theme={"system"}
    {
        "name": "Chargebee ZUGFeRD invoice",
        "description": "Sync from Chargebee and issue a ZUGFeRD invoice",
        "schema": "bill/invoice",
        "steps": [
            {
                "id": "ff581030-1943-11f0-b031-c71066181289",
                "name": "Import document from Chargebee",
                "provider": "chargebee.import"
            },
            {
                "id": "bd7eb640-abd0-11ef-a013-91c68ca9f44b",
                "name": "Set state",
                "provider": "silo.state",
                "summary": "Set state to `processing`{.state .processing}",
                "config": {
                    "state": "processing"
                }
            },
            {
                "id": "b913e860-1d43-11f1-a00f-9bd9990c5dfa",
                "name": "Download PDF from Chargebee",
                "provider": "chargebee.pdf.download"
            },
            {
                "id": "18910b60-6624-11f0-9087-c716f49f1585",
                "name": "Modify silo entry",
                "provider": "silo.modify",
                "summary": "Add `de-zugferd-v2` addon",
                "config": {
                    "addons": [
                        "de-zugferd-v2"
                    ],
                    "sign": false
                }
            },
            {
                "id": "c37c3860-abd0-11ef-a013-91c68ca9f44b",
                "name": "Sign envelope",
                "provider": "silo.close"
            },
            {
                "id": "3548d720-6623-11f0-b3db-e7255a5da07c",
                "name": "Generate CII document",
                "provider": "cii.generate",
                "summary": "ZUGFeRD v2",
                "config": {
                    "attach_invoice_pdf": false,
                    "doc_type": "zugferd-v2",
                    "validate_cii": true
                }
            },
            {
                "id": "8e665990-81a3-11f0-82cb-9160968ac068",
                "name": "Embed FacturX/ZUGFeRD",
                "provider": "cii.pdf.embed"
            },
            {
                "id": "c6192a60-abd0-11ef-a013-91c68ca9f44b",
                "name": "Set state",
                "provider": "silo.state",
                "summary": "Set state to `sent`{.state .sent}",
                "config": {
                    "state": "sent"
                }
            },
            {
                "id": "553f8c03-c0ff-4de5-9a66-33685b8f9c65",
                "name": "Update Chargebee",
                "provider": "chargebee"
            }
        ],
        "rescue": [
            {
                "id": "c94982c0-abd0-11ef-a013-91c68ca9f44b",
                "name": "Set state",
                "provider": "silo.state",
                "summary": "Set state to `error`{.state .error}",
                "config": {
                    "state": "error"
                }
            },
            {
                "id": "c35d34c0-b7af-11ef-86a5-99a247862412",
                "name": "Update Chargebee",
                "provider": "chargebee"
            }
        ]
    }

    ```
  </Tab>

  <Tab title="XRechnung (B2G)">
    <Card title="Chargebee XRechnung" icon="code-branch" iconType="duotone" href="https://console.invopop.com/redirect/workflows/new?template=chargebee-cb-xrechnung" cta="Add to my workspace">
      Syncs with Chargebee and generates a validated XRechnung CII XML for invoicing German public authorities.
    </Card>

    XRechnung is used for invoicing German public authorities. The template includes a few additional steps compared to ZUGFeRD, each addressing a specific requirement:

    **1. Bank details**

    XRechnung requires bank details to be present on the invoice. Chargebee typically includes this information in its PDF template, but it is not available via the API — so we cannot fetch it automatically. You will need to add your IBAN (and optionally your BIC/SWIFT code) directly into the **Adding bank details** workflow step. The IBAN alone is sufficient.

    **2. Leitweg-ID as the buyer reference (ordering code)**

    Some German public sector customers require a **Leitweg-ID** to be present on the invoice as the buyer reference. This is typically entered as the PO number on the subscription in Chargebee. However, XRechnung expects this value in the buyer reference field, which Invopop maps to the ordering code — not the purchase order code. The **Map PO to ordering code** step handles this automatically, moving the value from the PO field into the correct place.

    If you prefer not to use the PO number for this, or if you need to set it independently, you can use the `cf_gobl_ordering` custom field instead, providing the value as JSON:

    ```json theme={"system"}
    {"code": "991-12345678-06"}
    ```

    **3. Customer inbox (delivery routing)**

    Each public authority customer must have either a Peppol inbox or an email address configured so the invoice can be routed correctly. You can set these via custom fields on the customer in Chargebee:

    | Field                      | Metadata key                 | Custom field key                | Example                       |
    | -------------------------- | ---------------------------- | ------------------------------- | ----------------------------- |
    | Leitweg-ID (Peppol inbox)  | `gobl-customer-inbox-peppol` | `cf_gobl_customer_inbox_peppol` | `0204:991-12345678-06`        |
    | E-invoice email            | `gobl-customer-inbox-email`  | `cf_gobl_customer_inbox_email`  | `einvoice@behoerde.de`        |
    | Leitweg-ID (ordering code) | `gobl-ordering`              | `cf_gobl_ordering`              | `{"code": "991-12345678-06"}` |

    <Tip>
      Use Chargebee's [bulk operations](https://www.chargebee.com/docs/2.0/bulk-operations.html) to back-populate the inbox and ordering code fields across all your public sector customers before going live.
    </Tip>

    <Note>
      The **Adding bank details** step includes placeholder `bic` and `iban` fields that you must fill in with your own banking details. Note that Chargebee typically includes bank details directly in their PDF template, meaning this information is not available via the API for us to fetch automatically. As a result, bank details need to be added manually to the workflow step. If you don't need to include payment instructions in your invoices, you can remove this step entirely.
    </Note>

    <Note>
      The **Map PO to ordering code** step maps the first purchase order code from Chargebee into the `ordering.code` field that XRechnung requires as a buyer reference. This is particularly relevant when invoicing public entities (B2G), where a Leitweg-ID or PO number is mandatory. If the invoice has no purchase order code, the step is safely skipped. If you are not invoicing public entities and do not use ordering references, you can remove this step.
    </Note>

    ```json Example Chargebee XRechnung workflow theme={"system"}
    {
        "name": "Chargebee XRechnung invoice",
        "description": "Sync from Chargebee and issue an XRechnung invoice",
        "schema": "bill/invoice",
        "steps": [
            {
                "id": "ff581030-1943-11f0-b031-c71066181289",
                "name": "Import document from Chargebee",
                "provider": "chargebee.import"
            },
            {
                "id": "bd7eb640-abd0-11ef-a013-91c68ca9f44b",
                "name": "Set state",
                "provider": "silo.state",
                "summary": "Set state to `processing`{.state .processing}",
                "config": {
                    "state": "processing"
                }
            },
            {
                "id": "7dad54c0-154a-11f0-8028-c1ed648b57b5",
                "name": "Add bank details",
                "provider": "silo.modify",
                "notes": "Normalizes the payment key to SEPA credit transfer format",
                "summary": "Add bank details",
                "config": {
                    "allow_invalid_json": false,
                    "data": {
                        "doc": {
                            "payment": {
                                "instructions": {
                                    "credit_transfer": [
                                        {
                                            "bic": "",
                                            "iban": ""
                                        }
                                    ],
                                    "key": "credit-transfer"
                                }
                            }
                        }
                    },
                    "expr": "(doc?.payment?.instructions == nil || doc?.payment?.instructions?.key == \"credit-transfer\")\n&& doc?.payment?.terms?.due_dates != nil",
                    "merge_type": "application/merge-patch+json",
                    "sign": false
                }
            },
            {
                "id": "a3f12340-1d47-11f1-9c3e-4b2819e7f3a0",
                "name": "Map PO to ordering code",
                "provider": "silo.modify",
                "summary": "Map PO to ordering code",
                "config": {
                    "jq": "if (.ordering.code // null) == null and .ordering.purchases?[0]?.code != null then .ordering.code = .ordering.purchases[0].code else . end",
                    "merge_type": "application/jq",
                    "scope": "doc",
                    "sign": false
                }
            },
            {
                "id": "18910b60-6624-11f0-9087-c716f49f1585",
                "name": "Modify silo entry",
                "provider": "silo.modify",
                "summary": "Add `de-xrechnung-v3` addon",
                "config": {
                    "addons": [
                        "de-xrechnung-v3"
                    ],
                    "sign": false
                }
            },
            {
                "id": "c37c3860-abd0-11ef-a013-91c68ca9f44b",
                "name": "Sign envelope",
                "provider": "silo.close"
            },
            {
                "id": "3548d720-6623-11f0-b3db-e7255a5da07c",
                "name": "Generate CII document",
                "provider": "cii.generate",
                "summary": "XRechnung CII v3",
                "config": {
                    "doc_type": "xrechnung-v3",
                    "validate_cii": true
                }
            },
            {
                "id": "c6192a60-abd0-11ef-a013-91c68ca9f44b",
                "name": "Set state",
                "provider": "silo.state",
                "summary": "Set state to `sent`{.state .sent}",
                "config": {
                    "state": "sent"
                }
            },
            {
                "id": "553f8c03-c0ff-4de5-9a66-33685b8f9c65",
                "name": "Update Chargebee",
                "provider": "chargebee"
            }
        ],
        "rescue": [
            {
                "id": "c94982c0-abd0-11ef-a013-91c68ca9f44b",
                "name": "Set state",
                "provider": "silo.state",
                "summary": "Set state to `error`{.state .error}",
                "config": {
                    "state": "error"
                }
            },
            {
                "id": "c35d34c0-b7af-11ef-86a5-99a247862412",
                "name": "Update Chargebee",
                "provider": "chargebee"
            }
        ]
    }

    ```
  </Tab>
</Tabs>

<Note>
  The metadata keys listed above follow the Chargebee metadata format (hyphens, no `cf_` prefix). If you prefer to use custom fields instead, replace hyphens with underscores and add the `cf_` prefix. See [Custom fields & metadata](/guides/chargebee#custom-fields-metadata) for details.
</Note>

## FAQ

<AccordionGroup>
  <Accordion title="How do I configure my workspace for German invoicing?">
    Pick a format based on the recipient: XRechnung (UBL or CII) for B2G via Peppol, ZUGFeRD/Factur-X for B2B where a human-readable PDF is also wanted. Both are EN 16931-compliant — Invopop generates either from the same GOBL invoice.
  </Accordion>

  <Accordion title="What's the workflow for issuing Peppol invoices in Germany?">
    Generate a GOBL invoice with the `de-xrechnung-v3` addon, then run the Peppol Send workflow. Invopop emits XRechnung (UBL or CII per recipient preference), looks up the recipient's Access Point, and delivers via Peppol.
  </Accordion>

  <Accordion title="Which XRechnung syntax should I choose, UBL or CII?">
    Both syntaxes are equally valid and contain the same information, so in the majority of cases the choice has no consequences.

    If you plan on sending invoices through the Peppol network, we recommend using UBL as it is the supported format. If you plan on also issuing invoices in ZUGFeRD or Factur-X, it might be more convenient to use CII, as it is the syntax also supported by ZUGFeRD and Factur-X.
  </Accordion>

  <Accordion title="How can I view an XML attached to a PDF?">
    For ZUGFeRD PDFs, the XML file is embedded within the PDF itself. To extract and view it, you can use the `Attachments` section in Adobe Acrobat Reader.

    Alternatively, you can use specialized tools like the [SysTools PDF Extractor](https://www.systoolsgroup.com/pdf/extractor/) to extract the XML file.
  </Accordion>

  <Accordion title="Where do I find Germany-specific GOBL documentation?">
    See the [Germany tax regime in GOBL](https://docs.gobl.org/regimes/de) for tax categories and identifiers. The XRechnung mapping lives in [`de-xrechnung-v3`](https://docs.gobl.org/addons/de-xrechnung-v3); ZUGFeRD/Factur-X share the EN 16931 CII profile.
  </Accordion>

  <Accordion title="What should we do if the customer doesn't belong to the Peppol network?">
    In countries where Peppol is the standard but not mandatory, you may still need to issue an e-invoice when the recipient isn't on the network. Both parties can agree on an alternative transfer method, but the invoice must still be EN16931 compliant.

    Recommended approach:

    * Set up a separate workflow that generates the XML without the send-Peppol-document step
    * Or reuse your existing workflow without the customer Peppol ID — the send step is automatically skipped
    * Fetch the generated XML and deliver it through the agreed channel, typically email
  </Accordion>

  <Accordion title="How do I handle B2C invoices in Peppol?">
    B2C invoices typically lack the structured customer information required for Peppol delivery, and most consumers don't have inboxes. Use a conditional workflow:

    1. Add an **If/Else** step that checks for a customer inbox using `count(customer.inboxes, true) > 0`.
    2. On the `false` branch, generate a PDF and email it to the customer, then stop the flow.

    This routes B2B invoices through Peppol while keeping a smooth path for consumers.
  </Accordion>

  <Accordion title="How do I handle 'Receiver Not Found' errors?">
    If a job fails with `KO` and `receiver not found in the peppol network`, treat it like an invalid email address — the recipient simply isn't reachable on Peppol. Add the **Lookup Participant ID** step (ideally in a separate validation workflow run against customer data) so you catch missing IDs before generating the invoice.
  </Accordion>

  <Accordion title="Should I set the `$regime` field when using Peppol?">
    No. The regime is automatically derived from the supplier's settings, which is the recommended approach for Peppol — leave it unset on the document.
  </Accordion>

  <Accordion title="Where do I find Peppol GOBL documentation?">
    See the [`oasis-ubl-v2`](https://docs.gobl.org/addons/oasis-ubl-v2) addon and the [Peppol app reference](/apps/peppol) for required fields, supported document types, and Participant ID schemes.
  </Accordion>
</AccordionGroup>

More available in our [Germany FAQ](/faq/germany) section

***

<Card title="Participate in our community" icon="forumbee" href="https://community.invopop.com" arrow="true" horizontal>
  Ask and answer questions about your Chargebee integration →
</Card>
