E-Invoicing: XRechnung, ZUGFeRD and Peppol

Scipio ERP makes, sends, receives and archives electronic invoices to the European standard EN 16931: XRechnung, ZUGFeRD / Factur-X and Peppol BIS Billing 3.0, from the accounting application.

An e-invoice is not a PDF. It is a structured file, an XML document to the European standard EN 16931, that the receiver’s system books without anyone typing the invoice in. Since 1 January 2025 every business in Germany must be able to receive one. From 2027 businesses with more than EUR 800,000 turnover must send their B2B invoices this way, and from 2028 every business must. Belgium requires e-invoices over Peppol since January 2026, and France starts in September 2026; both build on the same standard.

Scipio ERP does all of it from the accounting application: it makes the file for a sales invoice or a credit note, checks it, sends it with the invoice email, keeps the sent file, and records a received e-invoice as a purchase invoice.

Formats#

FormatStandardFileUse it for
XRechnung 3.0 (UBL)EN 16931 with the German rulesXMLGerman public authorities, German businesses
XRechnung 3.0 (CII)EN 16931 with the German rulesXMLThe same, in the CII syntax
ZUGFeRD 2 / Factur-XEN 16931PDF/A-3 with the XML insideBusinesses in Germany and France: one file that a person can read and a system can book
Peppol BIS Billing 3.0EN 16931 with the Peppol rulesXML (UBL)Belgium, the Netherlands, the Nordic countries, Austria and every receiver on the Peppol network
EN 16931 (UBL), EN 16931 (CII)EN 16931XMLReceivers that ask for the plain standard

The files pass the official checks: the KoSIT validator with the XRechnung 3.0.2 configuration and with the Peppol BIS 3.0 configuration, and the Mustang validator with veraPDF for the ZUGFeRD PDF.

Before the first e-invoice#

An e-invoice carries more data than a printed invoice, and the check tells you what is missing. Set these once.

Your company#

  • Address with postal code and city.
  • VAT ID, under the tax authority information of the company party, for example DE123456789. A VAT ID without its country prefix gets the prefix of the tax authority’s country.
  • Tax number (Steuernummer) and commercial register number: party identifications of the types National tax number and Legal registration ID.
  • Bank account: an EFT account of the company with an IBAN. The account number field can hold the IBAN. For invoices in euro the payment means is a SEPA credit transfer.
  • Phone and email: XRechnung needs a contact person with a name, a phone number and an email address.

Open the E-Invoice tab of any sales invoice and follow the link to the e-invoice settings of your company. There you set the default format, the contact person, the bank account that appears on the invoice, your electronic address, and whether your company is a small business (Kleinunternehmer). A Peppol participant ID is an address and a scheme, for example scheme 9930 with your German VAT ID, or 0088 with your GLN.

Your customers#

Each customer has e-invoice settings of their own, on the same page:

  • Format: the file this customer receives.
  • Delivery channel: email attachment, download (you upload the file to the customer’s portal), or Peppol.
  • E-invoice email: the inbox for e-invoices, if it is not the billing email.
  • Buyer reference / Leitweg-ID: German public authorities need it on every invoice.
  • Electronic address and scheme: needed for Peppol. For XRechnung the billing email is used when the field is empty.

Taxes#

Every invoice line needs a VAT rate and a VAT category. The rate comes from the tax lines of the invoice. On a tax rate you can set the category code (S standard, Z zero rated, E exempt, AE reverse charge, K intra-community supply, G export, O not subject to VAT) and an exemption reason with its VATEX code. Without a code Scipio decides:

  • A rate above zero is S.
  • No tax, when your company is a small business, is E with the small-business note (see below).
  • No tax, to a business in another EU country that has a VAT ID, is K.
  • No tax, to a customer outside the EU, is G.
  • Anything else takes the category of einvoice.vat.category.noTax (E by default).

A line without VAT must say why. When the tax rate gives no exemption reason, the e-invoice carries the text and the code of its category:

CategoryText in the e-invoiceCode
KSteuerfreie innergemeinschaftliche LieferungVATEX-EU-IC
GSteuerfreie AusfuhrlieferungVATEX-EU-G
AESteuerschuldnerschaft des LeistungsempfängersVATEX-EU-AE
ONicht steuerbarer UmsatzVATEX-EU-O
ESteuerfreier Umsatznone

The text for E is only a placeholder: the real reason depends on the supply, so the check warns and asks for it. Enter the exact reason on the tax rate, or in einvoice.vat.exemptionReason.noTax when every exempt line has the same one.

Small business (Kleinunternehmer). A company that charges no VAT under § 19 UStG sets Small business in its own e-invoice settings. Every line without VAT is then exempt (E) and carries the note “Als Kleinunternehmer im Sinne von § 19 Abs. 1 UStG wird Umsatzsteuer nicht berechnet”. The company still needs its tax number or VAT ID on the e-invoice.

The texts go into the e-invoice in the language of the user who makes it. Set einvoice.document.locale (for example de) to fix the language of the e-invoice, whatever the language of the screen.

Units#

EN 16931 uses the UN/ECE unit codes: H87 for a piece, KGM for a kilogram, HUR for an hour. The standard units of Scipio carry their code. A line without a unit is sent as a piece.

Send an e-invoice#

  1. Open the invoice and its E-Invoice tab.
  2. Pick the format. The customer’s format is marked and selected.
  3. Read the check. An error says what to complete, for example “The customer has no buyer reference (Leitweg-ID)”.
  4. Download the file, or send the invoice by email.

When the customer has a format and receives by email, Send per email attaches the e-invoice by itself. An XML file goes next to the usual PDF; a ZUGFeRD PDF replaces it. If the e-invoice cannot be made, the email is not sent, and the reasons are shown.

The buyer reference comes from the first of these that is set: the invoice attribute EINV_BUYER_REFERENCE, the order attribute BUYER_REFERENCE, the customer’s setting. Without one, the customer number is used, with a warning, because public authorities reject an invoice without their Leitweg-ID.

A customer return invoice becomes a credit note (type 381) that your company sends, and it names the original invoice. Scipio finds the original through the return and the order; the invoice attribute EINV_PRECEDING_INVOICE overrides it.

The due date and the payment terms go into the file. A cash discount term becomes the #SKONTO# line that XRechnung defines.

EN 16931 calculates the VAT once per rate; Scipio rounds it per line. When the two totals differ by a few cents, the difference goes into the rounding amount, so the amount due stays equal to your receivable, and the check shows a warning. A larger difference stops the export: check the tax rates and the lines.

The sent file is kept#

Once an invoice has left In process, the first e-invoice of each format is stored with the invoice. Every later download and every later email returns that same file, unchanged, as the retention rules for tax records require. The E-Invoice tab lists the stored files. Correct an invoice before you approve it; after that, issue a credit note.

Receive an e-invoice#

Open Accounting › Import/Export › Receive e-invoice.

  1. Organization: the company that received the invoice.
  2. Supplier: leave it empty. Scipio finds the supplier by the VAT ID in the file, then by the registration or tax number, then by the electronic address.
  3. File: an XRechnung, any EN 16931 UBL or CII file, or a ZUGFeRD / Factur-X PDF.

The result is a purchase invoice in status In process: the lines with their allowances and charges, the VAT per rate and the rounding, with the supplier’s invoice number as the reference number. A credit note arrives with negative amounts. The same invoice of the same supplier is refused a second time.

The original file stays with the purchase invoice. Its E-Invoice tab downloads it, or shows it as a readable page (the XRechnung visualization), which opens in a sandbox because the file came from outside. The import warns when the amounts in the file do not add up, when the file says the invoice is already paid, and when the recipient VAT ID belongs to another organization.

Do it with an agent#

The invoice tool of the accounting MCP server has three actions for e-invoices:

ActionWhat it does
einvoice_checkSays whether the e-invoice of an invoice can be made, and what is missing
einvoice_generateReturns the file: XML as text, the ZUGFeRD PDF as base64
einvoice_importRecords a received e-invoice as a purchase invoice in process
json
{"action": "einvoice_check", "invoiceId": "EINV1001", "formatId": "XRECHNUNG_UBL"}

Configuration#

applications/accounting/config/einvoice.properties:

PropertyDefaultMeaning
einvoice.format.defaultemptyFormat when neither the customer nor your company has one
einvoice.unit.defaultH87Unit code of a line without a unit
einvoice.rounding.tolerance.min0.05Largest difference that goes into the rounding amount
einvoice.rounding.tolerance.perLine0.01The same, per line, when it is larger
einvoice.vat.category.noTaxEVAT category of a line without tax when no other rule applies
einvoice.vat.exemptionReason.noTaxemptyThe exemption text for that category; empty gives the placeholder and a warning
einvoice.document.localeemptyLanguage of the texts in the e-invoice; empty is the language of the user
einvoice.paymentMeans.iban58Payment means for an IBAN and euro (SEPA credit transfer)
einvoice.paymentMeans.other30Payment means for other currencies
einvoice.pdf.screenInvoicePDFThe screen of the visible part of a ZUGFeRD PDF
einvoice.import.itemType.productPINV_FPROD_ITEMItem type of an imported line with a known supplier product
einvoice.import.itemType.otherPINV_SUPLPRD_ITEMItem type of every other imported line

For developers#

  • Services: checkEInvoice, generateEInvoice, getEInvoiceEmailAttachments (used by sendInvoicePerEmail), importEInvoice and updatePartyEInvoicePref.
  • Requests of the accounting webapp: invoiceEInvoice (the tab), einvoice (download, with invoiceId and formatId), einvoiceOriginal, einvoiceOriginalView, EInvoiceImport, importEInvoice, EditPartyEInvoicePref.
  • Data: the entity PartyEInvoicePref; the fields EftAccount.ibanNumber and bicCode, TaxAuthorityRateProduct.vatCategoryCode, exemptionReasonCode and exemptionReason, and Uom.unCefactCode; the invoice content types EINVOICE_XML, EINVOICE_PDF and EINVOICE_ORIGINAL.
  • Libraries: Mustangproject writes the CII and the ZUGFeRD PDF and reads received files; the EN 16931 CII-to-UBL converter makes the UBL formats.
  • Tests: gradlew runTest -PtestComponent=accounting -PtestSuite=einvoicetests, on the demo invoices EINV1001 to EINV1003.

Not yet supported#

  • Sending over the Peppol network directly. That needs a certified access-point provider; until one is connected, download the file and upload it to the provider or the portal.
  • The US DBNAlliance network, which uses UBL 2.3 with US code lists.
  • National formats outside EN 16931: FatturaPA (Italy), KSeF (Poland), Facturae (Spain).
  • The national extensions for Romania (CIUS-RO), Croatia and the French rules of 2026.

Ask the people who wrote it.

Support, development and training from the team that builds Scipio ERP.