Building a School Fees and SME Payment System with MoMo in Uganda
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.
The Problem You Are Solving
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.
How the System Works (Architecture Overview)
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.
The Payment Flow in Detail
Here is what happens step by step when a parent pays school fees through the system.
- Parent initiates payment. The parent opens the system (a web app, a USSD menu, or a WhatsApp bot) and selects their child. The system shows the outstanding balance.
- System sends request to MoMo. Your server sends a POST request to the MoMo Collections API with the parent's phone number, the amount in UGX, and a unique transaction reference that includes the student ID.
- MoMo prompts the parent. A USSD prompt appears on the parent's phone asking them to confirm the payment by entering their MoMo PIN.
- Parent confirms or declines. If they confirm, MoMo processes the payment. If they decline or the prompt times out (typically 60 to 90 seconds), the transaction fails.
- MoMo sends callback. MoMo sends a POST request to your callback URL with the transaction result: success, failure, or timeout. Your server must be publicly accessible to receive this callback.
- System updates records. If successful, the payment is recorded against the student's account. The outstanding balance is reduced. The dashboard updates in real time.
- Confirmation sent. The system sends an SMS or WhatsApp message to the parent confirming the payment, including the student's name, the amount paid, and the remaining balance.
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.
Reconciliation: The Hard Part Nobody Talks About
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.
Beyond Schools: The Same Architecture for Any Ugandan SME
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.
How to Start Building This
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.
Key Takeaways
- ✓School fees collection via mobile money is one of the most practical and hirable use cases for Ugandan developers. Thousands of schools manage this process manually with spreadsheets, receipts, and cash, and they are ready to pay a developer to automate it.
- ✓The core architecture uses the MoMo Collections API (and Airtel Money equivalent) with a request-callback pattern. The parent initiates payment, confirms on their phone, and your system receives a callback with the transaction result.
- ✓Reconciliation is the hardest part and the part most tutorials skip. Matching a payment to the correct student when parents may pay from different phone numbers, make partial payments, or pay for multiple children requires careful database design.
- ✓This project works as both a portfolio piece and a real business. Schools will pay UGX 200,000 to UGX 1,000,000 per term for a working system. Build it for your portfolio, then sell it.
- ✓The same payment architecture applies to any Ugandan SME that needs to collect money: clinic fees, rent collection, event tickets, membership dues.
Frequently Asked Questions
- How much do schools pay for a payment system like this?
- Pricing varies widely. Small primary schools might pay UGX 200,000 to UGX 500,000 per term. Larger secondary schools or those with multiple branches pay UGX 500,000 to UGX 2,000,000 per term, or a percentage of transactions processed. Some developers charge a setup fee plus a monthly subscription. Research what existing solutions charge in your target market before setting your prices.
- Do I need production MoMo API credentials to build this as a portfolio project?
- No. The MoMo sandbox environment simulates the full payment flow without moving real money. You can build, test, and demonstrate the entire system using sandbox credentials. When you are ready to deploy for a real school, you apply for production credentials through MTN Uganda.
- Can I build this using Flutterwave or Pesapal instead of direct MoMo API?
- Yes. Payment aggregators like Flutterwave and Pesapal handle both MoMo and Airtel Money through a single API, which simplifies integration. The trade-off is that they charge transaction fees on top of the mobile money provider fees. For a portfolio project, either approach works. For a production system, compare the costs and decide based on your client's volume and budget.
- Is this the same architecture used for M-Pesa in Kenya?
- Yes. The request-callback pattern is fundamentally the same across M-Pesa (Daraja API), MTN MoMo, and Airtel Money. The endpoint URLs, authentication methods, and parameter names differ, but the flow is identical: send a request, the customer confirms on their phone, receive a callback with the result. A developer who builds this with MoMo can adapt it to M-Pesa or Airtel Money with minimal effort.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon