Developing USSD apps: Airtel Mobile money USSD app

images

I have just thought of this app right now because my MTN phone is out of battery otherwise we would have used the MTN mobile money app which is more popular in Uganda. Since I need to be navigating the menu as am developing the app, I will use my Airtel line.

If you are in Uganda, dial *185# on your Airtel line to follow along.

If you’re not, no worries, these are just simple menus and you probably have something similar with your local MSP. All the same, your only hustle should be getting to grips with manipulating ussdmenu-server.jar libraries to your advantage.

From the last post, our servlet looked something like this, only that we have filled in some values to return, if left null, the system will default to its original values:

package com.egima.ussd;
import
com.egima.ussdmenuserver.UssdReceiver;
import
com.egima.ussdmenuserver.UssdTree;
/**
 *
 * @author Egima
 *
 */
public class MyUssdReceiver extends UssdReceiver {
       private static final long serialVersionUID = 1L;
       @Override
       public String
getAppShortCode() {
             //can be any short
code of your choice, we are just simulating
             return “*185#”;
       }
       @Override
       public int getBufferLimit() {
             return 5;
       }
       @Override
       public String
getUssdAppId() {
             return “appid”;
       }
       @Override
       public String
getUssdAppPassword() {
             return “password”;
       }
       @Override
       public String
getUssdClientUrl() {
             return “http://127.0.0.1:8000/ussd/”;
       }
       @Override
       public UssdTree
getUssdTree() {
             return null;
       }
}

 

}
 
From the above code, the only thing our servlet lacks is the UssdTree, and that is the most important part of our app. For clarity purposes, we shall move it to another class MyTree.java which subclasses UssdTree.
So create MyTree.java in the existing package and put the following code there. It’s really self explanatory
package com.egima.ussd;
import java.util.HashMap;
import
com.egima.ussdmenuserver.UssdNode;
import
com.egima.ussdmenuserver.UssdPrompt;
import
com.egima.ussdmenuserver.UssdTree;
/**
 *
 * @author Egima
 *
 */
public class MyTree extends UssdTree {
       public MyTree(String
treeHeader) {
             super(treeHeader);
             initTree();
       }
       private void initTree() {
              /***********************************************************************
             add
first level children falling directly under root menu, give them suitable
             id’s
which must be unique across the whole tree
              ************************************************************************/
       addNode(new UssdNode(“Send
Money”
, “sendmoney”, “root”));
       addNode(new UssdNode(“Airtime/Data”, “airtimedata”, “root”));
       addNode(new UssdNode(“Widthdraw
Cash”
,
“withdrawcash”, “root”));
       addNode(new UssdNode(“Pay
Bill”
,
“paybill”, “root”));
       addNode(new UssdNode(“Buy
Goods”
, “buygoods”, “root”));
       addNode(new UssdNode(“Check
Balance”
, “checkbalance”, “root”));
       addNode(new UssdNode(“Financial
Services”
, “financialservices”, “root”));
       addNode(new UssdNode(“My
Account”
, “myaccount”, “root”));
       addNode(new UssdNode(“Messages”, “messages”, “root”));
      
       /***********************************************************************
        * add the children of each menu item in
similar manner e.g for paybill item
        *
********************************************************************/
        addNode(new UssdNode(“UMEME touchpay”, “umeme”, “paybill”));
        addNode(new UssdNode(“NWSC eWater”, “nwsc”, “paybill”));
        addNode(new UssdNode(“Pay TV”, “paytv”, “paybill”));
        /***********************************************************************
         * at this rate, you can pick on and supply
menus to the rest, lets look at
         * a UssdPrompt
         * Assume on selecting UMEME touchpay
option, you are asked for account number,
         * amount to pay and mobile money pin, each of
which are prompts
         */
        addNode(new UssdPrompt(“Enter UMEME account No”,“umemeaccno”,“umeme”) {
            
             @Override
             public boolean validate(Object
arg0) {
                    /*
                     * probably here you’d check if the input
account number is in your DB
                     * but lets assume there is only 1 client and
his account number is 1100
                     */
                    String
input=(String) arg0;
                    return “1100”.equals(input);
             }
            
             @Override
             public String
getValidationError() {
                    /*
                     * Incase the account number is not
valid
                     */
                    return “Unknown
account number, please check your entry”
;
             }
       });
        /******************************************************************
         * after the first prompt passes, the next
prompt is called, so a prompt
         * must have only 1 child i.e the next prompt
         */
        addNode(new UssdPrompt(“How much do you want to
pay”
,“amount”,“umemeaccno”) {
            
             @Override
             public boolean validate(Object
arg0) {
                    /*
                     *since this is a cash amount, we shall just
ensure it’s a valid double
                     *figure greater than 0
                     */
                    double amount=0;
                    try{
                           amount=Double.parseDouble((String)arg0);
                           }catch(Exception e){
                                 return false;
                           }
                    return amount>0;
             }
            
             @Override
             public String
getValidationError() {
                    return “Invalid cash
amount”
;
             }
       });
        /******************************************************************
         * finally we add another child to amount
prompt to ask for the pin,
         * since this is the last prompt(has no
children), we shall override the
         * processNodeEndEvent method to perform our
session end processing
         */
       addNode(new UssdPrompt(“Enter Mobile
money pin”
,“pin”,“amount”) {
            
             @Override
             public boolean validate(Object
arg0) {
                    /*
                     * lets assume the pin is 4649, otherwise you’d
check from the DB
                     */
                   
                    return “4649”.equals(arg0);
             }
            
             @Override
             public String
getValidationError() {
                    return “Invalid
pin”
;
             }
             @Override
             public String
processNodeEndEvent(HashMap userData) {
                    /*
                     * let’s retrieve all the data we need now by
node name
                     */
                    //umemeaccno
                    String
accno=(String) userData.get(
“umemeaccno”);
                    //amount
                    double amt=Double.parseDouble((String)userData.get(“amount”));
                    //pin
                    String
pin=(String) userData.get(
“pin”);
                    /*
                     * assume the initial balance was 300,000/= and
we are going to deduct th
                     * input amount
                     */
                    double balance=300000-amt;
                   
                    /*
                     * just for clarity and understanding purposes,
we shall send this
                     * data to display
                     */
                    StringBuilder
data=
new StringBuilder();
                    data.append(“Dear
customer
);
                    data.append(“ACC NO:”+accno+
);
                    data.append(“PIN:”+pin+
);
                    data.append(“AMT:”+amt+
);
                    data.append(“BAL:”+balance);
                    return data.toString();
             }
            
       });
       }
}
You can now return this new object in the servlet as our UssdTree like so:
@Override
       public UssdTree
getUssdTree() {
             return new MyTree(“Airtel
Money”
);
       }
 
 

Now redeploy your app and test from the simulator.

  • use the short code you set in the system for the app, or you can use others to test validation mechanism
  • select the pay bill option since it is what we have tackled so far
  • select umeme option 1
  • follow the prompts to input data according to the validation you had defined in the code, else you can test the validation with different data.
You can try out completing the menus and supplying them children as seen in the real app just to sharpen your skills at using the ussdmenu-server.jar lib.
It’s friday guys, PARTY TIME, don’t be like this