API Documentation

Introduction

Welcome to Safaricom APIs! In this release, we have exposed API endpoints for accessing M-Pesa services; we have M-Pesa API endpoints for B2B, B2C, and C2B. Our APIs are built on REST; data entities are represented as HTTP resources and are accessed using HTTP verbs, majorly GET and POST. API request parameters and responses - including errors - are encoded in JSON. Our APIs response status codes and error codes comply with HTTP status codes as defined in RFC 2616. You can invoke our API endpoints using REST clients like Postman or SoapUI and command line tools like cUrl and Node.js.

To get you started, we have provided code samples in curl, Ruby, PHP, Python, NodeJS, and Java! Sample JSON responses for each APIs request have also been availed. You can view the code examples to the right, and you can switch between the programming languages with the tabs on the top right.

Getting Started

Developer Sign-up

To use our APIs or invoke an API endpoint, you will need to register for an account. Available accounts are individual and company accounts. Company accounts are for users with an existing M-PESA shortcodes or billing accounts with Safaricom and wish to test our APIs with an intention to develop a production app; users intending to apply for an M-Pesa shortcode can also register with a company account.

An account activation link will be sent in an email to the email address you used in registering for a developer account; the activation link expires within 24 hours of it being sent, and you will need to register for another account. The account activation link enables you to activate your developer account and set a password for your account.

Creating a Sandbox App

The first time you log in into your developer account, after account activation, the sandbox apps page opens from which you can create an app by clicking

.

Creating an app involves setting an app name and choosing the API products for which you will want to use. API products are a business package of the available APIs and the rules for access built around them.

App Dashboard

Once you have created an app, a dashboard from which you can view details about the app(s) you have created. Clicking on an app reveals tabs with more information about the app; the tabs are Keys, Products, Details, Edit and Delete.

Keys

The app keys of an app are the consumer key and consumer secret. The Keys tab shows the app keys, the date they were issued and their expiry period. Sandbox keys do not expire.

Products

A product is an encapsulation of an API(s) with access rules and business rules around their use. The use case of an app the developer is building should be guided by an API product. Access rules involve the traffic generated by the app.

Details

The details tab gives you a summary of the details about your app and the terms and conditions for accessing the sandbox.

Analytics

From the analytics tab, you can gauge how you can gauge how your app is performing over a period of time - day, week(s) or month(s). We provide app analytics for throughput, maximum response time, minimum response time, endpoint response time, message count and error count

Edit

Should you need to change details about your app, like its name or API products, then you can do so in the Edit tab.

Delete

This delete tab, destroys your app and removes it from your dashboard.

Authentication

To authenticate your app and get an OAuth access token, use this code. An access token expires in 3600 seconds or 1 hour

# With cUrl, you can just pass the correct header with each request
curl -X GET https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials \
-H "Accept: application/json"\
-u "YOUR_APP_CONSUMER_KEY:YOUR_APP_CONSUMER_SECRET"

// Use base64 to encode the consumer key and secret.Stringapp_key="YOUR_CONSUMER_KEY";Stringapp_secret="YOUR_CONSUMER_SECRET";StringappKeySecret=app_key+":"+app_secret;byte[]bytes=appKeySecret.getBytes("ISO-8859-1");Stringauth=Base64.encode(bytes);OkHttpClientclient=newOkHttpClient();Requestrequest=newRequest.Builder().url("https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials").get().addHeader("authorization","Basic "+auth).addHeader("cache-control","no-cache").build();Responseresponse=client.newCall(request).execute();

{"access_token":"SGWcJPtNtYNPGm6uSYR9yPYrAI3Bm","expires_in":"3599"}

To make an API call, you will need to authenticate your app. We have provided an OAuth API for you to generate an access token, we support client_credentials grant type. To authorize your API call to the OAuth API, you will need a Basic Auth over HTTPS authorization token. The Basic Auth string is a base64 encoded string of your app’s client key and client secret. We have provided a means to obtain the Basic Auth string for your sandbox apps; while you are in the OAuth API’s sandbox. Click on ‘HTTP Basic Set Credentials’ button.

In the pop-up menu that appears, enter your consumer key and consumer secret. You have an option to save these credentials for 30 days and therefore, you do not need to set them every time you need an access token

The OAuth access token expires after an hour, after which, you will need to generate another access token. On a production app, use a base64 library of the programming language you are using to build your app to get the Basic Auth string that you will then use to invoke our OAuth API to get an access token.

HTTP Header Parameters

With an OAuth 2.0 Access Token, an application can now invoke our APIs by including the access token in the HTTP header. Our APIs currently only supports application/json content type.

Security Credentials

// Classes and Libraries to importimportjava.security.MessageDigest;importjava.security.Security;importjava.security.PublicKey;importjava.security.cert.CertificateFactory;importjava.security.cert.X509Certificate;importjavax.crypto.Cipher;importjava.math.BigInteger;importcom.sun.org.apache.xerces.internal.impl.dv.util.Base64;importjava.ioByteArrayOutputStream;// Function to encrypt the initiator credentialspublicstaticStringencryptInitiatorPassword(StringsecurityCertificate,Stringpassword){StringencryptedPassword="YOUR_INITIATOR_PASSWORD";try{Security.addProvider(neworg.bouncycastle.jce.provider.BouncyCastleProvider());byte[]input=password.getBytes();Ciphercipher=Cipher.getInstance("RSA/ECB/PKCS1Padding","BC");FileInputStreamfin=newFileInputStream(newFile(securityCertificate));CertificateFactorycf=CertificateFactory.getInstance("X.509");X509Certificatecertificate=(X509Certificate)cf.generateCertificate(fin);PublicKeypk=certificate.getPublicKey();cipher.init(Cipher.ENCRYPT_MODE,pk);byte[]cipherText=cipher.doFinal(input);// Convert the resulting encrypted byte array into a string using base64 encodingencryptedPassword=Base64.encode(cipherText);}catch(NoSuchAlgorithmExceptionex){Logger.getLogger(PasswordUtil.class.getName()).log(Level.SEVERE,null,ex);}catch(NoSuchProviderExceptionex){Logger.getLogger(PasswordUtil.class.getName()).log(Level.SEVERE,null,ex);}catch(NoSuchPaddingExceptionex){Logger.getLogger(PasswordUtil.class.getName()).log(Level.SEVERE,null,ex);}catch(FileNotFoundExceptionex){Logger.getLogger(PasswordUtil.class.getName()).log(Level.SEVERE,null,ex);}catch(CertificateExceptionex){Logger.getLogger(PasswordUtil.class.getName()).log(Level.SEVERE,null,ex);}catch(InvalidKeyExceptionex){Logger.getLogger(PasswordUtil.class.getName()).log(Level.SEVERE,null,ex);}catch(IllegalBlockSizeExceptionex){Logger.getLogger(PasswordUtil.class.getName()).log(Level.SEVERE,null,ex);}catch(BadPaddingExceptionex){Logger.getLogger(PasswordUtil.class.getName()).log(Level.SEVERE,null,ex);}returnencryptedPassword;}

varcrypto=require("crypto");varconstants=require("constants");// CAUTION: This is a 512 bit RSA demo key - NEVER USE THIS SOMEWHERE FOR REAL!varprivatekey="PATH_TO_CERTIFICATE_FILE";varbufferToEncrypt=newBuffer("abc");varencrypted=crypto.publicEncrypt({"key":privatekey,padding:constants.RSA_PKCS1_PADDING},bufferToEncrypt);console.log(encrypted.toString("base64"));null;

M-Pesa Core authenticates a transaction by decrypting the security credentials. Security credentials are generated by encrypting the base64 encoded initiator password with M-Pesa’s public key, a X509 certificate.

The algorithm for generating security credentials is as follows:

Write the unencrypted password into a byte array.

Encrypt the array with the M-Pesa public key certificate. Use the RSA algorithm, and use PKCS #1.5 padding (not OAEP), and add the result to the encrypted stream.

Convert the resulting encrypted byte array into a string using base64 encoding. The resulting base64 encoded string is the security credential.

Used to simulate a transaction taking place in the case of C2B Simulate Transaction or to initiate a transaction on behalf of the customer (STK Push).

TransactionStatusQuery

Used to query the details of a transaction.

CheckIdentity

Similar to STK push, uses M-Pesa PIN as a service.

BusinessPayBill

Sending funds from one paybill to another paybill

BusinessBuyGoods

sending funds from buy goods to another buy goods.

DisburseFundsToBusiness

Transfer of funds from utility to MMF account.

BusinessToBusinessTransfer

Transferring funds from one paybills MMF to another paybills MMF account.

BusinessTransferFromMMFToUtility

Transferring funds from paybills MMF to another paybills utility account.

Identifier Types

Identifier types - both sender and receiver - identify an M-Pesa transaction’s sending and receiving party as either a shortcode, a till number or a MSISDN (phone number). There are three identifier types that can be used with M-Pesa APIs.

Identifier

Identity

1

MSISDN

2

Till Number

4

Shortcode

M-Pesa Result and Response Codes

M-Pesa Result Codes

Result Code

Description

0

Success

1

Insufficient Funds

2

Less Than Minimum Transaction Value

3

More Than Maximum Transaction Value

4

Would Exceed Daily Transfer Limit

5

Would Exceed Minimum Balance

6

Unresolved Primary Party

7

Unresolved Receiver Party

8

Would Exceed Maxiumum Balance

11

Debit Account Invalid

12

Credit Account Invaliud

13

Unresolved Debit Account

14

Unresolved Credit Account

15

Duplicate Detected

17

Internal Failure

20

Unresolved Initiator

26

Traffic blocking condition in place

M-Pesa Response Codes (from client back to gateway)

Response codes are sent from the clients endpoints back to the gateway. This is done to acknowledge that the client has received the results.

Result Code

Description

0

Success (for C2B)

00000000

Success (For APIs that are not C2B)

1 or any other number

Rejecting the transaction

Test Credentials

To facilitate testing of sandbox apps, we have provided test credentials consisting of:

Test Shortcodes

Initiator Name

Security Credential

Test MSISDN

Lipa Na M-Pesa Online Shortcode

Lipa Na M-Pesa Online Passkey

There are two shortcodes in the test credentials page - Shortcode 1 and Shortcode 2. The initiator name and security credentials are associated with Shortcode 1. For M-Pesa APIs that have ‘PartyA’ in their request parameters, use Shortcode 1; Shortcode 2 will be used for ‘PartyB’.

The test credentials page has a utility to generate an M-Pesa security credential. You use the utility by entering the string alongside ‘Security Credential’ with no preceding and trailing spaces and then clicking on ‘Generate Credentials’ button. You will then get an M-Pesa security credential for use in invoking an API that requires a security credential in its request parameters.

The ‘Lipa Na M-Pesa Online Shortcode’ is a production shortcode. On the sandbox, API calls using Lipa Na M-Pesa Online Payment API can only be made to this shortcode and money will be transacted. Auto-reversal of funds received on this shortcode will be done every night at 23:59 HRS EAT (midnight).

The ‘Lipa Na M-Pesa Online Passkey’ is used to create a password for use when making a Lipa Na M-Pesa Online Payment API call. The password is generated by base64 encoding the passkey, shortcode and timestamp, the resultant string from this encoding is the password.

Test credentials expire after three days, after which you will be issued with fresh test credentials. Lipa Na M-Pesa Online Shortcode and Lipa Na M-Pesa Passkey do not expire.

Test Cases

The developer will download test cases when they are creating a sandbox app. The test cases are in an Excel spreadsheet which the developer will fill with results from the API calls they make for each test scenarios.

Once the test case scenarios have been duly filled, the developer will upload the filled Excel spreadsheet during the ‘Go Live’ process. Our support team will then review the test cases and then either approve or reject the production app.

Test cases are meant to ensure that the developer understands the structure of requests and responses of an API. The support team will approve or reject a production app based on the uploaded test cases. The developer does not need to fill all test case scenarios, only scenarios for the API they intend to consume.

Going Live

Having played with the APIs on the sandbox and filled the test cases for an API(s) that you would like to move into production with, the developer will initiate the ‘Go Live’ process.

To go live with an M-Pesa API, the developer will need to prove ownership or authorization to use an M-Pesa shortcode. M-Pesa Shortcodes are managed on the M-Pesa Web Portal where owners of the shortcodes can add users and assign roles. When a request to verify ownership or authorization to use an M-Pesa shortcode is received, an OTP - one time password - is sent to the user with a Business Manager and Business Administrator role and a notification is sent to users with a Business Manager role.

For non M-Pesa APIs, the developer will provide a valid identification document known to Safaricom for example a National ID or passport used to register as a Safaricom subscriber.

Step by Step Go Live Guide

1. Upload test cases

From the menu bar, click on ‘Go Live’

Upload a filled out test cases (Excel spreadsheet) and click ‘Upload’, once uploaded click on the check box as consent to the ‘Terms and Conditions’. Click on ‘Next’.

The ‘M-Pesa User Name’ is user name used on the M-Pesa Web Portal for the Business Administrator or Business Manager or Business Operator roles within the organisation in M-Pesa.

To verify a ‘Document ID’, select a ‘Document Type’, input the ‘Document ID’ and ‘Organisation Name’.

The ‘Document Type’ used are any document submitted to Safaricom while subscribing to any Safaricom services, for example, registering for an M-Pesa account or Safaricom MSISDN.

This verification type is for non M-Pesa APIs.

Click ‘Verify’

3. OTP Confirmation

During the verification stage you will be required to receive an OTP so as to verify you are the owner of the paybill.

This requires you to set the password on the M-Pesa portal. The steps are as below:

a) Login as a business administrator.

b) Click on operators on the left hand corner on the M-Pesa portal and click on search. This will show you all your operators.

c) You will find business administrators and business operators. Find the user which you are going to use on the portal and click edit.

d) Click on KYC Info and edit the following information as shown below

Ensure the MSISDN is entered in format 2547XXXXXXXX

e) Click submit and save the changes

You then Continue the rest of the process on daraja portal.

A verification will be done and a six digit passcode, OTP - one time password, will be sent via SMS to the MSISDN that you have entered above.

If the verification type was an M-Pesa Shortcode, the OTP will be sent to MSISDN belonging to the M-Pesa Business Administrator or Manager or Operator. An SMS notification will also be sent to other users within the M-Pesa organisation notifying them of the intention to integrate their shortcode to M-Pesa APIs.

If verification type was a Document ID, the OTP will be sent to the MSISDN associated with the document.(not applicable for M-Pesa APIs)

The OTP will expire after three minutes. If an OTP is not submitted for confirmation within three minutes you can request a new OTP by clicking ‘Resend OTP’. All OTPs will be sent via SMS. The M- Pesa Business Manager or Business Operator will need to log on to the M-Pesa Web portal and update their profiles with their current MSISDNs.

The developer will select the API Products they will be integrating to, select only the API Products for which you have filled test case scenarios for in the filled test cases Excel spreadsheet uploaded at step 1. The API Products will be presented depending on the verification type used. For M-Pesa shortcode verification type, the API products displayed will depend on the M-Pesa product type configured on M-Pesa for that shortcode.

Click ‘Submit’ once you have selected the API Product(s) and input the OTP.

4. Production URLs and Credentials

Your application to ‘Go Live’ will be reviewed for approval by our support teams. The approval process involves a review of the uploaded test cases ensuring that all test scenarios were successfully tested and the actual results filled for the test scenarios are appropriate.

To switch to your production app page, click on the switch adjacent to your email address and select the organisation name you submitted earlier during the verification process. Your production app will be automatically be assigned a name and will have a ‘pending’ tag.

Once your production app is approved, you will receive an email notification of the production urls for the APIs in the approved API Products. The production app will be tagged ‘approved’ and its consumer key and consumer secret can now be used.

The last step is setting the secruity credential tag. (This does not apply to Lipa Na Mpesa Online and C2B API’s) Security credential allows us as M-Pesa to authenticate that the request has been generated by a particular paybill owner.

After your app is approved you will receive an email from no_reply@m-pesa.com with the api password as follows:

“Your M-PESA user account has been created. Your operator id is null and your user name is testapi. Your PIN is null and your password is null.”

The following are the steps that are to be followed when setting the security credential:

a. The first step is ensuring that the web Operator has the correct role (Set Restricted ORG API PASSWORD). The web operator with the correct role logs in and clicks Search, then clicks Operator. The operator should then enter the API Username in the Username field and Click Search.

b. When the Operator details are displayed, click the icon in the Operation column.

c. The API Operator details will be displayed. Click the Set Password button.

d. Enter the preferred password. (Must contain a capital letter, small letter, number and special character)

Inviting Developers

Once you have an approved production app, you can now invite other developers to help you to develop your app. You can only invite developers who also have developer accounts on Daraja.

To invite a developer(s):

1. Switch to your production profile by clicking the switch to your right adjacent to your email address.

2. From the drop down menu that appears, click on ‘Manage Companies’.

3. The ‘Manage Companies’ page will open. The page will have a list of companies that you have created or have been invited to.

For companies you have created, your role will be ‘Owner’ and ‘Monetization Administrator’. You can invite developers to your company by providing the email address they used in registering for a developer account. They will then get an email with an invitation link and join your company by consenting to the invitation.

Once a developer has been invited to your company, they will have a ‘Developer’ role by default. You can give a developer ‘Company Administrator’ role. A developer with the ‘Company Administrator’ role can invite other developers, assign and revoke roles to other developers and remove developers.

If you have been invited to a company, you have access to the production apps of that company. You can then make API calls using the consumer key and consumer secret of any production app associated with the company you have been invited to.

Only the owner of a company can edit or delete a production app(s) of their company. Invited developers, even those with a ‘Company Administrator’ role, cannot edit or delete a production app(s).

M-Pesa APIs

The following are the M-Pesa APIs that are available to test. This documentation provides sample codes and JSON responses to the right with these APIs.

//SampleM-PesaCoreresponsereceivedonthecallbackurl.{"Result":{"ResultType":0,"ResultCode":0,"ResultDesc":"The service request has been accepted successfully.","OriginatorConversationID":"19455-424535-1","ConversationID":"AG_20170717_00006be9c8b5cc46abb6","TransactionID":"LGH3197RIB","ResultParameters":{"ResultParameter":[{"Key":"TransactionReceipt","Value":"LGH3197RIB"},{"Key":"TransactionAmount","Value":8000},{"Key":"B2CWorkingAccountAvailableFunds","Value":150000},{"Key":"B2CUtilityAccountAvailableFunds","Value":133568},{"Key":"TransactionCompletedDateTime","Value":"17.07.2017 10:54:57"},{"Key":"ReceiverPartyPublicName","Value":"254708374149 - John Doe"},{"Key":"B2CChargesPaidAccountAvailableFunds","Value":0},{"Key":"B2CRecipientIsRegisteredCustomer","Value":"Y"}]},"ReferenceData":{"ReferenceItem":{"Key":"QueueTimeoutURL","Value":"https://internalsandbox.safaricom.co.ke/mpesa/b2cresults/v1/submit"}}}}

This API enables Business to Customer (B2C) transactions between a company and customers who are the end-users of its products or services. Use of this API requires a valid and verified B2C M-Pesa Short code.

B2C Resource URL

POST https://sandbox.safaricom.co.ke/mpesa/b2c/v1/paymentrequest

B2C Query Parameters

Parameter

Description

InitiatorName

This is the credential/username used to authenticate the transaction request.

SecurityCredential

Base64 encoded string of the Security Credential, which is encrypted using M-Pesa public key and validates the transaction on M-Pesa Core system.

This API enables Business to Business (B2B) transactions between a business and another business. Use of this API requires a valid and verified B2B M-Pesa short code for the business initiating the transaction and the both businesses involved in the transaction.

B2B - Resource URL

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

B2B - Request Parameters

Parameter

Description

Initiator

This is the credential/username used to authenticate the transaction request.

SecurityCredential

Base64 encoded string of the Security Credential, which is encrypted using M-Pesa public key and validates the transaction on M-Pesa Core system.

The C2B Register URL API registers the 3rd party’s confirmation and validation URLs to M-Pesa ; which then maps these URLs to the 3rd party shortcode. Whenever M-Pesa receives a transaction on the shortcode, M-Pesa triggers a validation request against the validation URL and the 3rd party system responds to M-Pesa with a validation response (either a success or an error code). The response expected is the success code the 3rd party

M-Pesa completes or cancels the transaction depending on the validation response it receives from the 3rd party system. A confirmation request of the transaction is then sent by M-Pesa through the confirmation URL back to the 3rd party which then should respond with a success acknowledging the confirmation.

The 3rd party resource URLs for both confirmation and validation must be HTTPS in production. Validation is an optional feature that needs to be activated on M-Pesa, the owner of the shortcode needs to make this request for activation.

C2B Register URL - Resource URL

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

C2B Register URL - Request Parameters

Parameter

Description

ValidationURL

Validation URL for the client.

ConfirmationURL

Confirmation URL for the client.

ResponseType

Default response type for timeout.

ShortCode

The short code of the organization.

Register URL - Response Parameters

Parameter

Description

ConversationID

A unique numeric code generated by the M-Pesa system of the response to a request.

OriginatorConversationID

A unique numeric code generated by the M-Pesa system of the request.

ResponseDescription

A response message from the M-Pesa system accompanying the response to a request.

{"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"}}}}

Reverses a B2B, B2C or C2B M-Pesa transaction.

Reversal Resource URL

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

Reversal Request Parameters

Parameter

Description

Initiator

This is the credential/username used to authenticate the transaction request.

SecurityCredential

Base64 encoded string of the Security Credential, which is encrypted using M-Pesa public key and validates the transaction on M-Pesa Core system.

Lipa na M-Pesa Online Payment API is used to initiate a M-Pesa transaction on behalf of a customer using STK Push. This is the same technique mySafaricom App uses whenever the app is used to make payments.

Lipa na M-Pesa Online Payment - Resource URL

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

Lipa na M-Pesa Online Payment - Request Parameters

Parameter

Description

BusinessShortCode

The organization shortcode used to receive the transaction.

Password

The password for encrypting the request. This is generated by base64 encoding BusinessShortcode, Passkey and Timestamp.

Timestamp

The timestamp of the transaction in the format yyyymmddhhiiss.

TransactionType

The transaction type to be used for this request. Only CustomerPayBillOnline is supported.

{"ResponseCode":"0","ResponseDescription":"The service request has been accepted successfully","MerchantRequestID":"8555-67195-1","CheckoutRequestID":"ws_CO_27072017151044001","ResultCode":"1032","ResultDesc":"[STK_CB - ]Request cancelled by user"}

Lipa na M-Pesa Online Query Request - Resource URL

POST https://sandbox.safaricom.co.ke/mpesa/stkpushquery/v1/query

Lipa na M-Pesa Online Query Request - Request Parameters

Parameter

Description

BusinessShortCode

Business Short Code

Password

Password

Timestamp

Timestamp

CheckoutRequestID

Checkout RequestID

Lipa na M-Pesa Online Query Request - Response Parameters

Parameter

Description

MerchantRequestID

Merchant Request ID

CheckoutRequestID

Check out Request ID

ResponseCode

Response Code

ResultDesc

Result Desc

ResponseDescription

Response Description message

ResultCode

Result Code

Errors

Safaricom APIs are built to comply with HTTP Status codes. The following are error codes that will be returned whenever there are errors in a request. Server errors are rare but do occur whenever there are connectivity issues.

Error Code

Meaning

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

405

Method Not Allowed

406

Not Acceptable – You requested a format that isn’t json

429

Too Many Requests – You’re requesting too many kittens! Slow down!

500

Internal Server Error – We had a problem with our server. Try again later.

Creating a HTTP Server Listener

# import the Flask FrameworkfromflaskimportFlask,jsonify,make_response,requestapp=Flask(__name__)# Create the context (endpoint/URL) which will be triggered when the request# hits the above specified port. This will resolve to a URL like# 'http://address:port/context'. E.g. the context below would# resolve to 'http://127.0.0.1:80/mpesa/b2c/v1' on the local computer. Then# the Handler will handle the request received via the given URL.# You may create a separate URL for every endpoint you need@app.route('/mpesa/b2c/v1',methods=["POST"])deflistenB2c():#save the datarequest_data=request.data#Perform your processing here e.g. print it out...print(request_data)# Prepare the response, assuming no errors have occurred. Any response# other than a 0 (zero) for the 'ResultCode' during Validation only means# an error occurred and the transaction is cancelledmessage={"ResultCode":0,"ResultDesc":"The service was accepted successfully","ThirdPartyTransID":"1234567890"};# Send the response back to the serverreturnjsonify({'message':message}),200# Change this part to reflect the API you are testing@app.route('/mpesa/b2b/v1')deflistenB2b():request_data=request.dataprint(request_data)message={"ResultCode":0,"ResultDesc":"The service was accepted successfully","ThirdPartyTransID":"1234567890"};returnjsonify({'message':message}),200if__name__=='__main__':app.run(debug=True)

<?php$postData=file_get_contents('php://input');//perform your processing here, e.g. log to file....
$file=fopen("log.txt","w");//url fopen should be allowed for this to occur
if(fwrite($file,$postData)===FALSE){fwrite("Error: no data written");}fwrite("\r\n");fclose($file);echo'{"ResultCode": 0, "ResultDesc": "The service was accepted successfully", "ThirdPartyTransID": "1234567890"}';?>

//Requires the following libraries. Maven repositories given belowimportcom.sun.net.httpserver.HttpExchange;importcom.sun.net.httpserver.HttpHandler;importcom.sun.net.httpserver.HttpServer;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.OutputStream;importjava.net.InetSocketAddress;importorg.json.simple.JSONObject;publicclassMain{privateHttpServerserver;publicMain(){try{//Define the port over which the listener will accept requestsintport=8080;server=HttpServer.create(newInetSocketAddress(port),0);/**
* Create the context (endpoint/URL) which will be triggered when the request
* hits the above specified port. This will resolve to a URL like
* 'http://address:port/context'. E.g. the context below would
* resolve to 'http://127.0.0.1:80/confirm' on the local computer. Then
* the Handler will handle the request received via the given URL.
*
* You may create a separate context for every endpoint you need
*/server.createContext("/confirm",newConfirmHandler());server.setExecutor(null);//start the serverserver.start();System.out.println("Server started");}catch(Exceptionex){ex.printStackTrace();}}/**
* Class to handle incoming requests based on specified Contexts, you can
* create a class for each separate context/URL
*/publicclassConfirmHandlerimplementsHttpHandler{@Overridepublicvoidhandle(HttpExchangehe)throwsIOException{/**
* handle the request which comes through the '/confirm' context
*/System.out.println("Request received");/**
* Buffer and store the response in a string
*/BufferedReaderbr=newBufferedReader(newInputStreamReader(he.getRequestBody(),"UTF-8"));Stringline="";StringBuilderbuffer=newStringBuilder();while((line=br.readLine())!=null){buffer.append(line);}/**
* Once buffered, you can perform any other processing
* you need on the buffered response e.g. print out the response...
*/System.out.println("Res: "+buffer.toString());/**
* Prepare the response, assuming no errors have occurred. Any response
* other than a 0 (zero) for the 'ResultCode' during Validation means an
* error occurred and the transaction is cancelled
*/JSONObjectobj=newJSONObject();obj.put("ResultCode",0);obj.put("ResultDesc","The service was accepted successfully");obj.put("ThirdPartyTransID","1234567890");/**
* Respond to the server appropriately
*/Stringres=obj.toJSONString();he.sendResponseHeaders(200,res.length());OutputStreamos=he.getResponseBody();os.write(res.getBytes("UTF-8"));os.close();}}publicstaticvoidmain(Stringargs[]){Mainmain=newMain();}}/**
* Maven Repositories:
*
* <dependency>
* <groupId>com.sun.net.httpserver</groupId>
* <artifactId>http</artifactId>
* <version>20070405</version>
* </dependency>
*
* <dependency>
* <groupId>com.googlecode.json-simple</groupId>
* <artifactId>json-simple</artifactId>
* <version>1.1.1</version>
* </dependency>
*
* <repositories>
* <repository>
* <id>reficio</id>
* <url>http://repo.reficio.org/maven/</url>
* </repository>
* </repositories>
*
* More examples here: https://www.codeproject.com/Tips/1040097/Create-a-Simple-Web-Server-in-Java-HTTP-Server
*/}

M-Pesa APIs are asynchronous. When a valid M-Pesa API request is received by the API Gateway, it is sent to M-Pesa where it is added to a queue. M-Pesa then processes the requests in the queue and sends a response to the API Gateway which then forwards the response to the URL registered in the CallBackURL or ResultURL request parameter. Whenever M-Pesa receives more requests than the queue can handle, M-Pesa responds by rejecting any more requests and the API Gateway sends a queue timeout response to the URL registered in the QueueTimeOutURL request parameter.

To receive responses, either M-Pesa results or queue timeouts, an HTTP listener will be needed. The listener should be deployed to a server that can receive traffic over the internet. On local host, use an http tunnelling client like ngrok or localtunnel to get a public IP that will enable your local host to receive traffic over the internet. Sample json responses that are received on callback urls or queue timeout urls are provided in the ‘Json Response’ tab on the top right corner for each API. Sample http listeners are also provided on the right in Python, NodeJS, PHP and Java.

The API Gateway does not cache responses from M-Pesa, should the server running the HTTP listener be unavailable or inaccessible,the API Gateway will log a 503 error and discard the M-Pesa results.

The HTTP listner should deploy POST methods for receiving M-Pesa responses on CallBackURL or ResultURL and for receiving queue timeouts on QueueTimeOutURL.

Testing on local host

To test on local host, an http tunnelling client will be required to the http listner on your local host to make the services running their accessible over the internet.

Ngrok and LocalTunnel are examples of http tunnelling clients that you could use to get a public IP and make your local host accessible over the internet.