Skip to content

Result and Status Reference

Most Daraja APIs have two distinct stages:

  1. The synchronous API response says whether Daraja accepted the request for processing.
  2. The asynchronous callback says whether the payment or operation actually finished successfully.

Do not treat an accepted request as final financial success.

StageField to inspectMeaning
Initial API responseResponseCode === "0"Daraja accepted the STK request
STK callbackResultCode === 0customer approved and the payment completed
STK callbackResultCode !== 0payment failed or was cancelled
STK queryResultCode and ResultDescrecovery signal when callback timing is uncertain
CodeWhere you see itMeaning
0STK callback, Daraja result callbacksuccess
1C2B validation response that you send backreject the transaction
1032STK callbackcustomer cancelled the STK prompt

Safaricom may return other non-zero codes over time. Keep your business logic tolerant: treat 0 as success, treat known codes specially when useful, and log unknown non-zero codes instead of hardcoding exhaustive assumptions.

ResultCodeMeaning
0accept and allow the transaction to continue
C2B00011reject: invalid MSISDN
C2B00012reject: invalid account number
C2B00013reject: invalid amount
C2B00014reject: invalid KYC details
C2B00015reject: invalid shortcode
C2B00016reject: other error

The SDK exposes C2B_VALIDATION_ACCEPT and C2B_VALIDATION_REJECT, and it also exposes c2bValidationResponse() when you want to return a specific Daraja rejection code.

Async result callbacks for B2C, balance, status, and reversal

Section titled “Async result callbacks for B2C, balance, status, and reversal”

These flows use the Result wrapper parsed by parseDarajaResult().

FieldMeaning
Result.ResultCode === 0final operation success
Result.ResultCode !== 0final operation failure
Result.OriginatorConversationIDcaller-side correlation ID
Result.ConversationIDDaraja-side conversation ID
Result.TransactionIDtransaction identifier when provided

Use getResultParametersMap() to flatten result parameters into a normal object for logging and persistence.

  • A timeout callback is not the same as a final result callback.
  • Timeouts should move the record into a recoverable state such as timed_out or needs_review.
  • Final result callbacks should carry the authoritative outcome when they arrive.
FlowIDs to persist
STKCheckoutRequestID, MerchantRequestID, M-Pesa receipt number
C2BTransID, bill reference, shortcode
B2CConversationID, OriginatorConversationID, TransactionID if present
Balance / status / reversalConversationID, OriginatorConversationID, TransactionID if present