Spain is putting a hash chain behind every invoice, and almost everything written about it so far has been written for accountants. This is the version for whoever has to ship it.
The deadlines are January 1, 2027 for companies and July 1, 2027 for sole traders. If you read something last year that said 2026, that was true until RD-ley 15/2025 moved the whole calendar back twelve months. Software vendors have been on the hook since July 2025, which is a detail worth holding on to if you sell a product that issues invoices for other people.
At BeeL., we sell an API for this, so read the rest with that in mind.
The requirement
Each invoice your software issues has to produce a registro de facturaciΓ³n de alta: a record containing a defined set of fields, hashed with SHA-256, where the hash of each record folds in the hash of the one before it. One chain per issuing tax ID, growing forever, never edited.
Cancelling an invoice is not a delete. It's a second record type, a registro de anulaciΓ³n, which goes into the same chain. Same for corrections, which come in two flavours depending on whether you're amending a difference or replacing the original document. The printed invoice carries a QR code with verification data, plus the string VERI*FACTU if you're in submitting mode.
Then you either push each record to the tax agency as it happens, or you keep everything locally under stricter signing and retention rules and hand it over when asked.
Written down like that, it reads like an afternoon of work. A hash function, a previous_hash column, an HTTP call.
Where the estimate falls apart
The chain is strictly sequential, so two workers issuing invoices for the same tax ID at the same time are racing for the same link. You need a lock per issuer, or a queue, or both, and either way concurrent issuance stops being free.
Retries are worse than they look. A failed submission that you retry carelessly either duplicates a record or breaks the chain, and a broken chain isn't something you fix with a migration script. It's a tax record. The recovery path is procedural, not technical.
The transport is a different era of software. XML over web services, digital certificates, environments that go down, error codes you have to classify as retryable or terminal before you can write sensible handling.
The edge cases are most of the work: multiple VAT rates on one invoice, exemptions, non-subject operations, recargo de equivalencia, intra-community customers, tax ID validation, invoice series.
And if you're a platform issuing on behalf of your customers, none of the above is singular. You have one chain per client tax ID, each with its own certificate, its own state, its own stuck submissions at 3am.
One more thing that surprises people: article 201 bis of the general tax law doesn't only point at the business issuing invoices. A vendor selling non-compliant invoicing software is looking at up to β¬150,000 per year per product. If your SaaS issues invoices for third parties, you are that vendor, whether or not it says so anywhere in your positioning.
Three ways out
You can build it yourself against the tax agency. Full control, no per-invoice cost, and a multi-month project followed by permanent maintenance every time a spec changes. Worth it if invoicing is your product rather than a thing your product has to do.
You can put an off-the-shelf invoicing tool in the loop. Fine when the volume is low and a human is doing the clicking; awkward when your backend needs to emit thousands of invoices a month without anyone opening a browser.
Or you can hand the fiscal part to an API and keep a POST in your own code. You trade work for a dependency, which is the same trade you already made for payments.
What the third option looks like
import { BeeL } from '@beel_es/sdk';
const beel = new BeeL({ apiKey: process.env.BEEL_API_KEY });
const invoice = await beel.invoices.create({
customer: {
nif: 'B12345678',
name: 'Cliente SL',
email: 'facturas@cliente.es',
},
lines: [
{ description: 'Pro plan, July 2026', quantity: 1, unitPrice: 49.00, taxRate: 21 },
],
});
Hashing, chaining, QR generation and submission happen behind that call, and the resulting state arrives on a signed webhook. If you already bill through Stripe, the charge itself can be the trigger, so there's even less of your code involved.
Test keys are prefixed beel_sk_test_ and the sandbox has no limits, so the whole flow is buildable before anyone pays anything.
Three things Verifactu is not
It isn't the B2B e-invoicing mandate from the Crea y Crece law. Different regulation, different timeline, and complying with one does nothing for the other.
It doesn't cover the whole country the same way. The Basque Country and Navarre run on their own regional rules, TicketBAI among them.
And it isn't SII. If you're already reporting VAT through Suministro Inmediato de InformaciΓ³n, your obligations differ.
Why 2026 is the good year to do this
Right now, submitting is voluntary. You can integrate, keep the chain clean from invoice number one, and debug in an environment where nothing you get wrong is a sanctionable event.
The alternative is doing it next December, at the same time as everyone else who waited, with every vendor's support queue full.
If you're somewhere in this already, I'm curious how you're issuing invoices today and what's blocking you. The sandbox at beel.es doesn't ask for a card if you want to poke at it first.
Top comments (0)