The Daraja API documentation will get you to a successful STK push in an afternoon. It will not prepare you for the transactions that fail in ways your happy path never imagined. Here is what production actually requires.
Never trust the callback alone
Your callback URL is a public endpoint. Anyone can post to it. Validate every callback against your own record of the transaction: does this checkout request ID exist, is it still pending, does the amount match what was ordered? Then query the transaction status API to confirm independently before releasing goods.
Callbacks arrive twice, or late, or never
All three happen. Design accordingly:
- Make callback processing idempotent - keyed on the M-Pesa receipt number, so the second delivery is a no-op.
- Run a reconciliation job that polls pending transactions older than a few minutes and resolves them from the status API.
- Keep a pending state that survives an app restart, so a customer returning to the page sees the truth.
Handle the human timeouts
The STK prompt appears on the customer's phone and waits for a PIN. They might be driving, have a dead battery, or simply ignore it. Your UI needs a clear pending state with an honest message, a resend option after a sensible interval, and a graceful expiry that does not leave an order stuck forever.
Test with real money
The sandbox does not reproduce every production behaviour. Before launch, run a set of live transactions of one shilling each: successful payment, cancelled prompt, wrong PIN, timeout, insufficient funds. Watch what your system does in each case. Every one of those paths will occur in the first week.
Reconciliation is a feature, not a script
Finance needs to match M-Pesa statements against orders without a developer. Build a reconciliation view: transactions with no matching order, orders with no matching transaction, amount mismatches, and a way to resolve each manually with a note. This gets used every single day, and building it late means someone does it in a spreadsheet in the meantime.
The integration is the easy part. Everything around the integration is the work.
Brian Ochieng
Trenax
Working on something this touches on? We are happy to talk it through, whether or not it turns into a project.
Book a call