Case study · Taxation · Government Revenue
GRA MTS
Digitised taxpayer registration, payments and reporting for the informal sector on behalf of the Ghana Revenue Authority.
- Taxpayer payment processing
- Minutes → seconds
- Role
- System Modelling · Backend Architecture
- Team
- Co-led ~4 engineers
- Domain
- Taxation · Government Revenue
Overview
GRA MTS manages and taxes the informal sector. A core API sits over the main database and owns taxpayer management, payments and tax bill generation. Tax officers work through a dedicated portal, taxpayers self-register and pay through a mobile API, and approved third parties can register taxpayers and collect payments through a separate integration API.
The problem
Informal-sector taxpayers were registered on paper. Records could go missing, payments were slow to process and difficult to trace, and the authority had limited visibility into who had registered and paid.
My role
- Modelled the domain and set up the backend architecture from the start of the project.
- Led implementation of taxpayer registration across officer, self-service and third-party channels.
- Led implementation of taxpayer payments and payment tracking.
- Wrote the report queries used with FastReport for operational reporting.
- Co-led a team of around four engineers.
Architecture
-
Channels
- Tax officer portal
- Mobile app
- Third-party partners
-
APIs
- Portal API
- Mobile API Self-registration & payments
- Third-Party API Delegated registration & collection
-
Core
- Core API Taxpayers, payments, tax bills
- Reporting FastReport
-
Platform
- PostgreSQL / SQL Server
- Keycloak
- Azure
Scale
- API surfaces
- 4
- Core, officer portal, mobile and third-party.
- Registration channels
- 3
- Tax officers, taxpayers and approved third parties.
- Engineers co-led
- ~4
Engineering challenges
One domain, many channels
Tax officers, taxpayers and third parties all register taxpayers and take payments, but with different permissions, validation rules and audit requirements. The rules have to stay consistent regardless of the entry point.
Payments that can be trusted
Payments arrive from several channels and must be recorded once, linked to the right taxpayer and tax bill, and be traceable afterwards. Duplicate or orphaned payments directly affect revenue reporting.
Reporting on operational data
Revenue officers need reports over the same data that is being written throughout the day, with filters that span taxpayers, locations and time periods.
Approach
- Core API as the single owner of business rules. Channel-specific APIs handle authentication, shape and validation of requests, then delegate to the core for anything that changes taxpayer or payment state.
- Payment flows designed for traceability. Each payment carries references that tie it to a taxpayer and bill, so it can be reconciled and audited later.
- Report queries written for the reporting engine. Queries were built and tuned alongside the FastReport templates, using Dapper where the query shape needed to be controlled precisely.
- Keycloak for identity across channels. Officers, taxpayers and partners authenticate against one identity provider with role-based access per channel.
Impact
Paper → digital
Taxpayer registration
Registration moved away from paper records that could be lost or altered.
Minutes → seconds
Payment processing
-
Traceable payments
Every payment is recorded against a taxpayer, improving accountability and follow-up.
Technologies
- .NET
- C#
- PostgreSQL
- SQL Server
- Entity Framework
- Dapper
- FastReport
- Keycloak
- Azure
Lessons
- 01 Modelling the domain alongside the people who administer the tax surfaced edge cases that a schema designed in isolation would have missed.
- 02 Putting every channel behind a single core API kept business rules in one place, even though it added a hop for each client.
- 03 Reporting requirements should shape the data model early. Retrofitting reports onto a transactional schema is where most of the query work ends up.