Los vectores de prueba oficiales de la AEAT, listos para meter en el CI de tu librería.
Si estás implementando Verifactu —en Node, PHP, Python, .NET, Java, Go o lo que sea— tienes un problema: ¿cómo sabes que tu huella es la que calcula Hacienda? La especificación trae ejemplos, pero están dentro de un PDF. Aquí los tienes en JSON, con su procedencia y su referencia al documento oficial.
No es una librería más. Es el banco de pruebas que cualquier librería puede usar.
fixtures/huella.json Los 3 vectores oficiales de la huella (SHA-256), con su cadena canónica.
fixtures/qr.json URLs de QR válidas e inválidas, con los códigos de error esperados.
src/ Implementación de referencia en TypeScript (opcional: los fixtures son
agnósticos del lenguaje).
Los fixtures son JSON plano. No necesitas JavaScript para usarlos: cárgalos desde tu suite en el lenguaje que sea.
Descarga fixtures/huella.json y recorre sus casos. Cada uno trae los campos en orden, la
cadena canónica que se debe construir con ellos, y la huella que debe salir:
{
"id": "alta-primer-registro",
"procedencia": "oficial",
"referencia": "apartado 6.1",
"tipo": "alta",
"campos": [
{ "nombre": "IDEmisorFactura", "valor": "89890001K" },
{ "nombre": "NumSerieFactura", "valor": "12345678/G33" },
"…"
],
"cadena": "IDEmisorFactura=89890001K&NumSerieFactura=12345678/G33&…&Huella=&FechaHoraHusoGenRegistro=2024-01-01T19:20:30+01:00",
"huella": "3C464DAF61ACB827C65FDA19F352A4E3BDC2C640E9E9FC4CC058073F38F12F60"
}Ejemplo en Python:
import hashlib, json
casos = json.load(open("fixtures/huella.json"))["casos"]
for caso in casos:
cadena = "&".join(f'{c["nombre"]}={c["valor"]}' for c in caso["campos"])
assert cadena == caso["cadena"], caso["id"]
huella = hashlib.sha256(cadena.encode("utf-8")).hexdigest().upper()
assert huella == caso["huella"], caso["id"]
print(f"{len(casos)} casos conformes")Ejemplo en TypeScript, con la implementación de referencia:
import { CASOS_HUELLA, calcularHuella } from "verifactu-conformance";
for (const caso of CASOS_HUELLA) {
const huella = await calcularHuella(caso.campos);
if (huella !== caso.huella) throw new Error(`No conforme: ${caso.id}`);
}El campo NIF aparece dos veces en los registros de evento (posiciones 1 y 6): una para el
sistema informático y otra para el obligado a emitir. Si modelas los campos como un mapa
nombre → valor, el segundo pisa al primero y la huella sale mal. Los campos son una lista
ordenada, no un objeto. Por eso los fixtures los publican como array.
123.1 y 123.10 son ambos válidos. La norma dice que en los campos numéricos los ceros a la
derecha no son relevantes. Producen hashes distintos, y la AEAT acepta los dos. Un verificador que
solo pruebe el literal del XML dará falsos negativos.
Un & sin codificar en el número de serie parte la URL del QR y crea un parámetro que no
existe: la factura deja de poder cotejarse. Debe ir como %26. Es el error que la propia AEAT
publica como ejemplo de URL incorrecta, y está en los fixtures con su URL corregida al lado.
Cada caso declara su procedencia:
oficial— es un ejemplo literal de un documento de la AEAT, con sureferenciaal apartado. Los tres casos de la huella son oficiales.derivado— no es un ejemplo literal: es un caso construido a partir de una regla de la norma (por ejemplo, que el importe use punto decimal). Sigue siendo correcto, pero lo decimos claramente en vez de dártelo como si viniera del BOE.
Esa distinción está ahí a propósito. Un kit de conformidad que confunde lo que dice la norma con lo que interpreta su autor no vale para nada.
- Especificaciones de la huella o «hash», AEAT v0.1.2 (27/08/2024)
- Especificaciones del código «QR» de la factura, AEAT v0.5.0 (10/12/2025)
- Sistemas Informáticos de Facturación y VERI*FACTU, sede electrónica de la AEAT
Marco legal: Real Decreto 1007/2023 y Orden HAC/1177/2024. Fechas de exigibilidad: 1 de enero de 2027 (Impuesto sobre Sociedades) y 1 de julio de 2027 (autónomos y resto), tras el aplazamiento del Real Decreto-ley 15/2025.
Este kit solo valida. No emite facturas, no envía nada a la AEAT y no es un Sistema Informático de Facturación. Sirve para comprobar que tu implementación calcula bien la huella y construye bien el QR: la responsabilidad de cumplir la norma sigue siendo de tu software y de su fabricante.
Si encuentras un caso que la norma cubre y aquí falta, abre un issue o un PR. Dos condiciones: que venga con su referencia al documento oficial, y que declare su procedencia.
Si crees que un fixture está mal, dilo cuanto antes: es lo peor que le puede pasar a este repositorio, y se arregla el mismo día.
Los mismos fixtures alimentan Cotejo, donde puedes verificar tu cadena de hash y validar tu QR desde el navegador, sin subir nada a ningún servidor.
MIT. Úsalo como quieras.