</>CodeWithKarani
All of Payments & Fintech
Payments & Fintech

STK Push

Prompts that never reach the phone, timeouts and the failure codes.

12 articles

Payments & Fintech7 min read

Daraja API in Production: STK Push, C2B and B2C With Callbacks That Actually Work

A build-order guide to Safaricom's Daraja API with real payloads: OAuth token caching, STK Push, C2B v2 registration, B2C v3 with RSA security credentials, and the callback URL rules nobody documents.

Read
Payments & Fintech7 min read

Your M-Pesa Callback Will Fire Twice: Idempotency, Retries and the 1037 Problem

Daraja callbacks are unreliable notifications, not a source of truth. Seven production failure modes, with the database constraints, pollers and parsers that make double charges structurally impossible.

Read
Payments & Fintech7 min read

Daraja invalid access token: 401.003.01 is not 404.001.03

Two Daraja errors say 'Invalid Access Token' and mean different things. One is a wrong-environment token you can fix in code, the other is an entitlement problem only Safaricom can fix.

Read
Payments & Fintech7 min read

M-Pesa 1001 Transaction In Progress: Why Retrying Instantly Fails

Daraja error 1001 is a subscriber lock, not a transient error, and the usual retry loop makes it worse. The cooldown, the state machine and the copy customers can act on.

Read
Payments & Fintech7 min read

M-Pesa 'Unable to Send STK Prompt' (1025/9999): Check the Length

Daraja returns 1025 for both a too-long TransactionDesc and a genuine M-Pesa outage. One retries successfully, the other never will. Here is how to tell them apart.

Read
Payments & Fintech9 min read

M-Pesa Daraja 500.001.1001 when your consumer key is actually correct

Daraja's 'Wrong credentials' error hides two unrelated causes, and neither is your API key. Usually it is a timestamp generated twice that drifts by one second.

Read
Payments & Fintech7 min read

M-Pesa "Invalid BusinessShortCode": The Python requests Bug Behind It

Daraja error 400.002.02 blames your shortcode, but the real cause is usually data=payload instead of json=payload in Python requests. Here is how to prove it.

Read
Payments & Fintech9 min read

M-Pesa ResultCode 4999 Is Not a Failure: Handling Undocumented Daraja Codes

Daraja's STK query can return 4999, which no Safaricom document defines. Treating it as failed causes double charges. Here is the three-bucket model that prevents it.

Read
Payments & Fintech6 min read

Daraja Error 1032 'Request Cancelled by User' Is Not a Bug in Your M-Pesa Integration

M-Pesa STK Push ResultCode 1032 means the customer pressed Cancel, not that anything broke. Stop paging on it and handle it as the user action it is.

Read
Payments & Fintech9 min read

M-Pesa error 1037: the STK push that never reached the phone

Daraja 1037 is not a declined payment. It means the handset never answered the SIM toolkit prompt. How to classify it, poll for it, and retry without creating duplicate orders.

Read
Payments & Fintech8 min read

M-Pesa 1019 vs 1037 vs 1032: three STK failures that look identical and are not

1019 means the prompt arrived and the user was too slow. 1037 means it never arrived. 1032 means they cancelled. Conflating them hides whether your problem is network, copy or timeout.

Read
Payments & Fintech8 min read

M-Pesa STK Push Callback Never Arrives? Reconcile With the Transaction Status Query API

STK Push callbacks are not guaranteed even with a perfect URL. Build a reconciliation job that treats the Transaction Status Query API as the real source of truth.

Read