Shop orders become e-invoices automatically

A completed order goes in, a checked XRechnung or ZUGFeRD comes out — with no manual step in the backend.

The shop already knows the whole order: line items, tax rates, shipping, billing address. What it lacks is the format a business customer or a public body has to accept. One trigger on the order status, one call, and the invoice exists as XRechnung or as a ZUGFeRD PDF — for WooCommerce, Shopware, JTL and Magento through their integration pages, for everything else through a workflow or the REST interface.

What comes in

The order with line items, quantities, unit prices and tax rates

Shipping and discount rows, which belong in the invoice as their own line

The billing address and, for business customers, the VAT ID

The order status as the trigger, e.g. “completed”

For public sector buyers: the Leitweg-ID on the customer record

What this solves

01

The trigger sits in the shop, not in a calendar

The invoice is created when the order completes — not in a nightly job whose failure only shows at month end. In WooCommerce, Shopware, JTL and Magento the trigger hangs off the order status.

02

One record, two formats

The same order record yields an XRechnung for the business customer and a ZUGFeRD PDF for everyone else. You do not maintain two invoicing routes side by side.

03

Checked before it leaves the shop

Before generating, the validate endpoint checks the invoice data against the KoSIT rules. If the tax category or the contact is missing, the response names the rule and the field — the order itself is untouched.

04

Credit notes and cancellations belong to the job

A return is not an invoice with a minus in front. The document type credit_note models it and carries the original invoice number as a reference, so the recipient does not book it twice.

One real example

The line item from the recipe “Generate and send a ZUGFeRD PDF”, in the shape an order produces.

json
{
"invoice": {
"items": [
{
"position": 1,
"description": "Beratungsleistung",
"quantity": 10,
"unit": "HUR",
"unitPrice": 150,
"taxRate": 19,
"netAmount": 1500,
"taxAmount": 285,
"grossAmount": 1785
}
],
"taxSummary": [
{
"taxRate": 19,
"netAmount": 1500,
"taxAmount": 285
}
],
"subtotal": 1500,
"total": 1785
}
}

POST /api/v1/invoice/DE/zugferd/generate

10 × 150.00 € make 1,500.00 € net, 19 % make 285.00 € tax, total 1,785.00 €. The response is a Base64-encoded PDF/A-3 with embedded EN 16931 XML: the customer sees a PDF, their system reads the XML.

The full recipe

The endpoints involved

  • Invoice Creator

    POST /api/v1/invoice/{countryCode}/{format}/generate

    Live
  • Validator

    POST /api/v1/invoice/{countryCode}/validate

    Live

Compared to the alternative

The alternative is a shop plugin that builds the invoice itself. Then conformance depends on that plugin's release cadence and stops at the shop boundary — the plugin comparison shows what that means in practice.

Read the comparison

How it runs

  1. 1

    Set the trigger: order status “completed”, in the shop or in the workflow.

  2. 2

    POST /api/v1/invoice/DE/validate with the order data — the run continues only on a clean result.

  3. 3

    POST /api/v1/invoice/DE/xrechnung/generate or .../zugferd/generate, attach the file to the order and send it.

What it costs at this volume

Around 500 invoices per month fit the Starter plan at 23 € per month.

All prices net, plus VAT · 20 % off when billed annually · Free tier without a credit card

All plans

Limits

  • The Shopify app is submitted for Shopify App Store review and not publicly installable yet.
  • Peppol dispatch is not available yet (planned 2027).
  • Master data upkeep — Leitweg-ID, tax categories, VAT ID — stays your job.

Frequently asked questions

Do I need a separate plugin for every shop?

No. WooCommerce, Shopware, JTL and Magento each have an integration page with the route that fits; beyond those a workflow or a call from your shop code is enough. The API is the same in every case.

Does every order count against my quota?

Every generated invoice is one API call. A pure validation generates nothing and is not counted as generation; it still needs a valid key, and with an exhausted quota the API answers 429.

What happens with a return?

You generate a credit note with document type credit_note and a reference to the original invoice number. Amounts stay positive — the document type sets the direction, not the sign.

From order completion to e-invoice — in the same operation.