DEV Community

Ronny Nyabuto
Ronny Nyabuto

Posted on

Building eTIMS for Concurrent POS Traffic

Building an eTIMS integration that actually handles concurrent POS traffic taught me something I didn't expect to find in a government tax spec.
The scenario: a POS terminal submits an invoice, the network hiccups, the terminal retries. Both requests hit your signing service within milliseconds of each other. Standard idempotency pattern is: SELECT to check if this invoice key exists, proceed if absent. Under concurrent retry storms, both requests pass that check before either writes the result. Both invoke the VSCU JAR. Both get signed.
You now have two KRA fiscal receipt numbers for one commercial transaction.
This is not a deduplication problem you can fix in a database. KRA receipt numbers are issued by the JAR and registered upstream. The VSCU Specification v2.0 §4.4 has explicit sequence integrity requirements — gaps AND duplicates in rcptNo surface during KRA audits. You cannot unissue a receipt number. The defect is permanent.
Most engineers I've talked to immediately reach for Redis or a distributed lock manager. I get it — the instinct makes sense. But the database you're already running has atomic COMMIT semantics. That's your mutex.
The pattern that actually works: don't SELECT then INSERT. Just INSERT. Attempt the write immediately against a tenant-scoped key. Let the PRIMARY KEY constraint be the gate. INSERT succeeds → you're the winner, sign the invoice, commit the response. INSERT throws DataIntegrityViolationException → you're the loser, another thread owns this key. Poll for the winner's committed result and replay it verbatim. Winner crashes mid-flight → delete the placeholder, next attempt re-enters as a fresh winner.
Exactly-once fiscal receipt generation. No Redis. No Zookeeper. No distributed lock service. Just PostgreSQL doing what PostgreSQL has always done.
The deeper lesson building TaxID — our middleware layer that abstracts the VSCU JAR for ERP and POS integrations — is that you have to engineer to the cost of failure, not the probability. A 1-in-10,000 duplicate in a shopping cart is a recoverable annoyance. The same race condition in a government-mandated fiscal system is an audit defect with legal consequences under the Income Tax Act §16(1)(c). The probability is the same. The irreversibility is not.
One more §2.2 Policy 4 fact that surprises people: the VSCU JAR stops issuing receipt numbers after 24 continuous hours without a successful KRA sync. Not degrades. Stops signing entirely. If your offline queue architecture assumes unlimited buffering, it's wrong. The ceiling is documented, enforced by the JAR, and non-negotiable. At hour 24, the platform enters SUSPENDED state regardless of how much local queue capacity you have.
Read the spec before you build the queue.

Top comments (0)