Hoe de Verifactu-hash werkt
Wat het technische document van de AEAT zegt, uitgelegd voor wie het moet programmeren.
Welke velden erin gaan en in welke volgorde
De hash van een factuurrecord (registro de alta) wordt berekend over acht velden uit de XML, in deze volgorde: IDEmisorFactura, NumSerieFactura, FechaExpedicionFactura, TipoFactura, CuotaTotal, ImporteTotal, Huella (die van het vorige record) en FechaHoraHusoGenRegistro.
Het annuleringsrecord gebruikt er vijf: IDEmisorFacturaAnulada, NumSerieFacturaAnulada, FechaExpedicionFacturaAnulada, Huella en FechaHoraHusoGenRegistro. Het gebeurtenisrecord, dat alleen bestaat in de variant NO VERI*FACTU, gebruikt er negen, te beginnen met de gegevens van het informatiesysteem.
Hoe de string wordt opgebouwd
Elk veld wordt geschreven als naam=waarde en de velden worden verbonden met &. Spaties aan het begin en eind van de waarden worden verwijderd. Heeft een veld geen waarde, dan schrijft u alleen de naam en het isgelijkteken: in het eerste record van het systeem staat de vorige hash als Huella=. De string wordt gecodeerd in UTF-8 en gehasht met SHA-256; het resultaat is hexadecimaal, in hoofdletters, 64 tekens.
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
Waarom de records gekoppeld zijn
Elk record bevat de hash van het vorige, dus wie een oude factuur wijzigt, breekt alle hashes daarna. Daarom loopt de keten per systeem en installatie, en daarom moeten twee processen die tegelijk factureren de berekening serialiseren: als twee records dezelfde vorige hash pakken, splitst de keten zich.
In de variant VERI*FACTU herberekent de AEAT de hash van elk record dat binnenkomt. Komt die niet overeen met de uwe, dan krijgt het record de status «Aceptado con errores» (geaccepteerd met fouten).
En de QR-code
De QR-code op de factuur bevat een URL van de verificatiedienst van de AEAT met vier parameters: nif, numserie, fecha (DD-MM-JJJJ, met koppeltekens) en importe (met een punt als decimaalteken). De waarden worden URL-gecodeerd in UTF-8: een factuurnummer als 12345678&G33 moet mee als 12345678%26G33.
Het pad verschilt per variant: ValidarQR voor VERI*FACTU en ValidarQRNoVerifactu voor NO VERI*FACTU, op www2.agenciatributaria.gob.es (productie) of prewww2.aeat.es (test). De optionele parameter formato=json is bedoeld voor integraties, maar mag nooit in de geprinte QR-code staan.
We hebben het op 7 oktober 2026 gecontroleerd tegen de verificatiedienst in de testomgeving van de AEAT: de URL die deze tool genereert met 12345678&G33 wordt geaccepteerd en de belastingdienst leest het factuurnummer correct, en een bedrag met een komma geeft dezelfde fout 2005 die u hier te zien krijgt.