stack trace · Análisis técnico
Verifactu por dentro: Hacienda te ha mandado construir un ledger
Hash encadenado, firma XAdES, audit log obligatorio y un QR de cotejo. La especificación técnica del RRSIF explicada para desarrolladores, que son quienes van a tener que implementarla.
Por Francisco G-M López —
Todo lo que se ha escrito sobre Verifactu en español va dirigido al gestor o a la pyme: qué es, cuándo entra (spoiler: 2027, aunque media internet diga otra cosa), cuánto es la multa. Casi nada va dirigido a la persona que de verdad va a pelearse con esto: el desarrollador que mantiene, integra o evalúa un sistema de facturación.
Y es una pena, porque si le quitas la prosa de BOE, el Reglamento de Sistemas Informáticos de Facturación (RD 1007/2023 y su desarrollo técnico, la Orden HAC/1177/2024) describe algo que cualquier dev reconoce a la primera: un ledger append-only con encadenamiento criptográfico y audit log. Hacienda ha obligado a media España a implementar, sin decirlo con estas palabras, una cadena de registros inmutable. Una blockchain sin bloques, sin consenso y con un único nodo que importa: la AEAT.
Vamos a trazar el stack.
El modelo mental: una linked list con hash
La unidad básica no es la factura, es el registro de facturación: un documento XML que se genera en el momento de emitir (registro de alta) o anular (registro de anulación) una factura. Cada registro lleva una huella —un hash— y aquí está el truco: la huella de cada registro se calcula incorporando los primeros 64 caracteres de la huella del registro anterior.
El artículo 13 de la Orden define exactamente qué campos entran en el cálculo. Para un registro de alta: NIF del emisor, número y serie de la factura, fecha de expedición, tipo de factura, cuota total, importe total, huella del registro anterior y fecha, hora y huso horario de generación. El algoritmo y la codificación exactos los fija el documento técnico de la sede electrónica de la AEAT: SHA-256, con la huella expresada en 64 caracteres hexadecimales.
Si has implementado alguna vez un event log con integridad, ya lo has visto: es una lista enlazada donde el puntero es criptográfico. Modificar un registro antiguo cambia su huella, lo que invalida la huella del siguiente, y la del siguiente, hasta el final. No puedes tocar el pasado sin romper todo el futuro. La detección de la manipulación no requiere confianza en el software: requiere recalcular hashes.
Tres reglas de la cadena que importan al implementar:
El primer registro de la cadena no tiene huella anterior (obviamente) y debe identificarse explícitamente como primer registro del sistema desde su instalación. Cada obligado tributario tiene una única cadena por sistema informático: todos sus registros generados por el mismo SIF cuelgan de la misma secuencia. Y el sistema debe permitir recorrer la cadena en ambos sentidos, verificando en cada salto si el encadenamiento de huellas es correcto y si los timestamps respetan el orden temporal — es decir, la norma te obliga a implementar también el verificador, no solo el generador.
El concepto, ejecutable
Esto no es el formato oficial (el registro real es un XML con esquema propio y la concatenación exacta de campos la define el documento técnico de la AEAT), pero el mecanismo de fondo cabe en veinte líneas de Node:
import { createHash } from 'node:crypto';
const sha256 = (s) => createHash('sha256').update(s, 'utf8').digest('hex').toUpperCase();
function crearRegistro(factura, huellaAnterior) {
const base = [
factura.nif, factura.numSerie, factura.fechaExpedicion,
factura.tipo, factura.cuotaTotal, factura.importeTotal,
huellaAnterior ?? 'PRIMER_REGISTRO',
new Date().toISOString(),
].join('&');
return { ...factura, huellaAnterior, huella: sha256(base) };
}
function verificarCadena(registros) {
return registros.every((r, i) =>
i === 0 || r.huellaAnterior === registros[i - 1].huella
);
}
const cadena = [];
cadena.push(crearRegistro({ nif: 'B00000000', numSerie: 'F-2026-001', fechaExpedicion: '2026-07-11', tipo: 'F1', cuotaTotal: 210, importeTotal: 1210 }, null));
cadena.push(crearRegistro({ nif: 'B00000000', numSerie: 'F-2026-002', fechaExpedicion: '2026-07-11', tipo: 'F1', cuotaTotal: 42, importeTotal: 242 }, cadena[0].huella));
console.log(verificarCadena(cadena)); // true
// Ahora "maquillamos" la primera factura...
cadena[0].importeTotal = 1000;
cadena[0].huella = sha256('lo que sea');
console.log(verificarCadena(cadena)); // false — la cadena delata la manipulación
Eso es Verifactu en esencia. Todo lo demás de la Orden son las capas que convierten este concepto en un sistema auditable por la Administración.
Las dos arquitecturas: VERI*FACTU o custodia local
Aquí está la decisión de diseño más importante, porque el reglamento admite dos modos de operación y no son equivalentes en responsabilidad.
Modalidad VERI*FACTU (online): el sistema remite cada registro de facturación a la AEAT en el momento de la emisión, contra el servicio de su sede electrónica. A cambio, la Agencia pasa a custodiar esos registros y te quita de encima buena parte de la carga de conservación. El acoplamiento es el precio: tu flujo de facturación pasa a depender de un endpoint de Hacienda, con sus validaciones y sus códigos de error. Ojo también a la letra pequeña de la permanencia: si empiezas a operar en esta modalidad, hay reglas sobre mantenerse en ella hasta el fin del año natural, y la renuncia se comunica en los propios mensajes de remisión indicando la fecha de fin.
Modalidad no-VERI*FACTU (local): no envías nada en tiempo real, pero entonces la responsabilidad de la integridad es tuya al completo: cada registro debe firmarse electrónicamente, la conservación corre de tu cuenta durante el plazo de prescripción, y debes poder responder a un requerimiento de la AEAT entregando los registros con la misma estructura estandarizada. La firma no es un PKCS#7 cualquiera: la Orden fija el estándar ETSI EN 319 132 con firma XAdES Enveloped, y los detalles de la política de firma se publican en la sede de la AEAT.
Traducción arquitectónica: el modo online cambia disponibilidad por responsabilidad; el modo local cambia autonomía por criptografía y custodia. Para un SaaS de facturación, el online es casi siempre el camino; para un ERP interno con requisitos de red peculiares, el local existe, pero implica implementar firma cualificada y un régimen de conservación serio.
El registro de eventos: observabilidad por imperativo legal
La parte de la especificación que casi nadie cuenta: el sistema debe mantener, además de la cadena de facturación, un registro de eventos — un audit log del propio funcionamiento del software, con su propia cadena de huellas (identificador del productor, identificador y versión del SIF, número de instalación, NIF del obligado, tipo de evento, huella del evento anterior, timestamp).
Y hay un requisito que parece sacado de un runbook de SRE: si el sistema detecta cualquier circunstancia que vulnere o pueda vulnerar la integridad de los registros o su encadenamiento, debe mostrar una alarma visible en todos los terminales conectados, que no puede desactivarse hasta que la integridad vuelva a estar garantizada, y generar el correspondiente registro de evento. Es decir: la norma exige detección de corrupción, alerta bloqueante y trazabilidad del incidente. Observabilidad no como buena práctica, sino como obligación con rango de orden ministerial.
El QR: la verificación llega al usuario final
Cada factura (completa o simplificada) generada por el SIF debe incorporar un código QR con la URL de cotejo de la AEAT y la leyenda correspondiente (“Factura verificable en la sede electrónica de la AEAT” o “VERI*FACTU”, según modalidad). El QR codifica los datos que permiten a cualquiera —cliente, proveedor, inspector con el móvil— comprobar contra la sede si esa factura consta. Es la punta visible del iceberg: toda la criptografía de la cadena existe para que ese cotejo signifique algo.
La bomba enterrada: si tu ERP es a medida, tú eres el fabricante
Esto es lo que más afecta a la audiencia de esta casa y lo que menos se está contando. El reglamento no distingue entre Sage y el ERP interno que programaste para tu empresa en 2011: si un sistema informático soporta procesos de facturación, es un SIF, y quien lo produce responde como productor de software. Eso significa declaración responsable (artículo 15 de la Orden) certificando que el sistema garantiza integridad, conservación, accesibilidad, legibilidad, trazabilidad e inalterabilidad — y significa entrar en el régimen sancionador del fabricante, que llega a los 150.000 euros por ejercicio, frente a los 50.000 del usuario.
Hay miles de desarrolladores en España manteniendo facturadores a medida que, a partir de 2027, tendrán que elegir entre adaptar su criatura a esta especificación (huella, firma o remisión, registro de eventos, QR, exportación estandarizada, declaración responsable) o migrar a un software comercial que ya la cumpla, porque los fabricantes están obligados desde julio de 2025. Es una conversación que conviene tener con negocio ahora, no en junio de 2027.
Cómo trastear hoy
No hace falta esperar a la obligación para tocar esto con las manos. El entorno de pruebas externas de la AEAT está abierto desde septiembre de 2025, la propia Agencia publica una aplicación gratuita de facturación que sirve de implementación de referencia, y toda la documentación técnica —esquemas XML, servicio de remisión, algoritmo de huella, política de firma, especificación del QR— vive en la sección de sistemas informáticos de facturación de su sede electrónica. Para un dev, la ruta corta es: leer el documento de cálculo de la huella, generar tres registros encadenados contra el sandbox y ver los códigos de validación que devuelve. Ese día entenderás Verifactu mejor que el 99% de los artículos que hablan de él.
$ verifactu --arch
patrón: ledger append-only, hash SHA-256 encadenado
firma: XAdES Enveloped (ETSI EN 319 132), modo local
audit log: obligatorio, con alarma bloqueante
tu ERP a medida: eres fabricante; declaración responsable
sandbox AEAT: abierto; exit 0