1Sign up to the portal
2Creating your test app on Sandbox
3View your app details
4Connect your API
5Go live process

Sign up to the portal

  • You will need to register for an account. The available accounts are for individuals and company accounts.
  • Company accounts are for users with existing Mpesa Shortcodes (Paybill or Buygoods till number) or If you are intending to register a shorcode you can open a company account.
  • To login or sign up click here
  • An account activation link will be send on the email used to create the account. Remember, the link expires in 24 hours.

Creating your test app on Sandbox

 
  • Sandbox is a test environment for you to use in testing your app before going to production.
  • First time you log into your developer account,
    • Go through the detailed documentation here
    • Go to My Apps on the main menu and create a new app on the sandbox by clicking add a new app
  • Create an app by adding app name and select Product, either or both:
    • Lipa na Mpesa online
    • Mpesa Sandbox – {B2B (business to business), B2C (Business to Customer) and C2B (Customer to Business – Paybill and Buygoods tills)}
  • Your app will be created and approved.

View your app details

 
  • Click on your app to view details below:
  • You can access your apps here
    • KEYS: Access your consumer key and consumer secret on the keys tab, the date they were created and
    • PRODUCT: This will show the approval status of your applications API products.
    • DETAILS: The details tab will give you a summary of your app and the terms and conditions of accessing the sandbox.
    • ANALYTICS: This will gauge how your application is performing for a given period. (Day, Weekly, Monthly)
    • EDIT: You can edit the app name and product from the edit tab.
    • DELETE: You can choose to delete the app. This will delete all the related data and the action cannot be undone.

Connect your API

 

This API generates the tokens for authenticating your API calls. This is the first API you will engage with in the set of APIs available because all the other APIs require authentication information from this API to work.

You can access your Consumer key and Consumer Secret under the Keys tab from My apps here

To generate your access token follow the process here

The API works as detailed below:

 

Authentication: Basic U1BMd0xkMnVBM29ub1BSWENKRjZiV3FXR3hOdkE4Qlo6NldPZ2hNQUdUdUVZS2pYMw==
GET /oauth/v1/generate?grant_type=client_credentials HTTP/1.1
Host: sandbox.safaricom.co.ke
Authorization: Basic U1BMd0xkMnVBM29ub1BSWENKRjZiV3FXR3hOdkE4Qlo6NldPZ2hNQUdUdUVZS2pYMw==
Content-Type:application/json 
                                            
GET /oauth/v1/generate?grant_type=client_credentials HTTP/1.1
Host: sandbox.safaricom.co.ke
Authorization: Basic U1BMd0xkMnVBM29ub1BSWENKRjZiV3FXR3hOdkE4Qlo6NldPZ2hNQUdUdUVZS2pYMw==
Content-Type:application/json 
                                    
{
  "access_token": "hsHoclSD53UC3657NAD3d0qBE8cA",
  "expires_in": "3599"
}

 

Once generated, you somehow need to keep track of the timeout period so it does not expire. But know that when you get the "Invalid Access Token"error, your Auth token has expired or is not set. Get a new one. The panel on the right, is designed to help you test the APIs as you go through them. It shall consist of multiple tabs. At the minimum, it shall have a "Try it" tab for testing the specific API which you are working on, and a quick access "Refresh Credentials" tab for when the token expires in the middle of a session to quickly generate a new token. If the panel is not completely visible try zooming out to around 80-90%, to be able to view the scrollers.

The Register URL API under C2B APIs. It is the first half of the C2B API for receiving payment notifications to your paybill. This API enables you to register the callback URLs via which you shall receive payment notifications for payments to your paybill/till number. The URLs are used by the C2B payment simulation API for sending the transaction details to you.

There are two URLs required for RegisterURL API: Validation URL and Confirmation URL. The reason for two of them is due to the nature of C2B API calls. Below is a flowchart of the C2B process:

NB: Broker is the API interface between MPesa and 3rd parties.

C2B transaction flow

 

The process is explained as below:

  • A customer sends a payment request to your paybill from their phone
  • MPesa receives the request and validates it internally first
  • MPesa checks if you have enabled External Validation for the paybill receiving the request
  • If External Validation is enabled:
    • MPesa first sends a Validation request to the Validation URL registered in the system (3rd party) with the payment details.
    • The 3rd Party validates the request and sends an appropriate response to MPesa. This response must be received within a given time period or MPesa marks the endpoint system as unreachable. The response is either to complete or cancel the payment:
    • MPesa receives the response and processes the transaction accordingly:
    • If you had chosen to complete the transaction, MPesa sends a Confirmation request to your Confirmation URL with the details of the completed transaction. The transaction is then complete. Hence you receive two API calls on your system.
    • If you had chosen to cancel the payment, MPesa simply cancels the transaction and no other request is sent. The transaction is then completed and closed.
  • If External Validation is disabled, MPesa automatically completes the transaction, and if the transaction is a success, MPesa sends a Confirmation request to the Confirmation URL registered in the system. This is the only API call received on your end.
  • If External Validation is enabled, but for some reason MPesa could not reach your endpoint to validate the transaction within the stipulated time period (usually < 8 seconds), or no response was received by the time MPesa terminates the request, it checks on the default action value saved during registration of the URLs. If the default action was set to Completed, MPesa automatically completes the transaction and also tries to send a Confirmation request to your other endpoint. If the default action was set to Cancelled, MPesa simply cancels the transaction. The transaction is then complete.
  • If no URLs are registered in the system, MPesa automatically completes the request. MPesa then sends an SMS notification to both the customer and paybill owner with the results of the transaction as usual.
  • If the external notifications fails to sent, you can check on the MPesa Org portal and cross-check against received callbacks. The portal has all the payments made available, whether you received the callback or not.

For the two URLs, below are some pointers. This will also apply to the Callback URLs used on other APIs:

- Use publicly available (Internet-accessible) IP addresses or domain names.

- Do not use the words MPesa, M-Pesa, Safaricom or any of their variants in either upper or lower cases in your URLs, the system filters these URLs out and blocks them. Of course any Localhost URL will be refused.

- Do not use public URL testers e.g. mockbin or requestbin especially on production, they are also blocked by the API.

The request structure will be as shown below:

// URL
[POST] https://sandbox.safaricom.co.ke/mpesa/c2b/v1/registerurl

// HEADERS
Host: sandbox.safaricom.co.ke
Authorization: Bearer [access token]
Content-Type: application/json

// BODY
{
"ShortCode": "600610",
"ResponseType": "[Cancelled/Completed]",
"ConfirmationURL": "[confirmation URL]",
"ValidationURL": "[validation URL]"
}

The other parameters are:

Shortcode

This is your paybill number/till number, which you expect to receive payments notifications about.

Response Type

This is the default action value that determines what MPesa will do in the scenario that your endpoint is unreachable or is unable to respond on time. Only two values are allowed: Completed or Cancelled. Completed means MPesa will automatically complete your transaction, whereas Cancelled means MPesa will automatically cancel the transaction, in the event MPesa is unable to reach your Validation URL.

The success response will look as shown below:

{
  "ConversationID": "",
  "OriginatorCoversationID": "",
  "ResponseDescription": "success"
}

Anything else other than the above means there is an error, check error description to troubleshoot and fix errors.

This API is used for payment requests from clients to your API. You can use the sandbox to simulates a payment made from the client phone's STK/SIM Toolkit menu, and enables you to receive the payment requests in real time. It uses URL as described in the Register URL API and requires the URLs registered to work. For better understanding of this API, consider going through the Register URL section above to better understand the process flow of a C2B transaction and the requirements of URL

The basic C2B request looks like the sample below:

// URL
[POST] https://sandbox.safaricom.co.ke/mpesa/c2b/v1/simulate

// HEADERS
Host:sandbox.safaricom.co.ke
Authorization: Bearer [access token]
Content-Type: application/json

// BODY
{
   "ShortCode": "600610",
   "CommandID": "CustomerPayBillOnline",
   "Amount": "100",
   "Msisdn": "254708374149",
   "BillRefNumber": "account"
}

The parameters are as explained below:

Shortcode

This is your paybill number/till number, which you expect to receive payments notifications about.

CommandID

This is a transaction type identifier, which Identifies the type of C2B transaction being made. There are two options: CustomerPayBillOnline and CustomerBuyGoodsOnline.

CustomerPayBillOnline is used when simulating Pay Bill requests, which the customer does by going to the Lipa na M-PESA => Pay Bill option on mobile, and uses a Paybill number. Thus it requires an Account Number/Bill reference number for it to be valid.

CustomerBuyGoodsOnline is used for Buy Goods simulation, which is when a customer goes to Lipa na M-PESA => Buy Goods and Services on their mobile phones and uses a Till number. Beware that you cannot use a Till number with CustomerPayBillOnline command ID and you cannot use a Pay Bill number with CustomerBuyGoodsOnline Command ID.

Msisdn

This is the test phone number of the virtual customer paying to your paybill. Use the one given in your test credentials section (Test MSISDN) to test. Testing using your own phone number(s) will not work with this API on Sandbox since the numbers need to be registered on the testbed first. International numbers are not supported for now.

BillRefNumber

This simulates the account number that a user would have entered when making a Pay Bill request. This parameter is only required for CustomerPayBillOnline transaction type. It is sent as part of the validation and confirmation requests to you (3rd party) to validate and confirm. It has a maximum of 20 characters. After sending the request the success response should be as the acknowledgement below:

{
  "ConversationID": "AG_20180324_000066530b914eee3f85",
  "OriginatorCoversationID": "25344-885903-1",
  "ResponseDescription": "Accept the service request successfully."
}

The above response shows that your request has been accepted, and will be processed. The 'ConversationID and OriginatorCoversationID are unique identifiers of your transaction's journey on MPesa. MPesa processes transaction in 8 seconds, thus, it shouldn't take more than 10 seconds for the validation/confirmation request to hit your endpoint. If it is consistently above that, please check for network or processing delays around your system.

For those who have enabled External Validation, you will first receive a validation request on your Validation URL to validate the request. That request will have the structure below:

{
  "TransactionType": "",
   "TransID": "LHG31AA5TX",
  "TransTime": "20170816190243",
  "TransAmount": "200.00",
  "BusinessShortCode": "600610",
  "BillRefNumber": "account",
  "InvoiceNumber": "",
  "OrgAccountBalance": "",
  "ThirdPartyTransID": "",
  "MSISDN": "254708374149",
  "FirstName": "John",
  "MiddleName": "",
  "LastName": "Doe"
}

TransID

This is MPesa's unique transaction identifier for your transaction. This can be used to search for the transaction later on using the Transaction Query API.

TransTime

Simply the time the transaction was completed on MPesa in the format YYYYMMddHHmmss.

TransAmount

The amount transacted by the customer when paying to your paybill/till.

BusinessShortCode

The shortcode to which the customer paid to. This can be used to differentiate payments to different paybills via the same notification URLs.

BillRefNumber

The account number the customer entered on their phone when making the payment. Applicable to PayBill requests.

MSISDN

The phone number from which the payment was made.

FirstName, MiddleName, LastName

The names of the customer under whom the MSISDN above is registered. The First Name and Last Name are usually mandatory. The Middle Name is optional.

After receiving the request, you are supposed to process it and respond to the API call with either an accept or reject response. To accept, you send the below JSON making sure the value of ResultCode is 0 (zero), but the value of ResultDesc can be any alphanumeric value.

{
  "ResultCode": 0,
  "ResultDesc": "Accepted"
}

To reject a transaction, you send the same JSON above, but with the value of ResultCode being any integer, BUT NOT 0, as shown below

{
  "ResultCode": 1,
  "ResultDesc": "Rejected"
}

Therefore, sending a ResultCode value of 0 means you accept the transaction, and sending anything else rejects the transaction. Values below 0 are not accepted, and also constitute a rejection.

If transaction has been accepted, MPesa will complete the transaction and send a Confirmation request to you. This will have the same structure and values as the Validation request JSON above. This also applies for those who have disabled External Validation. You may respond to the Confirmation request with the JSON below. If you cancel the transaction, no Confirmation will be sent to you. Beware that you cannot cancel a transaction after the Confirmation request has been sent to you. Confirmation marks the completion of the transaction on MPesa.

{
  "C2BPaymentConfirmationResult": "Success"
}

That marks the end of the C2B transaction. If for any reason you are not receiving payment notification, you can always fall back to the MPesa Org Portal to confirm the transactions were received and processed as required.

B2C simply means Business to Customer. This is a transaction that comes from a Business (Bank) to Customer (Client). This API enables a Businesses or Organization to pay their customers. The most common reasons a business can pay their customer include salary payments, promotion payments or normal business payments (e.g. transfers from bank to mobile). Each of these scenarios has their own unique characteristics, but all lie under the B2C (Business to Customer) API category.

Below is the flow of a B2C transaction.

 

B2C transaction flow

  • The Business sets the data in the request and sends it.
  • MPesa received the request and validates it internally first, then sends an acknowledgement response.
  • MPesa processes the request, then sends the response back via the callback URL specified in your initial request.

Here is an explanation of B2C from the perspective of a client who has access to the MPesa Organization Portal, since we shall touch on that portal quite frequently from here on.

For one to be able to perform operations on the MPesa system, one must have access to it. Access to the system is mainly based on your identity, i.e. you are either a Customer, an Organization or Service Provider (SP). The SP is Safaricom, and they have full control over the other two entities. The customer is obviously the client registered on MPesa, who can perform the transactions allowed to them via phone or other means and are identified by their phone number/MSISDN. The Organization is the Business, Company e.t.c. who are identified by the shortcode they own and permits them to perform operations or transactions on the system.

Access to MPesa is via three channels: Web, API and Handset. Customers mainly use the handset channel, Organizations mostly use the Web and API channel. For Organizations, the access channels gives rise to two classes of users: Web Operators and API operators. Web operators can access MPesa via the MPesa Portal, commonly known as the Mpesa Org. Portal, to perform their transactions and operations there. They have no permissions to perform any operations or transaction via API. API operators, on the other hand, access the MPesa system via API calls. They can perform the operations/transactions assigned to them only via API calls, and cannot log into the system via the web portal. Also, Web operators have control over API operators.

Both types of operators are limited to their actions on the portal via roles assigned to them by the Service Provider. On a typical MPesa Org portal, there are at least three roles: Business Administrator, Business Manager and Org API operator. The Business Administrator is the overall admin of the account and has control over other users on the portal and can perform bulk operations for their organization. The Business Manager mainly controls the financial aspects of the system, including transactions overview, authorization, perform transactions and reverse them too via portal e.t.c. The Business Admin and Business Manager are both Web operators i.e. they can only access the system via the web portal.

The Org API Operator is the user allowed to perform transactions/actions over API calls. This is the user who is used in the B2C calls on the API portal. The actions they can perform are limited to the permissions assigned to them by their Business Administrator. The operator is identified as the Initiator in API calls. At the minimum, the below are the permissions assignable to them and the actions/transactions they perform.

ORG B2C API initiator

This enables the API operator to perform B2C and B2B transactions via API.

Transaction Status Query Org API

This enables the API operator to query for the status of transactions performed previously by the same operator via API. An operator can only query for their own transactions which they perfomed.

Balance Query Org API

This enables the API operator to query the balance of their Organization's MPesa accounts via API.

Note, the Org's Business Admin requires the Set Restricted Org API Password permission for them to set passwords for other users. Without that permission, you cannot set a password for other operators. This is assigned by the Support Team from MPesa after taking your paybill live.

This document shows how to create an API operator, give them their respective permissions and assign them a password for use in API calls. The same user can also be used by C2B paybill owners to perform transaction query and balance query API calls.

So, for you to be able to perform B2C API calls on the API, you need the below at a minimum:

Initiator username: this is the API operator's username as set on the portal when the user was created. For Sandbox users, the username is already created and assigned to them and is available on the test credentials page as Initiator Name (Shortcode 1).

Initiator Password: this is the password assigned to the API operator after being created by the Business Administrator. For Sandbox users, this is available as Security Credential (Shortcode 1) on the test credentials page. Note: the password should be limited to specific special characters such as '#', '&', '%' and '$'. Other characters might cause issues, and the password may refuse to be accepted e.g. using a '(' or ')' character will be refused. Also, '@' is not a special character on MPesa, it's treated as a normal character.

Public Key Certificate: this is the certificate used to encrypt the Initiator's plaintext password for use in the API calls. This is provided for both Sandbox and Production clients on the portal. The Sandbox offers the capability to encrypt your test password.

These credentials are not tied to the Developers Portal Consumer credentials. If your API calls are accepted, but you get errors such as "Initiator Information is invalid", it means its the above MPesa credentials which have a problem, not the API credentials. If the API credentials have any issue, you will definitely not be able to reach MPesa itself. But if you are able to reach MPesa (requests are being accepted), it means your API Consumer credentials are okay.

The B2C request structure is as shown below:

// URL
[POST] https://sandbox.safaricom.co.ke/mpesa/b2c/v1/paymentrequest
                                
// HEADERS
Host: sandbox.safaricom.co.ke
Authorization: Bearer [access token]
Content-Type: application/json
                                
// BODY
{
  "InitiatorName": "TestInit610",
  "SecurityCredential": "p/EseFqZ0ChfcNTwkQ2PFNg6DtvMQzFHitRhrnOTNKaca9zggoZk0aa1DmgraLUA0/cZJ5f9pdg9oRM9UEMk/Ixud8sU17pNO4z8/43c9XrG2kSHO9fWkPVSXmSLRswOsWDRdCb5Q9oEOB41SjIGlqMzUQ6tz34mO4ll6SJMU6Fwp/z15x8soHZRGyeYxrYDweKFIQMGnNWTMs4PkmQojsb3oNQMwL6tfQpc89bOpeSW5H4j4/aHRaQGl5nEIUngq5aiUhAPVTwGge9cWf5r5THMR/8lNBAidN3hNtTurvwYcydp0Xj0uxMv3Qg642aCoALkYvxd2fb36PVw==",
  "CommandID": "[CommandID]",
  "Amount": "1000",
  "PartyA": "600610",
  "PartyB": "254708374149",
  "Remarks": "",
  "QueueTimeOutURL": "https://ip:port/" ,
  "ResultURL": "https://ip:port/",
  "Occassion":  ""
}
                                

The parameters are explained below:

InitiatorName

The username of the API operator as assigned on the MPesa Org Portal.

SecurityCredential

The password of the API operator encrypted using the public key certificate provided.

CommandID

This specifies the type of transaction being performed. There are three allowed values on the API: SalaryPayment, BusinessPayment or PromotionPayment.

PartyA

This is the identifier of the Debit party of the transaction, in this case the debit party being the Organization thus the identifier being the Shortcode of the organization.

PartyB

This is the identifier of the Credit party of the transaction, here the credit party being the customer thus the identifier being the customer's phone number (beginning with 07XX or 2547XX)

Remarks, Occassion

A very short description of the transaction from your end. Occassion can be left blank, Remarks cannot be blank.

ResultURL

This is the callback URL where the results of the transaction will be sent. Please visit the API Apps section to understand how this is used if you are not familiar with it.

QueueTimeOutURL

This is the callback URL used to send an error callback when the transaction was not able to be processed by MPesa within a stipulated time period.

Once sent, you shall expect a success acknowledgement response from the API informing you that your request was accepted. The response format is as below:

 

{
  "ConversationID": "AG_20180326_00005ca7f7c21d608166",
  "OriginatorConversationID": "12363-1328499-6",
  "ResponseCode": "0",
  "ResponseDescription": "Accept the service request successfully."
}
                                

Note the value of ResponseCode. Any value other than 0 (zero) means the request was unsuccessful, and the error is defined in the ResponseDescription element. So you need to fix that first. A value of 0 means the request was accepted by the API.

After MPesa completes processing the transaction, it sends back the callback via the ResultURL you specified in the initial request. A callback from MPesa can either be a success callback or a failure callback. A sample of a successful transaction callback is as shown below:

{
"Result":
{
  "ResultType":0,
  "ResultCode":0,
  "ResultDesc":"The service request has been accepted successfully.",
  "OriginatorConversationID":"14593-80515-2",
  "ConversationID":"AG_20170821_000049448b24712383de",
  "TransactionID":"LHL41AHJ6G",
  "ResultParameters":
  {
   "ResultParameter":
   [
    {
      "Key":"TransactionAmount",
      "Value":100
    },
    {
      "Key":"TransactionReceipt",
      "Value":"LHL41AHJ6G"
    },
    {
      "Key":"B2CRecipientIsRegisteredCustomer",
      "Value":"Y"
    },
    {
      "Key":"B2CChargesPaidAccountAvailableFunds",
      "Value":0.00
    },
    {
      "Key":"ReceiverPartyPublicName",
      "Value":"254708374149 - John Doe"
                                                    },
    {
      "Key":"TransactionCompletedDateTime",
      "Value":"21.08.2017 12:01:59"
    },
    {
      "Key":"B2CUtilityAccountAvailableFunds",
      "Value":98834.00
    },
    {
      "Key":"B2CWorkingAccountAvailableFunds",
      "Value":100000.00
    }
   ]
  },
  "ReferenceData":
  {
  "ReferenceItem":
   {
    "Key":"QueueTimeoutURL",
    "Value":"https:\/\/internalsandbox.safaricom.co.ke\/mpesa\/b2cresults\/v1\/submit"
   }
  }
}
}

Of major importance are:

ResultCode

This is a simple outcome of the transaction. A 0 (zero) standing for successful transaction, and any other code standing for an unsuccessful transaction. If not successful, the description of the error that was raised is in the ResultDesc element.

ResultDesc

This is a one line description of the result code received above. It explains, if unsuccessful, why a transaction failed.

TransactionID, TransactionReceipt

This is MPesa's unique identifier of the transaction. As long as the request was accepted by MPesa, you can expect a transaction ID in your callback, whether the transaction was successful or not. Note: TransactionReceipt and TransactionID both represent the same transaction, thus are the same.

TransactionAmount

This is the amount that was transferred to the customer in this transaction.

ReceiverPartyPublicName

This is a concatenation of the receiver's phone number + First name + Last name as registered on MPesa

B2CUtilityAccountAvailableFunds, B2CWorkingAccountAvailableFunds

Simply the current usable balances of the Organization's Utility Account and Working account respecively as at the time of the current transaction.

For an unsuccessful transaction, the response format will be:

{
"Result":
{
    "ResultType":0,
    "ResultCode":>17,
    "ResultDesc":"System internal error.",
    "OriginatorConversationID":"16940-3815719-3",
    "ConversationID":"AG_20171228_00004fd3a482e7f73145",
    "TransactionID":"LLS81H3W6E",
    "ReferenceData":
    {
     "ReferenceItem":
     {
      "Key":"QueueTimeoutURL",
      "Value":"https:\/\/internalsandbox.safaricom.co.ke\/mpesa\/b2cresults\/v1\/submit"
     }
    }
}
}

Note the value of ResultCode, which gives an instant view of the status of the transaction. The cause of the error is then described in the ResultDesc element. For this specific error (System internal error), get in touch with the support team, something's wrong with the backend. Also note the transaction also has an MPesa Transaction ID, which identifies your transaction in the system.

That is pretty much B2C in a nutshell.

This API enables a Business or Organization to perform transactions between each other. The transaction flow is the same as the B2C API transaction flow, but this time the Credit Party is another Business/Company/Organization. It requires the same credentials and information as the B2C API.

Currently the B2B API allows an organization to perform 5 types of transfers:

Business Pay Bill: This is a transfer of funds from one Organization's Working Account to another Organization's Utility Account.

Business Buy Goods: A transfer of funds from one Organization's Working Account to another Organization's Merchant Account.

Disburse Funds To Business: A transfer of funds from one Organization's Utility Account to another Organization's Working Account.

Business To Business Transfer: A transfer of funds from one Organization's Working Account to another Organization's Working Account.

Merchant To Merchant Transfer: A transfer of funds from one Organization's Merchant Account to another Organization's Merchant Account.

For any two shortcodes to perform B2B transactions between themselves, they both need to have the B2B product assigned to them, otherwise the transaction request will fail. The B2B request structure is as shown below:

// URL
[POST] https://sandbox.safaricom.co.ke/mpesa/b2b/v1/paymentrequest
                                    
// HEADERS
Host:  sandbox.safaricom.co.ke 
Authorization:  Bearer [access token] 
Content-Type:  application/json 
                                    
// BODY
{ 
   "Initiator":  "TestInit610" ,
   "SecurityCredential":  "[encrypted password]" ,
   "CommandID":  "[CommandID]" ,
   "SenderIdentifierType":  "4" ,
   "RecieverIdentifierType":  "4" ,
   "Amount":  "100000" ,
   "PartyA":  "600610" ,
   "PartyB":  "254708374149" ,
   "AccountReference":  "" ,
   "Remarks":  "" ,
   "QueueTimeOutURL":  "https://ip:port/" ,
   "ResultURL":  "https://ip:port/"
} 

These are explained below:

Initiator

 

The username of the API operator as assigned on the MPesa Org Portal.

SecurityCredential

The password of the API operator encrypted using the public key certificate provided.

CommandID

This specifies the type of transaction being performed. There are five allowed values on the API: BusinessPayBill, BusinessBuyGoods, DisburseFundsToBusiness, BusinessToBusinessTransfer or MerchantToMerchantTransfer.

SenderIdentifierType, RecieverIdentifierType

This is the type of Identity performing the transaction. An organization's Identity type for a shortcode (identity being used in the request) is 4, thus for both the above parameters, the value will always be 4 for B2B transfers (NB: you cannot use Till numbers in B2B transfers).

PartyA

This is the identifier of the Debit party of the transaction, in this case the debit party being the Organization and the identifier being the Shortcode of the organization.

PartyB

This is the identifier of the Credit party of the transaction, here the credit party being another organization and the identifier being the other org's shortcode.

AccountReference

This is a custom value that may represent an account or unique value item being paid for. It is only required for the BusinessPayBill Command ID.

Remarks

A very short description of the transaction from your end, or just a minimum of 2 characters.

 

ResultURL

This is the callback URL where the results of the transaction will be sent. Please visit the API Apps section to understand how this is used if you are not familiar with it.

 

QueueTimeOutURL

This is the callback URL used to send an error callback when the transaction was not able to be processed by MPesa within a stipulated time period.

Once sent, you shall expect a success acknowledgement response from the API informing you that your request was accepted. The response format is as below:

{
  "ConversationID":  "AG_20180326_00005ca7f7c21d608166",
  "OriginatorConversationID":  "12363-1328499-6",
  "ResponseCode":  "0",
  "ResponseDescription":  "Accept the service request successfully."}

From here, process is the same as the B2C flow. A sample success B2B callback is shown below:

{
"Result":
{
    "ResultType":0,
    "ResultCode":0,
    "ResultDesc":"The service request has been accepted successfully.",
    "OriginatorConversationID":"8551-61996-3",
    "ConversationID":"AG_20170727_00006baee344f4ce0796",
    "TransactionID":"LGR519G2QV",
    "ResultParameters":
    {
    "ResultParameter":
    [
        {
    "Key":"InitiatorAccountCurrentBalance",
    "Value":"{ Amount={BasicAmount=46713.00, MinimumAmount=4671300, CurrencyCode=KES}}"
     },
     {
    "Key":"DebitAccountCurrentBalance",
    "Value":"{Amount={BasicAmount=46713.00, MinimumAmount=4671300, CurrencyCode=KES}}"
     },
     {
    "Key":"Amount",
    "Value":10
     },
     {
    Key":"DebitPartyAffectedAccountBalance",
    "Value":"Working Account|KES|46713.00|46713.00|0.00|0.00"
     },
     {
    "Key":"TransCompletedTime",
    "Value:"20170727102524
     },
     {
    "Key":"DebitPartyCharges",
    "Value":"Business Pay Bill Charge|KES|77.00"
     },
     {
    "Key":"ReceiverPartyPublicName",
    "Value":"603094 - Safaricom3117"
     },
     {
    "Key":"Currency",
    "Value":"KES"
     }
    ]
   },
   "ReferenceData":
   {
    ReferenceItem":
     [
    {
     "Key":"BillReferenceNumber",
     "Value":"aaa"
    },
    {
     "Key":"QueueTimeoutURL",
     "Value":"https://internalsandbox.safaricom.co.ke/mpesa/b2bresults/v1/submit"
    }
    ]
   }
  }
}

Some new elements descriptions:

ReceiverPartyPublicName

The Shortcode + Registered Name of the organization being credited in the transaction.

DebitPartyCharges

How much the debit party is being charged for the transfer.

For an unsuccessful transaction, the response format will be the same as the B2C callback, and follows the same rules.

The Lipa na MPesa (LNM) API is an API designed to utilize the new feature introduced by Safaricom known as STK Push. This feature allows the transaction initiation to be moved from the paying customer's side to the payee Organization's side. This eliminates the challenge of having to remember business paybill numbers and account numbers and allows customers to simply confirm the transaction by entering their MPesa PIN on their mobile phone. This is done via the STK push/Pop-up which appears on a customer's phone that prompts them to enter their PIN. For the business, this API enables them to preset all the correct info in the payment request and reduce chances of wrong payments being performed to their systems. It is a C2B transaction, but with the initiator being the organization instead of the customer. Since the organization has the option of presetting all required variables in the request before sending the request, this API has no Validation-Confirmation process like the previous C2B API.

The B2B process is as explained below:

  • The Business sets the data in the request and sends it
  • The API receives the request and validates it internally first, then sends you an acknowledgement response.
  • The API then sends an STK Push request to the target customer's mobile phone. The customer's phone has to be online and unlocked to receive the request.
  • The customer confirms the payment amount via the message displayed on-screen, then either enters the PIN or cancels the request accordingly.
  • The API receives the customer's response. If the response is a negative, it cancels the transaction and sends a corresponding callback to the initiating 3rd party via the predefined callback URL in the initial request, with the info on why the transaction was cancelled. The possible negative responses could be due to the following scenarios:
    • An invalid PIN entered by the customer
    • Timeout due to customer not entering the PIN within a given time period (usually 1 min 30 secs)
    • The customer's SIM card not having the STK applet on it
    • A literal request cancellation by the user on their phone
    • Another STK transaction is already underway on the customer's phone (no more than one request can be processed at the same time on the same phone)
  • If the PIN is correct, it means the customer accepted the request. The API forwards the transaction to MPesa.
  • MPesa automatically processes the request, then sends the response back to the API system which then forwards it to you via the callback URL specified in your initial request. Here, the callback can also either be a success or failure, just like a normal C2B transaction.
  • There are no repeat calls for failed callbacks, thus if the API is unable to send the callback to you, you have the Transaction Status Query API to confirm the status of the request, or also confirm via the MPesa Org. portal.

For this API, you will need your actual production line to test the API. Your line must have the STK applet installed (you can update by dialing *234*1*6# on your handset (as of the day of writing of this tutorial). If the update does not work and your physical SIM card is more than 3 years old, consider replacing it), and you must be registered on MPesa. The funds utilized are automatically refunded at midnight. I suggest using values as low as 1 - 10 shillings to perform your transactions to lengthen the number of tries you make. Also beware, the API does not allow one to perform more than 5 consecutive STK requests without completing them. This is marked as phishing, and will cause your line to be blocked from making any more STK requests over 24 hours.

The LNM request takes the format below:

 
// URL
[POST] https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest

// HEADERS
Host: sandbox.safaricom.co.ke
Authorization: Bearer [access token]
Content-Type: application/json

// BODY
{
    "BusinessShortCode": "174379",
    "Password": "MTc0Mzc5YmZiMjc5ZjlhYTliZGJjZjE1OGU5N2RkNzFhNDY3Y2QyZTBjODkzMDU5YjEwZjc4ZTZiNzJhZGExZWQyYzkxOTIwMTgwNDA5MDkzMDAy",
    "Timestamp": "20180409093002",
    "TransactionType": "[Transaction Type]",
    "Amount": "1000",
    "PartyA": "254708374149",
    "PartyB": "174379",
    "PhoneNumber": "254708374149",
    "CallBackURL": "https://ip:port/"
    "AccountReference": "account",
    "TransactionDesc": "test" ,
}

Here are some definitions

BusinessShortCode

This is the shortcode of the organization initiating the request and expecting the payment.

Password

This is the Base64-encoded value of the concatenation of the Shortcode + LNM Passkey + Timestamp, e.g. given the test values above, and using a timestamp of 20180409093002, the encoded password will be

MTc0Mzc5YmZiMjc5ZjlhYTliZGJjZjE1OGU5N2RkNzFhNDY3Y2QyZTBjODkzMDU5YjEwZjc4ZTZiNzJhZGExZWQyYzkxOTIwMTgwNDA5MDkzMDAy

You can use this site to confirm your encoding.

Timestamp

This is the same Timestamp used in the encoding above, in the format YYYMMDDHHmmss.

TransactionType

The type of transaction being performed. These are the same values as the C2B command IDs (CustomerPayBillOnline and CustomerBuyGoodsOnline) and the same rules apply here. For now, only CustomerPayBillOnline is supported.

Amount

Self explanatory.

PartyA

The Debit party of the transaction, hereby the phone number of the customer.

PartyB

The credit party of the transaction, hereby being the shortcode of the organization. This is the same value as the Business Shortcode

PhoneNumber

Same as PartyA.

CallBackURL

This is the endpoint where you want the results of the transaction delivered. Same rules for Register URL API callbacks apply

AccountReference

This is the value the customer would have put as the account number on their phone if they had performed the transaction via phone.

 

TransactionDesc

Short description of the transaction. Optional, but element must be present.

After sending a successful transaction, you can expect a response in the below format:

{
   "MerchantRequestID": "25353-1377561-4",
   "CheckoutRequestID": "ws_CO_26032018185226297",
   "ResponseCode": "0",
   "ResponseDescription": "Success. Request accepted for processing",
   "CustomerMessage": "Success. Request accepted for processing"
}

Note the ResponseCode. The value 0 (zero) means the request was accepted successfully. Any other value means there was an error validating your request. Confirm the error on the ResponseDescription and fix it. The CheckoutRequestID is your unique request ID and can be used later for the LNM Transaction Query API.

After sending the callback, and assuming a customer has accepted your request and responded to it, a successful callback will have the structure below:

{
 "Body": 
 {"stkCallback": 
  {
   "MerchantRequestID": "21605-295434-4",
   "CheckoutRequestID": "ws_CO_04112017184930742",
   "ResultCode": 0,
   "ResultDesc": "The service request is processed successfully.",
   "CallbackMetadata": 
    { 
     "Item":  
     [
     {
       "Name": "Amount",
       "Value": 1
     },
     {
       "Name": "MpesaReceiptNumber",
       "Value": "LK451H35OP"
     },
     {
       "Name": "Balance"
     },
     {
       "Name": "TransactionDate",
       "Value": 20171104184944
      },
     {
       "Name": "PhoneNumber",
       "Value": 254727894083
     }
     ]
    }
  }
 }
}

Lets shift focus to the ResultCode,which shows the status of the request. The 0 (zero) means a success as usual, anything else will be an error whose description is defined in ResultDesc. The MPesa Receipt Number is your unique identifier of the transaction on MPesa, and can be used with the Sandbox Transaction Query API.

This API enables reversal of transactions done.

You will be able to reverse a transaction where you are the credit party. This means it will be done via the Web portal, and may require manual authorization from the Service Provider side. But if you are allowed to reverse a transaction via API, it may also need to be authorized.

An initiator requires the Org Reversals Initiator role to be able to perform reversals via API.

The reversal request format is as below:

// URL
[POST] https://sandbox.safaricom.co.ke/mpesa/reversal/v1/request

// HEADERS
Host: sandbox.safaricom.co.ke
Authorization: Bearer [access token]
Content-Type: application/json

// BODY
{  
   "Initiator":"TestInit610",  
   "SecurityCredential":"[encrypted password]",  
   "CommandID":"TransactionReversal",  
   "TransactionID":"[original trans_id]",  
   "Amount":"[trans amount]",  
   "ReceiverParty":"600610",  
   "RecieverIdentifierType":"4",  
   "ResultURL":"https://ip:port/",  
   "QueueTimeOutURL":"https://ip:port/",  
   "Remarks":"please",  
   "Occasion":"work"
}

Important parameters:

TransactionID

This is the MPesa Transaction ID of the transaction which you wish to reverse.

Amount

The amount transacted in that transaction to be reversed, down to the cent.

ReceiverParty

Your Org's shortcode here.

A successful callback will be as shown below:

{
   "Result":
   {
    "ResultType":0,
    "ResultCode":0,
    "ResultDesc":"The service request has been accepted successfully.",
    "OriginatorConversationID":"10819-695089-1",
    "ConversationID":"AG_20170727_00004efadacd98a01d15",
    "TransactionID":"LGR019G3J2",
    "ReferenceData":
    {
     "ReferenceItem":
     {
       "Key":"QueueTimeoutURL",
       "Value":"https://internalsandbox.safaricom.co.ke/mpesa/reversalresults/v1/submit"
     }
    }
   }
 }

Note the TransactionID. This is the transaction ID of the reversal request itself, not the original transaction which was being reversed. The reversal request itself gets its own transaction ID.

Go live process

This is the process of moving your application from the developers sandbox environment to production/live environment which the developer uses to enable their application to carry out requests on the live API and begin processing client payments. For this process, you require at least the following two items already existing.

Paybill Number

This is the shortcode which you received after you registered to use MPesa services.

Business Administrator/Business Manager

These are admin users on your MPesa Organization portal who have the roles of either the Business Administrator or the Business Manager assigned to them. To confirm who this is, you can try to follow the steps below on the Mpesa Org Portal:

- Log into the Org portal using the shortcode which you shall use in the Go Live process using an admin user. - Check if you have the Browse Organization menu at the top of the screen. If not, you are not an admin, log out. If you have it, click on it.

 

Browse Org Menu Item

- Click on the Operators sub-menu on the bar that appears on the left of the screen

 

Operators Menu Item

- A list will appear showing all the users on your portal, and their roles. From this list, check on the Role column and see if anyone has the Business Administrator/Manager role on them. You can also click on the Operation icon at their far right on the list to see their profile and the complete list of roles assignable to them. That user with the Business Administrator/Manager role is the required one for the Go Live process.

 

Roles List

- Open the Business Administrator/Manager user's details by clicking the Operation icon at the far right. Once there, click on the KYC tab and confirm that the following details are there:

  • Identity Status is Active
  • Email
  • Preferred Contact Phone Number (starting with 2547XX)
  • Notification Receiving MSISDN (starting with 2547XX)
  • Notification Receiving E-Mail
  • ID type and Number
 

Operator Details

These details will be used for verification during the Go Live journey.

After confirming the above details, you may start the process. On the first step of the Go Live process, you shall be required to download and fill in a form specifying how your tests went along. These cases consist of the possible scenarios which you shall encounter as you test your application. The test cases just need a simple Success or Fail response on the Actual Results tab.

 

How to fill Test Cases form

Once downloaded and filled, go back to the same Page and upload the form via the Upload Test Results form, click on Upload, then after the form has been picked up, check the Terms and Conditions checkbox, then click on Next.

 

On the Verification section, you shall need to confirm your ownership of the paybill you are taking live. This will require you to enter your paybill and your contact details, receive a One Time Pin (OTP) on your registered Mobile Phone, then put that OTP on the portal to confirm your authenticity. On that page, you shall select Verification type as Short Code (only one supported for now), Organization Name as the name of the Organization as registered on MPesa, your Organization ShortCode, and the username of either the Business Administrator or Business Manager as filled in on the Org Portal (that's why I had you confirm the details exist first). Without either of these, the process will fail as there will be no contact phone to send you the OTP or the email to send the production URLs.

 

Once you click on Submit, and MPesa confirms the details you put as correct, it will send an OTP to the Phone Number registered on the Org Portal under the User whose username was filled on the verification form. Once you get the OTP on your phone (you might need a few retries), you shall fill it on the next section, the OTP Confirmation section. From the docs, the OTP has an expiry timeout of 3 minutes, thus you need to be fast, or you can just click on Resend OTP. Once the OTP has been confirmed, you shall then be given the chance to select the APIs you are applying for (note the limitations mentioed in the API Apps section). After completing the section, there shall also be created automatically the production apps for your account. These apps need to be approved internally, then after approval, you shall have the production URLs sent to the email registered against the same user who applied for Verification in step 2 of the process. You will then have the new Consumer Keys and Consumer Secrets for your app ready for use in production. Click here for the detailed go live process. For password creation, you can follow the steps given in the B2C section above