Skip to content
All work

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

  1. Channels

    • Tax officer portal
    • Mobile app
    • Third-party partners
  2. APIs

    • Portal API
    • Mobile API Self-registration & payments
    • Third-Party API Delegated registration & collection
  3. Core

    • Core API Taxpayers, payments, tax bills
    • Reporting FastReport
  4. Platform

    • PostgreSQL / SQL Server
    • Keycloak
    • Azure
Conceptual view of the API boundaries. Partner and infrastructure details omitted. Areas I built or led

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

  1. 01 Modelling the domain alongside the people who administer the tax surfaced edge cases that a schema designed in isolation would have missed.
  2. 02 Putting every channel behind a single core API kept business rules in one place, even though it added a hop for each client.
  3. 03 Reporting requirements should shape the data model early. Retrofitting reports onto a transactional schema is where most of the query work ends up.

Let’s build reliable systems.

I’m interested in teams working on hard backend problems — data-heavy platforms, integrations and systems that have to stay correct under load. Open to remote roles as a:

  • Senior Backend Engineer
  • Senior .NET Engineer
  • Senior Software Engineer
  • Backend-focused Full-Stack Engineer