Skip to content

Registro de Eventos

Jacobo Cantorna Cigarrán edited this page Oct 13, 2026 · 1 revision

Registro de eventos (NO VERI*FACTU)

Un sistema que funciona en modo NO VERI*FACTU debe llevar un registro de eventos (Orden HAC/1177/2024, artículo 9). En modo VERI*FACTU no es obligatorio. EventRecordService genera cada evento, lo encadena con el anterior y lo firma. Los eventos nunca se envían a la AEAT.

Uso

VeriFactuConfig config = new VeriFactuConfig("Mi Empresa S.L.", "B72877814");
config.setDeveloperNif("B72877814");
EventRecordService events = new EventRecordService("/ruta/certificado.p12", "password", config);

// El primer evento de la cadena de un obligado: sin evento anterior (PrimerEvento = S)
Map<String, Object> start = events.generate(
        new Event(EventType.NO_VERIFACTU_START, "B72877814", "Mi Empresa S.L."));

// Un evento posterior se encadena con el anterior
Event next = new Event(EventType.NO_VERIFACTU_END, "B72877814", "Mi Empresa S.L.")
        .setPrevious(new Event.Reference(EventType.NO_VERIFACTU_START,
                ZonedDateTime.parse((String) start.get("generated_at")), (String) start.get("hash")));
Map<String, Object> end = events.generate(next);

Respuesta

Clave Contenido
status success o error
hash Huella del evento (SHA-256, 64 caracteres hexadecimales en mayúsculas)
hashInput Cadena exacta sobre la que se calculó la huella. Guárdala junto a la huella para reverificar la cadena con HashHelper.verify
signedXml El RegistroEvento firmado, en base64
generated_at FechaHoraHusoGenEvento usada en la huella (ISO 8601 con huso)
event_type Código del tipo de evento
message, validation_errors Solo con status=error: el motivo y la lista de fallos de validación

Para encadenar el evento siguiente, guarda de cada evento su tipo, generated_at y hash.

Huella

La huella sigue el documento de la AEAT Detalle de las especificaciones técnicas para la generación de la huella o hash de los registros (apartado 3.c). Los campos, en este orden, como nombre=valor unidos por &:

  1. NIF del sistema informático (el del productor).
  2. ID (vacío).
  3. IdSistemaInformatico.
  4. Version.
  5. NumeroInstalacion.
  6. NIF del obligado.
  7. TipoEvento.
  8. HuellaEvento: la del evento anterior; vacía en el primer evento.
  9. FechaHoraHusoGenEvento.

Se codifica en UTF-8 y se aplica SHA-256, con la salida en hexadecimal y mayúsculas. Los datos del sistema informático salen de VeriFactuConfig. HashHelper.generateEventHash calcula la huella sin generar el XML.

Tipos de evento

EventType recoge la lista L2E del anexo de la orden:

Código Tipo Datos propios (setDetails)
01 Inicio del funcionamiento como NO VERI*FACTU —
02 Fin del funcionamiento como NO VERI*FACTU —
03 Lanzamiento de la detección de anomalías en los registros de facturación Event.ProcessLaunch
04 Detección de anomalías en los registros de facturación Event.AnomalyDetection (con setInvoice)
05 Lanzamiento de la detección de anomalías en los registros de evento Event.ProcessLaunch
06 Detección de anomalías en los registros de evento Event.AnomalyDetection (con setEvent)
07 Restauración de copia de seguridad —
08 Exportación de registros de facturación de un periodo Event.BillingExport
09 Exportación de registros de evento de un periodo Event.EventExport
10 Registro resumen de eventos Event.Summary
90 Otros eventos voluntarios —

El tipo de anomalía de los eventos 04 y 06 es AnomalyType (lista L1E: integridad de la huella o de la firma, trazabilidad de la cadena y de las fechas). Un evento con datos propios que no corresponden a su tipo es un error de validación.

El resumen (10) debe generarse al menos una vez por cada 6 horas de funcionamiento y antes de apagar el sistema. Lo gestiona quien llama al SDK.

Firma

El RegistroEvento se firma con XAdES enveloped sobre el nodo RegistroEvento. El esquema EventosSIF.xsd exige la firma como último hijo de Evento: el SDK la coloca allí (SignatureService.signXml(xml, placeAfterXPath)). El XML generado valida contra EventosSIF.xsd, que el SDK empaqueta.

Ejemplo completo: EventRecordExample.java

Clone this wiki locally