Cómo funciona la huella de Verifactu
Lo que dice el documento técnico de la AEAT, explicado para quien lo tiene que programar.
Qué campos entran y en qué orden
La huella de un registro de alta se calcula sobre ocho campos del XML, en este orden: IDEmisorFactura, NumSerieFactura, FechaExpedicionFactura, TipoFactura, CuotaTotal, ImporteTotal, Huella (la del registro anterior) y FechaHoraHusoGenRegistro.
El registro de anulación usa cinco: IDEmisorFacturaAnulada, NumSerieFacturaAnulada, FechaExpedicionFacturaAnulada, Huella y FechaHoraHusoGenRegistro. El registro de evento, que solo existe en la modalidad NO VERI*FACTU, usa nueve, empezando por los datos del sistema informático.
Cómo se construye la cadena
Cada campo se escribe como nombre=valor y se unen con &. A los valores se les quitan los espacios del principio y del final. Si un campo no tiene valor, se escribe solo el nombre y el igual: en el primer registro del sistema la huella anterior va como Huella=. La cadena se codifica en UTF-8 y se le aplica SHA-256; el resultado va en hexadecimal y en mayúsculas, 64 caracteres.
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
Por qué se encadena
Cada registro lleva la huella del anterior, así que cambiar una factura antigua rompe todas las huellas posteriores. Por eso la cadena es por sistema e instalación, y por eso dos procesos que facturan a la vez tienen que serializar el cálculo: si dos registros cogen la misma huella anterior, la cadena se bifurca.
En la modalidad VERI*FACTU la AEAT recalcula la huella de cada registro que recibe. Si no coincide con la tuya, el registro queda «Aceptado con errores».
Y el QR
El QR de la factura contiene una URL del servicio de cotejo de la AEAT con cuatro parámetros: nif, numserie, fecha (DD-MM-AAAA) e importe (con punto decimal). Los valores van con URL encoding en UTF-8: un número de serie como 12345678&G33 tiene que viajar como 12345678%26G33.
La ruta cambia según la modalidad: ValidarQR para VERI*FACTU y ValidarQRNoVerifactu para NO VERI*FACTU, en www2.agenciatributaria.gob.es (producción) o prewww2.aeat.es (pruebas). El parámetro opcional formato=json sirve para integraciones, pero nunca puede ir en el QR impreso.
Lo comprobamos el 7 de octubre de 2026 contra el servicio de cotejo del entorno de pruebas de la AEAT: la URL que genera esta herramienta con 12345678&G33 se acepta y la Agencia lee bien el número de serie, y un importe con coma devuelve el mismo error 2005 que te marca aquí.