Laravel in Spain
Laravel development services for Spanish businesses
Spain has moved invoicing from a document you keep to a record the tax authority sees, and the rules differ inside the country. What that means for an application that issues invoices.
Spain is the clearest example in Europe of a country where invoicing stopped being a document your application produces and became a record the tax administration can see. For software that issues invoices, that is an architectural constraint rather than a reporting feature.
The invoice becomes a chain, not a file
The direction of Spanish rules is consistent even as the timetables move: invoicing software must produce records that cannot be altered after the fact, each linked to the one before it, with the integrity of the sequence demonstrable. Some records are transmitted to the administration; the rest must be capable of it.
Three consequences reach the schema, and all three are expensive to retrofit.
Issued invoices become immutable. This is the one that breaks existing applications, because most let a user fix a typo on an invoice. Under this model a correction is a new document referencing the old one. Adding that constraint to a system with edited invoices already in it is not a migration so much as an archaeology project.
The sequence matters. Numbering is not cosmetic - gaps and reordering are
exactly what the chain exists to make visible. That means the number is
allocated by the system in a way that survives concurrent requests, which is a
database concern rather than an application one. Two workers issuing invoices
simultaneously must not produce the same number, and a naive max(number) + 1
under load will.
The structured record is the invoice. The PDF is a rendering. Validation happens against the record before anything is shown to anybody, and the archive stores the structured form.
The country has more than one regime
The Basque provinces administer their own invoicing system, with a separate technical specification and its own schedule. Navarre has its own arrangements too.
For an application with customers across Spain, this is the difference between one integration and several, and it is the kind of thing that should be known at scoping rather than discovered when a customer in Bilbao asks why their invoice was rejected.
Immediate reporting, for the ones it applies to
Larger filers report VAT records to the tax agency within a short window of issue rather than in a periodic return. That turns bookkeeping into a near-real-time integration, with everything that implies: a queue, retries, a state per record, and a screen where somebody can see what failed and why.
It also means an error is visible quickly, which is genuinely better than discovering it at quarter end - provided the application was built to show it to a human rather than to log it.
Identifiers and the small things
Spanish tax identifiers have check digits, and validating them at entry prevents a whole category of rejected submissions later. Individuals and companies use different formats, foreign residents another, and an application that stores them as free text will eventually try to file one that cannot be filed.
Names are the other quiet one: two surnames are the norm, so a single
last_name column produces sorting and matching that is subtly wrong for
every Spanish customer. It is a three-field decision made before there is
data.
Working with us
We work remotely from Ankara, an hour ahead of Madrid, in English.
The work is our usual application development and integration. What Spain adds is that the invoice is a record with a chain rather than a row that can be edited, numbering is a concurrency problem, and "Spain" may mean more than one set of technical rules depending on where your customers are.
An invoice chain is append-only with a hash in it, which makes its schema decisions permanent in a way most schema decisions are not. The same category as money columns and time zones. It is worth an hour before the first record is written.
Invoicing and payment. In euros, by bank transfer to an IBAN. The invoice is issued by Codefacture Yazılım A.Ş. in Türkiye and carries no Turkish VAT, because exported services are exempt. It stays outside the Verifactu chain, which covers the invoices you issue and not the ones that arrive from abroad.
