Most explanations of fiscalisation start with hardware. That is the wrong end for the person deciding what software to run, because the device is the easy part to buy and the hard part to live with is what your system has to do on every single taxable sale — and what it does on the afternoon the connection to the revenue service is unreachable and there are customers at the counter.
Read it as a data requirement, not a device requirement
Stripped to essentials, the obligation is this: every taxable document your business issues has to leave your system, be validated by something outside your system, come back with an identifier your system did not invent, and be reproducible on demand long after the sale. Every design decision below follows from that one sentence.
The five things your system has to do
- 01Number documents in one unbroken sequencePer till, per branch, per document type — but unbroken. No gaps, no reuse, no editing a number after the fact. If a user can delete an invoice, your sequence has a hole in it and you cannot explain the hole. Void and credit, never delete.
- 02Submit the document and keep what comes backThe fiscal identifier, the device or signature reference, the verification data and the fiscal day it fell in are not display fields. They belong in columns on the invoice row, indexed, and they must survive a database restore.
- 03Render the returned data on the customer copyThe customer copy carries what the revenue service returned, not what your system hoped it would return. Which means you cannot print the document until the response is in — or you print a clearly-marked provisional copy and reissue, and you decide that policy deliberately.
- 04Open and close a fiscal day, and reconcile itThe daily totals you report have to agree with your own sales ledger for the same period. Build the comparison as a report your bookkeeper runs, not as something a consultant checks once at go-live.
- 05Treat credit notes as fiscal documents in their own rightA credit note references the original document and is submitted like any other. The most common failure in a hurried implementation is a credit note that adjusts the ledger correctly and never reaches the revenue service at all.
The part people discover in week three: the network
Your interface to the revenue service will be unavailable sometimes. So will your connection to it. If your point of sale refuses to complete a sale when submission fails, you have converted a tax rule into a trading restriction, and your staff will find a way around it — usually a book, sometimes a second system, always something you cannot audit.
The design that survives contact with an actual shop floor is a queue. Sales complete locally against the sequence. Submission is a separate job with its own status and its own retries. Nobody at the counter waits on a request to a server in another building.
fiscal_documents
invoice_id uuid not null
sequence_number text not null -- unbroken, assigned locally
status text not null -- queued | submitted | accepted | rejected
idempotency_key text unique -- a retry must never double-submit
submitted_at timestamptz
accepted_at timestamptz
fiscal_reference text -- what came back, stored as returned
verification_payload jsonb -- the full response, kept forever
attempts integer not null default 0
last_error text- An idempotency key on every submission, because a retry after a timeout is not a second sale.
- The unsent count visible to the person on the till, not buried in an admin screen.
- An alert when the queue is older than a threshold you set — hours, not days.
- The full response body stored as returned. When a query arrives eighteen months later, this column is your answer.
- A reconciliation job that finds documents accepted by the service but never marked accepted locally. Both directions fail.
Capture the buyer details at the point of sale, not afterwards
A business customer who needs to claim input tax needs their own details on the document — the correct registered name and their tax identifiers. Getting them afterwards means reissuing, and reissuing means a credit note, a new document and an irritated customer who is standing in front of you.
- Tax identifiers belong on the customer record with validation, not typed into a notes field per sale.
- Prompt for them at capture above a value you choose, rather than hoping the operator remembers.
- Make the registered name a separate field from the trading name. They differ more often than you expect.
Currency is a fiscalisation problem too
A document has one currency, one rate applied, and both amounts stored. If your system holds a single amount column and converts on the way to a report, you will not be able to reproduce the document you issued — and reproducing it exactly is the whole point. That is a bigger topic than this page: see running USD and ZWG in one ledger.
Reprints, voids and the things staff will actually do
- A reprint is a copy, marked as a copy, carrying the original identifiers. It never draws a new number.
- A void before the fiscal day closes and a credit note after it are different operations. Your system should not let a user choose the wrong one.
- Every document records which operator issued it. This is the control that makes the rest of the audit trail usable.
- A discount is a line, not a hand-edited total. Editing the total is how a document stops agreeing with its own lines.
What to ask a vendor, before you pay anything
| Ask this | What a good answer sounds like |
|---|---|
| Show me a sale completing while the fiscal interface is unreachable. | They disconnect it in front of you, the sale completes, the queue shows one unsent document, and it clears when they reconnect. |
| Where is the response from the revenue service stored? | They show you the column, and they can produce the stored response for a document from last year. |
| Show me a credit note against a fiscalised invoice. | The credit note references the original, is submitted in its own right, and both appear in the day totals. |
| How do the daily totals reconcile to the sales ledger? | A standard report, run by our bookkeeper, not a consultant with database access. |
| Who is responsible when a submission is rejected? | A named queue, a visible error, and a documented path. Not an email to support. |
| What happens to all of this if we leave you? | A full export, in a standard format, including the stored fiscal responses. |
The short version
Fiscalisation is not hard to satisfy. It is hard to satisfy for two years without the sequence developing gaps, the credit notes drifting out of scope, or the shop floor inventing a workaround on the first bad afternoon. Judge a system on those three, not on whether it can print a compliant invoice on a good day.