The M-Pesa portfolio project that gets you hired is a working e-commerce checkout with STK Push payment, server-side verification, receipt generation, and a transaction admin dashboard. Build it with Node.js, React, and PostgreSQL. Deploy it live with a real URL. This single project demonstrates API integration, async callback handling, database design, and full-stack competence in a way that generic projects cannot.
Hiring managers at Kenyan tech companies see the same portfolio projects over and over. A to-do app. A weather dashboard. A Twitter clone. A calculator. These projects prove you can follow a tutorial. They do not prove you can build software for the Kenyan market.
An M-Pesa-integrated e-commerce checkout, on the other hand, signals something completely different. It tells a hiring manager: this developer understands the African tech stack. They can handle asynchronous workflows. They have dealt with real-world API integrations, not just CRUD operations. They think about failure cases, not just happy paths.
Here is the reality of Kenyan tech hiring in 2026. Nearly every product company in Nairobi needs M-Pesa integration at some point. Developers who already understand Daraja, STK Push, and callback handling are immediately more valuable than developers who would need to learn it on the job. Your portfolio project is proof that you already have this skill.
The project we are building is a small e-commerce store with a real checkout flow. Customers browse products, add items to a cart, and pay via M-Pesa STK Push. The server handles the payment callback, verifies the transaction, generates a receipt, and updates the order status. An admin dashboard shows transaction history and revenue metrics. It is not a massive project (you can build it in 2 to 3 weeks), but it covers enough ground to demonstrate serious capability.
Before writing any code, let us define exactly what this project includes. Scope creep kills portfolio projects. Be disciplined about what is in and what is out.
User registration and login (for the customer side). Product management (admin CRUD for products). Inventory tracking. Shipping calculations. Email notifications. These features are useful in a real product, but they distract from the core story your portfolio project tells: "I can integrate M-Pesa and build a real payment flow." Keep the focus tight.
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
Choose technologies that align with what Kenyan companies actually use. This is a portfolio project, and the stack itself sends a signal to employers.
Express is the most common Node.js framework in Kenyan job postings. Using it shows you are comfortable with the standard stack. TypeScript is a bonus. If you are comfortable with it, use it. If not, plain JavaScript is fine. The M-Pesa integration logic is the same either way.
Your backend handles: Daraja API calls (OAuth token management, STK Push initiation), callback processing, transaction database operations, and the admin API endpoints.
React is the most requested frontend framework in Kenyan and African tech hiring. Build the customer storefront and admin dashboard as a React SPA. Use React Router for navigation between the store, cart, checkout, and admin pages.
For styling, Tailwind CSS is a solid choice. It is popular, productive, and shows you can work with modern CSS tooling. If you prefer plain CSS or another framework, that is fine too. The payment integration is the star of this project, not the CSS.
PostgreSQL is the standard production database for Kenyan tech companies. Use it for storing products, orders, and transaction records. You can use Supabase (free tier) for a hosted PostgreSQL instance with zero configuration, or set up a local PostgreSQL server.
Your schema needs three main tables: products (id, name, price, image_url), orders (id, customer_phone, total_amount, status, created_at), and transactions (id, order_id, mpesa_receipt, checkout_request_id, result_code, amount, status, callback_payload, created_at). Keep it simple but complete.
The backend needs a server that can receive POST requests (for Daraja callbacks). Railway, Render, or a basic VPS on Hetzner all work. The frontend can go on Vercel, Netlify, or be served from the same server as the backend. The key is having a live URL that anyone can visit. A project that only runs on localhost is not a portfolio piece.
This is the section that matters most, both for the project and for impressing employers. The payment flow is where you demonstrate real engineering judgment.
When the customer clicks "Pay with M-Pesa," your frontend sends a POST request to your backend with the order details and the customer's phone number. Your backend does three things: creates an order record in the database with status "pending," generates a Daraja OAuth token (or uses a cached one), and sends the STK Push request to Daraja with the order amount, phone number, and callback URL.
Daraja responds with a CheckoutRequestID. Store this in your transaction record. You will need it to match the callback to the correct order later.
After initiating the STK Push, your frontend should show a clear waiting state. "We sent a payment request to your phone. Enter your M-Pesa PIN to complete the payment." Include a timer or animation so the customer knows something is happening. This is a UX detail, but it matters. Customers who stare at a blank screen while waiting for the STK Push will close the tab.
On the backend, you can use polling or WebSockets to notify the frontend when the callback arrives. Polling is simpler: the frontend sends a GET request every 3 seconds to check the transaction status. WebSockets are cleaner but add complexity. For a portfolio project, polling is perfectly fine.
When Daraja posts the callback to your server, parse the payload to extract the ResultCode, MpesaReceiptNumber, and the original CheckoutRequestID. Match the CheckoutRequestID to your pending transaction. If ResultCode is 0 (success), update the transaction status to "completed," update the order status to "paid," and store the M-Pesa receipt number. If the ResultCode indicates failure, update the status accordingly.
This is where idempotency matters. Check whether the transaction has already been processed before taking action. If the callback arrives twice (rare but possible), your second processing should be a no-op, not a duplicate credit.
After a successful payment, display a receipt to the customer. Include: order items and quantities, total amount paid (in KES), M-Pesa receipt number (this is what the customer will use for any disputes), date and time, and your business name. If you want to go the extra mile, generate a downloadable PDF receipt using a library like jsPDF or pdfmake. This is a nice touch that shows attention to the complete user experience.
Add a background verification step that queries the Daraja Transaction Status API for any transaction that has been pending for more than 2 minutes. This catches cases where the callback was lost (your server was briefly down, network issue, Daraja hiccup). This reconciliation step is what separates a tutorial project from production-quality code, and hiring managers notice it.
Most junior developer portfolios stop at the customer-facing interface. Adding an admin dashboard signals that you think about the full picture: operations, monitoring, and the business side of software.
A table showing all transactions, newest first. Columns: date, customer phone (mask the middle digits for privacy, like 2547***5678), amount, M-Pesa receipt number, status (with color-coded badges: green for success, red for failed, yellow for pending). Add search (by receipt number or phone) and filter (by status, by date range).
Pagination is important. If your table shows 1,000 transactions on a single page, it looks amateurish and performs poorly. Implement server-side pagination with 20 to 50 rows per page. This is a small detail that shows you think about performance and usability.
Show aggregate numbers: total revenue today, this week, this month. A simple bar chart showing daily revenue for the last 7 or 30 days. You do not need a complex charting library. Recharts or Chart.js handles this with minimal code.
These metrics are straightforward database queries (SUM with date filters), but they demonstrate that you can write aggregate queries and present data meaningfully. Every SaaS company has dashboards like this, so showing you can build one is directly relevant to most jobs.
A list of orders with their payment status and fulfillment status. Let the admin click into an order to see details: items ordered, payment transaction details, and the ability to update the fulfillment status (processing, shipped, completed). Simple CRUD, but it rounds out the project from a "payment demo" into a "mini product."
Protect the admin dashboard with a simple login. Even a hardcoded username and password behind a JWT token is enough for a portfolio project. The point is not building a full auth system. The point is showing that you understand the admin interface should not be publicly accessible. Use a simple middleware that checks for a valid JWT on all admin API routes.
Building the project is half the work. Presenting it well is the other half. Most junior developers under-invest in how they showcase their work, and it costs them interviews.
Your GitHub README is the first thing a hiring manager sees. It should include:
When discussing this project in an interview, focus on the decisions you made, not just the features you built. Explain why you implemented a reconciliation process for lost callbacks. Describe how you handle idempotency in callback processing. Talk about what you would change if the project needed to handle 10,000 transactions per day instead of 10.
Employers are not looking for perfection. They are looking for evidence that you think about edge cases, understand async workflows, and can reason about production concerns. This project gives you concrete examples to discuss in every technical interview.
Describe the project with specific outcomes: "Built an e-commerce platform with M-Pesa STK Push checkout, async callback processing, transaction reconciliation, and an admin dashboard with revenue analytics. Deployed live with end-to-end payment flow." That is one bullet point that carries more weight than three lines about a to-do app.
If you have a personal portfolio website, give this project its own page. Include a video walkthrough (2 to 3 minutes, recorded with Loom) showing the complete payment flow from adding items to cart through receiving the M-Pesa receipt. Video is underused in developer portfolios and makes a strong impression.
The core project (e-commerce checkout with STK Push, callback handling, receipts, and admin dashboard) is enough to impress. But if you want to stand out even more, here are stretch goals worth considering.
WhatsApp receipt notification. After a successful payment, send the receipt to the customer via WhatsApp using the Business API. This demonstrates multi-API integration and knowledge of another critical African stack technology. Even a simple text message with the receipt details is impressive.
B2C refund flow. Add the ability for an admin to refund a customer through the Daraja B2C API. The admin clicks "Refund" on a transaction, your server sends money back to the customer's M-Pesa. This shows you understand both sides of the M-Pesa API, not just collecting money but sending it back.
Real-time dashboard updates. Use WebSockets (Socket.io) to push new transaction notifications to the admin dashboard in real time. When a payment callback arrives, the admin dashboard updates immediately without a page refresh. This adds a real-time layer that demonstrates you can build beyond request-response patterns.
Transaction analytics. Add more sophisticated analytics: average transaction value, success/failure rate over time, peak payment hours, and repeat customer identification. These are the kinds of metrics real businesses care about, and building them shows product thinking alongside engineering skills.
Mobile-responsive checkout. Ensure the entire checkout flow works perfectly on mobile. In Kenya, most M-Pesa transactions happen on mobile devices. A checkout that only works on desktop misses the primary use case. Test on real phones, not just browser dev tools.
Each stretch goal adds maybe 2 to 3 days of work but significantly increases the project's impact. Pick one or two that interest you. Do not try to add all of them.
If you want structured guidance building this project with mentor code reviews and a cohort of peers, McTaba's M-Pesa Integration course (KES 9,999) walks through a similar project end to end. But the outline above is complete enough to build independently. The Daraja documentation, community forums, and the testing strategies from our other M-Pesa guides will get you through any blockers.
KES 9,999
Master Daraja API, STK Push, C2B, B2C, and callback handling. Build a real payment flow from scratch. 10 modules, 57 lessons.
Enrol in M-Pesa Integration