Get Paid In-App with Mobile Money
A tutorial on payment basics with the Hover SDK
Hover is a developer friendly Android SDK which makes it easy to accept in-app payments from users on any mobile money system that uses USSD.
This guide will cover integrating Hover into your existing app to accept payments. We will integrate a mobile money payment method, install the Hover SDK into an app, and process the payment confirmation. If you don’t already have an app you can fork our sample starter app.
The prerequisites are fairly basic:
- You can set up an account to receive the money. This can be any type of account: phone number, merchant till, or pay bill. If you have a working SIM that can send and receive money then you are good to go, no special agreement with the operator required!
- The mobile money provider has a USSD or SIM Toolkit menu system.
- You have an app that is installed via the Play Store or APK download. It can be native Java or Kotlin, React, Flutter or other cross platform framework. PWAs and basic mobile sites won’t work.
That’s it! Once the Hover SDK is integrated into your app you can start the payment flow when the user clicks a button, receives a notification, or any other trigger you choose. The user will be asked to confirm the details (such as amount and recipient) and enter their PIN, much like they would for a credit card or Paypal purchase.
Set up your in-app payments
We are going to set up a simple example of users in Tanzania buying a pair of shoes using Vodacom mobile money. We have a working Vodacom Tanzania SIM card registered on MPESA and a simple native Android app. When a user clicks a purchase button it will start the transaction with Hover and then our app will show them a confirmation if their purchase is successful.
Integrate the mobile money service
We are going to need a Hover account, so we sign-up for free and confirm our email. Once in the dashboard we need to add our app which will give us an API key we use later:
The package name must match the applicationId
in the app’s app/build.gradle
. You can leave the webhook blank. Next we need to create an “action” which is an end-to-end USSD flow. Our action will be Vodacom to Vodacom send money. Click the Actions tab:
Then click “+ New Action”:
We will name our action “Vodacom Tanzania Payment” and select the correct country and network:
Now we need to know what the USSD flow is on Vodacom in Tanzania. Since we have the SIM card we use our phone app to dial its short-code *150*00#
and then go through the steps to complete a payment. Since we are just getting started, we are going to accept money directly to our phone number. Later, if we decide to sign-up for pay bill we can change this configuration and it will automatically update for all our users without them having to update their app.
This is the flow for sending money to a Vodacom phone number from Vodacom TZ:
So we enter this flow in our form:
Note that we are essentially hard-coding the recipient number (ourselves) here. We won’t be able to change it at run-time in our app, but we can change it by updating this configuration. However, we have made the amount a variable so that we can change it at run-time based on the product that the user is purchasing.
After saving we are ready to write some code!
Add payments to our app
First let’s install Hover in our app. We need to add the Hover repo to our root build.gradle repositories:
allprojects {
repositories {
...
mavenCentral()
maven { url "http://maven.usehover.com/releases" }
}
}
Then add the SDK to our app-level build.gradle dependencies:
dependencies {
...
implementation 'com.hover:android-sdk:1.4.3'
}
Next we grab our Hover API key from the Hover dashboard:
And add it to our app Android Manifest:
<application>
...
<meta-data
android:name="com.hover.ApiKey"
android:value="ab00804f31a1722837a225804c585213" />
</application>
Finally, we initialize Hover when our app is launched so that it can set up and download our configuration:
import com.hover.sdk.api.Hover;
... public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
Hover.initialize(this);
}
...
}
Now we are ready to run our first transaction.
Making a purchase
Our example app is just a simple e-commerce app with a list items and a purchase button for each. If this were a real service we would obviously need a shopping cart and delivery location information. Here is our interface:
When a user clicks one of the buy now buttons the following function is called:
public void makeHoverRequest(View button) {
// Get the price from your data model, not your view!
View item = (View) button.getParent();
String price = ((TextView) item.findViewById(R.id.price)).getText();
price = price.replaceAll(",", ""); Intent i = new HoverParameters.Builder(this)
.request("ff568a4e")
.extra("amount", price)
.buildIntent();
startActivityForResult(i, 0);
}
We pull the price information from the view and use it to make a Hover request. Hover shows the following screens to the user to get their permission:
Once confirmed, the phone shows a processing screen while it contacts the USSD service, and when it is finished our app gets a callback with information about the transaction. We don’t yet know if the payment is successful. For that we need to process the SMS receipt.
Processing payment receipt
To automatically process orders before distributing our products we need to confirm that the user’s payment is successful. For this head back to the Hover dashboard and create a parser. This parser uses a regular expression to check that the response message is in fact a payment confirmation and get vital details from it, such as receipt number.
In the action detail view click New Parser:
This parser is a success parser to confirm payment, so set the details as shown below. Later we may want to improve our app’s UX by creating failure parsers that check different failure cases and show user friendly messages.
If we take a look in our Android logcat we can see that the Hover SDK has helpfully logged the SMS that we received in response to our test payment from a moment ago.
After copying over the sender we need to really get our hands dirty and write that regular expression. Regex Planet is a great tool for this. Let’s copy our SMS message into the Input 1 field and check the `CASE_INSENSITIVE` and `DOTALL` boxes since the SDK uses those.
The regular expression needs to be unique enough that it isn’t going to match messages other than the one we want and it needs to account for the various variables. Please see our upcoming post on writing regex for more pointers. Ultimately this is what we come up with:
When we run it in Regex Planet we especially want to make sure that the `matches()` box says “Yes” and that each of the `group()` boxes matches the whole variable value from the message. It is easy to accidentally lose some or most of a variable, and instead only get one or two characters.
Now we can copy the regex back into our parser form and save it.
To use it in our app we implement the BroadcastReceiver which will fire when the confirmation SMS comes in. Add it to the manifest:
<receiver
android:name=".TransactionReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action
android:name="com.hover.example.ecommerce.CONFIRMED_TRANSACTION"/>
</intent-filter>
</receiver>
And then create it:
public class TransactionReceiver extends BroadcastReceiver {
public TransactionReceiver() { }
@Override
public void onReceive(Context context, Intent i) {
Transaction t = Transaction.getByUuid(i.getStringExtra("uuid"), context);
if (t != null) {
t.status = i.getStringExtra("status");
t.updateTimestamp = i.getLongExtra("update_timestamp", Utils.now());
t.save(context);
}
openActivity(context, i);
}
private void openActivity(Context c, Intent receivedIntent) {
i = new Intent(i);
i.setClass(c, PurchaseDetailActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
i.putExtra(Transaction.UUID, receivedIntent.getStringExtra("uuid");
c.startActivity(i);
}
Back on our test device we need to make sure that Hover.initialize() is called again so that it downloads our new parser. With instant run, Android Studio often shortcuts this and prevents the update, so we are just going to uninstall and re-install our app on our test device. Finally we run our test purchase and wait for confirmation via SMS…
And success! We have made our first in-app purchase using mobile money.
Unlike other in-app payment systems that take up to 30%, you keep 100% of the money from these transactions. Note: Mobile money operator’s fees still apply. You pay Hover a simple monthly amount based on the total number of transactions your users make.
If you have any questions or would like to be featured in a future case study please reach out to us at support@usehover.com