STK Query
By the end of this track you can charge a phone and confirm the result.
0/4 finished
Step 1
The idea
If the callback is late or lost, ask Daraja directly using the CheckoutRequestID.
Step 2
How it works
When you need it
Callbacks can be late, or never arrive: your server was down, the URL was wrong, or the network dropped. STK Query asks Daraja directly what happened to one CheckoutRequestID.
The request
POST to /mpesa/stkpushquery/v1/query. It needs a fresh password and timestamp, built the same way as in C1.
{ "BusinessShortCode": "174379", "Password": "<base64 password>", "Timestamp": "20261029143512", "CheckoutRequestID": "ws_CO_29102026143012345678"}While the prompt is still open
Daraja returns an error saying the transaction is still being processed. Ask again with backoff (20 s, 40 s, 80 s), for up to about five minutes.
{ "errorCode": "500.001.1001", "errorMessage": "The transaction is being processed"}Once it is final
You get a ResultCode with the same meaning as in the callback: 0 paid, 1032 cancelled, and so on. The query answer has no receipt number; the callback is where that comes from.
{ "ResponseCode": "0", "ResponseDescription": "The service request has been accepted successsfully", "MerchantRequestID": "29115-34620561-1", "CheckoutRequestID": "ws_CO_29102026143012345678", "ResultCode": "0", "ResultDesc": "The service request is processed successfully."}Step 3
Try it
$ mpesa pay stk 2547XXXXXXXX 10 --no-wait $ mpesa result <id>
With the MCP server, ask your agent to use mpesa_stk_query
Step 4
Read the response
"Still processing" while the prompt is open, then a ResultCode once it's final.
Step 5
Common mistakes
- Polling every second. Back off between queries; too many requests get you a spike-arrest error.
- Reading
ResponseCodeinstead ofResultCode. The first only says the query was accepted. - Querying before saving the payment row, then losing the result.
Go deeper
When would your app call STK Query on its own?
Answer in your own words first.
Show the answerHide the answer
For payments still pending after a couple of minutes.