Build a VERI*FACTU Invoicing Record XML (RegistroAlta, RD 1007/2023)
Skill: Convert an issued invoice into a VERI*FACTU RegistroAlta XML
Region: Spain (España)
Category: E-invoicing / Anti-fraud — VERI*FACTU (SIF)
Does: Takes an issued invoice and produces the VERI*FACTU RegistroAlta (RegistroFacturacionAlta) XML that a Sistema Informático de Facturación (SIF) generates per invoice — computing the registration's Huella (SHA-256 footprint) and the Encadenamiento (hash chain) so the record can be sent to AEAT or retained under RD 1007/2023.
Standard: AEAT VERI*FACTU — RD 1007/2023, Orden HAC/1177/2024 (SuministroLR / RegistroFacturacionAlta schema)
The
Huella(hash) and theEncadenamientochain must be computed exactly per the AEAT specification — the concatenation field order, separators, casing and date formats are fixed — and the result validated before sending. OneRegistroAltais generated per invoice by the billing software at the moment of issue; each record chains to the previous one'sHuella, so an error breaks the entire chain. Validate against the active schema and the published hash rules before transmission.
When this applies
- A business or professional using a Sistema Informático de Facturación (SIF) issues an invoice and must generate a tamper-evident invoicing record under RD 1007/2023 and Orden HAC/1177/2024 (the anti-fraud invoicing-software regulation).
- The SIF operates in VERI*FACTU mode (records are sent to AEAT and a QR + "VERI*FACTU" mark is printed on the invoice) or in non-VERI*FACTU mode (records are retained with the same hash chain and made available to AEAT). This skill produces the
RegistroAlta(a new invoice); cancellations use a separateRegistroAnulacion. - Each issued invoice (
factura) produces exactly oneRegistroAlta, generated and footprinted at the time of issue, then chained to the immediately previous record of the same obligated party. - Excluded: taxpayers under SII (Suministro Inmediato de Información) for the same flows, and invoicing not performed through a SIF (e.g. issued directly by AEAT facilities) — confirm the obligation and mandatory-use date applicable to the issuer.
Input data required
| Input | RegistroAlta element |
|---|---|
| Issuer NIF | IDFactura/IDEmisorFactura |
| Invoice series + number | IDFactura/NumSerieFactura |
| Invoice issue date (dd-mm-yyyy) | IDFactura/FechaExpedicionFactura |
| Issuer name / business name | NombreRazonEmisor |
| Invoice type (F1, F2, R1…) | TipoFactura |
| Description of the operation | DescripcionOperacion |
| Tax (01 = IVA) | Desglose/DetalleDesglose/Impuesto |
| VAT regime key | Desglose/DetalleDesglose/ClaveRegimen |
| Operation qualification (S1/S2/N1/N2) | Desglose/DetalleDesglose/CalificacionOperacion |
| VAT rate (%) | Desglose/DetalleDesglose/TipoImpositivo |
| Taxable base (or non-subject amount) | Desglose/DetalleDesglose/BaseImponibleOimporteNoSujeto |
| Output VAT charged | Desglose/DetalleDesglose/CuotaRepercutida |
| Total VAT | CuotaTotal |
| Total invoice amount | ImporteTotal |
| First record? / previous record reference | Encadenamiento/PrimerRegistro or Encadenamiento/RegistroAnterior |
| Billing software identification | SistemaInformatico/... |
| Record generation timestamp (ISO 8601 + tz) | FechaHoraHusoGenRegistro |
| Footprint type (01 = SHA-256) | TipoHuella |
| Computed footprint (uppercase hex) | Huella |
Document structure
RegFactuSistemaFacturacion
└── RegistroFactura
└── sf:RegistroAlta
├── IDVersion (1.0)
├── IDFactura
│ ├── IDEmisorFactura (issuer NIF)
│ ├── NumSerieFactura (series + number)
│ └── FechaExpedicionFactura (dd-mm-yyyy)
├── NombreRazonEmisor
├── TipoFactura (F1, F2, R1–R5…)
├── DescripcionOperacion
├── Desglose
│ └── DetalleDesglose (one per rate / qualification)
│ ├── Impuesto (01 = IVA)
│ ├── ClaveRegimen (01 = general régimen)
│ ├── CalificacionOperacion (S1 / S2 / N1 / N2)
│ ├── TipoImpositivo (e.g. 21)
│ ├── BaseImponibleOimporteNoSujeto
│ └── CuotaRepercutida
├── CuotaTotal (sum of CuotaRepercutida)
├── ImporteTotal (base + cuota)
├── Encadenamiento
│ ├── PrimerRegistro (S) ─ first record of the chain, OR
│ └── RegistroAnterior ─ reference to the previous record
│ ├── IDEmisorFactura
│ ├── NumSerieFactura
│ ├── FechaExpedicionFactura
│ └── Huella (previous record's footprint)
├── SistemaInformatico
│ ├── NombreRazon
│ ├── NIF
│ ├── NombreSistemaInformatico
│ ├── IdSistemaInformatico
│ ├── Version
│ ├── NumeroInstalacion
│ ├── TipoUsoPosibleSoloVerifactu
│ ├── TipoUsoPosibleMultiOT
│ └── IndicadorMultiplesOT
├── FechaHoraHusoGenRegistro (ISO 8601 with timezone)
├── TipoHuella (01 = SHA-256)
└── Huella (uppercase hex SHA-256)
Encadenamiento carries either PrimerRegistro (value S) for the very first record or RegistroAnterior (never both). Desglose may contain several DetalleDesglose blocks when an invoice mixes rates or qualifications.
Source → RegistroAlta field map
| From the source | → RegistroAlta element |
|---|---|
| Issuer tax ID (NIF) | IDFactura/IDEmisorFactura |
| Invoice series + number | IDFactura/NumSerieFactura |
| Issue date | IDFactura/FechaExpedicionFactura (dd-mm-yyyy) |
| Issuer legal name | NombreRazonEmisor |
| Document kind (full invoice, simplified, rectifying) | TipoFactura |
| Free-text operation description | DescripcionOperacion |
| Tax applied | Desglose/DetalleDesglose/Impuesto (01) |
| VAT special-regime indicator | Desglose/DetalleDesglose/ClaveRegimen (01) |
| Subject/exempt classification | Desglose/DetalleDesglose/CalificacionOperacion |
| VAT % | Desglose/DetalleDesglose/TipoImpositivo |
| Net taxable base | Desglose/DetalleDesglose/BaseImponibleOimporteNoSujeto |
| VAT charged | Desglose/DetalleDesglose/CuotaRepercutida |
| Total VAT | CuotaTotal |
| Invoice grand total | ImporteTotal |
| Hash of the previous record (or first-record flag) | Encadenamiento/RegistroAnterior/Huella (or Encadenamiento/PrimerRegistro = S) |
| Software vendor + product details | SistemaInformatico/... |
| When the record was generated | FechaHoraHusoGenRegistro |
| Hash algorithm | TipoHuella (01) |
| Computed footprint | Huella |
Code tables
TipoFactura (invoice type)
| Code | Meaning |
|---|---|
F1 |
Factura (complete / ordinary invoice) |
F2 |
Factura simplificada (ticket / simplified invoice) |
R1 |
Factura rectificativa — error fundado en derecho / art. 80.1, 80.2, 80.6 LIVA |
R2 |
Factura rectificativa — art. 80.3 (concurso de acreedores) |
R3 |
Factura rectificativa — art. 80.4 (créditos incobrables) |
R4 |
Factura rectificativa — resto |
R5 |
Factura rectificativa en facturas simplificadas |
CalificacionOperacion (operation qualification)
| Code | Meaning |
|---|---|
S1 |
Sujeta y no exenta — sin inversión del sujeto pasivo |
S2 |
Sujeta y no exenta — con inversión del sujeto pasivo |
N1 |
No sujeta — art. 7, 14, otros |
N2 |
No sujeta por reglas de localización |
(For exempt operations, OperacionExenta with a CausaExencion code E1–E6 is used instead of CalificacionOperacion.)
ClaveRegimen (VAT regime key, IVA)
| Code | Meaning |
|---|---|
01 |
Operación de régimen general |
02 |
Exportación |
03 |
Bienes usados, objetos de arte, antigüedades (REBU) |
04 |
Régimen especial del oro de inversión |
05 |
Régimen especial de las agencias de viajes |
06 |
Régimen especial grupo de entidades en IVA |
07 |
Régimen especial del criterio de caja |
… |
Further keys (08–20) per the AEAT regime-key list |
TipoHuella (footprint type)
| Code | Meaning |
|---|---|
01 |
SHA-256 |
Impuesto (tax)
| Code | Meaning |
|---|---|
01 |
IVA (Impuesto sobre el Valor Añadido) |
02 |
IPSI (Ceuta y Melilla) |
03 |
IGIC (Canarias) |
05 |
Otros |
Calculation rules
- CuotaRepercutida (per
DetalleDesglose) =BaseImponibleOimporteNoSujeto×TipoImpositivo/ 100, rounded to 2 decimals. - CuotaTotal = sum of every
DetalleDesglose/CuotaRepercutida, rounded to 2 decimals. - ImporteTotal = sum of bases +
CuotaTotal(plus any recargo de equivalencia), rounded to 2 decimals. - All monetary amounts use a dot decimal separator and 2 decimals; rates are written as the percentage value (e.g.
21or21.00). - Recompute every total from the line detail; if a printed total on the source invoice disagrees with the recomputed value, flag the discrepancy rather than copying either figure.
Huella (footprint) computation
The Huella is the SHA-256 of a concatenation string built from key fields in this exact order, each rendered as clave=valor and joined by the & separator:
IDEmisorFactura=<NIF>&NumSerieFactura=<serie+número>&FechaExpedicionFactura=<dd-mm-yyyy>&TipoFactura=<F1…>&CuotaTotal=<importe>&ImporteTotal=<importe>&Huella=<huella anterior>&FechaHoraHusoGenRegistro=<ISO 8601 con huso>
- Then apply SHA-256 to the UTF-8 bytes of that string and emit the digest as uppercase hexadecimal (64 characters) in
<Huella>. - The
&characters above are separators inside the footprint source string only — they are not part of any XML element value, so they never need escaping. (Any literal&that did appear inside an XML text value would be written&.) - Use the field values exactly as they appear in the record (same casing, same date format
dd-mm-yyyy, same numeric formatting). The footprint algorithm and the precise list of fields are fixed by the AEAT specification — confirm the active version before computing.
Encadenamiento (hash chain)
- The first record ever produced for the obligated party sets
Encadenamiento/PrimerRegistro=S. In the footprint string, theHuella=segment is then empty (no previous footprint exists). - Every subsequent record sets
Encadenamiento/RegistroAnteriorwith the previous record'sIDEmisorFactura,NumSerieFactura,FechaExpedicionFacturaand itsHuella. That previousHuellais theHuella=<huella anterior>value fed into the new record's footprint string — this is what chains the records together. - Because each footprint depends on the prior footprint, records must be generated in strict issue order; any gap or out-of-order record breaks the chain and must be detectable by AEAT.
Worked example (end-to-end)
A Spanish issuer (NIF B12345678, "Ejemplo Comercial SL") issues one ordinary invoice 2026/0001 dated 31-03-2026: base 1000.00, VAT 21% → CuotaRepercutida 210.00, CuotaTotal 210.00, ImporteTotal 1210.00. It is the first record of the chain (PrimerRegistro = S), generated at 2026-03-31T12:00:00+01:00, footprinted with SHA-256.
<?xml version="1.0" encoding="UTF-8"?>
<sf:RegFactuSistemaFacturacion
xmlns:sf="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tikeV1.0/cont/ws/SuministroInformacion.xsd"
xmlns:sf1="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tikeV1.0/cont/ws/SuministroLR.xsd">
<sf:RegistroFactura>
<sf:RegistroAlta>
<sf:IDVersion>1.0</sf:IDVersion>
<sf:IDFactura>
<sf:IDEmisorFactura>B12345678</sf:IDEmisorFactura>
<sf:NumSerieFactura>2026/0001</sf:NumSerieFactura>
<sf:FechaExpedicionFactura>31-03-2026</sf:FechaExpedicionFactura>
</sf:IDFactura>
<sf:NombreRazonEmisor>Ejemplo Comercial SL</sf:NombreRazonEmisor>
<sf:TipoFactura>F1</sf:TipoFactura>
<sf:DescripcionOperacion>Prestacion de servicios de consultoria</sf:DescripcionOperacion>
<sf:Desglose>
<sf:DetalleDesglose>
<sf:Impuesto>01</sf:Impuesto>
<sf:ClaveRegimen>01</sf:ClaveRegimen>
<sf:CalificacionOperacion>S1</sf:CalificacionOperacion>
<sf:TipoImpositivo>21</sf:TipoImpositivo>
<sf:BaseImponibleOimporteNoSujeto>1000.00</sf:BaseImponibleOimporteNoSujeto>
<sf:CuotaRepercutida>210.00</sf:CuotaRepercutida>
</sf:DetalleDesglose>
</sf:Desglose>
<sf:CuotaTotal>210.00</sf:CuotaTotal>
<sf:ImporteTotal>1210.00</sf:ImporteTotal>
<sf:Encadenamiento>
<sf:PrimerRegistro>S</sf:PrimerRegistro>
</sf:Encadenamiento>
<sf:SistemaInformatico>
<sf:NombreRazon>Software Facturacion SL</sf:NombreRazon>
<sf:NIF>A87654321</sf:NIF>
<sf:NombreSistemaInformatico>FacturaPlus</sf:NombreSistemaInformatico>
<sf:IdSistemaInformatico>01</sf:IdSistemaInformatico>
<sf:Version>2.3.1</sf:Version>
<sf:NumeroInstalacion>0001</sf:NumeroInstalacion>
<sf:TipoUsoPosibleSoloVerifactu>S</sf:TipoUsoPosibleSoloVerifactu>
<sf:TipoUsoPosibleMultiOT>N</sf:TipoUsoPosibleMultiOT>
<sf:IndicadorMultiplesOT>N</sf:IndicadorMultiplesOT>
</sf:SistemaInformatico>
<sf:FechaHoraHusoGenRegistro>2026-03-31T12:00:00+01:00</sf:FechaHoraHusoGenRegistro>
<sf:TipoHuella>01</sf:TipoHuella>
<sf:Huella>3F9A2B7C1D4E5F60718293A4B5C6D7E8F90112233445566778899AABBCCDDEEF</sf:Huella>
</sf:RegistroAlta>
</sf:RegistroFactura>
</sf:RegFactuSistemaFacturacion>
Footprint source string for this (first) record — note the empty Huella= segment because it is the PrimerRegistro:
IDEmisorFactura=B12345678&NumSerieFactura=2026/0001&FechaExpedicionFactura=31-03-2026&TipoFactura=F1&CuotaTotal=210.00&ImporteTotal=1210.00&Huella=&FechaHoraHusoGenRegistro=2026-03-31T12:00:00+01:00
SHA-256 of that UTF-8 string, hex uppercase, goes into <sf:Huella> (the value above is illustrative; recompute it for real data). The next invoice's Encadenamiento/RegistroAnterior/Huella will reference exactly this Huella. Normalisation transformations shown: issue date 2026-03-31 → 31-03-2026; generation timestamp kept as ISO 8601 with timezone 2026-03-31T12:00:00+01:00; rate 21% → 21; amounts to 2 decimals with a dot separator.
Validation checklist
- Current VERI*FACTU / SIF schema version confirmed (
SuministroLR/RegistroFacturacionAlta) andIDVersioncorrect - Issuer
IDEmisorFactura(NIF) valid;NumSerieFacturaandFechaExpedicionFactura(dd-mm-yyyy) match the invoice -
TipoFactura,CalificacionOperacion,ClaveRegimen,Impuestouse valid codes from the AEAT lists - Each
DetalleDesglose:CuotaRepercutida=BaseImponibleOimporteNoSujeto×TipoImpositivo/ 100 (2 decimals) -
CuotaTotal= ΣCuotaRepercutida;ImporteTotal= Σ bases +CuotaTotal; recomputed totals reconcile with the source (discrepancies flagged) -
Encadenamientocarries exactly one ofPrimerRegistro(S) orRegistroAnterior(with the prior record'sIDEmisorFactura,NumSerieFactura,FechaExpedicionFactura,Huella) -
SistemaInformaticofully populated (vendorNombreRazon/NIF, product name/ID,Version,NumeroInstalacion, use indicators) -
FechaHoraHusoGenRegistrois ISO 8601 with timezone offset -
TipoHuella=01;Huellais uppercase 64-hex-char SHA-256 of the concatenation string in the AEAT-fixed field order (with the emptyHuella=segment for the first record) - Records generated in strict issue order so the chain is unbroken; QR / "VERI*FACTU" mark produced where applicable
- XML well-formed, every namespace prefix declared, validated against the official AEAT schema before sending
Last updated: 2026-06-12 — verify the active VERI*FACTU/SIF schema version, the hash concatenation rules, and AEAT submission requirements against the current specification before use.