E-Rechnung im SDK prüfen: XRechnung, ZUGFeRD und Factur-X validieren (Beta)

Thema
VB.NET
Codebeispiele
VB.NET, C#, VB6 / VBScript (COM)
Veröffentlicht

Kurz: Ab Version 11.0.0.10 prüft das Aloaha ZUGFeRD SDK eine E-Rechnung selbst – mit ValidateInvoiceXML, ValidateInvoicePDF oder ValidateInvoiceXMLString. Geprüft wird gegen das XML-Schema und die veröffentlichten Prüfregeln: für XRechnung 3.0 und EN 16931 dieselben Regeln wie im KoSIT-Validator, für die ZUGFeRD-/Factur-X-Profile MINIMUM, BASIC WL, BASIC und EXTENDED die offiziellen Prüfregeln von FeRD und FNFE (ZUGFeRD 2.5.2 / Factur-X 1.09.2). Damit lässt sich jede Rechnungsart prüfen, die das SDK erzeugt. Die Prüfung läuft offline in Ihrem Programm, ohne Java und ohne die Rechnung irgendwohin hochzuladen. Jede Meldung gibt es als verständliche Erklärung mit den betroffenen Feldern (BT-Nummern) und als offiziellen Regeltext. Die Funktion ist Beta bis auf Weiteres, und wir freuen uns über jedes Feedback.

Auf einen Blick

FrageAntwort
Was wird geprüft?CII-Rechnungen: XRechnung 3.0 (inkl. Extension und CVD) und ZUGFeRD / Factur-X in allen Profilen – MINIMUM, BASIC WL, BASIC, EN 16931 und EXTENDED. Je nach Profil: XML-Schema, EN-16931-Regeln (BR-…, BR-CO-…, BR-CL-…, CII-SR-…), XRechnung-Regeln (BR-DE-…) und die Factur-X-Regeln des Profils (z. B. BR-FXEXT-…)
Welche Eingaben?XML-Datei, XML als Text (z. B. aus einer Datenbank) oder die in einer ZUGFeRD-/XRechnung-PDF eingebettete XML
ErgebnisTrue = angenommen (keine Fehler), False = abgelehnt; dazu Meldungen mit Regel-ID, Stufe, Stelle und Erklärung
SprachenErklärungen und Bericht auf Deutsch oder Englisch (ValidationLanguage)
Nicht geprüftUBL-Rechnungen, ZUGFeRD 1.0, XRechnung-Versionen vor 3.0 (die Meldung nennt die gefundene Kennung) sowie die PDF/A-Konformität der PDF selbst
VoraussetzungAloaha ZUGFeRD SDK ab 11.0.0.10 mit gültiger Lizenz; mit gültigem Wartungsvertrag ist das Upgrade kostenlos
StatusBeta bis auf Weiteres – Feedback an info@aloaha.com

Angeklagter und Richter in einer Person?

Eine ehrliche Vorbemerkung: Wer Rechnungen erzeugt, sollte sie nicht allein selbst für gültig erklären. Das SDK erstellt Ihre E-Rechnung – wenn dasselbe SDK sie anschließend prüft, wären wir Angeklagter und Richter in einer Person. Deshalb gilt: Ob eine Rechnung angenommen wird, entscheidet immer das System des Empfängers. Für neue Rechnungsarten, neue Kunden oder nach Änderungen an Ihrer Software prüfen Sie Beispielrechnungen zusätzlich unabhängig, etwa mit dem offiziellen KoSIT-Validator – wie das geht, steht in Wie prüfe ich meine XRechnung vor dem Versand?

Wir haben die Prüfung deshalb bewusst so gebaut, dass sie nicht nach eigenen Regeln urteilt: Sie verwendet ausschließlich die veröffentlichten Regeln von CEN und KoSIT, und jede Meldung trägt die offizielle Regel-ID und den offiziellen Regeltext. In unseren Tests lieferte sie bei allen 5.944 Testrechnungen dieselben Regeln, dieselben Stufen, dieselben Fundstellen und dasselbe Ergebnis wie der KoSIT-Validator 1.6.3 mit der Prüfkonfiguration vom 31.08.2026. Für die ZUGFeRD-Profile MINIMUM bis EXTENDED stimmten bei 10.179 Testdokumenten alle Meldungen, Fundstellen und Ergebnisse mit den offiziellen Prüfregeln überein.

Hilfreich ist die eingebaute Prüfung vor allem in diesen Fällen:

  • Rechnungseingang: Sie prüfen Rechnungen, die Ihnen andere schicken. Hier gibt es keinen Interessenkonflikt – das SDK hat diese Rechnungen nicht erzeugt.
  • Rechnungen aus anderen Programmen: Ihre ERP- oder Fakturasoftware erzeugt das XML selbst, und das SDK bettet es nur in die PDF ein oder liest es aus.
  • Vorabprüfung vor dem Versand: Jede Rechnung wird geprüft, bevor sie das Haus verlässt. Fehler wie falsche Summen oder ein Skonto im Freitext fallen sofort auf, nicht erst beim Empfänger.
  • Datenschutz: Rechnungen enthalten Geschäftsdaten. Die Prüfung läuft lokal, nichts wird an ein Prüfportal hochgeladen.
  • Massenprüfung und Automatisierung: Ganze Ordner oder Datenbanken lassen sich ohne Web-Oberfläche prüfen, etwa nach einem Update Ihrer Software.
  • Entwicklung und Support: Die verständlichen Meldungen nennen das betroffene Feld und die passende SDK-Funktion. Das verkürzt die Fehlersuche deutlich.

Beta: Ihr Feedback ist willkommen

Die Prüfung ist bis auf Weiteres eine Beta-Funktion. Die Ergebnisse stimmen in unseren Tests mit dem KoSIT-Validator überein, trotzdem kann es Rechnungen geben, die wir noch nicht gesehen haben. Wenn Ihnen ein Unterschied zu einem anderen Prüfwerkzeug auffällt oder eine Erklärung unklar ist, schicken Sie uns bitte die Rechnung (gern anonymisiert) und den Bericht aus ValidationReport an info@aloaha.com.

Beispiel: XML-Datei prüfen (VB.NET)

Das häufigste Szenario: Die Rechnung ist mit SaveXML gespeichert und soll vor dem Versand geprüft werden. Der Rückgabewert sagt, ob die Rechnung angenommen wird. LastError ist nur bei technischen Problemen gefüllt, etwa wenn die Datei fehlt oder die Lizenz nicht passt – das Prüfergebnis selbst steht ausschließlich in den Validation…-Eigenschaften.

' VB.NET
Dim alo As New Aloaha_ZUGFeRD.XML("IHR-LIZENZSCHLUESSEL")
Dim datei As String = "C:\Rechnungen\RE-1001.xml"

If alo.ValidateInvoiceXML(datei) Then
    Console.WriteLine("Angenommen, Prüfung: " & alo.ValidationScenario)
ElseIf alo.LastError <> "" Then
    Console.WriteLine("Prüfung nicht möglich: " & alo.LastError)
Else
    Console.WriteLine("Abgelehnt, Fehler: " & alo.ValidationErrorCount)
End If

For i As Integer = 0 To alo.ValidationMessageCount - 1
    Console.WriteLine(alo.ValidationMessageLevel(i) & " " & alo.ValidationMessageID(i))
    Console.WriteLine("  " & alo.ValidationMessageText(i))
    Console.WriteLine("  Stelle: " & alo.ValidationMessageLocation(i))
Next

Auch eine angenommene Rechnung kann Warnungen und Hinweise haben; sie stehen ebenfalls in der Meldungsliste. Der Index der Meldungen beginnt bei 0.

Beispiel: direkt nach dem Erstellen prüfen und Bericht speichern

' VB.NET – am Ende Ihrer Rechnungserstellung
alo.SaveXML("C:\Rechnungen\RE-1001.xml", "IHR-LIZENZSCHLUESSEL")

If Not alo.ValidateInvoiceXML("C:\Rechnungen\RE-1001.xml") Then
    System.IO.File.WriteAllText("C:\Rechnungen\RE-1001_pruefbericht.txt", alo.ValidationReport, System.Text.Encoding.UTF8)
    ' Rechnung nicht versenden, Bericht an die Buchhaltung oder den Support geben
End If

Beispiel: ZUGFeRD- oder XRechnung-PDF prüfen

ValidateInvoicePDF liest die eingebettete Rechnungs-XML aus der PDF und prüft sie. Enthält die PDF keine Rechnungs-XML, gibt die Funktion False zurück und LastError nennt den Grund.

' VB.NET
If Not alo.ValidateInvoicePDF("C:\Rechnungen\RE-1001.pdf") Then
    If alo.LastError <> "" Then
        MsgBox("Keine prüfbare Rechnung: " & alo.LastError)
    Else
        MsgBox(alo.ValidationReport)
    End If
End If

Geprüft wird die XML in der PDF, nicht die PDF/A-Konformität der Datei selbst.

Beispiel: C#

// C#
var alo = new Aloaha_ZUGFeRD.XML("IHR-LIZENZSCHLUESSEL");
alo.ValidationLanguage = "de";

bool angenommen = alo.ValidateInvoicePDF(@"C:\Rechnungen\RE-1001.pdf");
if (!angenommen && alo.LastError != "")
{
    Console.WriteLine("Prüfung nicht möglich: " + alo.LastError);
}
for (int i = 0; i < alo.ValidationMessageCount; i++)
{
    Console.WriteLine(alo.ValidationMessageLevel(i) + " " + alo.ValidationMessageID(i) + ": " + alo.ValidationMessageText(i));
}

Beispiel: VBA, Access und VB6 (COM)

Über COM übergeben Sie den Lizenzschlüssel als zweiten Parameter. Den vollständigen Bericht geben Sie am besten im Direktfenster aus, weil MsgBox lange Texte abschneidet.

' VBA / VB6 (COM)
Dim alo As Object, i As Long
Set alo = CreateObject("Aloaha_ZUGFeRD.XML")
alo.ValidationLanguage = "de"

If alo.ValidateInvoiceXML("C:\Rechnungen\RE-1001.xml", "IHR-LIZENZSCHLUESSEL") Then
    MsgBox "Rechnung angenommen (" & alo.ValidationScenario & ")"
ElseIf alo.LastError <> "" Then
    MsgBox "Prüfung nicht möglich: " & alo.LastError
Else
    Debug.Print alo.ValidationReport
    For i = 0 To alo.ValidationMessageCount - 1
        If alo.ValidationMessageLevel(i) = "error" Then
            Debug.Print alo.ValidationMessageID(i) & ": " & alo.ValidationMessageText(i)
        End If
    Next
End If

Steht die Rechnungs-XML in einem Datenbankfeld, prüfen Sie den Text direkt mit ValidateInvoiceXMLString:

' VBA (Access)
Dim xmlText As String
xmlText = Nz(DLookup("XmlInhalt", "tblRechnungen", "RechnungsNr='RE-1001'"), "")
If Not alo.ValidateInvoiceXMLString(xmlText, "IHR-LIZENZSCHLUESSEL") Then Debug.Print alo.ValidationReport

Beispiel: Rechnungseingang – einen Ordner prüfen

' VB.NET – alle eingegangenen PDF-Rechnungen prüfen und das Ergebnis als CSV protokollieren
Dim alo As New Aloaha_ZUGFeRD.XML("IHR-LIZENZSCHLUESSEL")
Dim protokoll As String = "C:\Eingang\pruefung.csv"
System.IO.File.WriteAllText(protokoll, "Datei;Ergebnis;Fehler;Warnungen;Hinweis" & vbCrLf)

For Each datei As String In System.IO.Directory.GetFiles("C:\Eingang", "*.pdf")
    Dim ok As Boolean = alo.ValidateInvoicePDF(datei)
    Dim ergebnis As String = If(ok, "angenommen", If(alo.LastError <> "", "nicht prüfbar", "abgelehnt"))
    System.IO.File.AppendAllText(protokoll, System.IO.Path.GetFileName(datei) & ";" & ergebnis & ";" &
        alo.ValidationErrorCount & ";" & alo.ValidationWarningCount & ";" & alo.LastError & vbCrLf)
Next

Das Ergebnis lesen

MitgliedInhalt
RückgabewertTrue = angenommen; False = abgelehnt oder nicht prüfbar
ValidationScenarioxrechnung, xrechnung-extension, xrechnung-cvd, en16931, minimum, basicwl, basic, extended oder none (nicht geprüft)
ValidationErrorCount, ValidationWarningCountAnzahl der Fehler und Warnungen
ValidationMessageCountAnzahl aller Meldungen (Fehler, Warnungen, Hinweise)
ValidationMessageID(i)Regel-ID, z. B. BR-CO-10, BR-DE-18, BR-FXEXT-03; XSD für Schemafehler; bei den Strukturregeln der ZUGFeRD-Profile FX-NOT-USED, FX-OCCURS, FX-CODE
ValidationMessageLevel(i)error, warning oder information
ValidationMessageText(i)verständliche Erklärung mit betroffenen Feldern, gefundenem Wert und passender SDK-Funktion
ValidationMessageRuleText(i)offizieller Regeltext (EN-16931- und Factur-X-Regeln englisch, XRechnung-Regeln deutsch)
ValidationMessageLocation(i)Stelle in der XML, z. B. /rsm:CrossIndustryInvoice[1]/rsm:SupplyChainTradeTransaction[1]
ValidationReportvollständiger Bericht als Text
ValidationRulesVersionverwendete Regelversionen
ValidationLanguagede (Standard) oder en

Die Stufen entsprechen der Bewertung der KoSIT-Prüfkonfiguration: Für XRechnung zählt zum Beispiel BR-CL-21 nur als Warnung, CII-SR-465 dagegen als Fehler. Warnungen und Hinweise verhindern die Annahme nicht. In den ZUGFeRD-Profilen ist jeder Verstoß gegen eine Prüfregel ein Fehler; Angaben, die im Profil nicht vorgesehen sind (FX-NOT-USED), sind Warnungen – der Empfänger ignoriert sie.

Verständliche Meldungen statt Regelsprache

Die offiziellen Regeltexte sind präzise, aber schwer zu lesen. Deshalb liefert ValidationMessageText zu jeder Regel eine Erklärung in normaler Sprache: was nicht stimmt, welche Felder betroffen sind (BT-Nummer und Name), welcher Wert gefunden wurde und mit welcher SDK-Funktion Sie das Feld setzen. So sieht der Bericht für eine Rechnung mit einem Rechenfehler aus:

Ergebnis: abgelehnt
Prüfung: XRechnung 3.0 (CIUS)
XML-Schema: gültig
Fehler: 2, Warnungen: 0, Hinweise: 1

[FEHLER] BR-CO-10
  Rechenfehler: Die Summe der Positionsnettobeträge (BT-106) stimmt nicht mit der Summe
  der einzelnen Positionen (BT-131) überein. Betrifft: BT-106 Summe der Nettobeträge aller
  Rechnungspositionen; BT-131 Nettobetrag der Rechnungsposition. Im SDK: getTotals, WriteTotals.
  Stelle: /rsm:CrossIndustryInvoice[1]/rsm:SupplyChainTradeTransaction[1]/…
  Regeltext: [BR-CO-10]-Sum of Invoice line net amount (BT-106) = Σ Invoice line net amount (BT-131).

[FEHLER] BR-DEC-23
  Zu viele Nachkommastellen: erlaubt sind höchstens 2. Betrifft: BT-131 Nettobetrag der
  Rechnungsposition. Im SDK: AddProduct_Comfort, AddProduct_Comfort_Quick.

[HINWEIS] …

Mit ValidationLanguage = "en" kommen Erklärungen und Bericht auf Englisch; die offiziellen Regeltexte bleiben unverändert.

Welche Rechnungen werden geprüft?

Wie beim KoSIT-Validator entscheidet die Spezifikationskennung (BT-24), welche Regeln gelten. Für die ZUGFeRD-Profile gelten auch die gleichwertigen Kennungen mit urn:zugferd.de:2p0:….

BT-24 in der RechnungPrüfung
urn:cen.eu:en16931:2017 (ZUGFeRD/Factur-X Profil EN 16931)Schema + EN-16931-Regeln
urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0Schema + EN-16931-Regeln + XRechnung-Regeln
XRechnung 3.0 Extension bzw. CVDwie XRechnung, mit den Bewertungen dieser Varianten
urn:factur-x.eu:1p0:minimum (MINIMUM)Schema + Regeln des Profils MINIMUM
urn:factur-x.eu:1p0:basicwl (BASIC WL)Schema + Regeln des Profils BASIC WL
urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic (BASIC)Schema + Regeln des Profils BASIC
urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended (EXTENDED)Schema + Regeln des Profils EXTENDED
andere, z. B. UBL, ZUGFeRD 1.0 oder XRechnung 2.xkeine Prüfung, Meldung NO-SCENARIO mit der gefundenen Kennung, Ergebnis False

Erzeugt das SDK Ihre XRechnung ungewollt als EXTENDED, wird sie nach den EXTENDED-Regeln geprüft – eine XRechnung ist sie dann nicht mehr. Warum das passiert, erklärt Warum wird meine XRechnung als Factur-X EXTENDED erstellt?

So funktioniert die Prüfung

Die Regeln für EN 16931 und XRechnung werden als Schematron veröffentlicht, einer Regelsprache, die normalerweise ein Java-Programm wie der KoSIT-Validator ausführt. Wir haben die veröffentlichten Regeln in VB.NET-Code übersetzt, der direkt im SDK läuft – ohne Java, ohne zusätzliche Installation und mit derselben Rechenlogik (z. B. bei Rundung und Dezimalzahlen). Das CII-Schema ist im SDK enthalten. Die Prüfregeln für die ZUGFeRD-Profile veröffentlichen FeRD und FNFE als kompiliertes XSLT; wir haben sie in Schematron-Regeln zurückgeführt und ebenso in VB.NET-Code übersetzt, samt der Codelisten der Profile. Neue Regelversionen von KoSIT und FeRD übernehmen wir mit einem SDK-Update; vor jeder Auslieferung vergleichen wir die Ergebnisse wieder mit den offiziellen Werkzeugen.

Getestet haben wir mit 5.944 Rechnungen: den offiziellen Testdateien von KoSIT und CEN, 3.363 gezielt fehlerhaft gemachten Rechnungen und 2.400 Rechnungen aus unserer eigenen Regressionsprüfung. Regel-IDs, Stufen, Fundstellen, Regeltexte und das Ergebnis stimmten in allen Fällen mit dem KoSIT-Validator überein. Für die ZUGFeRD-Profile MINIMUM, BASIC WL, BASIC und EXTENDED haben wir 10.179 Dokumente geprüft – 1.826 echte Rechnungen (darunter SDK-Ausgaben und die offiziellen Beispiele), 1.169 profilgerechte Rechnungen und 7.184 gezielt fehlerhafte Varianten – und mit den offiziellen XSLT-Prüfregeln in Saxon verglichen: Meldungen, Fundstellen und Ergebnis waren identisch.

Woher die Regeln stammen

Die Prüfung verwendet diese veröffentlichten Regelwerke. Wir danken den Herausgebern für ihre Arbeit:

  • EN 16931 Validierungsartefakte (CII) 1.3.16 von CEN/TC 434 – github.com/ConnectingEurope/eInvoicing-EN16931, Lizenz EUPL 1.2
  • XRechnung Schematron 2.6.0 für XRechnung 3.0.2 der Koordinierungsstelle für IT-Standards (KoSIT) – github.com/itplr-kosit/xrechnung-schematron, Lizenz Apache 2.0
  • Bewertung der Meldungen nach der KoSIT-Prüfkonfiguration für XRechnung vom 31.08.2026 – github.com/itplr-kosit/validator-configuration-xrechnung
  • XML-Schema UN/CEFACT Cross Industry Invoice D16B (uncoupled), wie in der KoSIT-Prüfkonfiguration verwendet
  • ZUGFeRD 2.5.2 / Factur-X 1.09.2 – XML-Schemas, Prüfregeln (Schematron) und Codelisten der Profile MINIMUM, BASIC WL, BASIC und EXTENDED von FeRD (Forum elektronische Rechnung Deutschland) und FNFE-MPE – Nutzungsbedingungen: Apache 2.0
  • Vergleichsmaßstab in unseren Tests: KoSIT-Validator 1.6.3 sowie für die ZUGFeRD-Profile die offiziellen XSLT-Prüfregeln, ausgeführt mit Saxon-HE 12.5

Typische Fragen bei der Prüfung

  • False, aber LastError ist leer: Die Rechnung wurde geprüft und abgelehnt. Die Gründe stehen in den Meldungen bzw. in ValidationReport.
  • False und LastError = „License Problem“: Der Lizenzschlüssel fehlt oder ist ungültig. Übergeben Sie ihn als Parameter oder im Konstruktor.
  • Meldung NO-SCENARIO: Die Datei wird nicht geprüft, etwa eine UBL-Rechnung, ZUGFeRD 1.0 oder eine XRechnung vor Version 3.0. Die Meldung nennt die gefundene Spezifikationskennung (BT-24).
  • Meldung FX-NOT-USED (Warnung): Eine Angabe ist im gewählten ZUGFeRD-Profil nicht vorgesehen und wird vom Empfänger ignoriert. Weglassen oder ein umfangreicheres Profil verwenden.
  • Meldung FX-CODE oder FX-OCCURS: Ein Code steht nicht in der Codeliste des Profils, oder eine Angabe kommt zu oft oder gar nicht vor.
  • Meldung XSD: Die Struktur entspricht nicht dem CII-Schema, etwa ein Element an falscher Stelle. Dann prüft das SDK – wie der KoSIT-Validator – die Geschäftsregeln nicht mehr.
  • Meldung PROCESSING-ERROR: Ein Feld kommt mehrfach oder mit unerwartetem Inhalt vor, sodass ein Regelwerk nicht vollständig geprüft werden konnte. Der KoSIT-Validator lehnt solche Rechnungen ebenfalls ab.
  • Skonto-Fehler BR-DE-18: Das Format erklärt Skonto in der XRechnung.

Häufige Fragen

Kann das Aloaha ZUGFeRD SDK eine XRechnung prüfen?

Ja, ab Version 11.0.0.10 mit ValidateInvoiceXML, ValidateInvoicePDF und ValidateInvoiceXMLString. Geprüft wird gegen das XML-Schema und die veröffentlichten Regeln für XRechnung 3.0, EN 16931 und die ZUGFeRD-Profile MINIMUM bis EXTENDED. Die Funktion ist Beta.

Ersetzt die eingebaute Prüfung den KoSIT-Validator?

Nein. Sie verwendet dieselben Regeln und lieferte in unseren Tests dieselben Ergebnisse, aber das SDK hat die Rechnung auch erzeugt. Für neue Rechnungsarten prüfen Sie Beispiele zusätzlich unabhängig; maßgeblich ist das System des Empfängers.

Werden Rechnungen dafür ins Internet übertragen?

Nein. Die Prüfung läuft vollständig lokal im SDK, ohne Java und ohne Upload.

Kann ich auch die XML in einer ZUGFeRD-PDF prüfen?

Ja, mit ValidateInvoicePDF. Das SDK liest die eingebettete Rechnungs-XML aus und prüft sie. Die PDF/A-Konformität der Datei selbst wird nicht geprüft.

Werden auch EXTENDED-, BASIC- und MINIMUM-Rechnungen geprüft?

Ja. Für MINIMUM, BASIC WL, BASIC und EXTENDED prüft das SDK gegen das XML-Schema und die offiziellen Prüfregeln des Profils nach ZUGFeRD 2.5.2 / Factur-X 1.09.2. Nicht geprüft werden UBL-Rechnungen, ZUGFeRD 1.0 und XRechnung-Versionen vor 3.0.

Gibt es die Meldungen auch auf Englisch?

Ja. Mit ValidationLanguage = "en" kommen Erklärungen und Bericht auf Englisch. Die offiziellen Regeltexte bleiben wie veröffentlicht.