PesaGuard: Building Real-Time Reconciliation for M-Pesa, and Getting It Into a Real Customer's Hands
If you've ever built anything on top of M-Pesa, you know the pain: money moves in seconds, but knowing what actually happened — which transaction matched which order, which webhook fired twice, which payment silently vanished — often takes hours of manual spreadsheet work. That gap is what PesaGuard exists to close.
I'm excited to share that PesaGuard, my real-time M-Pesa reconciliation and anomaly detection tool, has hit a real milestone: it's live, deployed, and running against real transaction data for its first pilot customer.
The Problem
Most businesses running M-Pesa payments — from small merchants to fintech platforms — reconcile manually. Someone downloads a CSV from the Safaricom portal, opens it next to their internal ledger, and starts cross-referencing by eye. It's slow, it's error-prone, and it means fraud or failed transactions can go unnoticed for days.
PesaGuard watches transactions as they happen, matches them against expected records in real time, and flags anomalies — duplicate charges, mismatched amounts, missing callbacks — the moment they occur instead of at month-end.
What It Does
At its core, PesaGuard is a streaming reconciliation engine built around the Safaricom Daraja API:
Real-time ingestion of M-Pesa transaction events as they land
Automated matching against internal order/payment records
Anomaly detection for duplicates, mismatches, and suspicious patterns
Alerting so issues surface in minutes, not at the end of the month
It's currently deployed on Render and running against a live pilot customer's transaction flow — which has been the most valuable part of this whole process. Nothing exposes the gap between "works in my test suite" and "works in production" quite like a real business depending on your webhook handler at 2am.
What I've Learned Getting to MVP
A few things stood out on the way here:
Ship before it feels ready. It was tempting to keep expanding the architecture — more edge cases, more configurability — before ever showing it to a real user. The moment I put a rough version in front of an actual pilot customer, the priorities became obvious in a way no amount of planning could replicate.
Idempotency is not optional. M-Pesa callbacks can and do arrive more than once. If your system isn't built to safely handle a duplicate webhook from the start, you will eventually double-count someone's money. Designing for this from day one — rather than bolting it on later — has been core to how I approach this project.
Production hardening is its own phase. Getting to MVP and getting to "I trust this with someone else's transaction data" are different bars. Right now my focus has shifted from adding features to tightening webhook idempotency, security, and observability — the unglamorous work that actually earns trust.
What's Next
The immediate focus is hardening: making sure PesaGuard behaves correctly under retries, failures, and edge cases before taking on more pilot customers. If you're building on M-Pesa and reconciliation pain sounds familiar, I'd love to hear how you're currently solving it.
I'm Victor Kipruto Rop, building under the DataForge brand — focused on data engineering and fintech infrastructure for East Africa. Follow along as PesaGuard grows from pilot to production.
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (1)
Does Daraja give you any way to prove a callback really came from Safaricom? Last time I looked the payload carried no signature, so most setups end up allowlisting their IP ranges or re-querying transaction status before trusting the money moved. Since you're already deep in the idempotency and hardening pass, I'm curious which of those PesaGuard leans on.