App Verify API - Review app best practices

This page goes over all the best practice to take into consideration for your application when designing it.

Ensure secure communication

For best effect, ensure that end user devices communicate to your server securely when initiating the App Verify API voice call. Do not store your API key on the application for communication with Telesign.

Verify the code before finalizing

You should make sure to verify the code received from the call to the device on your server before calling finalize. Avoid sending the verification code to the device for validation.

Prompt user to enter phone number of mobile device

Telesign recommends that you show a message prompting end users to enter the mobile phone number of the device on which the application is downloaded and installed, not the number of another device or landline. For example, the message might read:

"Please enter the mobile phone number of the device on which this application is installed and make sure that the cellular connection is on."

You should attempt auto verification only on mobile devices capable of receiving a circuit-switched voice call. For example, if an end user downloads your app to a tablet that can perform only data traffic, auto verification will fail.

In cases where the end user does not want to provide a mobile number, you should design your application workflow appropriately to utilize other types of non-mobile verification (such as Voice Verify API or SMS Verify API) to provide the user with an option for an alternate form of verification, along with an appropriate message.

Enter country and phone number separately

Your application should display the country code (or country name) and the phone number in separate input text boxes. Recommended layouts are to position the fields vertically on different lines, or to position them horizontally with a gap between them. Often when end users enter the country code and phone number in the same field, it results in mistakes such as users adding a preceding '0' or '+', or inserting a '0' between country code and phone number, as practiced in different countries.

Auto-extraction

Telesign recommends that your application not auto-extract phone numbers. Programmatic auto-extraction of phone numbers does not work consistently for various service providers and locales. If the auto-extraction support of phone number is provided, it is recommended that developers provide an option for the end users to edit the phone number.

Auto extraction does not work well in every country, however, it can be a nice feature to offer in your application. Auto-extraction of a phone number works reliably (80% of the time or more) in many countries.

Notify the end user they will receive a voice call

Make sure your end user is aware that they will receive a voice call for verification purposes and that they should ignore it.

Check if isVoiceCapable is true

Check if isVoiceCapable is true and if so, use the value to decide if the phone can be verified using App Verify API. If it cannot be used, your implementation can fail over to another verification method. You can also choose to create a popup on your end user's screen stating something like "Please use a device capable of Voice calls if you want to use this verification option."

Java

// Requires TargetApi Build.VERSION_CODES.LOLLIPOP_MR1
boolean isVoiceCapabale = telephonyManager.isVoiceCapabale();

## Tell users to omit non-numerals from phone numbers

You should instruct end users to enter their phone number without spaces, dashes, or special characters, because phone number formatting varies by country. Your application should prevent end users from entering their phone number in a formatted way.

## Best practices for phone number formatting
When you pass mobile phone numbers, you must follow strict formatting rules in order for the Telesign server to be able to verify the number. You must normalize the phone number prior to submitting it to the auto verification service.

Telesign accepts phone numbers in the [E.164 format](https://en.wikipedia.org/wiki/E.164), which includes country codes, area codes, and phone number (number string with no spaces, dashes, and so on). For example:

* 13101234567 is normalized from 1(310)123-4567 (United States)
* 447981897555 is normalized from +44-7981-897555 (United Kingdom)

Allow the user to input the phone number.

You must normalize the phone number prior to submitting for processing by doing the following:
* Use regular expressions to strip characters.
* Ensure that there are no characters, such as "," and spaces.

For more information on phone number formatting for Android, see [PhoneNumberUtils](http://developer.android.com/reference/android/telephony/PhoneNumberUtils.html) in the Android Developer Reference.

Telesign recommends that developers allow end users to input the phone number directly in the application. 

## Handling duplicate verification requests
Ensure that a duplicate verification request for the same number is not sent to Telesign for verification when there is an on-going request. For example, the application should not call Telesign API methods to trigger a duplicate verification process. The request should be either a success/failure/timeout which gets returned to the application. You should disable or hide the button which is provided to the end user to trigger the Auto Verification process after the verification process is already triggered. This is to prevent duplicate verification requests originating from the application.

## Tips for cleansing caller ID/CLI

This section provides code samples and information about cleansing an incoming caller ID/Calling Line Identification (CLI) to ensure a greater chance that it will be correctly recognized by your application. 

Telecom providers may add extra digits or characters when sending country code or phone number information. For example, they may prepend +, 0, or 00 to the caller id along with country code that is shown on the mobile phone. They might remove the country code and display only the number, or append additional digits at the end of caller id in rare cases. To handle these situations, do the following: 

1. Sanitize the incoming number by removing any white spaces, special characters, non digits, or leading 0s. You can review the sample code for an example of how you might handle this. 

**Example Caller ID Cleansing Code** 
```java
/***
* Create a sanitized version of a raw phone number using some simple rules:
* Strip any leading characters in the set {'+', '0', '0'}
* Strip out all ' ' characters anywhere in the string.
*
* @param original PhoneNumber The raw phone number retrieved from the runtime or entered * by a User.
* @return The sanitized phone number
*/

String mkSanitizedPhoneNumber(String originalPhoneNumber) {

    try {
        return originalPhoneNumber
                // strip any non digits such as +, whitespace and any other phone number formatting
                .replaceAll("\\D", "")
                // strip any leading 0's
                .replaceFirst("\\A0+", "");

    } catch (Exception e) {
        logger.w(TAG, "Unable to mkSanitizedNumber: ", e);
        return originalPhoneNumber;
    }
}
  1. Check that the sanitized phone number contains the prefix as a substring and retrieve the subsequent digits as the verification code. The reason Telesign suggests checking for a substring match and not an exact prefix match is due to minor CLI mutations performed by downstream providers and carriers to the head or tail of the incomingNumber (in addition to those addressed in the first step). To achieve this and also parse out the verification code,use a regular expression as follows (prefix=”4478730” and CODE_LENGTH=5).

Check for prefix and retrieve verification code

String parseChallengeCode(String sanitizedPhoneNumber, String prefix) {

    String challengeCode = null;

    if (sanitizedPhoneNumber != null) {

        String pattern = String.format(Locale.US, "\\A(.*)(%s)([0-9a-z]{%s})(.*)\\z",
                prefix, CODE_LENGTH);

        try {
            Pattern r = Pattern.compile(pattern);
            Matcher m = r.matcher(sanitizedPhoneNumber);

            if (m.find()) {
                challengeCode = m.group(3);
            }

        } catch (Exception e) {
            logger.e(TAG, "", e);
        }
    }

    return challengeCode;