Daraja SDK Logomark
Daraja SDK
Payouts & Disbursements

B2C Account Top Up

Move funds from a Pay Bill's Working account directly into a B2C shortcode's disbursement account.

Lets a business load funds into a B2C shortcode for disbursement, moving money from the sender's MMF/Working account into the recipient's Utility account.

Endpoint

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

This is the same underlying endpoint documented for Business Pay Bill and Business Buy Goods; Safaricom's B2B family of APIs share one URL and are distinguished by CommandID. Here it's BusinessPayToBulk.

Request

{
  "Initiator": "testapi",
  "SecurityCredential": "IAJVUHDGj0yDU3aop/WI9oSPhkW3DVlh7EAt3iRyymTZhljpzCNnI/xFKZNooOf8PUFgjmEOihUnB24adZDOv3Ri0Citk60LgMQnib0gjsoc9WnkHmGYqGtNivWE20jyIDUtEKLlPr3snV4d/H54uwSRVcsATEQPNl5n3+EGgJFIKQzZbhxDaftMnxQNGoIHF9+77tfIFzvhYQen352F4D0SmiqQ91TbVc2Jdfx/wd4HEdTBU7S6ALWfuCCqWICHMqCnpCi+Y/ow2JRjGYHdfgmcY8pP5oyH25uQk1RpWV744aj2UROjDrxTnE7a6tDN6G/dA21MXKaIsWJT/JyyXg==",
  "CommandID": "BusinessPayToBulk",
  "SenderIdentifierType": "4",
  "RecieverIdentifierType": "4",
  "Amount": "239",
  "PartyA": "600979",
  "PartyB": "600000",
  "AccountReference": "353353",
  "Requester": "254708374149",
  "Remarks": "OK",
  "QueueTimeOutURL": "https://mydomain/path/timeout",
  "ResultURL": "https://mydomain/path/result"
}
FieldDescriptionTypeSample value
CommandIDOnly BusinessPayToBulk for this API.StringBusinessPayToBulk
InitiatorAPI operator username, needs the Org Business Pay To Bulk API initiator role.Stringjohndoe
SecurityCredentialEncrypted initiator password.String(encrypted string)
PartyAYour short code, debited.Number600979
SenderIdentifierTypeOnly 4 is allowed.Number4
PartyBRecipient B2C short code, credited.Number600000
RecieverIdentifierType (sic)Only 4 is allowed.Number4
RequesterOptional; the consumer's mobile number, if paying on their behalf.Mobile254708374149
AmountTransaction amount.Number300
RemarksUp to 100 characters.StringFree text
QueueTimeOutURL / ResultURLTimeout and result callback URLs.URLhttps://domain:port/path

Defect in the source material

RecieverIdentifierType is spelled that way, "Reciever" rather than "Receiver," throughout Safaricom's B2B family of APIs. It's kept exactly as documented, since it's the literal field name the API expects. Safaricom's own sample value for CommandID in this API's Request Parameter Definition table is also given, in one place, as BusinessPayToBullk (an extra "l"), which is reproduced here in this note rather than in the table itself, since the actual field only accepts BusinessPayToBulk.

Response

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

Defect in the source material

Safaricom's own response parameter table for this API is headed "Repsonse Parameter Definition" (missing the first "s" in "Response"), and lists the field itself as OriginatorConverstionID rather than OriginatorConversationID. The response body sample above is spelled correctly; only the table heading and one field-name row in Safaricom's documentation carry the typo.

Callback payload

{
  "Result": {
    "ResultType": "0",
    "ResultCode": "0",
    "ResultDesc": "The service request is processed successfully",
    "OriginatorConversationID": "626f6ddf-ab37-4650-b882-b1de92ec9aa4",
    "ConversationID": "12345677dfdf89099B3",
    "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": "000000 - Biller 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/businessbuygoods/queue/"
        }
      ]
    }
  }
}

Defect in the source material

Safaricom's own sample for the ReceiverPartyPublicName value is not valid JSON at all: it renders as "Value":000000– Biller Companty in their documentation, an unquoted number followed by an em dash and the misspelling "Companty" for "Company." The version above is corrected to valid JSON ("000000 - Biller Company") purely so the sample can parse; the real returned value has not been independently confirmed against a live sandbox call.

FieldDescription
ResultType / ResultCode / ResultDescStandard result envelope; 0 is success.
TransactionIDM-PESA transaction ID.
DebitAccountBalance, DebitPartyAffectedAccountBalance, InitiatorAccountCurrentBalanceBalances on the sending organization's accounts, in mixed formats (delimited string in one field, a JSON-like {Amount={...}} string in others).
ReceiverPartyPublicNameRecipient short code and public name.
DebitPartyChargesFee charged, if any.

Unsuccessful result

{
  "Result": {
    "ResultType": 0,
    "ResultCode": 2001,
    "ResultDesc": "The initiator information is invalid.",
    "OriginatorConversationID": "12337-23509183-5",
    "ConversationID": "AG_20200120_0000657265d5fa9ae5c0",
    "TransactionID": "OAK0000000",
    "ResultParameters": {
      "ResultParameter": { "Key": "BillReferenceNumber", "Value": 12323333 }
    },
    "ReferenceData": {
      "ReferenceItem": [
        { "Key": "BillReferenceNumber", "Value": 12323333 },
        {
          "Key": "QueueTimeoutURL",
          "Value": "https://internalapi.safaricom.co.ke/mpesa/abresults/v1/submit"
        },
        { "Key": "Occassion" }
      ]
    }
  }
}

Defect in the source material

Safaricom's own unsuccessful-result sample has multiple JSON structure problems: the ResultParameters.ResultParameter array is malformed, and the last ReferenceItem entry, {"Key":"Occassion"}, has no Value field at all. The version above is reformatted into valid JSON while keeping the same field names and values.

On this page