Daraja SDK Logomark
Daraja SDK
Account & Ledger

Transaction Status

Check the status of a past transaction, used as a secondary reconciliation path when a callback never arrives.

Endpoint

https://sandbox.safaricom.co.ke/mpesa/transactionstatus/v1/query

Overview

To check a transaction's status, you need either its M-PESA receipt number (TransactionID) or the OriginalConversationID returned when it was first submitted. Safaricom documents this as usable against C2B, B2B, B2C, Reversal, and IMT transactions.

How it works

The organization sends the query to Daraja, which authenticates it and forwards it to M-PESA. M-PESA checks the transaction's status and responds to Daraja, which posts the result back to the organization's ResultURL.

Prerequisites

  • Daraja account and sandbox app.

Request

{
  "Initiator": "testapiuser",
  "SecurityCredential": "ClONZiMYBpc65lmpJ7nvnrDmUe0WvHvA5QbOsPjEo92B6IGFwDdvdeJIFL0kgwsEKWu6SQKG4ZZUxjC",
  "CommandID": "TransactionStatusQuery",
  "TransactionID": "NEF61H8J60",
  "OriginalConversationID": "7071-4170-a0e5-8345632bad442144258",
  "PartyA": "600782",
  "IdentifierType": "4",
  "ResultURL": "http://myservice:8080/transactionstatus/result",
  "QueueTimeOutURL": "http://myservice:8080/timeout",
  "Remarks": "OK",
  "Occasion": "OK"
}
FieldDescriptionSample value
CommandIDAlways TransactionStatusQuery.TransactionStatusQuery
PartyAOrganization short code or MSISDN that received the transaction.6 to 9 digit short code or 12-digit MSISDN
IdentifierType4 for an organization short code.4
InitiatorUsername authenticating the request.Username
SecurityCredentialEncrypted initiator credential.(encrypted string)
TransactionIDThe M-PESA receipt number of the transaction being checked.LXXXXXX1234
OriginalConversationIDThe Originator Conversation ID of the transaction being checked.7071-4170-a0e5-8345632bad442144258
ResultURL / QueueTimeOutURLResult and timeout callback URLs.https://domain:port/path
RemarksUp to 100 characters.Free text
OccasionOptional, up to 100 characters.Free text

Note the spelling here: this API's optional field is Occasion (single "s"), unlike the Occassion (double "s") documented on the B2C/B2B family. Both are reproduced as Safaricom spells them on their respective pages.

Response

{
  "OriginatorConversationID": "1236-7134259-1",
  "ConversationID": "AG_20210709_1234409f86436c583e3f",
  "ResponseCode": "0",
  "ResponseDescription": "Accept the service request successfully."
}

Callback payload

{
  "Result": {
    "ConversationID": "AG_20180223_0000493344ae97d86f75",
    "OriginatorConversationID": "3213-416199-2",
    "ReferenceData": {
      "ReferenceItem": { "Key": "Occasion" }
    },
    "ResultCode": 0,
    "ResultDesc": "The service request is processed successfully.",
    "ResultParameters": {
      "ResultParameter": [
        { "Key": "DebitPartyName", "Value": "600310 - Safaricom333" },
        { "Key": "DebitPartyName", "Value": "254708374149 - John Doe" },
        { "Key": "OriginatorConversationID", "Value": "3211-416020-3" },
        { "Key": "InitiatedTime", "Value": "20180223054112" },
        { "Key": "DebitAccountType", "Value": "Utility Account" },
        {
          "Key": "DebitPartyCharges",
          "Value": "Fee For B2C Payment|KES|22.40"
        },
        { "Key": "TransactionReason" },
        {
          "Key": "ReasonType",
          "Value": "Business Payment to Customer via API"
        },
        { "Key": "TransactionStatus", "Value": "Completed" },
        { "Key": "FinalisedTime", "Value": "20180223054112" },
        { "Key": "Amount", "Value": "300" },
        {
          "Key": "ConversationID",
          "Value": "AG_20180223_000041b09c22e613d6c9"
        },
        { "Key": "ReceiptNo", "Value": "MBN31H462N" }
      ]
    },
    "ResultType": 0,
    "TransactionID": "MBN0000000"
  }
}

Defect in the source material

Safaricom's own sample lists the DebitPartyName key twice, with two different values, in the same ResultParameter array, and includes a TransactionReason entry with no Value at all. Both are reproduced exactly as documented.

FieldDescription
ConversationIDUnique identifier generated by M-PESA for the request.
OriginatorConversationIDIdentifier of the original request message.
ResultCode0 for success.
ResultDescDescription of the result code, up to 1024 characters per Safaricom's documentation.
ResultType0 completed, 1 waiting for further messages.
TransactionIDM-PESA's own transaction identifier, present only for transaction requests.
ResultParameters.ResultParameterKey-value detail: debit/credit party names, account type, timestamps, amount, charges, receipt number, and transaction status.

Error codes

CodeCauseFix
500.003.1001Server failureConfirm setup and endpoint match the documentation.
400.003.01Invalid access tokenRegenerate the token; confirm no copy-paste errors.
400.003.02Bad requestConfirm the request matches the documentation.
500.003.03Quota violationReduce request rate.

Transaction status values

Safaricom documents three broad states a transaction can be in:

  • Initiated, pending revalidation.
  • Authorized / Pending Authorized, waiting on the credit party's validation response.
  • Final status: Cancelled, Declined, Completed, or Expired.

Testing

Step 1: Get your app's Consumer Key and Consumer Secret from the portal. Step 2: Generate an access token from the sandbox or production OAuth endpoint. Step 3: Submit the query with either TransactionID or OriginalConversationID, plus PartyA.

Go Live

Requires the Transaction Status Query ORG API role on the initiator; see Organization Portal & Go Live for creating and configuring that operator.

FAQs

On this page