Skip to content

Securing M-PESA Callbacks Without a Signature

· m-pesa, security, woocommerce

Safaricom’s Daraja API calls your callback URL when an STK Push completes, but it sends no signature and cannot set auth headers. So how do you trust it?

Defense in depth

  1. Secret path token. Register the callback at a URL with a random token embedded in the path, compared in constant time. A guessed URL gets nothing.
  2. Validate structure. Reject any payload missing CheckoutRequestID before doing any work.
  3. Verify the amount. This is the one that matters: confirm the paid amount equals the order total before completing payment. Never take the callback’s word for the money.
  4. Be idempotent. Daraja retries. A paid order must never be processed twice.

Bonus: IP allowlisting

Where the host supports it, restrict the endpoint to Safaricom’s published callback IP ranges as a secondary control — but never rely on it alone.