Ironfang Finance validiert Rechnungen und Gutschriften nach ZUGFeRD und Factur-X entweder als hybrides PDF, also das PDF mit eingebettetem Rechnungs-XML, oder als XML allein. ZUGFeRD 2.5.2 und Factur-X 1.09.2 sind derselbe Standard, und ein Dokument, das einen der beiden angibt, wird auf dieselbe Weise geprüft. Probieren Sie es ohne Konto im ZUGFeRD- und Factur-X-Validator aus, den es neben Englisch auch auf Deutsch gibt.
Profile und Versionen
Das Profil wird aus der Spezifikationskennung im XML gelesen (der Guideline-ID, ram:GuidelineSpecifiedDocumentContextParameter), und jedes Profil hat seine eigene Version: sein Schema und das offizielle ZUGFeRD-2.5.2-Schematron für dieses Profil, aus dem Paket des FeRD. Das Ergebnis nennt sie in ruleset.variant, ruleset.official_release (2.5.2) und ruleset.technical_release (1.09.2).
| Profil | variant | Hinweis |
|---|---|---|
| MINIMUM | minimum | Keine vollständige Rechnung nach EN 16931; das Ergebnis sagt das. |
| BASIC WL | basic-wl | Keine vollständige Rechnung nach EN 16931; das Ergebnis sagt das. |
| BASIC | basic | |
| EN 16931 | en16931 | Das Profil der europäischen Norm. |
| EXTENDED | extended | |
| XRECHNUNG | xrechnung | Wird erkannt und mit unsupported_variant abgelehnt. |
Jedes Profil ist UN/CEFACT CII D22B, für Rechnungen und Gutschriften. Eine XRechnung in UBL oder CII wird als Familie xrechnung validiert; siehe den XRechnung-Leitfaden.
Was geprüft wird
Ein PDF wird in drei Gruppen geprüft, die in groups gemeldet werden und jeweils ihre Prüfschritte enthalten. Schlägt ein Schritt fehl, laufen die folgenden nicht mehr, und das Ergebnis weist jeden späteren Schritt als nicht erreicht aus, nicht als bestanden. XML allein durchläuft nur die Gruppe des Rechnungs-XML.
| Gruppe | Prüfschritt | Was er prüft |
|---|---|---|
pdfa | input | Die Anfrage und das PDF innerhalb ihrer Grenzen. Ein verschlüsseltes PDF, oder eines ohne genau ein eingebettetes Rechnungs-XML, wird stattdessen mit einer Problem-Antwort abgelehnt. |
pdfa | pdfa | Das PDF gegen die PDF/A-Konformität, die es angibt, mit veraPDF. Eine hybride Rechnung muss PDF/A-3 oder PDF/A-4f angeben. |
attachment_metadata | hybrid_binding | Die Regeln des FeRD für den Container, als Prüfungen von Ironfang FW-HYB-001 bis FW-HYB-013: Die Rechnung ist eine zugeordnete Datei (Associated File) mit zulässiger Beziehung, zulässigem Namen und Medientyp, und die Factur-X-XMP-Metadaten geben das eigene Profil des XML an, den Namen der eingebetteten Datei, den Dokumenttyp INVOICE und eine Factur-X-Version. |
invoice_xml | xml | Wohlgeformtes XML innerhalb der Grenzen, ohne DTD, ohne Entitäten über die fünf vordefinierten hinaus und ohne XInclude. |
invoice_xml | xsd | Das XML-Schema des Profils. |
invoice_xml | zugferd_profile | Das offizielle ZUGFeRD-2.5.2-Schematron für das Profil, einschließlich der Geschäftsregeln der EN 16931, die das Profil anwendet. |
Nur Befunde der Stufe fatal (Fehler) lassen ein Dokument durchfallen; warning (Warnung) und information (Hinweis) nie. Die Prüfungen der Einbettung tragen die Stufe, die der FeRD für jede Anforderung festlegt.
Was nicht geprüft wird
Jedes Ergebnis führt in coverage.not_checked auf, was es nicht feststellen kann:
| Aspekt | Wann |
|---|---|
visual_consistency | Jedes PDF. Ob die sichtbaren Seiten dieselbe Rechnung zeigen wie das XML, wird nicht verglichen; das XML sind die Rechnungsdaten. |
digital_signature | Jedes PDF. Signaturen liegen außerhalb des Prüfumfangs. |
pdf_container | XML allein: Über ein PDF wurde nichts geprüft. |
en16931_semantics | MINIMUM und BASIC WL, die keine vollständige Rechnung nach EN 16931 enthalten. |
Mit der API validieren
POST /finance/v2/einvoices/validate nimmt das PDF als application/pdf oder das XML als application/xml entgegen. Nennen Sie die Familie, wie es dieses Skript tut, damit ein Dokument, das eine andere Familie angibt, abgelehnt wird; die Ablehnung nennt, welche es angibt. Das Skript speichert das Ergebnis in result.json und leitet den Idempotency-Key aus der Datei ab, sodass eine Wiederholung das erste Ergebnis liefert und nicht erneut berechnet wird.
#!/usr/bin/env bash
# Validate one ZUGFeRD / Factur-X invoice, PDF or XML, with the Ironfang
# Finance API and keep the result.
#
# IRONFANG_API_KEY=... ./validate-zugferd.sh invoice.pdf
#
# A .pdf is checked as a hybrid invoice (PDF/A, attachment and metadata,
# then its embedded XML); anything else is sent as the invoice XML alone.
# The result is written to result.json. A retry with the same file sends
# the same Idempotency-Key, so it returns the first result and is not
# charged again.
set -euo pipefail
file="$1"
base="${IRONFANG_FINANCE_API:-https://api.ironfang.uk/finance}"
key="zf-$(sha256sum "$file" | cut -c1-40)"
case "$file" in
*.pdf|*.PDF) type="application/pdf" ;;
*) type="application/xml" ;;
esac
curl --fail-with-body --silent --show-error \
"$base/v2/einvoices/validate?family=zugferd-facturx" \
-H "Authorization: Bearer $IRONFANG_API_KEY" \
-H "Content-Type: $type" \
-H "Idempotency-Key: $key" \
--data-binary "@$file" \
--output result.json
grep -o '"outcome":"[a-z]*"' result.json | head -n 1
| Query-Parameter | Bedeutung |
|---|---|
family | zugferd-facturx. Ohne ihn wird die Familie aus der Spezifikationskennung des Dokuments gelesen. |
variant | Ein Profil aus der Tabelle oben. Ohne ihn wird das Profil aus dem Dokument gelesen; ein Profil, das dem Dokument widerspricht, ergibt family_mismatch. |
document_type | invoice, credit_note oder auto (der Standardwert: aus dem Dokument gelesen). |
scope | xml oder hybrid_pdf. Er folgt dem Anfragekörper: Ein PDF wird im Umfang hybrid_pdf geprüft und XML im Umfang xml; wer den jeweils anderen anfordert, erhält scope_unavailable. |
ruleset | latest (der Standardwert) oder die genaue ID einer Version aus GET /finance/v2/einvoices/rulesets. |
Ein PDF darf bis zu 20 MiB groß sein, mit höchstens 200 Seiten und 20 eingebetteten Dateien, 25 MiB dekodierten Anhängen und 256 MiB dekodiertem Inhalt; sein Rechnungs-XML, wie auch XML allein, bis zu 5 MiB. Ein PDF hat 30 Sekunden, um zu einem Urteil zu kommen. Ohne API-Schlüssel ist dieselbe Anfrage anonym: Es wird nichts gespeichert, und es gelten strengere Ratenbegrenzungen. Mit einem Schlüssel zählt eine abgeschlossene Validierung als ein Vorgang aus Ihrem Finance-Kontingent, und das Ergebnis wird 30 Tage unter GET /finance/v2/einvoices/results/{id} aufbewahrt. Der vollständige Vertrag ist das V2-OpenAPI-Dokument, und wie sich V2 von V1 unterscheidet, steht im Leitfaden zu V1 und V2.
Ein Ergebnis lesen
outcome ist bei einer abgeschlossenen Validierung valid oder invalid; alles, was ein Urteil verhindert hat, etwa eine Zeitüberschreitung, ist eine Problem-Antwort mit outcome: indeterminate, und es wird nichts berechnet. Bei einem PDF beschreibt input das PDF und input.embedded_xml das geprüfte XML (Größe, SHA-256 und Dateiname); declared.pdf gibt unverändert wieder, was die Metadaten des PDF über es selbst sagen: die Factur-X-Konformitätsstufe, Dateiname, Dokumenttyp und Version sowie PDF/A-Teil und -Konformität.
Befunde in den Prüfschritten input, pdfa und hybrid_binding tragen eine Fundstelle pdf, den Pfad des PDF-Objekts; Befunde im XML tragen einen XPath. Die Regeln von veraPDF werden als ISO19005-<part>:<clause>-<test> gemeldet, einmal je verletzter Regel. engines nennt beide Prüfmodule, das für XML und das für PDF, jeweils mit dem Digest ihres Images. next_actions enthält bei einem PDF extract_xml.
Das XML aus einem PDF herauslösen
POST /tools/v2/invoice/extract nimmt ein PDF entgegen (application/pdf, bis zu 20 MiB) und antwortet mit seinem Rechnungs-XML, Byte für Byte, als application/xml. Die Rechnung wird genau so erkannt wie bei der Validierung, das XML ist also dasjenige, das eine Validierung desselben PDF prüft. Es wird nichts beurteilt und nichts gespeichert. Ein PDF ohne eingebettete Rechnung, mit mehr als einer, verschlüsselt oder über einer Grenze wird mit dem passenden Code abgelehnt. Um das XML als Dokument zu lesen, öffnen Sie es im XRechnung-Viewer, der das CII-XML von ZUGFeRD und Factur-X liest.
Problem-Antworten
| Code | Wann |
|---|---|
no_embedded_invoice | Das PDF enthält kein Rechnungs-XML: Es ist möglicherweise eine gewöhnliche PDF-Rechnung. |
ambiguous_embedded_invoice | Das PDF enthält mehr als ein Rechnungs-XML. |
encrypted_pdf | Das PDF ist verschlüsselt oder mit einem Passwort geschützt. |
processing_limit, payload_too_large | Über einer veröffentlichten Grenze. |
family_mismatch | Das XML gibt eine andere Familie oder ein anderes Profil an als das genannte; detected sagt, welches. |
family_undetected | Es wurde kein Profil genannt, und das XML gibt keines an, das Ironfang erkennt. |
unsupported_variant | Das Profil XRECHNUNG. |
unsupported_document_type | Keine Rechnung und keine Gutschrift, oder eine Art, die der genannten widerspricht. |
scope_unavailable | Ein Umfang, in dem der Anfragekörper nicht geprüft werden kann. |
validator_unavailable, validation_timeout, internal_error | Kein Ergebnis: unbestimmt und nicht berechnet. Wiederholen Sie die Anfrage. |

