Skip to main content
All posts

Business Systems

Taking an M-Pesa Integration from Sandbox to Production

9 min read

Kenyan retail counter using a phone payment and connected operations workflow

A successful sandbox STK Push proves only that one happy path can start. Production readiness is about knowing what happened when callbacks arrive late, users retry, phones are offline, or the amount in your database does not match the money received.

Model payment as states

Create a payment record before requesting the STK Push and give it your own immutable reference. The record should move through explicit states such as initiated, pending, paid, cancelled, failed, and reconciliation-required. Do not infer payment from the browser returning to a success screen.

Safaricom callbacks are the source of the asynchronous result, but your handler must tolerate retries and out-of-order delivery. Store the provider identifiers and raw result safely enough to investigate a dispute without exposing secrets.

  • Make callback processing idempotent
  • Reject amount or account-reference mismatches
  • Preserve provider and internal transaction identifiers
  • Use server time consistently and record every transition

Design for uncertainty

A customer can approve the prompt while your page loses connectivity. Show a pending state that can be revisited, and let the order status come from the backend. Repeated taps must not create repeated orders or silently collect payment twice.

Write customer-facing messages for cancellation, insufficient funds, timeout, and delayed confirmation. Each message should say what is known, what the customer should do, and how to contact support with a useful reference.

  • Disable duplicate initiation briefly but allow a deliberate retry
  • Separate payment status from fulfilment status
  • Provide a receipt or confirmation reference
  • Never ask support staff to search by phone number alone

Reconcile and operate

Production systems need a daily comparison between provider records and internal records. Flag paid transactions without orders, orders marked paid without a matching transaction, and amount differences. Reconciliation is a normal operating process, not an admission that the integration failed.

Before launch, rotate credentials, restrict access, verify the callback domain over HTTPS, and document who can refund, reverse, or manually resolve a payment. Test with small real transactions and record the evidence.

  • Alert on callback failure rates and long-pending payments
  • Keep credentials out of client-side code and logs
  • Document escalation and refund authority
  • Test restore procedures for the payment database
Chat with me