Parsing

Hover's SDK includes an easy way to help you parse out messages from USSD sessions and SMS responses. While the text of USSD sessions is always returned when you use Hover's SDK, and you can use Android APIs to get SMS responses, we want to make it as easy as possible for you to get what you need.

After you create an action in your Hover dashboard you have the option of adding parsers. When the Hover SDK recieves a USSD or SMS message which matches a parser, then the parser will set status related fields on the most recent, still pending transaction which belongs to the same action as the parser. A parser matches when it's regular expression successfully matches the message and, if it is for SMS, its SMS sender matches.

Choosing a status and reason

The status that a parser sets must be either failed, pending, or succeeded. Status reason is used alongside status to tell you quickly the reason for the state of a transaction, and it will also be used in Hover's dashboard and exports to categorize transactions. It must be unique among all the parsers for a single action.

You should generally not need to set a `pending` status, since this is the default. Only use this if you want to parse something out of a USSD message and then wait for another response. `Failed` should be used to watch for failure messages such as too low a balance to complete a transaction or an invalid recipient. You might then set status reason to "low-balance" and "invalid-recipient" respectively. `Succeeded` should be used to process confirmation messages. In this case the status reason might just be "confirmed". Since status reason must be unique across parsers within an action, if you have multiple confirmation possibilities, for example: multiple languages such as English and Swahili, then you could have "confirmed-en" and "confirmed-sw" to mark the different confirmation matches.

Writing the regex

See our blog post for more on writing regular expressions for parsers.

Your regex should be as specific as possible to prevent matching unrelated messages. However, you should also account for variation that can occur, such as ads at the end of the message. We recommend ending your regex with .* and replacing whitespace with [\s]*. The SDK uses named-groups in the regex to parse out variables and return them to you. So if you want to run a balance check and get the balance parsed out of the message, the balance in the regex might look like (?<balance>[0-9\,\.]+). Any named groups parsed out of the confirmation will show in the transaction details for that transaction in the Hover Dashboard. See below for how to get this information in-app.

Matching SMS

If you choose a message type of "SMS" and specify an SMS sender, then the SDK will watch for any SMS message from that sender and attempt to use the regular expression to match the message. If it matches, then the SMS will be assumed to be related to the most recent pending transaction for the parser's action. You can use this to match a mobile money confirmation from the operator, or you could use it to match a related SMS, for example an electricity token from the electricity provider after taking a Pay Bill action. This field is case-sensitive.

Status Description

This is an optional field that you can use to associate a user friendly message when this parser matches.

Implement the Parsed Message Receiver In-App

Add a BroadcastReceiver which receives intents with the action YOUR.PACKAGE.NAME.CONFIRMED_TRANSACTION to your Android Manifest. Make sure exported is false otherwise another app could spoof successful transactions:

<receiver
	android:name=".TransactionReceiver"
	android:enabled="true"
	android:exported="false">
	<intent-filter>
		<action android:name="app.package.name.CONFIRMED_TRANSACTION"/>
	</intent-filter>
</receiver>

Create the Receiver itself and use the intent as you need:

public class TransactionReceiver extends BroadcastReceiver {
	public TransactionReceiver() { }

	@Override
	public void onReceive(Context context, Intent intent) {
		String uuid = intent.getStringExtra("uuid");
		String confirmationCode, balance;
		if (intent.hasExtra("transaction_extras")) {
			HashMap<String, String> t_extras = (HashMap<String, String>) intent.getSerializableExtra("transaction_extras");
			if (t_extras.containsKey("confirmCode"))
				confirmationCode = t_extras.get("confirmCode");
			if (t_extras.containsKey("balance"))
				balance = t_extras.get("balance");
		}
	}
}

The intent received will contain the meta data about the transaction, such as the action, transaction uuid, and original message. The named-groups that have been parsed out are in a serialized HashMap extra called transaction_extras. It is recomended that you check that an extra is present first with extras.containsKey()

Type Extra Description
String uuid Unique Identifier for the transaction
String action_id The action id from our supported operators page
String response_message Full message used for parsing
String status "pending", "failed", or "succeeded"
String status_meaning What you specified for the latest matched parser or one of the default failed cases above
String status_description Message you specified for the latest matched parser
Int matched_parser_id Unique identifier for the parser which matched, causing this transaction to update
String message_type “ussd” or “sms”
String message_sender If SMS, the sender id from the parser form, null if USSD
String regex Regular expression you specified in the parser form
String sim_hni The Home Network Identifier (MCC + MNC) of the SIM used
Int environment 0 for normal, 1 for debug, 2 for test
Long request_timestamp Time user initiated transaction (Unix time)
Long update_timestamp Time at which the transaction last updated (SMS arrival or USSD finished)
Long (depreciated) response_timestamp Same as updated_timestamp
Hashmap<String, String> transaction_extras A HashMap object of all named groups parsed out of the response message based on your regex
String[ ] ussd_messages Array of all USSD session messages in order encountered