A school fees payment system in Uganda collects payments from parents via MTN MoMo and Airtel Money, matches each payment to the correct student, and gives the school a dashboard showing who has paid and who has not. The core technical components are: a student/parent database, a payment API integration with MoMo Collections and Airtel Money, callback handlers that update payment records, a reconciliation system for matching payments to students, and a reporting dashboard. This is a real project you can build for your portfolio, and it solves a problem that thousands of Ugandan schools face every term.
Walk into most primary and secondary schools in Uganda and ask how they collect fees. The answer is almost always the same: parents bring cash to the school bursar, or they send money via MoMo and then send a screenshot of the transaction to a teacher on WhatsApp. The school manually records the payment in a ledger or spreadsheet. At the end of the term, someone spends hours cross-referencing who has paid and who has not.
This process is slow, error-prone, and frustrating for everyone involved. Parents worry their payment was not recorded. Bursars spend days on reconciliation instead of their actual work. Headteachers cannot get a real-time picture of fee collection status. And when a parent disputes a payment, finding the record takes time that nobody has.
The solution is a system where parents pay school fees via MTN MoMo or Airtel Money through a structured process, and the system automatically records the payment, matches it to the correct student, and updates a dashboard. The school can see in real time who has paid, who has a balance, and how much revenue has been collected. No screenshots. No manual ledgers. No reconciliation headaches.
This is not a theoretical exercise. This is a product that Ugandan schools will pay for. Several startups have built versions of this, and the market is far from saturated. Building it is also one of the strongest portfolio projects a Ugandan developer can have, because it demonstrates full-stack skills plus mobile money integration plus understanding of a local business problem.
The system has five main components. You do not need to build them all at once, but understanding how they fit together is important before you write any code.
1. Student and Parent Database
A database (PostgreSQL recommended) that stores student records, parent information, fee structures per term, and payment history. Each student has a unique ID. Each payment is linked to a student ID. This is your source of truth for who owes what.
2. Payment Request Module
When a parent wants to pay, the system sends a payment request to the MoMo Collections API (or Airtel Money API). The request includes the parent's phone number, the amount in UGX, and a reference that links back to the student record. MoMo sends a USSD prompt to the parent's phone. The parent confirms by entering their PIN.
3. Callback Handler
After the parent confirms (or declines, or the request times out), MoMo sends a callback to your server. Your callback handler receives this POST request, verifies its authenticity, and updates the payment record in your database. This is the most important piece to get right. If your callback handler fails or mishandles a response, payments get lost.
4. Reconciliation Engine
This matches payments to students. In the simple case, a parent pays from a registered phone number, and the system matches by phone number and reference. In the messy real-world case, a grandmother pays from a different number, a parent makes a partial payment, or someone pays for two children in one transaction. Your reconciliation logic needs to handle these edge cases.
5. School Dashboard
A web-based dashboard (React front-end) where the school bursar and headteacher can view payment status by class, by student, and by date range. Export to CSV for their own records. Send payment reminders to parents who have outstanding balances.
This is the same architecture used by any mobile money collection system in Uganda, whether for school fees, clinic payments, rent, or membership dues. Learn it once and you can adapt it to any collection use case.
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
Here is what happens step by step when a parent pays school fees through the system.
The same flow applies for Airtel Money, with different API endpoints and authentication methods. Supporting both MoMo and Airtel Money is important because Ugandan parents use both networks. Some families have one parent on MTN and the other on Airtel.
McTaba teaches this exact payment callback pattern using M-Pesa Integration for Developers (KES 9,999, approximately UGX 280,000). The architecture is the same across M-Pesa, MoMo, and Airtel Money. The request-callback model, the sandbox testing flow, the error handling patterns: learn one, and adapting to the others is a matter of changing endpoints and authentication, not learning a new architecture.
Tutorials show you how to send a payment request and receive a callback. They rarely cover what happens when real people use the system in ways you did not anticipate. Here are the reconciliation challenges you will face in a Ugandan school fees system.
Partial payments. Fee per term is UGX 500,000, but the parent sends UGX 200,000 now and plans to send the rest next month. Your system needs to track partial payments and show the remaining balance accurately.
Payments from unknown numbers. The parent registered their number, but the grandmother sends the money from her phone. Your system receives a callback from a number not in the database. You need a process for matching these payments, whether automated (by allowing parents to register multiple numbers) or manual (flagging unmatched payments for the bursar to review).
Multiple children. A parent with three children at the same school might send one payment intended to cover all three. Your system needs to handle splitting a single payment across multiple student accounts, or at minimum, flag it for manual allocation.
Duplicate transactions. Network issues can cause MoMo to send the same callback twice. If your system processes both, you will double-count the payment. Use the transaction reference as a unique key and check for duplicates before updating records.
Failed callbacks. Sometimes the callback does not arrive. Network issues between MoMo's servers and yours, your server being temporarily down, a timeout. You need a fallback: polling the MoMo API for transaction status if the callback does not arrive within a reasonable time (5 to 10 minutes).
These problems are why developers who can build complete payment systems are well-paid in Uganda. Anyone can follow a tutorial to send a payment request. Building a system that handles the messy reality of how Ugandan families actually pay school fees is the valuable skill.
The school fees system architecture applies directly to any Ugandan business that collects recurring or one-time payments. Swap "student" for "patient," "tenant," or "member," and the system works the same way.
Medical clinics: Collect patient fees via MoMo. Track which patients have paid. Generate receipts for insurance claims.
Landlords and property managers: Collect monthly rent via mobile money. Send automated reminders when rent is due. Track payment history per tenant.
Churches, mosques, and community organizations: Collect membership dues, tithe, or event fees. Track contributions per member. Generate reports for leadership.
Event organizers: Sell tickets via MoMo. Generate QR codes for ticket verification. Track attendance and revenue.
Small retail businesses: Accept payments for goods delivered. Track who has paid and who has outstanding credit.
Each of these use cases is a potential freelance project or product business for a Ugandan developer. The school fees system teaches you the patterns. Every subsequent implementation gets easier because you already understand the callback flow, the reconciliation logic, and the edge cases.
If you want to build this system, here is the recommended sequence.
Prerequisites: You need working knowledge of React (front-end), Node.js with Express (back-end), PostgreSQL (database), and basic API integration skills. If you do not have these yet, follow the right order to learn coding in Uganda guide first. Steps 1 through 5 prepare you for this project.
Phase 1: Database and basic CRUD. Design your database schema (students, parents, fee structures, payments). Build the API endpoints for creating and reading records. Build a basic React dashboard that displays student data. No payment integration yet.
Phase 2: MoMo sandbox integration. Sign up for the MoMo Developer Portal. Get sandbox credentials. Implement the payment request flow. Build your callback handler. Test with simulated transactions. Make sure you can send a request, receive a callback, and update your database correctly.
Phase 3: Reconciliation and edge cases. Handle partial payments, unknown numbers, duplicates, and failed callbacks. This is where the project goes from "tutorial quality" to "production quality."
Phase 4: Dashboard and reporting. Build the school-facing dashboard with real-time payment status, class-level summaries, and CSV export. Add the ability to send payment reminders.
Deploy the whole thing to Vercel (front-end) and Railway or Render (back-end). Put the code on GitHub with clear documentation. This single project demonstrates full-stack skills, mobile money integration, and understanding of a real Ugandan business problem. It is one of the strongest portfolio pieces a Ugandan developer can have.
If you want to learn the payment integration patterns before building this, McTaba's Full-Stack Software + AI Engineering course (KES 120,000, approximately UGX 3,400,000) covers the entire stack from database design through payment integration and deployment.
Create a free McTaba Academy account. Access starter lessons, join the community, and explore at your own pace.
Create Free Account