Daraja SDK Logomark
Daraja SDK
B2B & Tax Transfers

Tax Remittance

Submit a tax payment to the Kenya Revenue Authority (KRA) directly from a business account.

Endpoint

https://sandbox.safaricom.co.ke/mpesa/b2b/v1/remittax

Overview

Remits tax to KRA in real time. Using this API requires prior integration with KRA itself for tax declaration and generation of a Payment Registration Number (PRN), since the PRN is what identifies which tax obligation the payment settles.

Unlike the rest of the B2B family, this uses its own /remittax path rather than the shared /mpesa/b2b/v1/paymentrequest endpoint used by Business Pay Bill and Business Buy Goods.

Request

{
  "Initiator": "TaxPayer",
  "SecurityCredential": "FKXl/KPzT8hFOnozI+unz7mXDgTRbrlrZ+C1Vblxpbz7jliLAFa0E/…../uO4gzUkABQuCxAeq+0Hd0A==",
  "Command ID": "PayTaxToKRA",
  "SenderIdentifierType": "4",
  "RecieverIdentifierType": "4",
  "Amount": "239",
  "PartyA": "888880",
  "PartyB": "572572",
  "AccountReference": "353353",
  "Remarks": "OK",
  "QueueTimeOutURL": "https://mydomain.com/b2b/remittax/queue/",
  "ResultURL": "https://mydomain.com/b2b/remittax/result/"
}

Defect in the source material

Two things carried directly from Safaricom's own sample. First, the field is written "Command ID" with a space, rather than CommandID as used in the parameter table below it, the same inconsistency documented on Business Pay Bill. Second, the sample has a trailing comma after the ResultURL value, which makes it invalid JSON as published; it's removed above.

FieldDescriptionSample value
CommandIDOnly PayTaxToKRA for this API.PayTaxToKRA
InitiatorAPI operator username.Username
SecurityCredentialEncrypted initiator password.(encrypted string)
PartyAYour own short code, debited.123454
SenderIdentifierTypeOnly 4 is allowed.4
PartyBOnly 572572 is documented as valid for this use case, KRA's collection account.572572
RecieverIdentifierType (sic)Only 4 is allowed.4
AmountTransaction amount.3000
AccountReferenceThe PRN issued by KRA.PRN1234XN
RemarksUp to 100 characters.Free text
QueueTimeOutURL / ResultURLTimeout and result callback URLs.https://domain:port/path

Response

{
  "OriginatorConversationID": "5118-111210482-1",
  "ConversationID": "AG_20230420_2010759fd5662ef6d054",
  "ResponseCode": "0",
  "ResponseDescription": "Accept the service request successfully."
}

Defect in the source material

Safaricom's response parameter table again spells this field OriginatorConverstionID, the same typo repeated across the B2B family's documentation.

Successful result callback

{
  "Result": {
    "ResultType": "0",
    "ResultCode": "0",
    "ResultDesc": "The service request is processed successfully",
    "OriginatorConversationID": "626f6ddf-ab37-4650-b882-b1de92ec9aa4",
    "ConversationID": "AG_20181005_00004d7ee675c0c7ee0b",
    "TransactionID": "QKA81LK5CY",
    "ResultParameters": {
      "ResultParameter": [
        {
          "Key": "DebitAccountBalance",
          "Value": "{Amount={CurrencyCode=KES, MinimumAmount=618683, BasicAmount=6186.83}}"
        },
        { "Key": "Amount", "Value": "190.00" },
        {
          "Key": "DebitPartyAffectedAccountBalance",
          "Value": "Working Account|KES|346568.83|6186.83|340382.00|0.00"
        },
        { "Key": "TransCompletedTime", "Value": "20221110110717" },
        { "Key": "DebitPartyCharges", "Value": "" },
        {
          "Key": "ReceiverPartyPublicName",
          "Value": "00000 - Tax Collecting Company"
        },
        { "Key": "Currency", "Value": "KES" },
        {
          "Key": "InitiatorAccountCurrentBalance",
          "Value": "{Amount={CurrencyCode=KES, MinimumAmount=618683, BasicAmount=6186.83}}"
        }
      ]
    },
    "ReferenceData": {
      "ReferenceItem": [
        { "Key": "BillReferenceNumber", "Value": "19008" },
        {
          "Key": "QueueTimeoutURL",
          "Value": "https://mydomain.com/b2b/remittax/queue/"
        }
      ]
    }
  }
}

Defect in the source material

Safaricom's own sample for this callback is not valid JSON: the ResultParameter array's entries are written as loose "Key": ..., "Value": ..., pairs missing their enclosing {} braces, and ReferenceItem mixes an array with an unmatched brace. Reformatted above into valid JSON with the same field names and values.

Unsuccessful result callback

Same shape as the Business Pay Bill unsuccessful callback: ResultCode 2001 with ResultDesc "The initiator information is invalid" is the documented sample.

Testing and Go Live

Daraja Simulator: create a test app with the Tax Remittance product attached.

Postman: token from the sandbox OAuth endpoint, then call the endpoint above.

Going live follows Organization Portal & Go Live, requiring the Tax Remittance to KRA API role on the operator used as Initiator.

On this page