So funktioniert der Verifactu-Hash
Was im technischen Dokument der AEAT steht, erklärt für die, die es programmieren müssen.
Welche Felder einfließen und in welcher Reihenfolge
Der Hash eines Rechnungsdatensatzes (registro de alta) wird über acht Felder des XML berechnet, in dieser Reihenfolge: IDEmisorFactura, NumSerieFactura, FechaExpedicionFactura, TipoFactura, CuotaTotal, ImporteTotal, Huella (der Hash des vorherigen Datensatzes) und FechaHoraHusoGenRegistro.
Der Stornodatensatz (registro de anulación) verwendet fünf: IDEmisorFacturaAnulada, NumSerieFacturaAnulada, FechaExpedicionFacturaAnulada, Huella und FechaHoraHusoGenRegistro. Der Ereignisdatensatz, den es nur in der Variante NO VERI*FACTU gibt, verwendet neun, beginnend mit den Daten des Rechnungssystems.
Wie die Zeichenkette aufgebaut wird
Jedes Feld wird als name=wert geschrieben, die Felder werden mit & verbunden. Führende und abschließende Leerzeichen werden aus den Werten entfernt. Hat ein Feld keinen Wert, stehen nur Name und Gleichheitszeichen: Beim ersten Datensatz des Systems steht der vorherige Hash als Huella=. Die Zeichenkette wird in UTF-8 kodiert und mit SHA-256 gehasht; das Ergebnis ist hexadezimal, in Großbuchstaben und 64 Zeichen lang.
IDEmisorFactura=89890001K&NumSerieFactura=12345678/G33&FechaExpedicionFactura=01-01-2024&TipoFactura=F1&CuotaTotal=12.35&ImporteTotal=123.45&Huella=&FechaHoraHusoGenRegistro=2024-01-01T19:20:30+01:00
→ 3C464DAF61ACB827C65FDA19F352A4E3BDC2C640E9E9FC4CC058073F38F12F60
Warum verkettet wird
Jeder Datensatz enthält den Hash des vorherigen, deshalb bricht die Änderung einer alten Rechnung alle nachfolgenden Hashes. Darum gilt die Kette pro System und Installation, und darum müssen zwei Prozesse, die gleichzeitig fakturieren, die Berechnung serialisieren: Greifen zwei Datensätze auf denselben vorherigen Hash zu, verzweigt sich die Kette.
In der Variante VERI*FACTU berechnet die AEAT den Hash jedes empfangenen Datensatzes nach. Stimmt er nicht mit Ihrem überein, erhält der Datensatz den Status „Aceptado con errores“ (angenommen mit Fehlern).
Und der QR-Code
Der QR-Code der Rechnung enthält eine URL des Prüfdienstes der AEAT mit vier Parametern: nif, numserie, fecha (TT-MM-JJJJ) und importe (mit Dezimalpunkt). Die Werte werden URL-kodiert in UTF-8 übergeben: Eine Seriennummer wie 12345678&G33 muss als 12345678%26G33 übertragen werden.
Der Pfad hängt von der Variante ab: ValidarQR für VERI*FACTU und ValidarQRNoVerifactu für NO VERI*FACTU, auf www2.agenciatributaria.gob.es (Produktion) oder prewww2.aeat.es (Test). Der optionale Parameter formato=json dient Integrationen, darf aber nie im gedruckten QR-Code stehen.
Wir haben es am 7. Oktober 2026 gegen den Prüfdienst der Testumgebung der AEAT getestet: Die URL, die dieses Tool mit 12345678&G33 erzeugt, wird akzeptiert und die Behörde liest die Seriennummer korrekt, und ein Betrag mit Komma liefert denselben Fehler 2005, den Ihnen das Tool hier anzeigt.