Achekam

When an M-Pesa payment prompt fails

Why an M-Pesa payment prompt to a customer fails or is cancelled, what Safaricom's result codes mean and how the real outcome is confirmed.

By Achekam · · 4 min read · For Running a business businesses in Kenya

STK push failed cancelled

The customer is standing at the counter, or on the phone, ready to pay. You send the M-Pesa prompt. Nothing appears on their screen, or it appears and then vanishes, or they say they entered their PIN but your system still shows the invoice as unpaid. Now both of you are unsure whether money has moved.

Most of that uncertainty disappears once you know how the prompt works and how Safaricom reports the outcome. This article explains the journey of a payment prompt, what the result codes mean, the technical failure that stops prompts being sent at all, and how to confirm what actually happened before anyone pays twice.

How the prompt reaches the customer

Safaricom calls the service M-PESA Express, also known as Lipa na M-PESA Online, and the payment prompt is often called an STK push. Safaricom describes it as a merchant-initiated C2B payment: the business sends a payment prompt to the customer's M-PESA-registered phone, and the customer approves it by entering their M-PESA PIN.

Two things follow from that description. The prompt goes to the number registered on M-PESA, so a mistyped number or a customer's second line will not work. And nothing is paid until the customer enters their PIN; the prompt is a request, not a charge.

Result codes, including cancellation by the customer

When the customer responds, or fails to, Safaricom reports back. It says a successful M-PESA Express callback returns ResultCode 0, with metadata that includes the amount, the M-PESA receipt number, the transaction date and the phone number. Any other code means failure. The example Safaricom gives is 1032, "Request cancelled by user".

So the rule is simple: 0 is a payment; everything else is not. A 1032 means the request was cancelled on the customer's side. That is not a fault in your set-up, and if the customer still wants to pay, the answer is to send a fresh prompt.

When you see a code you do not recognise, look it up in Safaricom's documentation rather than guessing, and treat the invoice as unpaid until a 0 comes back. It also helps to note the code against the invoice whenever a payment fails. If the customer later disputes what happened, that note is the record of what Safaricom reported at the time, rather than anyone's memory of the conversation at the counter.

Expired access tokens

Some failures happen before the customer sees anything. Every request to Safaricom's Daraja platform carries an access token, and Safaricom says these tokens expire hourly and must be regenerated with the app's consumer key and consumer secret. An expired or wrong token returns error 404.001.03, "Invalid Access Token".

If your prompts suddenly stop reaching any customer at all, rather than one customer cancelling, an access problem like this is a likely suspect. Check that the consumer key and secret in your set-up are the current ones for your live app.

Querying the status with the CheckoutRequestID

What if no result arrives? Safaricom provides the M-Pesa Express Query API, which checks the status of an STK push payment using the CheckoutRequestID returned when the payment was started. The query carries the business short code, a password built from the short code, passkey and a timestamp, and the timestamp itself.

Safaricom says that in the query response, a ResultCode of 0 means the payment was processed successfully, any other code means an error or failure, and 1032 again means the customer cancelled. Safaricom's M-Pesa Express Query documentation describes the request and the response codes, and is worth passing to whoever looks after your integration.

How Achekam confirms with Safaricom before recording

In Achekam, a Kenyan business can send an M-Pesa payment prompt to a customer's phone for a shilling invoice, paid to its own paybill or Buy Goods till, through its own Daraja app. The payment is confirmed with Safaricom before it counts: Achekam records it only after that confirmation, not on the strength of a screenshot or a customer's word.

A few details are worth knowing:

  • Only whole shillings are requested. If the invoice has cents, they stay due on the invoice.
  • The same phone can be prompted once a minute, so a customer who cancels by mistake can be prompted again after a short wait.
  • Production use needs Safaricom Go-Live, so a business that has not completed it cannot prompt real customers yet. The steps are covered in taking M-Pesa live.
  • The address Safaricom calls back avoids the word "mpesa", because Safaricom refuses addresses containing it.

If the notification from Safaricom never arrives, the payment is not lost. Achekam asks the provider about open payments on a schedule and while the pay page is open, so a payment the customer did approve is still picked up. More on that in recovering M-Pesa payments whose alerts never came.

What to tell the customer

A calm script helps when a prompt fails:

  1. "The prompt shows as cancelled on our side. Shall I send it again?" Then wait a minute before resending.
  2. "Please check the number the prompt should go to is the one registered on M-PESA."
  3. "If you did enter your PIN, don't pay again yet. We are confirming with Safaricom, and the invoice will update once they confirm."
  4. "If the amount has cents, the prompt asks for the whole shillings, and the balance stays on the invoice."

For very large invoices, a prompt may not be the right tool at all; see M-Pesa limits and large invoices. For everyday sales, the habit that matters most is the one Achekam already follows: an invoice is paid when Safaricom says so, and not before.

General guidance only, not advice on your own circumstances. Tax and payroll rules change: check the current position with the authority or your adviser.

Related articles

More on Running a business

See how Achekam handles it with your own records: create your account