Intergrating Mobile Money like Mpesa and AirtelMoney with Android App

2.2k views Asked by At

In Kenya and now spreading to Africa and the rest of the world we have an amazing way of sending and receiving money via cellphones coined mobile money. Two leading service providers Safaricom and Airtel have their mobile money platforms namely Mpesa and AirtelMoney respectively.

Since Google Merchant services are not available in Kenya and also using them will shy off potential consumers, I have been thinking of using both Mpesa and AirtelMoney to sell my app to users. Now both Mobile Money services send confirmation text messages to the sender and receivers whenever a transaction occurs.

Now how will i use this services on my app since i have been unsuccessfuly to use available apis which use web platform among other technologies. Not all of my users use internet on a daily basis since mine is an app that is used by church members. But for sure they do use mobile money on a daily basis. I will appreciate any effort towards this.

I want my app to be able to change from trial to premium when a user pays me via Mpesa because it kind of appears working with sms is easier compared with web apis

3

There are 3 answers

0
Jack Siro On BEST ANSWER

I had a similar problem to you and decided to use sms to achieve that objective. First of all I used the permissions for allowing me to do that:

    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <receiver
            android:name="com.example.myapp.IncomingMessage"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS" >
            <intent-filter android:priority="2147483647" >
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

and in my IncomingMessage activity I added the following code:

package com.example.myapp;

import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;

@SuppressLint("ShowToast")
public class IncomingMessage extends BroadcastReceiver
{

  final SmsManager sms = SmsManager.getDefault();

  public void onReceive(Context paramContext, Intent paramIntent)
  {
      SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(paramContext.getApplicationContext()).edit();

      if (!PreferenceManager.getDefaultSharedPreferences(paramContext.getApplicationContext()).getBoolean("js_vsb_is_paid", false))
        {

          Bundle localBundle = paramIntent.getExtras();
            if (localBundle != null) {}
            for (;;)
            {
              int i;
              String sender;
              String message;
              try {
                Object[] arrayOfObject = (Object[])localBundle.get("pdus");
                i = 0;
                if (i >= arrayOfObject.length) {
                  return;
                }
                SmsMessage localSmsMessage = SmsMessage.createFromPdu((byte[])arrayOfObject[i]);
                sender = localSmsMessage.getDisplayOriginatingAddress();
                message = localSmsMessage.getDisplayMessageBody();
                Log.i("SmsReceiver", "senderNum: " + sender + "; message: " + message);

                if (sender.equalsIgnoreCase("MPESA")) {
                    if (message.contains("JACKSON SIRO"))
                    {
                        editor.putBoolean("app_is_paid", true);
                        editor.commit();
                        //Toast.makeText(paramContext, "App Has been Activated!", Toast.LENGTH_LONG).show();

                    }
                 } 
                   else if (sender.equalsIgnoreCase("AirtelMoney")) {
                    if (message.contains("JACKSON SIRO"))  {
                        editor.putBoolean("app_is_paid", true);
                        editor.commit();
                        //Toast.makeText(paramContext, "App Has been Activated!", Toast.LENGTH_LONG).show();
                    }
                  } 

              } catch (Exception localException) {
                Log.e("SmsReceiver", "Exception smsReceiver" + localException);
                return;
              }

     }
    }
  }

I hope this helps. The code is simple as such maybe you will modify it to suit your needs

2
Beliot On

Safaricom has released the M-Pesa APIs as RESTful APIs accessible through their developer portal.

The Safaricom github repository, has a sample android application that uses "Lipa na M-Pesa Online" API. This API initiates an M-Pesa transaction on behalf of the user of an app, the user needs only to input their M-Pesa PIN to complete the transaction.

0
GuruCoder On

Using a back end language of your choice (Java, php, ETC), the best way to address MPESA integration is to have Mpesa Payments stored in a Database table and then extending your business logic from there.

You can also require/include your business logic file as soon as there is a Payment conformation in the confirmation file and execute your business logic from there. This works for C2B mpesa API. Check this Mpesa C2B integration guide for more info.

On the other hand, the B2C mpesa integration is best done on the back end too. Just require the B2C payment request file as soon as the business logic is script is done.

Read on Mpesa B2C integration guide here for more details.