STK Query
User stories
- As an online merchant, I want customers to pay with M-Pesa STK Push so they can pay on their phones without leaving my site or app.
- As a developer, I want to start an STK Push and check its status so I can update orders even if callbacks are late or missing.
- As a support agent, I want to look up STK Push results to troubleshoot problems and confirm payments before issuing refunds or fulfilling orders.
Parameters
Parameter | Type | Description |
---|---|---|
BusinessShortCoderequired int | Integer | Merchant shortcode (PayBill or BuyGoods). |
CheckoutRequestIDrequired str | String | The CheckoutRequestID returned when the STK Push was initiated. |
Passkey str | String | Shortcode passkey. If provided, the SDK can derive Password + Timestamp. |
Password str | String | Base64(Shortcode + Passkey + Timestamp). Provide this together with Timestamp if not using Passkey. |
Timestamp str | String | Timestamp used when generating Password. Format: YYYYMMDDHHMMSS. |
Overview
Use STK Query to retrieve the processing result for an STK Push when the callback is missing or to cross-check a callback payload.
Use the query API when you didn't receive a callback, want to reconcile a transaction, or need to poll for a final status after initiating an STK Push.
Use the high-level client for token handling and simpler calls.
Example (MpesaClient)
# Build and send a query using the high-level client.import osfrom dotenv import load_dotenvfrom mpesakit import MpesaClient
load_dotenv()
# Initialize the clientclient = MpesaClient( consumer_key=os.getenv("MPESA_CONSUMER_KEY"), consumer_secret=os.getenv("MPESA_CONSUMER_SECRET"), environment="sandbox",)
# Perform the STK queryresult = client.stk_query( business_short_code=123456, checkout_request_id="ws_CO_20250101_ABC123", passkey="your_passkey_here", # or provide password + timestamp)
if result.is_successful(): print("Transaction processed:", result.ResultDesc)else: print("Status:", result.ResponseDescription, "| Code:", result.ResponseCode)
You can give either Passkey
(SDK generates Password
+Timestamp
) or provide password
and timestamp
directly by passing them to the stk_query
method.
Response shape & interpretation
- The query response is a
StkPushQueryResponse
Pydantic object that contains identifiers and status fields such as MerchantRequestID, CheckoutRequestID, ResponseCode, ResponseDescription, ResultCode and ResultDesc. - Interpreting results:
- ResponseCode of 0 generally means the query request was accepted.
- ResultCode of 0 indicates the transaction was successful. Other ResultCodes convey errors, timeouts or user cancellation.
# Example handling snippet (pseudo)resp = stk_service.query(request=q)if resp.is_successful(): # Final state returned by Daraja handle_success(resp)else: # Log / inspect resp.ResponseCode, resp.ResultCode and resp.ResultDesc handle_failure(resp)
- If you wish to use the response as a
Dict
, you can do so byresponse.model_dump(mode="json")
.
If you received an STK callback, compare its CheckoutRequestID and MerchantRequestID with the query result to ensure they refer to the same transaction.
Next steps
After confirming final status, update your order state, notify the user, and persist the complete response for auditing.