The invoice counter had to stay atomic with twenty writers at once.
- Work
- Hotel PMS and RMS with electronic invoicing
- Role
- Architecture and build
- Period
- 2024 — 2025
- PMS/RMS
- E-invoicing
- PostgreSQL
- Concurrency
The brief
A hotel needed booking and rate management with invoicing valid for the Peruvian tax authority. The hard requirement was not volume: it was that the invoice counter must never duplicate, with several processes issuing at once, and that VAT reconcile to the cent.
How it is built
Hotel PMS and RMS with electronic invoicing. Counters use INSERT ... ON CONFLICT with a retry on P2002, tested with 20 concurrent processes.
VAT is computed backwards from the total: base = round2(total/1.18) and then igv = total - base. The other way round, rounding leaves one-cent gaps that the tax authority rejects.
One caveat
SUNAT response codes: 0 and 4000 or above are accepted, 2000 to 3999 are rejected, 100 to 1999 is inconclusive. There the rule is do not reissue.
Where it breaks
SUNAT between 100 and 1999 is inconclusive
Where and why
There is no way to know whether the document was registered. The rule is not to reissue and to wait for the status query, because reissuing duplicates the counter.