M-Pesa is a mobile phone-based money transfer, financing and microfinancing service. The service allows users to deposit, withdraw, transfer money and pay for goods and services (Lipa na M-Pesa) easily with a mobile device. To help developers implement Mpesa on their platforms, Safaricom released the Daraja API, a REST-based API that shifts the functionalities of Mpesa to system developers.
Lipa na Mpesa Online is one of the functionalities provided by the Daraja API. It’s a service used to initiate Mpesa transactions on behalf of the customer using STK-PUSH. This means that the user is only required to enter the PIN. It’s applied in e-commerce and bill payment systems among others. Some of the prerequisites are:
- Have a Safaricom phone number.
- Have Node.js installed on your computer.
- Have some basic knowledge of JavaScript and Express JS.
- Have Postman installed on your computer.
1. Create a Safaricom developer account
Safaricom controls all the operations concerning Mpesa and Daraja API. For you to access Daraja API, you need to have a developer account. The following steps explain how you can create a developer account.
- Proceed to Safaricom Developer website.
- Click on the “Sign Up” button, and proceed to the signup section.
- After registering, a welcome message with further instructions is sent to your email address. In the email, you will find a confirmation link, click on it and it will direct you to a password entry page.
- Enter your password and confirm it and then click “Login”.
2. Create an app
To be able to use the Daraja API, you need to have an app so that you have the required access keys. Follow these steps to create an app.
- Click on “My Apps” on the navbar on the developer portal.
- On that page, click “Add a new app”.
- On the page that follows, enter your preferred app name. Check the Lipa na Mpesa Sandbox and then click “Create app”.
a. Configuring the application
Having set up the developer account and an app, it’s time to set up your application. Implement a REST API with Express.js framework. Your end goal is to implement a working endpoint for Lipa na Mpesa online. To handle communication to and from the Daraja API you can use Axios. To follow along effectively, clone the finalized project from GitHub. To test your API, you can use Postman.
b. Obtaining consumer key and consumer secret
On the portal’s apps page, click on the newly created app from the previous process. In the keys section, copy the consumer key and the consumer secret and paste them in your .env file respectively as shown below:
//in the .env file
consumer_key = "your consumer key"
consumer_secret = "your consumer secret"
After you have saved the consumer key and the consumer secret, you are set to proceed to the next step of getting an OAuth token.
3. Get an OAuth token
To make every call to the Daraja API, you need to always supply an OAuth token. For this reason, you will implement it as middleware to be called every time you are accessing an endpoint. The function will be as follows:
async getOAuthToken(req,res,next){
let consumer_key = process.env.consumer_key;
let consumer_secret = process.env.consumer_secret;
let url = process.env.oauth_token_url;
//form a buffer of the consumer key and secret
let buffer = new Buffer.from(consumer_key+":"+consumer_secret);
let auth = `Basic ${buffer.toString('base64')}`;
try{
let {data} = await axios.get(url,{
"headers":{
"Authorization":auth
}
});
req.token = data['access_token'];
return next();
}catch(err){
return res.send({
success:false,
message:err['response']['statusText']
});
}
};
- Receiving req,res,next as parameter. Since the function will be called as middleware, you need to pass the appropriate parameters. req has access to the request object whereas res has access to the response object. next is used to execute the next middleware on that particular endpoint.
- Access the environmental variables consumer_key,consumer_secret and oauth_token_url.
- Create a buffer and then encode it to a base64 string.
- Use a try,catch block to communicate with the Daraja API. If the request is successful, set the token on the request object, and then execute the next middleware. Otherwise return the error.
4. Implementing Lipa na M-Pesa online
Having generated an access token, you can now implement your core functionality. Since Express.js is a series of middleware calls, you will also implement it as a middleware. The implementation shall be as follows:
async lipaNaMpesaOnline(req,res){
let token = req.token;
let auth = `Bearer ${token}`;
//getting the timestamp
let timestamp = require('../middleware/timestamp').timestamp;
let url = process.env.lipa_na_mpesa_url;
let bs_short_code = process.env.lipa_na_mpesa_shortcode;
let passkey = process.env.lipa_na_mpesa_passkey;
let password = new Buffer.from(`${bs_short_code}${passkey}${timestamp}`).toString('base64');
let transcation_type = "CustomerPayBillOnline";
let amount = "1"; //you can enter any amount
let partyA = "party-sending-funds"; //should follow the format:2547xxxxxxxx
let partyB = process.env.lipa_na_mpesa_shortcode;
let phoneNumber = "party-sending-funds"; //should follow the format:2547xxxxxxxx
let callBackUrl = "your-ngrok-url/mpesa/lipa-na-mpesa-callback";
let accountReference = "lipa-na-mpesa-tutorial";
let transaction_desc = "Testing lipa na mpesa functionality";
try {
let {data} = await axios.post(url,{
"BusinessShortCode":bs_short_code,
"Password":password,
"Timestamp":timestamp,
"TransactionType":transcation_type,
"Amount":amount,
"PartyA":partyA,
"PartyB":partyB,
"PhoneNumber":phoneNumber,
"CallBackURL":callBackUrl,
"AccountReference":accountReference,
"TransactionDesc":transaction_desc
},{
"headers":{
"Authorization":auth
}
}).catch(console.log);
return res.send({
success:true,
message:data
});
}catch(err){
return res.send({
success:false,
message:err['response']['statusText']
});
};
};
The implementation follows these steps:
- Access the token that we stored in the request object.
- Append Bearer in front of the string to create the authorization string.
- Get the current timestamp.
- Get the Lipa na Mpesa URL that is stored as an environmental variable.
- Get your business short code and passkey. Proceed to your test credentials. Then copy and paste the Lipa Na Mpesa Online Shortcode as the business short code to your .env file and Lipa Na Mpesa Online Passkey as the passkey.
- Get the password that is generated from a buffer composed of business short code, passkey, and timestamp. The buffer is then encoded to a base64 string.
- Set the transaction type to CustomerPayBillOnline that is the only one supported. Don’t change it.
- Set the amount to be paid.
- Set the PartyA that is the phone number sending the funds. The phone number should use the 2547xxxxxxxx format.
- Set the PartyB which is the business short code.
- Set the phone number that is the phone number sending the funds. Use the format as explained in PartyA.
- Set the callback Url. The callback Url is where the response will be processed. You can use ngrok.
Make sure your server is running with the command:
npm run dev
Then open another tab and run the following command:
npm run ngrok
This will forward you to a particular link such as http://78066c1c2d6b.ngrok.io. Copy that link and paste in the callBackUrl variable. Note that the link is different each time you stop and start the server again.
- Set the account reference which can be any string you set. It references where the money is being paid to.
- Set the transaction description which describes what the transaction is for.
- Use a try,catch block when communicating with the Daraja API. If the process is successful, return the message from the API. Otherwise return the error from the API.
Lipa na Mpesa online callback
When you send a request, the response from the API will be sent through the callback. In case you want to update some records, you can update them here based on the response sent back. You implement a simple callback as a method in the class.
lipaNaMpesaOnlineCallback(req,res){
//Get the transaction description
let message = req.body.Body.stkCallback['ResultDesc'];
return res.send({
success:true,
message
});
};
Access the description of the transaction carried out or return the message sent.
Takeaway
If you want to push your app into production, you must change the callback URL to your server domain when hosted online. After you have added credentials to the .env file, add it to your .gitignore file so that you do not expose your credentials when you push your project to GitHub.