Introduction

Proxy API is a simple, intuitive JSON/REST API built upon the stable and well known G2 SOAP/XML API. It aims to provide stability via the use of as few nuts and bolts as possible, and also provides extra features needed by developers during the on-boarding process. Some new developments have been made to try and make the integration process as smooth as possible. Some of those new developments include:

  • - CommandIDs are not being used as part of the request. Instead, the specific CommandID will be determined by the endpoint URL e.g. for a B2C transaction, the CommandID BusinessPayment will be inferred by the URL ~/b2c/businesspayment, and the CommandID PromotionPayment will be inferred by the URL ~/b2c/promotionpayment
  • - C2B Callback URLs can now be changed on the fly on the portal. No need to write long emails requesting for the same ever again.
  • - All requests and callbacks to the Proxy API are recorded, thus one can follow the chronological order of callbacks from their system using the 3rd party RequestID (OriginatorConversationID) to M-Pesa and back. This will be useful for troubleshooting where a request failed or was terminated.
  • - The RequestID (OriginatorConversationID) is now in the control of the 3rd Party, and directly tied to the third party requests, thus one will actually be able to assign own request IDs to their own API requests and eliminate chances of double transactions for the same API request.

This guide explains how Proxy API works.

Apps

This API seeks to emulate Safaricom Daraja API where possible to make it easier to jump on board and begin using. To begin with, you will create Apps which shall be the central point via which you access the API

One can have a maximum of 50 Apps on their account. Each app can be later tied to a specific Shortcode when moving to Production and that app will be used to control access to the Shortcode. Once assigned, the app assignment to the Shortcode cannot be changed. One can perform the following actions on an App:

An App's status determines if an application can be used to make API calls for outgoing requests, or allow processing of validation and confirmation requests for incoming C2B requests. If an App is disabled, it will not be allowed to make any outgoing API calls, and will not allow incoming API requests to its Shortcode to which it is tied to (including C2B).

For you to be able to either delete an app or modify it, you must first fulfill the following conditions:

  • - To delete an app, the app must not be assigned to any Shortcode in Production.
  • -To change the current environment where an app will be used, the app must not be assigned to a shortcode.

Adding an app

To add an App:

  • - Select the Apps menu on the main menu on the left side of the page, then click on the Add button near the top right of the page.
  • - Set the app name and current environment. The App name must be a minimum of 8 characters and must contain only alphanumeric characters, dashes and spaces. Then click on Save.

    NB: Once set, the app name cannot be modified afterwards.

  • If you want to be able to perform B2B requests using the new App, check the App is a B2B App checkbox before you save. Note that this app will be able to perform only B2B requests.


Once created, the App is automatically assigned a set of credentials: an App key and an App secret. These can be used later on to receive an access token to be able to make API calls to the API. To get the API credentials of an existing app, double click on the app from the apps list, and click on Credentials button on the popup that appears. A JSON file with the credentials of the app should download to the current machine. Please keep the credentials in a safe location.

Modifying/Deleting an app

To modify an existing app:

  • - Select the Apps menu on the main menu on the left side of the page, then double-click on the specific app you want to edit.
  • - Change the parameters as needed on the pop-up that appears, then click on Save to save the details
  • - To delete an app, click on Delete and confirm the action. If the criteria for deleting an app are not satisfied, the respective message will be displayed and the request cancelled.

API Tokens

Proxy API tries to simplify account creation and on-boarding by using available and existing Single Sign-On Providers. As of now, only Google and Microsoft are supported, but requests can be made to add more available Providers and depending on the number of requests for a specific Provider, a case can be made to add the Provider onto the system. This allows us to onboard a client with a single operation only.

NB: Closing an account deletes all info related to the client on the system, including apps, transactions and Shortcodes tied to the user. So always confirm before you perform any such action

The Account section controls the Authorization aspect of the API. One can see the scopes assigned to their Shortcodes once they go live.

Account

Allows one to view the scopes currently assigned to their production Shortcodes.


Modifying an app

To modify an existing app:

  • - Select the Apps menu on the main menu on the left side of the page, then double-click on the specific app you want to edit.
  • - Change the parameters as needed on the pop-up that appears, then click on Save to save the details
  • - To delete an app, click on Delete and confirm the action. If the criteria for deleting an app are not satisfied, the respective message will be displayed.

To get the API credentials of an existing app, double click on the app from the apps list, and click on Credentials on the popup page that appears. A JSON file with the credentials of the app should download to the current machine. Please keep the credentials in a safe location.

Scopes

This API has provided the following scopes for use:

  • Oauth
  • C2B Paybill
  • C2B Till
  • B2C
  • B2B
  • Transaction Query
  • Reversal

Scopes are assigned to Shortcodes during the go live process. The assignment is done automatically based on the client's Shortcode type and M-Pesa Organization Portal access availability.

Once assigned during Go Live, the client can view a Shortcode's assigned scopes by going to Account -> Scopes tab.

Sandbox

The Sandbox is where you get to test out your API prior to going live. There are 4 APIs to be tested out depending on your use case:

Oauth: for creation and refreshing of Authorization tokens C2B: for testing out C2B Validation/Confirmation callbacks B2C: for testing out B2C requests and callbacks B2B: for testing out B2B requests and callbacks Reversal: testing out reversal of C2B transactions Transaction Query: for querying status of 3rd-party initiated requests

Sandbox Settings

Enables registration of Sandbox callback URLs for C2B. The Sandbox Validation URL will be called during validation requests, and the Sandbox Confirmation URL will be called during Confirmation requests. One can test the callback access using the Test button on the right side of the input fields. The test will send a dummy C2B Validation request to the endpoint and return the HTTP response code received, and time taken to perform the HTTP request. This can be used to test the status and how long Validation requests will take to execute on your end. The dummy C2B Validation request has the below structure:

{
	"TransactionType": "CustomerPayBillValidation",
	"TransactionTime": "20190101235959",
	"TransactionID": "IMJ****RMN",
	"TransactionAmount": 10,
	"BusinessShortcode": "000000",
	"AccountReference": "ref0123456789",
	"SenderMSISDN": "254722000111",
	"SenderFirstName": "John",
	"SenderMiddleName": null,
	"SenderLastName": "Doe",
	"Signature":"Dw/vBzfZsRDGeLbmoJ5LS8sa3bBEjE204OwvTRdAD49GM2hQIdPhkFcintk/C7pegwzXPEx6GtYDlCo1Qy7hZVyejWF7j+iTuhpYpjT8nHhkZB6ChGGnu29G71APMK9gTeZc6Uh0reswI5VAI6me9reJAtbsm1oaT8UAB/YTqXk=",
	"PublicKey":"-----BEGIN RSA PUBLIC KEY-----rnMIGJAoGBAKPa4uBuIwACpMH3adHspUbT+jO0g4mm2uyYSZGvSR58SgnLai0KP71xrnKzvicbB/hAq34Ah5bmqW6vq78CXPorQPzf8Q8rmzYkhBj4zLKRwxiqkLlaBE82aarnscW00dV8k88zJChK4o91TE1NEBNIaWi0ZQJJCU/MlBcEXz5y0qrNAgMBAAE=rn-----END RSA PUBLIC KEY-----"
}

The dummy request will have a randomly generated sample TransactionID for every test request, but all the other values will remain the same.

C2B Transaction Validation Default Action simulates what will happen to a transaction when Proxy API is called by M-Pesa to forward a request, but is unable to reach you. Cancelled means Proxy API will automatically cancel the transaction after receiving no or partial response within up to 6 seconds. Completed means Proxy API will automatically complete the transaction following the above scenario.

Allow C2B Payment Validation sets whether a C2B payment will be forwarded to the 3rd party system for validation or will simply take the default action set above. If not set, the default action will be executed. Otherwise, the request will be forwarded to the 3rd Party and normal execution flow will occur. This is explained in more details in the C2B section

Oauth

Creates the Access tokens used in making API calls. This works as below:

  • Get the SHA3-256 hash of App Key + ":" + App Secret (note the full colon in the encoding, don't include the quotes) e.g. using a random key 1234567890-abcdefghijklmnopqrstuvwxyz and random secret abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz, the SHA3-256 hash will be calculated as sha3_256("1234567890-abcdefghijklmnopqrstuvwxyz:abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz") giving the result fb94869a5819dfb9677585d00f4a6f7325e5313cbbc6d62bbb0c27ed0b29827e. You can always confirm the value and result using the Utilities section under Sandbox.
  • Create a GET request and set an Authentication header with the value as Basic + [space] + encoded value from above step e.g. using the sample Credentials above, the header will be X-Authorization: Basic fb94869a5819dfb9677585d00f4a6f7325e5313cbbc6d62bbb0c27ed0b29827e. Note: there is no Base64 encoding being done on the result of the above function.
  • Send the request to the endpoint https://api.proxyapi.co.ke/sandbox/mpesa/v1/auth. The raw request will be as follows:

    
    GET /sandbox/mpesa/v1/auth HTTP/1.1
    
    Host: api.proxyapi.co.ke
    X-Authorization: Basic fb94869a5819dfb9677585d00f4a6f7325e5313cbbc6d62bbb0c27ed0b29827e
    Content-Type: application/json
    
  • You shall receive a response in the format shown below, showing your access token and the expiry date in Unix timestamp format. Default expiry time is 1 hour, and subsequent requests for the API key will return the same value until the expiry time is over. Once expired, any subsequent calls to the API using the same key will result in a 403: Unauthorized error.

    {
    	"StatusCode": 200,
    	"ResponseCode": "200",
    	"ResponseDesc": "Success",
    	"ServiceStatus": 0,
    	"Data":
    	{
    		"AccessToken": "fa1378e17e8bebd998c94b959ff81195c5ac8989a44ead3c408d3b7076a4ba59",
    		"Expiry": 1564327581
    	}
    }

C2B Paybill

Simulates C2B Paybill requests (payments from customers to businesses) to the M-Pesa API. The C2B Paybill request is the payment a customer makes by going to M-PESA -> Lipa na M-PESA -> Pay Bill option on mobile STK, and uses a Paybill/Store number. Thus it requires an Account number/Bill reference number for it to be valid. The flow on how C2B works can be found in the tutorial available here. The C2B Paybill request has the format shown below:

/ URL
[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/c2b/customerpaybill

// HEADERS
Host: api.proxyapi.co.ke
X-Authorization: Bearer da5eabaefca067ec4ae0d19994f4812d2e3542da765423f1d5afe2779db17584

// BODY
{
	"SenderMSISDN": "254796778039",
	"ReceiverShortcode": "999112",
	"Amount": 1,
	"AccountReference": "acc_ref"
}

Note the endpoint for this specific request type. The descriptions of the parameters above are defined below:

SenderMSISDN
The phone number of the paying client. It must be a Kenyan number and begin with '+2547...', '2547...' or '07...' (might change later due to addition of MNO codes in Kenya)
ReceiverShortcode
This is the paybill number which you expect to receive payments notifications about
Amount
The amount being transferred, up to a maximum of KES. 70000 inclusive
AccountReference
This simulates the account number that a user would have entered when making a Pay Bill request. This parameter is only required for C2B PayBill 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 and usually accepts the following character regex: /\w\[\]\-\@\$\^\(\):;\./

After sending the request, and assuming you have all the correct details, the success acknowledgement response should have the following format, with the ResponseCode being "0" (a String) for a success:

{
	"StatusCode": 200,
	"ResponseCode": "0",
	"ResponseDesc": "Accept the service request successfully.",
	"ServiceStatus": 0
}

If there was any error in making the request, the callback will have the same format, but the ResponseCode will NOT be "0", instead it will have another value and the explanation for the error in the ResponseDesc parameter. A sample is shown below:

{
	"StatusCode": 503,
	"ResponseCode": "SVC0001",
	"ResponseDesc": "Internal Server Error",
	"ServiceStatus": 0
}

The StatusCode is the standard HTTP status code showing the status of the request with respect to Proxy API. The ResponseCode can take either of two values: a HTTP status code in String format if the request did not reach M-Pesa or was an invalid request and thus was terminated before reaching M-Pesa; or the M-Pesa ResponseCode if the request reached M-Pesa and was received and an acknowledgement returned e.g. if there was an issue with M-Pesa, and the proxy was not able to reach M-Pesa, or if the request was deemed invalid and terminated, the ResponseCode will contains a standard 503 HTTP status code as shown below:

{
	"StatusCode": 401,
	"ResponseCode": "401",
	"ResponseDesc": "Invalid Credentials",
	"ServiceStatus": 0
}

If the request was received by M-Pesa, the ResponseCode will then contain the usual response code from M-Pesa with the status of the request in the same format as for the success or failed requests above.

C2B Paybill Validation

Once a request has been sent, M-Pesa will send a validation request to the Proxy, which will be processed and forwarded according to the rules set for each Shortcode in the Shortcodes section. A validation request is dependent on validation being enabled on M-Pesa, thus if you do not receive any validation requests on production, confirm the C2B Shortcode has validation enabled from the M-Pesa team or simply ask for it to be enabled. The rules below assume validation has been enabled on M-Pesa and that M-Pesa is allowed to send validation requests to 3rd parties for the specified Shortcode. For each request...

  • If the user is disabled on the system, the transaction is automatically cancelled.
  • If validation is not allowed in Shortcode Settings or Sandbox Settings, depending on the environment, the request is recorded in the system then automatically completed. Setting Allow C2B Payment Validation to false/disabled is translated to mean the 3rd Party wants all payments to go through automatically, even if external validation is enabled on M-Pesa end.
  • If validation is allowed...
    • ...and the Validation URL is not set, the transaction is recorded in the system then automatically cancelled
    • ...and the Validation URL is set, the API tries to reach the URL and get the validation response. If a response is received within 6 seconds, it repackages the HTTP response into an M-Pesa validation response and pipes back the response back to M-Pesa. If the Validation URL is set but unreachable or no response is received within 6 seconds, the transaction is recorded then automatically cancelled by the API with a 5XX HTTP response code to M-Pesa.

Once a validation request is received and processed internally, if validation is allowed and the request allowed to be forwarded, a Proxy validation request is sent to the 3rd Party system. The format of the request is as below:

{
		"TransactionType": "CustomerPayBillValidation",
		"TransactionTime": "20190616152507",
		"TransactionID": "NFG46QC4NI",
		"TransactionAmount": 10,
		"BusinessShortcode": "999112",
		"AccountReference": "acc_ref",
		"SenderMSISDN": "254713170997",
		"SenderFirstName": "Pombe",
		"SenderMiddleName": null,
		"SenderLastName": "Magufuli",
		"RemainingCredits": 0,
		"Signature":"Dw/vBzfZsRDGeLbmoJ5LS8sa3bBEjE204OwvTRdAD49GM2hQIdPhkFcintk/C7pegwzXPEx6GtYDlCo1Qy7hZVyejWF7j+iTuhpYpjT8nHhkZB6ChGGnu29G71APMK9gTeZc6Uh0reswI5VAI6me9reJAtbsm1oaT8UAB/YTqXk=",
		"PublicKey":"-----BEGIN RSA PUBLIC KEY-----rnMIGJAoGBAKPa4uBuIwACpMH3adHspUbT+jO0g4mm2uyYSZGvSR58SgnLai0KP71xrnKzvicbB/hAq34Ah5bmqW6vq78CXPorQPzf8Q8rmzYkhBj4zLKRwxiqkLlaBE82aarnscW00dV8k88zJChK4o91TE1NEBNIaWi0ZQJJCU/MlBcEXz5y0qrNAgMBAAE=rn-----END RSA PUBLIC KEY-----"
}

The parameter definitions are:

TransactionType
The transaction type and action, in this case CustomerPayBillValidation means its a validation request for a C2B Paybill transaction.
TransactionTime
The time the transaction was completed on M-Pesa in the format YYYYMMddHHmmss (https://en.wikipedia.org/wiki/Date_format_by_country)
TransactionID
M-Pesa's unique transaction identifier for your transaction. This can be used for searching for the transaction later on using the Transaction Query API.
TransactionAmount
The amount transacted by the customer when paying to your Shortcode
BusinessShortcode
The specific Shortcode to which the customer paid to.
AccountReference
The account number the customer entered on their phone or other interface when making the payment.
SenderMSISDN
The phone number from which the payment was made or will be deducted.
SenderFirstName
The first name of the customer under whom the MSISDN above is registered. The First and Last names are usually mandatory. The Middle Name is optional.
SenderMiddleName
The middle name of the customer under whom the MSISDN above is registered, if available.
SenderLastName
The last name of the customer under whom the MSISDN above is registered, if available.
RemainingCredits
The remaining credits left for the Application under the current shortcode after current API transaction has been completed. Not in use anymore. Not in use anymore.
Signature
This is a security signature of the concatenation of some of the callback parameters from above, signed using a one-time RSA 1024-bit private key. A small private key is used as this is expected to be a one-off operation and thus reduces the time complexity expected for encryption operations. Thus the user is expected to verify and discard the signature and PK, but can be stored if the need arises. A unique RSA SK/PK pair is generated for every request. More on this can be found in the Callback verification section
PublicKey
The Public key derived from the Private key used to create the above signature and to be used to verify the above Signature.

Once the 3rd party has validated the transaction, the 3rd party responds with a standard HTTP Status Code of either 200 or any other status code from the 2XX family to complete a request; or any other error codes (4XX, 5XX) to cancel a request. This will be mapped to the respective M-Pesa Complete or Cancel responses respectively.

C2B Paybill Confirmation

C2B Paybill Confirmation occurs once either validation has been successfully completed, or the Shortcode does not have validation enabled, meaning all transactions are automatically completed. Once a request is received, M-Pesa will send a Confirmation request, which will be forwarded to the 3rd party according to the following rules:

  • If there does not exist a Confirmation URL for the 3rd party set in the system, the API will record the request as a 404 - Not found response in the system. This request can be viewed later in the transaction log.
  • If there exists a Confirmation URL for the 3rd party set in the system, the API wll try to send a Confirmation request to that URL. The 3rd party will then respond with a HTTP 2XX status code within 6 seconds to affirm reception of the request. Otherwise the API will deem the request as failed and record it as such in the system. The request can be viewed later in the transaction log. Both results will be mapped to the respective response codes to M-Pesa.

A C2B Paybill Confirmation request has the below structure:

{
		"TransactionType": "CustomerPayBillConfirmation",
		"TransactionTime": "20190616152503",
		"TransactionID": "NFG36QC4NH",
		"TransactionAmount": 1,
		"BusinessShortcode": "999112",
		"AccountReference": "acc_ref",
		"SenderMSISDN": "254713170997",
		"SenderFirstName": "Pombe",
		"SenderMiddleName": null,
		"SenderLastName": "Magufuli",
		"RemainingCredits": 0,
		"Signature":"Dw/vBzfZsRDGeLbmoJ5LS8sa3bBEjE204OwvTRdAD49GM2hQIdPhkFcintk/C7pegwzXPEx6GtYDlCo1Qy7hZVyejWF7j+iTuhpYpjT8nHhkZB6ChGGnu29G71APMK9gTeZc6Uh0reswI5VAI6me9reJAtbsm1oaT8UAB/YTqXk=",
		"PublicKey":"-----BEGIN RSA PUBLIC KEY-----rnMIGJAoGBAKPa4uBuIwACpMH3adHspUbT+jO0g4mm2uyYSZGvSR58SgnLai0KP71xrnKzvicbB/hAq34Ah5bmqW6vq78CXPorQPzf8Q8rmzYkhBj4zLKRwxiqkLlaBE82aarnscW00dV8k88zJChK4o91TE1NEBNIaWi0ZQJJCU/MlBcEXz5y0qrNAgMBAAE=rn-----END RSA PUBLIC KEY-----"
}

The parameters are the same as for the validation request except for TransactionType, which shows the request to be a C2B Paybill Confirmation request

C2B Buy Goods

Simulates C2B BuyGoods requests to the M-Pesa API. The C2B BuyGoods request is the payment a customer makes by going to M-PESA -> Lipa na M-PESA -> Buy Goods and Services option on mobile STK, and uses a Till number. The flow on how C2B works can be found in the tutorial available here. The C2B BuyGoods request has the format shown below:

/ URL
[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/c2b/customerbuygoods

// HEADERS
Host: api.proxyapi.co.ke
X-Authorization: Bearer da5eabaefca067ec4ae0d19994f4812d2e3542da765423f1d5afe2779db17584

// BODY
{
	"SenderMSISDN": "254796778039",
	"ReceiverTill": "9991121",
	"Amount": 1
}

Note the endpoint for this specific request type. The descriptions of the parameters above are:

SenderMSISDN
The phone number of the paying client. It must be a Kenyan number and begin with '2547...' or '07...'
ReceiverTill
This is the till number which you expect to receive payments notifications about
Amount
The amount being transferred, up to a maximum of KES. 70000 inclusive

After sending the request, the success or error acknowledgement response should have the same format as for a C2B Paybill acknowledgement described before.

C2B BuyGoods Confirmation

A Buy Goods transaction has no validation, thus one should not expect validation requests on their endpoints. This is due to a Till being simply a collection account for incoming payments. There is only a confirmation request with the details of the transaction sent to the 3rd party. A BuyGoods confirmation request from the API has the below structure:

{
		"TransactionType": "CustomerBuyGoodsConfirmation",
		"TransactionTime": "20190616153501",
		"TransactionID": "NFG36QC343",
		"TransactionAmount": 1,
		"BusinessShortcode": "999112",
		"SenderMSISDN": "254713170997",
		"SenderFirstName": "Pombe",
		"SenderMiddleName": null,
		"SenderLastName": "Magufuli",
		"RemainingCredits": 0,
		"Signature":"Dw/vBzfZsRDGeLbmoJ5LS8sa3bBEjE204OwvTRdAD49GM2hQIdPhkFcintk/C7pegwzXPEx6GtYDlCo1Qy7hZVyejWF7j+iTuhpYpjT8nHhkZB6ChGGnu29G71APMK9gTeZc6Uh0reswI5VAI6me9reJAtbsm1oaT8UAB/YTqXk=",
		"PublicKey":"-----BEGIN RSA PUBLIC KEY-----rnMIGJAoGBAKPa4uBuIwACpMH3adHspUbT+jO0g4mm2uyYSZGvSR58SgnLai0KP71xrnKzvicbB/hAq34Ah5bmqW6vq78CXPorQPzf8Q8rmzYkhBj4zLKRwxiqkLlaBE82aarnscW00dV8k88zJChK4o91TE1NEBNIaWi0ZQJJCU/MlBcEXz5y0qrNAgMBAAE=rn-----END RSA PUBLIC KEY-----"
}

The parameters have the same definition as a C2B Paybill Confirmation request defined above, except for TransactionType which shows the transaction type to be a BuyGoods confirmation request

B2C

Also known as the Bulk Payment API, the Business to Consumer (B2C) API enables a Business or Organization to pay their customers for a variety of reasons. The most common reasons a business can pay their customer include salary payments, promotion payments (e.g. betting winnings payouts) or normal business payments (e.g. transfers from bank to mobile accounts). Each of these scenarios has their own unique characteristics, but all lie under the B2C API category

To learn more on how B2C works, please check out the B2C section in the tutorial.

NB: Existing B2C clients on Broker have their own VPN connections to perform API requests with. So on Proxy API, we have added the capability to utilize the API using their own SP credentials. This will involve sending a request to M-Pesa VAS team for the addition of the API's IP address(es) onto their SP credentials config on Broker to be able to make API requests via Proxy API. Thus the 3rd Party will be able to make API requests both via their systems and Proxy API. For new API clients, they can fully utilize Proxy API using its own SP credentials, and later on configure their own VPN anytime they wish to use for their own systems.

On Proxy API, there are three allowed B2C Command IDs, and each Command ID is mapped to a specific URL. Thus, to make e.g. a BusinessPayment request, the request is sent to the ~/b2c/businesspayment endpoint. This makes it easier to determine and know how to work with the API following the REST standard as closely as possible.

A sample standard Business Payment B2C Request has the following format:

[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2c/businesspayment

// HEADERS
X-Authorization: Bearer 7becb0f4f704877e2311e25ba962872ccf0eb779498e9d22b42cab86e6c8f06d

// BODY
{
	"RequestID": "7351306617410682",
	"SPID": "107040",
    "SPPassword": "ZWY1YWViYmE3ZTZmZDI3N2RmOGQzMzY4NDE3ZmIxODRmNDZkMDljZWMyYzBkNjk4NGUzZjhhMWE1NmI3NmIzYg==",
    "ServiceID": "107040000",
    "Timestamp": "20170623114011",
	"SenderShortcode": "999112",
	"ReceiverMSISDN": "254796778039",
	"Amount": 10,
	"InitiatorUsername": "testapi",
	"InitiatorEncryptedPassword": "V2Avw4CSEyQlEQLmMo8kwEPlWC1p4NLXmtRaW5GWTfwj21lKr9kOhhgG3ERlWpX3nobp/ZiqNPHa0iEwdh3ABufnAB6AKclsWzpYoVYXUv2nm0dtbAW0BTx061rlUbadvhN8tQb7HaBh4uy2xsuECR2G+PNDf/NTi8CS0F6J+AuyyJwwoeQr+W/Nk4isFmclIfXQ7z6kuRX9R9wvq1Qgz8bBsVsVvsqj210ITEBMQmzwbutYDVfSxQsptYFbrEJQXv3sm3QHfaquE37lACT1SUXzjhpvL2nLB/A1ubGLYVTVmCaJ8m78jyJ4389twKwqZ1Lr0fVn4NflpKzOxRJbag==",
	"CallbackURL": "https://example.domain.com/callback",
	"ReferenceData": [
    	{
    		"Key": "Value"
    	}
    ]
}

Or for non VPN clients:

[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2c/businesspayment

// HEADERS
X-Authorization: Bearer 7becb0f4f704877e2311e25ba962872ccf0eb779498e9d22b42cab86e6c8f06d

// BODY
{
	"RequestID": "7351306617410682",
	"SenderShortcode": "999112",
	"ReceiverMSISDN": "254796778039",
	"Amount": 10,
	"InitiatorUsername": "testapi",
	"InitiatorEncryptedPassword": "V2Avw4CSEyQlEQLmMo8kwEPlWC1p4NLXmtRaW5GWTfwj21lKr9kOhhgG3ERlWpX3nobp/ZiqNPHa0iEwdh3ABufnAB6AKclsWzpYoVYXUv2nm0dtbAW0BTx061rlUbadvhN8tQb7HaBh4uy2xsuECR2G+PNDf/NTi8CS0F6J+AuyyJwwoeQr+W/Nk4isFmclIfXQ7z6kuRX9R9wvq1Qgz8bBsVsVvsqj210ITEBMQmzwbutYDVfSxQsptYFbrEJQXv3sm3QHfaquE37lACT1SUXzjhpvL2nLB/A1ubGLYVTVmCaJ8m78jyJ4389twKwqZ1Lr0fVn4NflpKzOxRJbag==",
	"CallbackURL": "https://example.domain.com/callback",
	"ReferenceData": [
    	{
    		"Key1": "Value1"
    	},
		{
    		"Key2": "Value2"
    	}
    ]
}

The parameters are:

RequestID
A unique identifier of the request specific to the 3rd party. This parameter is appended to a hash of the 3rd party's Shortcode to create a reference unique to the 3rd party.
SPID
For existing VPN clients. 3rd Party SPID. Optional
SPPassword
For existing VPN clients. 3rd Party hashed SP Password. Optional
ServiceID
For existing VPN clients. 3rd Party SPID. Optional
Timestamp
For existing VPN clients. The timestamp used in the hashing of the SP Password above in the format YYYYMMddHHmmss. Optional
SenderShortcode
The Shortcode of the organization sending the funds.
ReceiverMSISDN
The MSISDN of the receiver party of the transaction. Should be a valid Safaricom Mobile No.
Amount
The amount being transferred, up to a maximum of KES. 70000 inclusive
InitiatorUsername
The username of the API operator as assigned on the M-Pesa Org Portal by the 3rd Party.
InitiatorEncryptedPassword
The password of the API operator assigned by the 3rd Party and encrypted using the public key certificate provided by M-Pesa
CallbackURL
This is the callback URL where the results of the transaction will be sent. Please read the tutorial to understand how this is used if you are not familiar with it.
ReferenceData
An optional array of data in object format which the 3rd party would like associated with the current request and returned to them in the callback. The array can hold up to five objects, and each object is limited to 1 property, having a key of less than or equal to 125 characters. Also, each object key should be unique in the array

For existing VPN clients' parameters, all SP parameters must be present if they are to be used.

For each supported Command ID, the respective endpoints are as shown below:

Command ID Sandbox Production
BusinessPayment https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2c/businesspayment https://api.proxyapi.co.ke/mpesa/v1/b2c/businesspayment
SalaryPayment https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2c/salarypayment https://api.proxyapi.co.ke/mpesa/v1/b2c/salarypayment
PromotionPayment https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2c/promotionpayment https://api.proxyapi.co.ke/mpesa/v1/b2c/promotionpayment

Once the request has been sent, an acknowledgement is sent in the format shown below.

{
	"RequestID": "419315161054942",
	"MpesaRequestID": "AG_20190727_000049a4a79eb257c1a4",
	"StatusCode": 200,
	"ResponseCode": "0",
	"ResponseDesc": "Accept the service request successfully.",
	"ServiceStatus": 0,
	"RemainingCredits": 0
}

If there was any problem with the request, and the API or M-Pesa terminates the request, the format will be as shown below:

{
	"StatusCode": 503,
	"ResponseCode": "15",
	"ResponseDesc": "Duplicate OriginatorConversationID.",
	"ServiceStatus": 0
}

The parameters are:

RequestID
The unique identifier of the request from the 3rd Party. This is only present if the request was accepted successfully by M-Pesa.
MpesaRequestID
A unique ID from M-Pesa (ConversationID) that tracks the request from beginning to end. This is only present if the request was accepted successfully by M-Pesa.
StatusCode
The API's HTTP status code.
ResponseCode
A code from M-Pesa giving the status of the request (if available). If not available, the HTTP status coe is instead returned in String format. A "0" response code means the request was accepted. Any other value means the request failed.
ResponseDesc
A short description of the response code given above.
ServiceStatus
Status of the Proxy API. A 0 means the API is up and running. Any other value means the API is not available.
RemainingCredits
The remaining credits left for the Application under the current shortcode after current API transaction has been sent. Not in use anymore.

Once a request has been submitted and processed, a callback will be received and forwarded to the client. The format of the callback for a successful request will be as below:

{
	"ResultCode": 0,
	"ResultDesc": "The service request is processed successfully.",
	"RequestID": "1560676855",
	"MpesaRequestID": "AG_20190616_000068281cafb1773a99",
	"MpesaTransactionID": "NFG16QC1WT",
	"ResultData":
	{
		"TransactionAmount": 20,
		"ReceiverPartyName": "254713170997 - Pombe Magufuli",
		"IsReceiverRegistered": "Y",
		"UtilityAccBalance": 1.0223207E7,
		"WorkingAccBalance": 5745441,
		"TransactionCompleteTime": "16.06.2019 12:15:48"
	},
	"ReferenceData":
	[
		{
			"Key1": "Value 1",
			"Key2": "Value 2"
		}
	],
	"Signature":"Dw/vBzfZsRDGeLbmoJ5LS8sa3bBEjE204OwvTRdAD49GM2hQIdPhkFcintk/C7pegwzXPEx6GtYDlCo1Qy7hZVyejWF7j+iTuhpYpjT8nHhkZB6ChGGnu29G71APMK9gTeZc6Uh0reswI5VAI6me9reJAtbsm1oaT8UAB/YTqXk=",
	"PublicKey":"-----BEGIN RSA PUBLIC KEY-----rnMIGJAoGBAKPa4uBuIwACpMH3adHspUbT+jO0g4mm2uyYSZGvSR58SgnLai0KP71xrnKzvicbB/hAq34Ah5bmqW6vq78CXPorQPzf8Q8rmzYkhBj4zLKRwxiqkLlaBE82aarnscW00dV8k88zJChK4o91TE1NEBNIaWi0ZQJJCU/MlBcEXz5y0qrNAgMBAAE=rn-----END RSA PUBLIC KEY-----"
}

If there was an error during the processing of the request, a failed request callback will be sent, and the format for the callback will be as below

{
	"ResultCode": "2001",
	"ResultDesc": "The initiator information is invalid.",
	"RequestID": "419315161054942",
	"MpesaRequestID": "AG_20190727_000049a4a79eb257c1a4",
	"MpesaTransactionID": "NGR9HBCJ19",
	"ReferenceData":
	[
		{
			"Key1": "Value 1",
			"Key2": "Value 2"
		}
	]
}

The difference between the two being the absence of the ResultData element if the request has failed. The parameters are:

ResultCode
Digit String value showing the current status of the request. A "0" means the request was successful, any other value means the request failed.
ResultDesc
Short description of the response code above
RequestID
3rd Party Unique identifier of the original request.
MpesaRequestID
M-Pesa's Unique identifier of the original request.
MpesaTransactionID
Globally unique identifier of the completed transaction within M-Pesa.

All the above parameters will always be present in every callback for all API requests whose initial requests were initiated from the 3rd party (that's you). The ResultData element is special in that it holds the specific data tied to the current request. It is only available for a successful completion of an action/transaction.

ResultData
The inner elements for a successful B2C transaction are:
  • TransactionAmount: The amount transacted during the transaction.
  • ReceiverPartyName: The MSISDN and name of the recipient combined.
  • IsReceiverRegistered: whether the receiver was registered in M-Pesa at the time the transaction was executed.
  • UtilityAccBalance: The balance of the Utility Account of the initiating Shortcode as at the end of the transaction.
  • WorkingAccBalance: The balance of the Working Account of the initiating Shortcode as at the end of the transaction.
  • TransactionCompleteTime: The time the transaction was completed in the system.
ReferenceData
The initial data attached to the original request. Note how the array elements have been squeezed into one Object.

B2B

The Business to Business (B2B) API enables a Business or Organization to pay other businesses using M-Pesa or transfer cash between their own separate or other paybills.

To learn more on how B2B works, please check out the B2B section in the tutorial.

The B2B API requires a separate app to perform the request. This app is created as outlined in the Adding an App section above.

On Proxy API, there are three allowed B2B Command IDs, and each Command ID is mapped to a specific URL. This makes it easier to determine and know how to work with the API following the REST standard as closely as possible.

A sample standard B2B Request has the following format:

[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2b/businesspaybill

// HEADERS
X-Authorization: Bearer 7becb0f4f704877e2311e25ba962872ccf0eb779498e9d22b42cab86e6c8f06d

// BODY
{
    "RequestID": "{{$timestamp}}",
    "SPID": "107031",
    "SPPassword": "Y2Y3M2I2NDgzZTVkNmZlZDQ1MDY0MWY0MDBhYzY5MTgxNDJiNDJlZjI3ODY0ODFjYzQwMGZkYWY1NmQ1MzIwMA==",
    "ServiceID": "107031000",
    "Timestamp": "20190101235959",
    "SenderShortcode": "107039",
    "ReceiverShortcode": "999112",
    "Amount": 1500,
    "AccountReference": "acc_ref",
    "InitiatorUsername": "testapi",
    "InitiatorEncryptedPassword": "EkXOoZzJKbElqemQHdwnINCRZG0w0BfWcYqREq3XsSdNrLBza3eFHR7byNNmJ3HSkfpX/IOIxrVOIo5PflJ5tq4BM33p6bxfDFJ9OrMyBcI/dgR3NyqIiAimVRrmIWaxRMNC3UMltr7yO5CvEvk2sZstnarvaYMxekKYNkli8aSgNCYF9j6EF1Ju8usZbBMfRyTG2gN+oludeUpRHBhiBiMu7itR8gLcqfWERhYZ3kSSqUnxYAzwcOtGu+KCr/sz3DFWNwOzU4Z7VACu7PZ/Ye8wfNGUyOPjYUbG/fRNJ0MGfh7NOfAAJwUdYDJecVclQhJ5mRY92BLf5V29Jp7Xzg==",
    "CallbackURL": "https://example.domain.com/callback",
    "ReferenceData":
    [
    	{
    		"Key": "Value"
    	}
    ]
}

Or for non VPN clients:

[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2b/businesspaybill

// HEADERS
X-Authorization: Bearer 7becb0f4f704877e2311e25ba962872ccf0eb779498e9d22b42cab86e6c8f06d

// BODY
{
    "RequestID": "{{$timestamp}}",
    "SenderShortcode": "107039",
    "ReceiverShortcode": "999112",
    "Amount": 1500,
    "AccountReference": "acc_ref",
    "InitiatorUsername": "testapi",
    "InitiatorEncryptedPassword": "EkXOoZzJKbElqemQHdwnINCRZG0w0BfWcYqREq3XsSdNrLBza3eFHR7byNNmJ3HSkfpX/IOIxrVOIo5PflJ5tq4BM33p6bxfDFJ9OrMyBcI/dgR3NyqIiAimVRrmIWaxRMNC3UMltr7yO5CvEvk2sZstnarvaYMxekKYNkli8aSgNCYF9j6EF1Ju8usZbBMfRyTG2gN+oludeUpRHBhiBiMu7itR8gLcqfWERhYZ3kSSqUnxYAzwcOtGu+KCr/sz3DFWNwOzU4Z7VACu7PZ/Ye8wfNGUyOPjYUbG/fRNJ0MGfh7NOfAAJwUdYDJecVclQhJ5mRY92BLf5V29Jp7Xzg==",
    "CallbackURL": "https://example.domain.com/callback",
    "ReferenceData":
    [
    	{
    		"Key": "Value"
    	}
    ]
}

The parameters are the same as B2C parameters. The new parameters are described below:

ReceiverShortcode
The shortcode of the receiver party of the transaction. Should be a valid Safaricom Paybill/B2C Shortcode for Business Paybill or Business to Business Transfer, or a valid Safaricom Till for Business BuyGoods.
AccountReference
This is a parameter specific to the Business PayBill API, and is similar to the C2B Account Reference parameter, except that it applies to Businesses. The other two APIs do not need this parameter.

For existing VPN clients' parameters, all SP parameters must be present if they are to be used.

For each supported Command ID, the respective endpoints are as shown below:

Command ID Sandbox Production
BusinessPayBill https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2b/businesspaybill https://api.proxyapi.co.ke/mpesa/v1/b2b/businesspaybill
BusinessBuyGoods https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2b/businessbuygoods https://api.proxyapi.co.ke/mpesa/v1/b2b/businessbuygoods
BusinessToBusinessTransfer https://api.proxyapi.co.ke/sandbox/mpesa/v1/b2b/businesstobusiness https://api.proxyapi.co.ke/mpesa/v1/b2b/businesstobusiness

Once the request has been sent, an acknowledgement is sent in the format shown below.

{
	"RequestID": "419315161054942",
	"MpesaRequestID": "AG_20190727_000049a4a79eb257c1a4",
	"StatusCode": 200,
	"ResponseCode": "0",
	"ResponseDesc": "Accept the service request successfully.",
	"ServiceStatus": 0,
	"RemainingCredits": 0
}

If there was any problem with the request, and the API or M-Pesa terminates the request, the format will be as shown below:

{
	"StatusCode": 503,
	"ResponseCode": "15",
	"ResponseDesc": "Duplicate OriginatorConversationID.",
	"ServiceStatus": 0
}

The parameters are the same as the B2C parameters described before.

Once a request has been submitted and processed, a callback will be received and forwarded to the client. The format of the callback for a successful request will be as below:

{
	"ResultCode": "0",
	"ResultDesc": "The service request is processed successfully.",
	"RequestID": "1567964133",
	"MpesaRequestID": "AG_20190908_00006360f11d96becd48",
	"MpesaTransactionID": "NI87HBHOJJ",
	"ResultData":
	{
		"TransactionAmount": 1500,
		"ReceiverPartyName": "999112 - Peter Test Shortcode",
		"DebitAccBalance": 610012,
		"TransactionCompleteTime": "20190908203346"
	},
	"ReferenceData":
	{
		"BillReferenceNumber": "acc_ref",
		"Key": "Value"
	},
	"Signature":"Dw/vBzfZsRDGeLbmoJ5LS8sa3bBEjE204OwvTRdAD49GM2hQIdPhkFcintk/C7pegwzXPEx6GtYDlCo1Qy7hZVyejWF7j+iTuhpYpjT8nHhkZB6ChGGnu29G71APMK9gTeZc6Uh0reswI5VAI6me9reJAtbsm1oaT8UAB/YTqXk=",
	"PublicKey":"-----BEGIN RSA PUBLIC KEY-----rnMIGJAoGBAKPa4uBuIwACpMH3adHspUbT+jO0g4mm2uyYSZGvSR58SgnLai0KP71xrnKzvicbB/hAq34Ah5bmqW6vq78CXPorQPzf8Q8rmzYkhBj4zLKRwxiqkLlaBE82aarnscW00dV8k88zJChK4o91TE1NEBNIaWi0ZQJJCU/MlBcEXz5y0qrNAgMBAAE=rn-----END RSA PUBLIC KEY-----"
}

Note how the Account Reference is returned as part of the ReferenceData object specifically for a Business Paybill request under the name BillReferenceNumber. If there was an error during the processing of the request, a failed request callback will be sent, and the format for the callback will be as below

{
	"ResultCode": "2001",
	"ResultDesc": "The initiator information is invalid.",
	"RequestID": "419315161054942",
	"MpesaRequestID": "AG_20190727_000049a4a79eb257c1a4",
	"MpesaTransactionID": "NGR9HBCJ19",
	"ReferenceData":
	[
		{
			"Key1": "Value 1",
			"Key2": "Value 2"
		}
	]
}

The difference between the two being the absence of the ResultData element if the request has failed. The parameters are the same as the B2C parameters described before except for the ResultData parameters, which are described below.

ResultData
The inner elements for a successful B2B transaction are:
  • TransactionAmount: The amount transacted during the transaction.
  • ReceiverPartyName: The Shortcode and name of the business which received the funds.
  • DebitAccBalance: The balance of the Account which was debited of the initiating Shortcode as at the end of the transaction. The account debited depends on the API (command ID) used.
  • TransactionCompleteTime: The time the transaction was completed in the system.

Reversal

The Reversal API enables a Business or Organization to reverse transactions received by error or mistake into their C2B accounts. One can only reverse C2B transactions that have been received into their own C2B Shortcodes. Thus, only C2B clients can be assigned access to the Reversal API scope.

To learn more on how Reversal works, please check out the Reversal section in the tutorial.

A sample standard Reversal Request has the following format:

[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/reversal

// HEADERS
X-Authorization: Bearer 7becb0f4f704877e2311e25ba962872ccf0eb779498e9d22b42cab86e6c8f06d

// BODY
{
	"RequestID": "2417563671386226",
	"SPID": "107040",
    "SPPassword": "ZWY1YWViYmE3ZTZmZDI3N2RmOGQzMzY4NDE3ZmIxODRmNDZkMDljZWMyYzBkNjk4NGUzZjhhMWE1NmI3NmIzYg==",
    "ServiceID": "107040000",
    "Timestamp": "20170623114011",
	"OriginalTransactionID": "NGR8HBCJ0Y",
	"Shortcode": "999112",
	"InitiatorUsername": "testapi",
	"InitiatorEncryptedPassword": "[encrypted password]",
	"CallbackURL": "http://example.domain.com/callback"
}

Or for non VPN clients:

[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/reversal

// HEADERS
X-Authorization: Bearer 7becb0f4f704877e2311e25ba962872ccf0eb779498e9d22b42cab86e6c8f06d

// BODY
{
	"RequestID": "2417563671386226",
	"OriginalTransactionID": "NGR8HBCJ0Y",
	"Shortcode": "999112",
	"InitiatorUsername": "testapi",
	"InitiatorEncryptedPassword": "[encrypted password]",
	"CallbackURL": "http://example.domain.com/callback"
}

The parameters are:

RequestID
A unique identifier of the request specific to the 3rd party. This parameter is appended to a hash of the 3rd party's Shortcode to create a reference unique to the 3rd party.
SPID
For existing VPN clients. 3rd Party SPID. Optional
SPPassword
For existing VPN clients. 3rd Party hashed SP Password. Optional
ServiceID
For existing VPN clients. 3rd Party SPID. Optional
Timestamp
For existing VPN clients. The timestamp used in the hashing of the SP Password above in the format YYYYMMddHHmmss. Optional
OriginalTransactionID
The transaction ID of the C2B transaction to be reversed.
Shortcode
The Shortcode of the receiving organization trying to reverse the transaction.
InitiatorUsername
The username of the API operator as assigned on the M-Pesa Org Portal by the 3rd Party.
InitiatorEncryptedPassword
The password of the API operator assigned by the 3rd Party and encrypted using the public key certificate provided by M-Pesa
CallbackURL
The callback URL where the results of the transaction will be sent.
ReferenceData
An optional array of data in object format which the 3rd party would like associated with the current request and returned to them in the callback. The array can hold up to five objects, and each object is limited to 1 property, having a key of less than or equal to 125 characters. Also, each object key should be unique in the array

For existing VPN clients' parameters, all must be present if they are to be used.

Once the request has been sent, an acknowledgement is sent in the format shown below. Note how the acknowledgements all share the same format.

{
	"RequestID": "455750110110306",
	"MpesaRequestID": "AG_20190728_00004024e0050253fec3",
	"StatusCode": 200,
	"ResponseCode": "0",
	"ResponseDesc": "Accept the service request successfully.",
	"ServiceStatus": 0,
	"RemainingCredits": 0
}

If there was any problem with the request, and the API or M-Pesa terminates the request, the format will be as shown below:

{
	"StatusCode": 503,
	"ResponseCode": "15",
	"ResponseDesc": "Duplicate OriginatorConversationID.",
	"ServiceStatus": 0
}

The parameters are as explain in the B2C section above.

Once a request has been submitted and processed, a callback will be received and forwarded to the client. The format of the callback for a successful request will be as below:

{
	"ResultCode": "0",
	"ResultDesc": "The service request is processed successfully.",
	"RequestID": "5111472807369880",
	"MpesaRequestID": "AG_20190728_000059a4dc7b99a91fc6",
	"MpesaTransactionID": "NGS5HBCJAL",
	"ResultData":
	{
		"TransactionAmount": "10.00",
		"TransactionCharge": "0.00",
		"CreditPartyName": "254796778039 - Peter Test",
		"DebitPartyName": 999112,
		"TransactionCompleteTime": "20190728085345"
	},
	"ReferenceData": [],
	"Signature":"Dw/vBzfZsRDGeLbmoJ5LS8sa3bBEjE204OwvTRdAD49GM2hQIdPhkFcintk/C7pegwzXPEx6GtYDlCo1Qy7hZVyejWF7j+iTuhpYpjT8nHhkZB6ChGGnu29G71APMK9gTeZc6Uh0reswI5VAI6me9reJAtbsm1oaT8UAB/YTqXk=",
	"PublicKey":"-----BEGIN RSA PUBLIC KEY-----rnMIGJAoGBAKPa4uBuIwACpMH3adHspUbT+jO0g4mm2uyYSZGvSR58SgnLai0KP71xrnKzvicbB/hAq34Ah5bmqW6vq78CXPorQPzf8Q8rmzYkhBj4zLKRwxiqkLlaBE82aarnscW00dV8k88zJChK4o91TE1NEBNIaWi0ZQJJCU/MlBcEXz5y0qrNAgMBAAE=rn-----END RSA PUBLIC KEY-----"
}

If there was an error during the processing of the request, a failed request callback will be sent, and the format for the callback will be as below

{
	"ResultCode": "2001",
	"ResultDesc": "The initiator information is invalid.",
	"RequestID": "6840837476710556",
	"MpesaRequestID": "AG_20190728_00005db1aa617ead16ba",
	"MpesaTransactionID": "NGS4HBCJAK",
	"ReferenceData": []
}

For extra info, if the transaction had already been reversed, the expected callback will be as below:

{
	"ResultCode": "R000001",
	"ResultDesc": "The transaction has already been reversed.",
	"RequestID": "5350296948124188",
	"MpesaRequestID": "AG_20190728_0000683cba2713d49f90",
	"MpesaTransactionID": "NGS0000000",
	"ReferenceData": []
}

Note the generic transaction ID for this type of error. This indicates the transaction could not be assigned its own unique transaction ID. The extra specific parameters for a successful reversal are:

TransactionAmount
The amount that was transacted during the request and is to be reversed in this request.
TransactionCharge
The charge applied during the transaction, usually charged to the debit party.
CreditPartyName
The credit party/receiver of the amount after reversal has been completed.
DebitPartyName
The debit party for the reversal who shall be debited the above amount.
TransactionCompleteTime
The time the reversal transaction was completed.
ReferenceData
The initial data attached to the original request. Note how the array elements have been squeezed into one Object.

Transaction Query

The Transaction API enables a Business or Organization to query transactions and their status from M-Pesa. One can query a transaction based on either the M-Pesa Transaction ID or the 3rd Party Request ID (OriginatorConversationID) for 3rd-party initiated requests.

A standard Transaction Query Request using the M-Pesa Transaction ID has the following format:

[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/transactionquery/transactionid

// HEADERS
X-Authorization: Bearer f48cefb8c36d07f18554da22e0ac587d0d9e374a07f5fc579cb15f494afba200

// BODY
{
	"RequestID": "2417563671386226",
	"SPID": "107040",
    "SPPassword": "ZWY1YWViYmE3ZTZmZDI3N2RmOGQzMzY4NDE3ZmIxODRmNDZkMDljZWMyYzBkNjk4NGUzZjhhMWE1NmI3NmIzYg==",
    "ServiceID": "107040000",
    "Timestamp": "20170623114011",
	"QueryTransactionID": "NGS7HBCJAN",
	"Shortcode": "999112",
	"InitiatorUsername": "testapi",
	"InitiatorEncryptedPassword": "[encrypted password]",
	"CallbackURL": "http://example.domain.com/callback"
}

Or for non VPN clients:

[POST] https://api.proxyapi.co.ke/sandbox/mpesa/v1/transactionquery/transactionid

// HEADERS
X-Authorization: Bearer f48cefb8c36d07f18554da22e0ac587d0d9e374a07f5fc579cb15f494afba200

// BODY
{
	"RequestID": "2417563671386226",
	"QueryTransactionID": "NGS7HBCJAN",
	"Shortcode": "999112",
	"InitiatorUsername": "testapi",
	"InitiatorEncryptedPassword": "[encrypted password]",
	"CallbackURL": "http://example.domain.com/callback"
}

For querying using the request ID, the format is the same except for the endpoint URL and the query parameter.

https://api.proxyapi.co.ke/sandbox/mpesa/v1/transactionquery/requestid

// HEADERS
X-Authorization: Bearer f48cefb8c36d07f18554da22e0ac587d0d9e374a07f5fc579cb15f494afba200

// BODY
{
	"RequestID": "2417563671386226",
	"SPID": "107040",
    "SPPassword": "ZWY1YWViYmE3ZTZmZDI3N2RmOGQzMzY4NDE3ZmIxODRmNDZkMDljZWMyYzBkNjk4NGUzZjhhMWE1NmI3NmIzYg==",
    "ServiceID": "107040000",
    "Timestamp": "20170623114011",
	"QueryRequestID": "3415694472581614",
	"Shortcode": "999112",
	"InitiatorUsername": "testapi",
	"InitiatorEncryptedPassword": "[encrypted password]",
	"CallbackURL": "http://example.domain.com/callback"
}

The new parameters are:

QueryRequestID
The request ID of the original transaction being queried.
QueryTransactionID
The M-Pesa transaction ID of the original transaction being queried.

Once the request has been sent, an acknowledgement is sent in the format shown below. Note how the acknowledgements for all APIs share the same format.

{
	"RequestID": "2018896566326572",
	"MpesaRequestID": "AG_20190728_0000539ee0368ae20bec",
	"StatusCode": 200,
	"ResponseCode": "0",
	"ResponseDesc": "Accept the service request successfully.",
	"ServiceStatus": 0,
	"RemainingCredits": 0
}

The format for an error acknowledgement is the same as the other APIs.
Once a request has been submitted and processed, a callback will be received and forwarded to the client. The format of the callback for a successful request will be as below:

{
	"ResultCode": "0",
	"ResultDesc": "The service request is processed successfully.",
	"RequestID": "4361455347430956",
	"MpesaRequestID": "AG_20190728_00006661fc3c50049d23",
	"MpesaTransactionID": "NGS0000000",
	"ResultData":
	{
		"TransactionRequestID": "3415694472581614",
		"TransactionID": "NGS7HBCJAN",
		"TransactionType": "Business Payment to Customer via API",
		"TransactionAmount": 10,
		"TransactionCreditPartyName": "254796778039 - Peter Test",
		"TransactionDebitPartyName": "999112 - Peter Test Shortcode",
		"TransactionStatus": "Completed",
		"TransactionStartTime": "20190728091017",
		"TransactionCompleteTime": "20190728091017"
	},
	"ReferenceData": []
}

Extra example: the expected successful callback for querying a reversal of a C2B transaction will be as below:

{
	"ResultCode": "0",
	"ResultDesc": "The service request is processed successfully.",
	"RequestID": "4451103425677044",
	"MpesaRequestID": "AG_20190728_0000685c2939caa61d64",
	"MpesaTransactionID": "NGS0000000",
	"ResultData":
	{
		"TransactionRequestID": "6021749668517066",
		"TransactionID": "NGS9HBCJAP",
		"TransactionType": "Pay Utility Reversal",
		"TransactionAmount": 1,
		"TransactionCreditPartyName": "254796778039 - Peter Test",
		"TransactionDebitPartyName": "999112 - Peter Test Shortcode",
		"TransactionStatus": "Completed",
		"TransactionStartTime": "20190728093738",
		"TransactionCompleteTime": "20190728093738"
	},
	"ReferenceData": []
}

...and querying the original C2B transaction that was reversed by the above reversal transaction will return the below callback:

{
	"ResultCode": "0",
	"ResultDesc": "The service request is processed successfully.",
	"RequestID": "1356960165189202",
	"MpesaRequestID": "AG_20190728_0000589f4178ae4533dc",
	"MpesaTransactionID": "NGS0000000",
	"ResultData":
	{
		"TransactionRequestID": null,
		"TransactionID": "NGS8HBCJAO",
		"TransactionType": "Pay Bill Online",
		"TransactionAmount": 1,
		"TransactionCreditPartyName": "999112 - Peter Test Shortcode",
		"TransactionDebitPartyName": "254796778039 - Peter Test",
		"TransactionStatus": "Completed",
		"TransactionStartTime": "20190728093704",
		"TransactionCompleteTime": "20190728093706"
	},
	"ReferenceData": []
}

A failed request callback will have a similar format as the other APIs. Querying for a non-existent transaction will return the following callback:

{
	"ResultCode": "2032",
	"ResultDesc": "The transaction receipt number does not exist.",
	"RequestID": "3223253853436322",
	"MpesaRequestID": "AG_20190728_00007983339b06e6b48b",
	"MpesaTransactionID": "NGS0000000",
	"ReferenceData": []
}

Note the generic transaction ID for the callbacks of transaction query requests. This indicates the transaction could not be assigned its own unique transaction ID. The extra specific parameters for a transaction query are as below:

TransactionRequestID
The original request ID for the transaction being queried. NB: if you query a transaction that has already been reversed, this parameter will be null
TransactionID
The M-Pesa transaction ID of the transaction being queried.
TransactionType
A short description of the type of transaction for the transaction being queried.
TransactionAmount
The amount that was transacted when the transaction was executed.
TransactionCreditPartyName
The name of the credit party of the above amount during the transaction.
TransactionDebitPartyName
The name of the debit party of the above amount during the transaction.
TransactionStatus
The status of the queried transaction. Can be any of "Completed", "Expired", "Cancelled", "Declined" or others as they are made available.
TransactionStartTime
The time the queried transaction was initiated.
TransactionCompleteTime
The time the queried transaction was completed.

Pay via Proxy API

This is a new feature designed and developed to provide a more stable integration approach to the existing Lipa na M-Pesa API (LnM)/STK Push for merchants or developers having or making online systems that need to integrate or are already integrated into Lipa na M-Pesa API. LnM/STK Push is known to have some issues especially with callbacks, thus this feature combines Lipa na M-Pesa API and C2B API to provide a double-edged approach to integrating into the M-Pesa C2B APIs. It enables one to send LnM API requests and expect both the LnM callback and C2B Confirmation request initiated either via a simple One-click Button approach on the 3rd party/Merchant website, similar to PayPal or Stripe et al buttons; or via a direct request to ProxyAPI with all parameters prefilled and validated. The second approach is described in the PVP Direct section. This arrangement tries to ensure that at least one callback gets back to the 3rd party who initiated the API request instead of no callback getting back at all. The system works as explained next:

NB: this is a commercial API, charging on a monthly basis. Always ensure to keep track of your due dates via the callbacks sent to your endpoints. More details on this can be found at the end of this section.

Also, the Proxy API callback is only expected to come after successful completion of a transaction, as without that, no validation/confirmation requests are sent by M-Pesa in the first place. When a transaction is not completed successfully, one can expect a maximum of only one callback from Daraja.

  • First, 3rd party or Merchant onboards their shortcode onto Proxy API and integrates Pay via ProxyAPI, henceforth PVP, into their website. Due to there being minimal opportunity for testing on sandbox, this service is only available on Production.
  • Once integrated, a 3rd party or Merchant, via either the default Lipa na M-Pesa button or a custom button, sends a request to Proxy API to initiate a Lipa na M-Pesa request. This process will be explained in detail in the next sections.
  • The button initiates parameter verification, then opens a pop-up window for the client to enter their Phone Number. The client can either enter their phone number or cancel the request. If the user enters their phone number and submits the request, the transaction is then sent to the backend and a Lipa na M-Pesa API request to Daraja API is initiated. The system then receives the response from Daraja and sends it back to the 3rd party/merchant website via the provided 3rd party callback function. If the user cancels, an error response is sent back to the 3rd party callback function.
  • Once the LnM request is sent to Daraja, Daraja initiates the STK Push request to the client's phone. The client responds to the prompt and sends the response. Daraja then initiates a C2B request to M-Pesa.
  • M-Pesa processes the C2B request, and, if the URLs are present/registered, sends the C2B validation request to Proxy API for paybill requests. Proxy API automatically accepts the validation request and M-Pesa then sends the C2B callback to Daraja. Daraja receives the M-Pesa callback and sends the LnM callback to the 3rd party callback URL. M-Pesa then sends the Confirmation request to Proxy API and Proxy API then formats and forwards the request to the same 3rd party Callback URL too.
  • 3rd party receives either one or both callbacks, and processes the callbacks respectively.

As noted above, on a successful prompt to the customer, the 3rd party is expected to receive at least one callback, or even better, both the LnM callback from Daraja and C2B Confirmation from Proxy API. This reduces the cases of missed callbacks for client transactions experienced when using LnM API alone.

Due to the nature of LnM requests, there are some behaviours which are assumed or automatically handled by Proxy API. These are:

  • All parameters are assumed to be pre-validated by the third party (that's the primary reason the API was created, right?), thus Proxy API responds to all received validation requests affirmatively without hitting any 3rd party validation endpoints.
  • To prevent a lot of modification on the codebase for clients already integrated into Daraja, the confirmation request has been modified to closely resemble the Daraja LnM callback request, so beware of the differences which shall be explained in later sections.
  • The callback URL set in the PVP request is also set directly into the LnM request to Daraja, thus the 3rd party can expect one callback directly from Daraja, and the other from Proxy API.
  • To provide a link between the initiated LnM request and C2B Confirmation callback, a unique combination of the shortcode, sender phone number, amount, and current timestamp rounded off to the nearest minute will be used to identify a unique transaction in the system. This decision was made given the lack of enough data between an LnM request and C2B request to link them when initiated together. Thus, for every client/payee paying into a given shortcode, if the first PVP request fails, subsequent requests will be blocked for a period of around 1 minute to ensure uniqueness in the system. After that period, the client is free to try again, following the same cycle. Account reference numbers cannot be used as
    1. Buy Goods requests do not have that parameter in their requests, and
    2. Because some PayBill payment requests use the same Account reference numbers for every payment request e.g. paying into an account for a given organization, thus they cannot be depended on or enforced to be unique.

Integrating into Pay via Proxy API

To utilize the PVP API, one first has to onboard their shortcode onto Proxy API. This is described in the Shortcodes/Onboarding section below. The next section details how to enable PVP on your shortcode.

  • Once onboarded, both new and existing clients can go to Shortcodes using the main menu on the left, and double click on their preferred Shortcode to use for PVP. This opens the Shortcode's settings.
  • To use the shortcode for PVP, enable the Use Shortcode for Pay via ProxyAPI switch on the left side of the view. This will disable the validation and confirmation URL fields, enabling only the required fields for PVP.
  • Fill in the Shortcode name, and, if you onboarded a Store number, the Till number that comes with it. Then, if you are comfortable enough, fill in the LnM passkey field to use in the LnM requests. The presence or absence of the passkey determines the name shown on the STK Push prompt sent to the client. If the LnM passkey is not set, the API uses the system's LnM key, which causes the API's shortcode name (Njeka) to be shown on the STK Push prompt, but the cash to be paid to the 3rd party shortcode. So to prevent confusion in clients, its recommended to fill in the passkey.
  • Click on Save. On success the API Key field will be populated with the API Key to use on your site or in your requests. Clicking on Save will always generate a new API Key for the shortcode, so beware of performing multiple changes in quick succession.

Once configured, the Shortcode is now ready to use with PVP. To configure the site to use PVP, the steps are as below:

  • This site required jQuery to work, thus first insert a script tag into the head of your HTML document or web app pointing to a valid jQuery script e.g.:
  • <script src="https://pvp.proxyapi.co.ke/dist/jquery-3.4.1.min.js"></script>
  • Insert another script tag into the head of your HTML document or web app pointing to the PVP script at https://pvp.proxyapi.co.ke/dist/pvp.min.js. This script contains the logic required to initiate the PVP payment request e.g.:
  • <script src="https://pvp.proxyapi.co.ke/dist/pvp.min.js"></script>
  • Either:
    1. Create a div element with ID pvp_checkout_button in your HTML at your preferred location. This is the preferred option for merchants with all the required data ready just awaiting to send the API request. This button will trigger the payment prompt for you e.g.:
    2. <div id="pvp_checkout_button"></div>
    3. Or create a custom button for your checkout experience which will trigger the payment prompt. This is preferred for merchants who need to dynamically create the required parameters and initiate the prompt after all processing is complete. The button must call the function pvp.execute() when the app is ready to initiate the request.
  • Implement the function pvp.createRequest(). This function will return an object will the necessary parameters set, and includes a callback function provided by the 3rd party that will receive the success or error response received from the popup Window after the PVP request is initiated and sent. A sample implementation is as shown below:
  • pvp.createRequest = function()
    {
    	const requestId = Math.round(Math.random() * 1000000);
    	const callBackUrl = "https://example.com/callback";
    	const timestamp = Math.round((new Date()).getTime() / 1000);
    	const amount = 10;
    
    	return {
    		request_id: requestId,
    		request_timestamp: timestamp,
    		callback_url: encodeURIComponent(callBackUrl),
    		api_key: "0123456789-1xc1ieyy5f24dyiuu5hg",
    		origin: "http://localhost",
    		amount: amount,
    		account_ref: requestId,			//optional
    		description: "Tight Pants",     //optional
    		callback: function(eventObject)
    		{
    			/**
    			 * Prints out:
    			 * {
    			 *      StatusCode: 0,                    // or -1 on failure
    			 *      StatusDescription: "Success",       //or other message on failure
    			 *      MerchantRequestID: "12801-2646216-1",           //or null on failure
    			 *      CheckoutRequestID: "ws_CO_040220202222099388"   //or null on failure
    			 * }
    			 */
    			console.log(eventObject);
    		}
    	};
    };
    
  • The parameters are:
    request_id
    A unique identifier of the transaction from the 3rd party. This is required/mandatory.
    request_timestamp
    The Unix timestamp of a transaction. This is used to ensure a request is as close to recent as possible, and prevents possible request-replay using the same transaction ID. All requests are expected to be made within one minute of the current unix timestamp. Feedback on this from the ground will be appreciated. This is required.
    callback_url
    The callback URL where the results will be sent. This is the same URL that is used in the LnM API request, and will be inserted directly into the LnM request to Daraja.This is required.
    api_key
    The unique API key assigned to you on the Proxy API Portal. To renew or change the key, just go to the Shortcode settings and click on Save without changing any existing values. A new key will be automatically generated and displayed in the API Key field. This is required.
    origin
    This is a security setting for the JS code, which limits the receiver of the data posted to your callback function to the domain URL specified in the above field. It is usually the same domain as where the site is hosted e.g. if one specifies https://example.com as the origin, the callback will be filtered to only be received by the domain example.com on SSL. The format is http(s)://[subdomain.]domain.tld, with no endpoints or query params. The insecure http://... is only allowed for localhost domain. This is required.
    amount
    This is of course the amount to be paid in the request. This is required.
    account_ref
    This is the account reference value for Pay Bill requests. It is optional for till number requests. If left empty, the request ID will be used instead. Its value will be used as the AccountReference in the LnM request
    description
    This is a short description of the transaction. If present, its value will be used as the TransactionDesc in the LnM request. If absent, the shortcode number is used instead.
    callback
    This is the callback function that will receive the result of the PVP request. The basic structure of the callback eventObject is as below:
    {
    	StatusCode: 0,
    	StatusDescription: "Success",
    	MerchantRequestID: "12801-2646216-1",
    	CheckoutRequestID: "ws_CO_040220202222099388"
    }
    

    The parameters are:

    StatusCode
    Shows the status of the request. a -1 indicates an unexpected error, such as the Window being closed by the user without interacting with the Pop-up, with the error description in the StatusDescription parameter. A -2 indicates the request was received, but the user either cancelled it explicitly or it was refused due to other failed API constraints or checks e.g. the client taking too long to respond, thus it expired. A 0 indicates a successful request to LnM API and response from the API.
    StatusDescription
    A short description of the result of the request depending on the StatusCode above, for both errors and successful requests
    MerchantRequestID
    The Merchant Request ID as received from LnM API for a successful request, or null otherwise.
    CheckoutRequestID
    The Checkout Request ID as received from LnM API for a successful request, or null otherwise.

    The callback will be called for any errors caused or raised by the Client during the request, when the client explicitly cancels the request via the Cancel button on the Pop-up window, or when the Window is unexpectedly closed by the user.

PVP Callback

Once the request has been initiated, sent and successfully processed, the client will most probably receive a callback from both Daraja and Proxy API, or at least one callback from either. For Proxy API, the callback structure is modified to be as close as possible to the original LnM Daraja callback, but with some differences to enable one to easily identify either from the other. A sample response showing the structure is as below:

{
	"Body":
	{
		"pvpCallback":
		{
			"RequestID": "689734",
			"CheckoutRequestID": "ws_CO_100220202302034801",
			"CallbackMetadata":
			{
				"TransactionTime": "20200210230214",
				"TransactionID": "OBA0Z6O54H",
				"TransactionAmount": 10,
				"BusinessShortcode": "123456",
				"AccountReference": "689734",
				"SenderMSISDN": "254722000111",
				"SenderFirstName": "JOHN",
				"SenderMiddleName": null,
				"SenderLastName": "DOE",
				"DueDate": 1582477758,
				"Signature": "fS1APn44Uo...3vJYYwQSXc=",
				"PublicKey": "-----BEGIN RSA PUBLIC KEY-----\r\nMIGJAoGBAM...rVNAgMBAAE=\r\n-----END RSA PUBLIC KEY-----"
			}
		}
	}
}

Note the pvpCallback element. Daraja uses stkCallback for the element at the same location, thus that element can be used to perform a quick check to determine whether the callback is coming from Daraja or Proxy API. The RequestID is the request ID assigned to the request by the 3rd Party, and the CheckoutRequestID is the request ID from LnM API as usual. All other parameters are gleaned from the C2B Confirmation request sent by the C2B API, and their definitions can be checked in the C2B Confirmation section above. Also note the cleaner structure of the CallbackMetadata structure as compared to LnMs, providing a more convenient way to get keys and their respective values.

The mandatory parameters that can always be expected in the callback from Proxy API are:

  • RequestID
  • CheckoutRequestID
  • TransactionTime
  • TransactionID
  • TransactionAmount
  • BusinessShortcode
  • SenderMSISDN
  • SenderFirstName
  • DueDate

Renewing PVP Subscription

The DueDate is the Unix timestamp of when the current shortcode's PVP subscription will expire, so keep track of that. To renew your PVP subscription:

  • Log into Proxy API Portal and click on Account on the main menu.
  • Click on Transactions tab, then click on Renew PVP button near the top right of the page.
  • Select the shortcode you wish to renew the PVP Subscription for in the selection field, enter the Phone number you wish to pay with in the text field, then click on Submit. This will initiate an STK Push request for payment. Check your phone for the STK Push prompt and respond appropriately. You can always view all your past latest transactions in the Transactions tab under Account menu.
  • The next due date will always be sent in the PVP Callback request to the 3rd party callback URL set in all requests.

Code samples are available over at Github.

PVP Direct

This is the API at the back of PVP. It enables one to send a pre-prepared request with all parameters present to LnM API via ProxyAPI, then receive the callbacks in the same manner described above. Its a simple extension of a PVP request, but with a phone number as part of the request. The Full request is as below:

{
	"RequestID": "8cad5088-d15b-4227",
	"ApiKey": "1234567890-erwerwrwerwerwerrer",
	"CallbackUrl": "https://example.co.ke/callback",
	"RequestTimestamp": 1582140654 ,
	"Amount": 100,
	"SenderMSISDN": "254722000111",
	"AccountReference": "accref",
	"Description": "Description",
	"Origin": "https://example.co.ke"
}

The format for the requests and callbacks are also available in the Swagger Specification available via the Button at the top right.

Code samples are available over at Github.

Callback Verification

Proxy API is looking forward to adding the capability to verify callbacks were actually sent by the API. This will be achieved through the following means:

For successful callbacks from M-Pesa Broker, Proxy API creates a signature using a One-time RSA Private Key/Public Key pair, and appends the signature and RSA Public Key to the callback. Once received on the 3rd Party system, the user can use the appended RSA Public key to verify the appended Signature. Only specific mandatory parameters are included in the signature, and those are as outlined in the table shown below. One-time means the RSA SK/PK pair is only used once, to verify the current callback request, and is never reused. The key is created using 1024 bits of security. This allows a fast generation of Key pairs and creation of the signature as the authentication process is only expected to last a few seconds or so, and the key pair is never expected to be reused, thus can never be applied to "replay" attacks (Possible attacks on RSA). Thus it is expected that the user will verify the signature within a short period of time, if not immediately, after receiving the callback, discard the Public Key and encrypt/protect the rest of the data using more long-term and stronger techniques. However, the developer should make sure to protect their systems against MITM attacks, which make any authentication or verification process, inclusive of this one, a big risk if not handled with care.

We have sample implementations of signature verifications for some languages i.e. Java, PHP and JavaScript, that developers can borrow to use in their systems. These are available on Github as outlined below:

All projects have a simplified structure: a sample callback simulator represented by either an Index class/script, that simulates a received callback, and a Verifier class/script that shows the actual verification. The embedded Public Key string is first converted into a Public Key resource for the current system, and then used to verify the embedded signature. The key size is 1024 bits, the signature mode used is PKCS#1, and the hashing scheme used is SHA-1 for those opting to use other languages. The signature itself is Base64 encoded from binary data, thus needs to be decoded back into binary data before verification. The project is currently a WIP, thus bugs should be expected, especially related to PHP's float handling.

The table below shows the API callbacks supported by the verification process, and the specific data being signed. The order in which they are listed is the same order in which they are concatenated for signing and verification.

Callback Signature Data Parameters
C2B Paybill Validation/Confirmation
  • TransactionTime
  • TransactionID
  • TransactionAmount
  • AccountReference
  • SenderMSISDN
  • BusinessShortcode
C2B Buy Goods Confirmation
  • TransactionTime
  • TransactionID
  • TransactionAmount
  • SenderMSISDN
  • BusinessShortcode
B2C Callback
  • RequestID (from the 3rd Party's initial request)
  • MpesaRequestID
  • MpesaTransactionID
  • TransactionAmount
  • ReceiverPartyName
  • UtilityAccBalance
  • WorkingAccBalance
  • TransactionCompleteTime
B2B Callback
  • RequestID
  • MpesaRequestID
  • MpesaTransactionID
  • TransactionAmount
  • ReceiverPartyName
  • DebitAccBalance
  • TransactionCompleteTime
Reversal Callback
  • RequestID
  • MpesaRequestID
  • MpesaTransactionID
  • TransactionAmount
  • CreditPartyName
  • DebitPartyName
  • TransactionCompleteTime

The modifications are not expected to have any breaking changes to existing API implementations. The callbacks only add extra fields to the expected data, thus existing implementations are assumed to be safely ignoring any unknown or extra fields until when programmed to pick them up. But, if the Swagger specification is being used to create the API objects, it is advised that the respective libraries should be configured to ignore unknown properties (e.g. using @JsonIgnoreProperties(ignoreUnknown = true) on the class level for Java's Jackson library) to prevent any new/additional properties from causing the libraries to throw errors.

Transactions

This section enables one to view live/production transactions in almost real time as they come in. One can only view the transactions that their Shortcodes have done and only up to the last 100 latest transactions as received by the API.

Shortcodes

The Shortcodes section allows one to add Shortcodes to the system and view/modify added Shortcodes.

Adding a new Shortcode

To add a new Shortcode to the system, the process is as follows:

  • Pre-check: Ensure you have at least one Application set aside for Production environment in the Apps section.
  • Click on the Add button at the top right of the Shortcodes section.
  • Click on Start button.
  • On the Shortcode Type prompt which appears, select the type of Shortcode you are adding. Then click on Next. If you are onboarding a Till and selected the C2B Till shortcode type, note that you should use the parent Store Number for onboarding and not the actual Till number.
  • On the Shortcode Number prompt, enter the Shortcode you wish to add, and optionally add a name. The name can only contain alphanumeric characters, spaces, underscores and dashes. The system will then check if it already exists in the backend and inform you if so. Then click on Next.
  • On the Portal Access prompt, choose if you have access to the official M-Pesa Portal. If not, your Shortcode will have to go through manual verification means to confirm the ownership of your Shortcode. Then click on Next.
  • If you have access to the official Portal, it means you can easily verify ownership of your Shortcode by means of making an API request. On the portal, create an API operator (e.g. with username shortcodegolive) with the Transaction Status query ORG API permission only, then assign them a password. Also, pick a single transaction on the portal under the given Shortcode to be queried during the process. Encrypt the operator password using the Production Operator encryption certificate, and save the result for later. You can use the Utilities on the portal for that.
  • On the Confirm Access prompt on Proxy API, fill in the Initiator Username, encrypted password and Transaction ID to be queried, then click on Validate. The process takes 30 seconds max (if there is an error) or much less if there was no issue. The last error to be encountered will then be shown after the 30 seconds are up and validation did not work. If it worked, you are asked to assign the Shortcode a Production App that will be used to control access to the Shortcode. This app cannot be changed later, so make sure at least you give it a sensible name.

    NB: The Initiator used in this process will be barred from performing any more outgoing API requests once a Shortcode has been added. This is an extra security measure to protect our clients.

  • Then complete the process.

Deleting a Shortcode

To delete a Shortcode you have to get in touch with us directly.

Modifying a Shortcode

To modify a Shortcode, go to the Shortcodes section and double click on the respective Shortcode. A new view appears with the details of the Shortcode. For all Shortcode types, one can set/modify the name of the Shortcode, and change the status of the Shortcode to Active or Disabled. Disabling a Shortcode means it can no longer be used in transaction requests, and if its a C2B Shortcode, all its validation requests will be cancelled.

For C2B Shortcodes, one can set/modify the Validation and Confirmation URLs, and also test reachability using a dummy C2B Validation/Confirmation request same as the testing in the Sandbox section by clicking on the Test button on the right of the input fields. Beware of the consequences of this action on your system before attempting it.

The C2B Callback URLs can be modified anytime, but leaving them blank will cause all C2B Paybill validation requests to fail, and no C2B callbacks to reach your system. So make sure you set these immediately after adding your C2B Shortcode.

All production callbacks must be secure HTTPS URLs, otherwise the system will refuse to save them.

Logs

This section enables one to view all API requests, both from testbed and production in almost real time as they come in. The requests are ordered in the same order as received and processed by the API. You can trace a request using the request ID through all paths involved in the execution of the request and track where exactly a request failed. The Status codes of each request are also shown to determine what was the outcome of the request.

NB: All API request tracing logs are kept for a maximum of 24 hours. All Transaction logs are kept for a maximum of 3 months. It is expected that the client will ensure proper logs are also kept on their end for reference purposes.

Statistics

This is still a W.I.P. It will be a collection of transaction stats collected in the system e.g. failed transactions, completed transactions, total number of transactions e.t.c.

Endpoints

The URLs for all available endpoints are as given below. The base URL for all APIs is https://api.proxyapi.co.ke:

API Sandbox Production
Oauth /sandbox/mpesa/v1/auth /mpesa/v1/auth
C2B Paybill /sandbox/mpesa/v1/c2b/customerpaybill N/A
C2B BuyGoods /sandbox/mpesa/v1/c2b/customerbuygoods N/A
B2C BusinessPayment /sandbox/mpesa/v1/b2c/businesspayment /mpesa/v1/b2c/businesspayment
B2C SalaryPayment /sandbox/mpesa/v1/b2c/salarypayment /mpesa/v1/b2c/salarypayment
B2C PromotionPayment /sandbox/mpesa/v1/b2c/promotionpayment /mpesa/v1/b2c/promotionpayment
B2B Business PayBill /sandbox/mpesa/v1/b2b/businesspaybill /mpesa/v1/b2b/businesspaybill
B2B Business BuyGoods /sandbox/mpesa/v1/b2b/businessbuygoods /mpesa/v1/b2b/businessbuygoods
B2B Business To Business Transfer /sandbox/mpesa/v1/b2b/businesstobusiness /mpesa/v1/b2b/businesstobusiness
Reversal /sandbox/mpesa/v1/reversal /mpesa/v1/reversal
Transaction Query
by Transaction ID
/sandbox/mpesa/v1/transactionquery/transactionid /mpesa/v1/transactionquery/transactionid
Transaction Query
by Request ID
/sandbox/mpesa/v1/transactionquery/requestid /mpesa/v1/transactionquery/requestid
Pay via ProxyAPI Direct N/A /pvp/lnm

For those wishing to secure their endpoints by limiting the callbacks to the API's IP addresses, please get in touch with us to get the list of IPs we use.

Comments

© Novacom Technologies Ltd. 2019