Skip to content

fix(einvoice): make XRechnung and ZUGFeRD output pass KoSIT validation - #15

Closed
ElCarsti wants to merge 1 commit into
pigontech:mainfrom
ElCarsti:fix/e-rechnung-validation
Closed

ElCarsti wants to merge 1 commit into
pigontech:mainfrom
ElCarsti:fix/e-rechnung-validation

Conversation

@ElCarsti

@ElCarsti ElCarsti commented Oct 4, 2026

Copy link
Copy Markdown

Neither format passed the official KoSIT validator (XRechnung 3.0.2 configuration): 0 of 20 generated test documents were accepted.

XRechnung (UBL):

  • use the KoSIT CustomizationID (urn:...#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0)
  • emit Party and PostalAddress elements in UBL schema order
  • add the fields XRechnung requires: BuyerReference, seller and buyer EndpointID, seller contact (name, phone, email), PaymentMeans (BR-DE-1)
  • omit the header DueDate on credit notes

ZUGFeRD (CII):

  • emit TradeParty, TradeAddress, TradeTax and header settlement elements in CII schema order
  • seller electronic address as URIUniversalCommunication instead of a SEID tax registration; add contact, BuyerReference, due date, payment means

Both, via a shared xml/en16931.ts:

  • map the reduced-rate code AA (not in EN 16931) to S; always emit the rate for Z/E/AE; exempt (E) with reason for Kleinunternehmer
  • tax number as scheme FC instead of DE-TAX; drop the buyer tax number, which EN 16931 has no field for
  • one allowance per VAT category for the document discount (BR-32)
  • emit negatively stored credit notes with positive amounts (BR-27)
  • payee account from the structured IBAN/BIC settings, falling back to a checksum-valid IBAN in the bank details text

Settings: add company_contact_name (contact person / Ansprechpartner), used as the e-invoice seller contact and falling back to the company name.

Validator: report missing seller VAT ID (BR-CO-26), XRechnung phone/email/ buyer address, a missing IBAN, and VAT that does not match the taxable amount. The latter flags invoices with a document discount, because calculateInvoiceTotals computes VAT before the discount (separate fix).

Neither format passed the official KoSIT validator (XRechnung 3.0.2
configuration): 0 of 20 generated test documents were accepted.

XRechnung (UBL):
- use the KoSIT CustomizationID (urn:...#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0)
- emit Party and PostalAddress elements in UBL schema order
- add the fields XRechnung requires: BuyerReference, seller and buyer
  EndpointID, seller contact (name, phone, email), PaymentMeans (BR-DE-1)
- omit the header DueDate on credit notes

ZUGFeRD (CII):
- emit TradeParty, TradeAddress, TradeTax and header settlement elements in
  CII schema order
- seller electronic address as URIUniversalCommunication instead of a SEID
  tax registration; add contact, BuyerReference, due date, payment means

Both, via a shared xml/en16931.ts:
- map the reduced-rate code AA (not in EN 16931) to S; always emit the rate
  for Z/E/AE; exempt (E) with reason for Kleinunternehmer
- tax number as scheme FC instead of DE-TAX; drop the buyer tax number,
  which EN 16931 has no field for
- one allowance per VAT category for the document discount (BR-32)
- emit negatively stored credit notes with positive amounts (BR-27)
- payee account from the structured IBAN/BIC settings, falling back to a
  checksum-valid IBAN in the bank details text

Settings: add company_contact_name (contact person / Ansprechpartner),
used as the e-invoice seller contact and falling back to the company name.

Validator: report missing seller VAT ID (BR-CO-26), XRechnung phone/email/
buyer address, a missing IBAN, and VAT that does not match the taxable
amount. The latter flags invoices with a document discount, because
calculateInvoiceTotals computes VAT before the discount (separate fix).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ElCarsti ElCarsti closed this Oct 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant