MPP Android SDK

Provides API for In-App Push Provisioning functionality on Android devices.

Requirements

  • Agreement with Google granting permission to use the Google Pay API for Push Provisioning.
  • App package name and SHA-256 certificate fingerprint whitelisted by Google.
  • The device must be able to connect to the Internet.
  • Android version must be 5.0 (Lollipop) or above.

 

Installation

It is recommended to use Android Studio and Gradle to build the project.

Gradle Configuration

MPP library should be added to the project as a dependency. MPP library is hosted in a private Maven repository, so you need to configure build.gradle by setting the assigned URL and credentials.

Environments (library flavors):

  • test – test (staging) environment
  • prod – production environment
				
					repositories {
    maven {
        url 'https://nexus-developer.meawallet.com/content/groups/<user>-group'

        credentials {
            username '<user>-user'
            password '<password>'
        }
    }
}

dependencies {
    ...
    implementation 'com.meawallet:mpp-<user>-<environment>:<version>'
    ...
}				
			

Example

Debug version:

				
					implementation 'com.meawallet:mpp-mea-test:1.1.0-debug'				
			

Release version:

				
					implementation 'com.meawallet:mpp-mea-test:1.1.0'				
			

App Manifest

No need to specify any permissions for SDK in AndroidManifest.xml file. A special marker tools:overrideLibrary can be used with uses-sdk declaration to override importing a library whose minimum SDK version is above the application’s minimum SDK version. Without such a marker, the manifest merger will fail. The marker will allow users to select which libraries can be imported ignoring the minimum SDK version.

MPP library is using the following permissions which are merged with the application manifest file:

				
					<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>				
			

Enabling issuer app for Google Pay Push Provisioning

Google grants access to the Push Provisioning API only to participating financial institutions. Therefore, issuer apps need to be whitelisted before they can call the API: Google Pay – Issuers – Android Push Provisioning API – Whitelist your app

… if Google Pay has not yet launched in your country, you need to test with the special ‘Alienfood’ version of the Google Pay app: Google Pay – Issuers – Get the Google Pay app

To request access to Google Pay documentation, use the following links:


Google Pay push provisioning guide

Before starting implementation you should have completed the installation of the MPP library.

The MPP library helps the Issuers with Google Pay Push Provisioning API implementation. Google Pay Push Provisioning API lets issuers provision cards to Google Pay and perform common actions like setting the default payment token and deleting a token from within the Issuer banking application.

Sequence diagram

Push Provisioning implementation approaches

Android MPP SDK provides 2 main approaches for Google Pay Push Provisioning implementation:

  • MeaPushProvisioning.GooglePay helper interface simplifies Google Pay Push Provisioning API usage and implementation.
  • Directly using Tokenization Data with Opaque Payment Card (OPC) allows to implement push provisioning flow using Google Pay Push Provisioning API, which allows developers to have more control over implementation, however, requires more effort.

Guide for encryptedCardData generation can be found in the How-To section.

GooglePay helper interface

MeaPushProvisioning.GooglePay helper interface provides the following methods to interact with Google Pay wallet:

  • pushCard() – initiates push provisioning flow.
  • requestTokenSelectDialog – opens a dialog asking the user’s confirmation to set the passed Google Pay token as selected (default) card in the Google Pay wallet.
  • requestTokenDeleteDialog – opens a dialog asking the user’s confirmation to delete the passed Google Pay token from the Google Pay wallet.
  • handleOnActivityResult() – mandatory method if any of the 3 methods above are being used.

  • checkWalletForCardToken – checks for Google Pay token presence and info in the active Google Pay wallet using card data. This method requires a network connection.

  • checkWalletForToken – checks for Google Pay token presence and info in the active Google Pay wallet using particular token data.

MeaPushProvisioning.GooglePay relies on the Google TapAndPay library.

Card data parameters

Push provisioning flow is started by initializing MppCardDataParameters object with CardIdCardSecret or EncryptedPan.

Initialize MppCardDataParams.

				
					String cardId = "<value>";
String cardSecret = "<value>";

MppCardDataParameters cardParams = MppCardDataParameters.withCardSecret(cardId,
                                                                        cardSecret));				
			

or

				
					String encryptedCardData = "<value>";
String publicKeyFingerprint = "<value>";
String encryptedKey = "<value>";
String initialVector = "<value>";

MppCardDataParameters cardParams = MppCardDataParameters.withEncryptedPan(encryptedCardData,
                                                                          publicKeyFingerprint,
                                                                          encryptedKey,
                                                                          initialVector));				
			

Initialize and push provision card

First, the issuer app should initialize MeaPushProvisioning instance.

				
					if (!MeaPushProvisioning.isInitialized()) {
    MeaPushProvisioning.initialize(this);
}				
			

When library is initialized, issuer app can push provision card using MeaPushProvisioning.GooglePay.pushCard(...) and MppCardDataParameters. This method checks the state of Google Pay wallet and creates a new instance when necessary. Backend generated opaque payment card (OPC) is received, and if the specific card is not added to Google Pay wallet already, it pushes the card to the Google Pay wallet via Google Push Provisioning API.

				
					MeaPushProvisioning.GooglePay.pushCard(cardParams,
                                    "My Card",
                                    userAddress,
                                    getActivity(),
        new MppPushCardToGooglePayListener() {
                @Override
                public void onSuccess(String tokenReferenceId,
                                    String cardLastFourDigits, 
                                    MppPaymentNetwork cardNetwork){
                    ...
                }

                @Override
                public void onFailure(MppError mppError,
                                    int tapAndPayStatusCode){
                    ...
                }
        });				
			

Handle Google Pay result callbacks

Google Pay push provisioning results are returned through the Activity.onActivityResult(int, int, Intent) method. Application should forward these intermediate results to the MeaPushProvisioning.GooglePay.handlePushCardOnActivityResult(int, int, Intent, Activity) method. The final result of push provisioning is returned to MppPushCardToGooglePayListener callback.

				
					@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (MeaPushProvisioning.GooglePay.handleOnActivityResult(requestCode, resultCode, data, this)) {
        // handled by MPP SDK, no action needed
    } else {
        // Optionaly handle results for other request codes.
    }
}				
			

Handle Google Pay data changed events

Registering for data changed events allows an issuer app to re-query information about their digitized cards whenever the user makes a change in Google Pay wallet.

MPP SDK will immediately call an issuer app callback whenever the following events occur:

  • The active wallet changes (by changing the active account).
  • The selected card of the active wallet changes.
  • Tokenized cards are added or removed from the active wallet.
  • The status of a token in the active wallet changes.
GooglePayDataChangedListener

Only foreground applications will be notified of the data changed events. Therefore, each application should update the token statuses not only by receiving GooglePayDataChangedListener, but also when the application launches or returns to the foreground.

				
					GooglePayDataChangedListener listener = new GooglePayDataChangedListener() {
    @Override
    public void onDataChanged() {
        // reload data in UI
    }
};

MeaPushProvisioning.registerDataChangedListener(listener);				
			

Stop listening data changed events by removing GooglePayDataChangedListener.

				
					MeaPushProvisioning.removeDataChangedListener(listener);				
			

Add to Google Pay button

The Add to Google Pay button is used exclusively to initiate the Google Pay card provisioning flow from an issuer app.
The “Add to Google Pay” are available as resizable bitmaps (NinePatch files) suitable for including in your layout: Download Assets.

Show or hide Add to Google Pay button

The app is responsible to check and decide if “Add to Google Pay” should be shown or hidden for the user. The button should be shown only when the card is not added to Google Pay already.

MPP SDK provides 2 methods to check if the corresponding card for a token is available in Google Pay active wallet:

  • MeaPushProvisioning.GooglePay.checkWalletForCardToken(MppCardDataParameters cardData, GooglePayTokenListener listener) – using card data, requires a network connection.
  • MeaPushProvisioning.GooglePay.checkWalletForToken(MppPaymentNetwork paymentNetwork, String tokenId, GooglePayTokenListener listener) – using pre-fetched token data.

If card exists in Google Pay wallet, both methods return GooglePayTokenInfo that contains information about the specific Google Pay token, use getTokenId()getTokenState()getPaymentNetwork() and isSelectedAsDefault() methods to get the values.

The issuer app should hide the “Add to Google Pay” button when the card exists in the Google Pay wallet. If methods above return null, the issuer app should show the “Add to Google Pay” button.

Use GooglePayTokenInfo.getTokenState() to get additional info about the token state.

Managing default NFC payment app

Issuer app can check if Google Pay is set as the default NFC payment app after push provisioning a card. This allows users to pay with Google Pay using their new cards.

Check if Google Pay is set as the default NFC payment app:

				
					boolean result = MeaPushProvisioning.GooglePay.isDefaultPaymentApplication(getContext());				
			

Set Google Pay as default NFC payment app:

				
					MeaPushProvisioning.GooglePay.setAsDefaultPaymentApplication(getActivity(), SET_DEFAULT_PAYMENTS_REQUEST_CODE);				
			

Testing in sandbox mode

By default, Google Pay works in production mode with real payments. During development and pre-production testing, you can reconfigure Google Pay to work in sandbox mode by placing a special file on your device. Once connected to the sandbox, requests will be routed to Google’s sandbox environment which connects to the TSP’s sandbox environment.

Working in sandbox mode: Google Pay sandbox mode

Use adb command to toggle sandbox mode. To turn sandbox mode on, add an empty file and reboot:

$ adb shell touch /sdcard/Download/android_pay_env_override_sandbox
$ adb reboot

To switch back to production mode, delete the file and reboot the device:

$ adb shell rm /sdcard/Download/android_pay_env_override_sandbox
$ adb reboot

Troubleshooting

In case you are encountering problems when pushing the card to Google Pay, please prepare following information to speed up debugging process:

  1. Provide video to see exactly after which screen in the Google Pay app provisioning stops.
  2. Enable additional OPC debugging by submitting a request to Google to add a tester user account to OPC debugging allowlist. (Additional OPC logs are available both for sandbox and production.)
    1. https://developers.google.com/pay/issuers/apis/push-provisioning/android/push-provisioning-objects#troubleshooting_opc_errors
  3. Provide device logs with both MPP-SDK (filter by MPP-SDK) logs and Google Pay logs (filter by TapAndPay and TokenizePanChimeraActiv).

Directly using Tokenization Data with Opaque Payment Card (OPC) for Google Pay

By directly using Tokenization Data developers can implement push provisioning flow using Google Pay Push Provisioning API, which allows developers to have more control over implementation, however requires more effort.
MPP SDK provides opaque payment card (OPC) with MeaPushProvisioning.getGooglePayTokenizationData(...) method.

				
					MeaPushProvisioning.getGooglePayTokenizationData(
        cardParams,
        "wallet-id-12345",
        "device-id-12345",
        this,
        new MppGetOemTokenizationDataListener() {

            @Override
            public void onSuccess(String opaquePaymentCard,
                                  String lastFourDigits,
                                  MppPaymentNetwork paymentNetwork) {
                ...
            }

            @Override
            public void onFailure(MppError mppError) {
                ...
            }
        });				
			

or

				
					MppGetOemTokenizationDataResponseData responseData = MeaPushProvisioning
        .getGooglePayTokenizationData(
                        cardParams,
                        "wallet-id-12345",
                        "device-id-12345",
                        this);

String opaquePaymentCard = responseData.getOpaquePaymentCard();
String lastFourDigits = responseData.getLastFourDigits();
MppPaymentNetwork paymentNetwork = responseData.getPaymentNetwork();				
			

Use OPC data for Google Pay Push Provisioning API implementation:


 

Directly using Tokenization Data with Opaque Payment Card (OPC) for Samsung Pay

By directly using Tokenization Data developers can implement push provisioning flow using Samsung Pay Push Provisioning API, which allows developers to have more control over implementation, however requires more effort.
MPP SDK provides opaque payment card (OPC) with MeaPushProvisioning.getSamsungPayTokenizationData(...) method.

				
					MeaPushProvisioning.getSamsungPayTokenizationData(
    cardParams,
    "wallet-id-12345",
    "device-id-12345",
    this,
    new MppGetOemTokenizationDataListener() {

        @Override
        public void onSuccess(String opaquePaymentCard,
                                String lastFourDigits,
                                MppPaymentNetwork paymentNetwork) {
            ...
        }

        @Override
        public void onFailure(MppError mppError) {
            ...
        }
    });				
			

or

				
					MppGetOemTokenizationDataResponseData responseData = MeaPushProvisioning
        .getSamsungPayTokenizationData(
            cardParams,
            "wallet-id-12345",
            "device-id-12345",
            this);

String opaquePaymentCard = responseData.getOpaquePaymentCard();
String lastFourDigits = responseData.getLastFourDigits();
MppPaymentNetwork paymentNetwork = responseData.getPaymentNetwork();				
			

Third-party wallet providers push provisioning guide

Before starting implementation you should have completed the installation of the MPP library.

The push provisioning to third-party wallets provides an improved experience for cardholders, issuers and Digital Wallet Providers by allowing issuer mobile applications to push customer’s PAN data securely to participating third-party Wallet Providers.

The MPP library enables push provisioning to both Mastercard MDES Token Connect and Visa VTS Push Provisioning using one API.

Initialization

Before you can use the MPP library in your application, you must initialize it MeaPushProvisioning.initialize(Context context). The application should initialize the library only once during its lifetime.

Get Token Requestors

First, the Issuer has to retrieve information about Token Requestors that are enabled for their account ranges. This information can be used to create a list of Token Requestors for the User.

There are two functions for the Issuer to use for building the list:

  • MeaPushProvisioning.getTokenRequestors(List accountRanges) : to retrieve information such as Token Requestor type, user-friendly name, available user interfaces (Android/iOS app, web).
  • MeaPushProvisioning.getAsset(String assetId): to retrieve the image (logo) associated with the Token Requestor. In case of Mastercard MDES the supplied images are square with a white background. For each Token Requestor, MDES supplies the logo in two formats: .svg (rescalable) and .png (192 x 192 pixels).

The User Interface should filter out the Token Requestors that are not applicable, for example, Token Requestors with an inappropriate user interface.

Sync example:

				
					List<String> accountRangesList = Arrays.asList("512345678901", "512345678902", "512345678903");
List<MppTokenRequestor> tokenRequestors = MeaPushProvisioning.getTokenRequestors(accountRangesList);				
			

Async example:

				
					List<String> accountRangesList = Arrays.asList("512345678901", "512345678902", "512345678903");
MeaPushProvisioning.getTokenRequestors(accountRangesList, new MppGetTokenRequestorsListener() {
    @Override
    public void onSuccess(List<MppTokenRequestor> list) {
        ...
    }

    @Override
    public void onFailure(@NonNull MppError mppError) {
        ...
    }
});				
			

Get Tokenization Receipt

When the User has selected the target Token Requestor as well as the sourcing card(s), application has to invoke MeaPushProvisioning.getTokenizationReceipt(String tokenRequestorId, MppCardDataParameters cardData) method.

Card data can be provided in two ways – MppCardDataParameters.withCardSecret(...)MppCardDataParameters.withEncryptedPan(...).

				
					MppCardDataParameters cardDataWithCardSecret =
        MppCardDataParameters.withCardSecret("4C2044415441202D2074686", "41202D207468");

MppCardDataParameters cardDataWithEncryptedPan =
        MppCardDataParameters.withEncryptedPan(encryptedCardData, publicKeyFingerprint, encryptedKey, initialVector);				
			

The response will include a receipt (pushAccountReceipt) representing the card/account to be pushed.

Sync example:

				
					MppCardDataParameters cardDataParameters =
        MppCardDataParameters.withCardSecret("4C2044415441202D2074686", "41202D207468");
MppGetTokenizationReceiptResponseData responseData =
        MeaPushProvisioning.getTokenizationReceipt("12345678901", cardDataParameters);

String pushAccountReceipt = responseData.getPushAccountReceipt();
List<MppAvailablePushMethod> pushMethods = responseData.getAvailablePushMethods();				
			

Async example:

				
					MppCardDataParameters cardDataParameters =
        MppCardDataParameters.withCardSecret("4C2044415441202D2074686", "41202D207468");
MeaPushProvisioning.getTokenizationReceipt("12345678901",
                                           cardDataParameters, 
                                           new MppGetTokenizationReceiptListener() {
    @Override
    public void onSuccess(String pushAccountReceipt, List<MppAvailablePushMethod> list) {
        ...
    }

    @Override
    public void onFailure(@NonNull MppError mppError) {
        ...
    }
});				
			

Send user to Token Requestor (deep-linking)

To send User to the Token Requestor the issuer has to use the pushAccountReceipt instead of the original card/account data to request tokenization.

Additionally to pushAccountReceiptMeaPushProvisioning.getTokenizationReceipt(...) response includes list of push methods supported by the Token Requestor and their URI for redirecting the user.

Response list can hold up to 3 URIs – with a minimum of 1 URI:

  • One URI for the Token Requestor’s Android app.
  • One URI for the Token Requestor’s iOS app.
  • One URI for the Token Requestor’s web browser experience.

Issuer must respect specific rules when selecting the URI where they will send the consumer. Because Android or iOS mobile application provide a better mobile experience than the web browsers, Issuers should always try and direct the consumer to the Android or iOS application of the Token Requestor, when possible. If the Android or iOS app URI is supplied, the web browser should remain a backup solution only.

The MPP library provides a helper method MeaPushProvisioning.sendUserToTokenRequestor(...) for handling user redirect to the right Token Requestor URI.

Method has parameters to provide both an application URI and WEB URI, if an application URI is provided it will check if it is safe to send user to this Token Requestor application, else if it is not safe or if application URI is not provided, method will redirect user to the WEB URI. In any case, if additional URI parameters are provided (pushAccountReceiptParametercallbackUrlParametercompleteIssuerAppActivationParametercompleteWebsiteActivationParameter), method will build URI by appending them to final URI used for the redirect.

Receive response from Token Requestor

If callbackUrlParameter is provided in the redirect to the Token Requestor, the response can include a map of results for the tokenization attempts.

The resulting URI called by the Token Requestor is: moonbank://pushcallback?results[MCC-C307F0AE-298E-48EB-AA43-A7C40B32DDDE]=APPROVED|DWSPMC000000000132d72d4fcb2f4136a0532d3093ff1a45

The Issuer should use the response from the Token Requestor to display relevant messaging to the User, as well as to update their Issuer’s back-end information if needed.


 

Changelog

1.2.1

2021-04-19

MODIFIEDUpdated TapAndPay client from 17.0.1 to 17.1.0.

1.2.0

2021-02-15

ADDEDListener interfaces:

  • GooglePayDataChangedListener

ADDEDMethods:

  • MeaPushProvisioning.GooglePay.registerDataChangedListener(GooglePayDataChangedListener
  • MeaPushProvisioning.GooglePay.removeDataChangedListener(GooglePayDataChangedListener)
  • MeaPushProvisioning.getGooglePayTokens(MppCardDataParameters, String, String, Context)
  • MeaPushProvisioning.getGooglePayTokens(MppCardDataParameters, String, String, Context, MppGetTokensListener)
  • MeaPushProvisioning.getSamsungPayTokens(MppCardDataParameters, String, String, Context)
  • MeaPushProvisioning.getSamsungPayTokens(MppCardDataParameters, String, String, Context, MppGetTokensListener)

1.1.0

2020-10-20

ADDEDClasses:

  • MppBillingAddress
  • GooglePayTokenInfo
  • GooglePayTokenState

ADDEDListener interfaces:

  • GooglePayTokenListener
  • GooglePayTokenDeleteListener
  • GooglePayTokenSelectListener

ADDEDMethods:

  • MppError.getGooglePayErrorCode()
  • MeaPushProvisioning.GooglePay.handleOnActivityResult(int, int, Intent, Activity)
  • MeaPushProvisioning.GooglePay.checkWalletForCardToken(MppCardDataParameters, GooglePayTokenListener)
  • MeaPushProvisioning.GooglePay.checkWalletForToken(MppPaymentNetwork, String, GooglePayTokenListener)
  • MeaPushProvisioning.GooglePay.requestTokenDeleteDialog(Activity, GooglePayTokenInfo, GooglePayTokenDeleteListener)
  • MeaPushProvisioning.GooglePay.requestTokenSelectDialog(Activity, GooglePayTokenInfo, GooglePayTokenSelectListener)
  • MppBillingAddress getBillingAddress() and List getTokensIdList() to MppGetOemTokenizationDataResponseData object

ADDEDParameters:

  • @Nullable MppBillingAddress billingAddress and @Nullable List tokensIdList to MppGetOemTokenizationDataListener.onSuccess() callback

ADDEDError codes:

  • GOOGLE_PAY_ERROR (701)
  • GOOGLE_PAY_TOKEN_NOT_FOUND (702)
  • GOOGLE_PAY_TOKEN_ALREADY_EXISTS (703)

MODIFIEDcompileSdkVersion/targetSdkVersion updated to API 30 (Android 11)
MODIFIEDminSdkVersion updated to API 21 (Android 5.0)
MODIFIEDonFailure() callback method of MppPushCardToGooglePayListener no longer has a second parameter Integer tapAndPayStatusCodetapAndPayStatusCode value now can be accessed using MppError.getGooglePayErrorCode() method
MODIFIEDDeprecated methods MeaPushProvisioning.GooglePay.isPushCardRequestCode() and MeaPushProvisioning.GooglePay.handlePushCardOnActivityResult()
MODIFIEDNullability Annotation improvements
MODIFIEDMppException can be thrown now for MeaPushProvisioning.isDefaultPaymentApplication() method
MODIFIEDMppException can be thrown for all methods where MppInitializationFailedException or MppNotInitializedException was thrown before

REMOVEDMppInitializationFailedException and MppNotInitializedException classes

1.0.1

2020-03-17

MODIFIED Added deviceId parameter for following methods: MeaPushProvisioning.getGooglePayTokenizationData()
MeaPushProvisioning.getSamsungPayTokenizationData()

1.0.0

2020-01-30

MODIFIED Updated Android compileSdkVersion and targetSdkVersion to API 29.
MODIFIED Updated Google TapAndPay library version to 17.0.1Migration checklist from Google
MODIFIED Updated GSON library version to 2.8.6.
MODIFIED Migrated from Android Support Annotations 28.0.0 library to AndroidX Annotation 1.0.0 library.
MODIFIED MeaPushProvisioning.GooglePay.isPushCardRequestCode() method now throws MppNotInitializedException.

REMOVED MeaPushProvisioning.getPaymentAppInstanceId(Context) method.
REMOVED GoogleApiClient googleApiClient parameter from MeaPushProvisioning.GooglePay.pushCard() method due to changes in Google’s TapAndPay library.
REMOVED GoogleApiClient googleApiClient parameter from MeaPushProvisioning.GooglePay.handlePushCardOnActivityResult() method due to changes in Google’s TapAndPay library.

0.4.0

2019-07-11

Public stable version of MeaWallet Push Provisioning Android SDK.

On this page