Electronic Fiscal Taxing
This engineering skill builds the software boundary between a commercial system and an electronic fiscal authority. It supports one-client deployments and multi-tenant systems without mixing tax identities, credentials, devices, catalogues, queues, or evidence. It is general by design; Uganda EFRIS is the detailed reference implementation.
Prerequisites
Load system-architecture-design, api-design-first,
database-design-engineering, distributed-systems-patterns,
reliability-engineering, observability-monitoring, and
vibe-security-skill as applicable. For accounting, tax, or statutory output,
also load the external chwezi-accounting-doctrine electronic fiscal taxing
skill and the finance quality gate.
Use When
- An ERP, POS, billing, e-commerce, or mobile-backed system must fiscalise invoices, receipts, credit notes, debit notes, or cancellations.
- A provider requires signed/encrypted requests, device registration, rotating keys, acknowledgements, or authority-specific dictionaries.
- A system must support multiple tenants, each with a distinct TIN/tax ID, fiscal profile, branch/device mapping, and credentials.
- A remote fiscal service needs an outbox, idempotent retries, dead-letter, replay, reconciliation, or controlled offline mode.
- A mobile client needs fiscal status and receipt artefacts without direct access to authority credentials.
Do Not Use When
Do not use for tax-law interpretation without the accounting doctrine and current source register, for generic payment integrations, or for visual receipt/UI styling without the design engine. Do not call a third-party fiscal API directly from an untrusted browser or mobile client.
Inputs
| Artifact | Required | Produced by |
|---|---|---|
| Context map and critical flows | yes | system architecture |
| Source system schema and writers | yes | database/POS audit |
| Jurisdiction technical pack and source register | yes | authority/onboarding owner |
| Tenant and identity model | yes for SaaS | SaaS/security architecture |
| API consumers and latency/failure budget | yes | product/operations |
| Accounting/tax mapping | yes where financial | accounting doctrine/controller |
If the technical pack or credentials are absent, build contracts and test fixtures only; block production activation and mark the gap explicitly.
Outputs
- jurisdiction-neutral fiscal port and adapter contract;
- tenant/client fiscal-profile and isolation map;
- versioned API/OpenAPI and error/idempotency contract;
- schema and expand-contract migration plan;
- canonical fiscal-document builder and validation rules;
- outbox/queue/retry/dead-letter/replay/reconciliation design;
- security, secrets, audit, observability, runbook, rollback, and UAT pack;
- client/mobile read model that exposes status and authority artefacts safely.
Acceptance requires executable or recorded contract evidence, negative tenant tests, duplicate/replay tests, redacted evidence, rollback instructions, and an explicit release state.
Non-negotiables
- The authenticated session or service context determines tenant scope; never
accept
tenant_id, TIN, or fiscal profile from a request body/query as the authority for routing. - A single-client deployment may use an implicit profile, but the same profile interface must exist so it can be isolated later.
- Every fiscal side effect has a stable tenant-scoped idempotency key. A timeout is an unknown result; reconcile before retrying.
- Store raw authority responses only under explicit retention and redaction rules. Never log private keys, tokens, passwords, or symmetric keys.
- Provider FDN/verification/QR artefacts are persisted atomically with the fiscal result and are never fabricated by a fake client in production.
- Online, authority-approved offline, manual exception, rejected, and disabled states are distinct. Offline is bounded by current authority rules.
- A queue is at-least-once unless the provider proves otherwise. Workers must be concurrency-safe, bounded, observable, replayable, and quarantine poison messages.
- A mobile app consumes ERP fiscal projections; it does not contain URA credentials/private keys or become a second fiscalisation writer.
Decision Rules
| Situation | Choose | Failure avoided |
|---|---|---|
| One legal entity, one deployment | One profile behind the common interface | Hard-coded identity that cannot evolve |
| Shared SaaS schema | Tenant-scoped rows, composite uniqueness/indexes, trusted context | Cross-tenant submission |
| Strong tenant boundary required | Schema/database isolation with profile resolver | Credential/data contamination |
| Immediate fiscal response required | Synchronous adapter within bounded timeout, then durable unknown state | False success or duplicate retry |
| Bursty/slow provider | Transactional outbox and worker | Lost side effects and blocked checkout |
| Offline permitted by authority | Isolated local/enabler store with deadline and upload audit | Unlimited unfiscalised backlog |
| Technical contract not current | Contract tests and blocked adapter activation | Production protocol drift |
Core Workflow
- Inventory writers and ownership. Find every invoice, receipt, payment, stock, correction, print, queue, and mobile sync path; select one canonical fiscalisation hook.
- Define the domain port. Use provider-neutral commands/results for fiscalise, query, correct, cancel, sync catalogue, and reconcile. Preserve provider codes and payload hashes alongside normalized states.
- Prove identity isolation. Resolve tenant/profile from trusted auth, validate branch/device/product ownership, and test wrong-tenant requests as indistinguishable not-found outcomes.
- Design contract first. Specify request/response schemas, auth, version, time, idempotency, rate limits, errors, telemetry, and consumer projections.
- Build durable state. Add additive schema changes, unique keys, immutable evidence, outbox claims, retry policy, dead-letter, replay authorization, and retention.
- Implement adapter. Keep EFRIS cryptography, envelope, dictionary IDs, endpoint, and response parsing inside the Uganda adapter; do not leak them through domain or mobile APIs.
- Integrate commercial paths. Route POS, manual, order, and agent sales through the canonical service; preserve accounting/stock transaction truth.
- Verify and release. Run unit, contract, integration, failure, isolation, offline, load, security, migration, UAT, and rollback checks. Activate only after current source-register and authority onboarding gates pass.
- Kaizen. Record the baseline, smallest experiment, evidence, standardised learning, owner, rollback, and next re-measurement in the engine.
Anti-Patterns
- Direct URA calls from Android or browser code. Fix: ERP gateway and safe read-only projection.
- Client-supplied tenant/TIN routing. Fix: derive profile from verified context.
- One global AES/key cache or offline store. Fix: tenant/profile-scoped key and device lifecycle with explicit isolation tests.
- New idempotency key after timeout. Fix: reconcile and reuse the original key.
FakeEfrisClientin production wiring. Fix: fail closed unless a configured, authorized adapter is selected.- Storing only normalized status. Fix: retain redacted provider code/message, hashes, version, and attempt evidence.
- Retrying validation or authorization failures. Fix: classify deterministic, transient, unknown, and manual-review outcomes.
- Adding
tenant_idto a table without backfill/index/rollback evidence. Fix: use expand-contract and prove zero unowned rows before enforcement.
Read Next
chwezi-accounting-doctrineelectronic fiscal taxing for tax and ledger rulesapi-design-first,database-design-engineering,distributed-systems-patterns, andreliability-engineeringmulti-tenant-saas-architecture,saas-erp-system-design, andpos-sales-operations-engineeringandroid-development,android-data-persistence, andandroid-tddfor downstream mobile projections
References
- Architecture and tenant isolation
- Adapter, API, and queue contract
- Uganda EFRIS source register
- Uganda EFRIS interface catalogue
- Uganda offline and device deployment
- Testing, observability, and release
- ERP mapping example