Skip to main content

Implementation Guide

Before starting implementation you should have completed Installation of the MPP React Native.

MPP React Native

Android

Google Pay

MPP React Native component helps 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 card and deleting a card from within Issuer banking application.

info

For more details about Google Pay Push Provisioning workflow refer to MPP SDK Android documentation.

Samsung Pay

MPP React Native component helps Issuers with Samsung Pay Push Provisioning API implementation. Samsung Pay Push Provisioning API lets Issuers provision cards to Samsung Pay and perform common actions like setting the default payment card and deleting a card from within Issuer banking application.

iOS

MPP React Native component helps Issuers with Apple Pay Push Provisioning API implementation. Apple Pay Push Provisioning API lets Issuers provision cards to Apple Pay.

info

For more details about Apple Pay Push Provisioning workflow refer to MPP SDK iOS documentation.

Main Interface

Initialize

To begin Issuer app should initialize MeaPushProvisioning instance.

import MeaPushProvisioning from '@meawallet/react-native-mpp';

// ...

MeaPushProvisioning.initialize()
.then(() => console.log("Success"))
.catch((error) => console.error("Error: " + error));

Card Data Parameters

Push provisioning flow is started by initializing MppCardDataParameters object with CardId, CardSecret or EncryptedPan. After initializing card data parameters push provisioning can be started with push card method.

Card ID & Secret
import { MppCardDataParameters } from '@meawallet/react-native-mpp';

// ...

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

const cardParams = MppCardDataParameters.withCardSecret(cardId, cardSecret);
EncryptedCardData
import { MppCardDataParameters } from '@meawallet/react-native-mpp';

// ...

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

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

Guide for encryptedCardData generation can be found in Card Data Encryption manual.

Loading Configuration

By default MPP SDK is loading mea_config configuration file, however a custom name can be used. When defining a custom name for the configuration file use MeaPushProvisioning.Configuration.loadConfig(string) to load the configuration. Configuration file should be placed in application resources res/raw folder.

MeaPushProvisioning.Configuration.loadConfig("custom_config_name")
.then(() => console.log("Success"))
.catch((error) => console.error("Error: " + error));
info

MPP SDK throws exception if configuration file is missing, broken or otherwise fails to load.

Apple Pay

Initialize Apple Pay In-App Provisioning

MPP React Native provides MeaPushProvisioning.ApplePay.initializeOemTokenization(cardDataParameters: MppCardDataParameters) method to initiate Apple Pay In-App provisioning.

Check if the payment card can be added to Apple Pay by using primaryAccountIdentifier field in response. Go to Show or hide "Add to Apple Wallet" button.

info

primaryAccountIdentifier
1. Value is always empty for the very first push provisioning of the specific card. Empty value indicates that card can be added to Apple Pay.
2. Users may have different passes installed on different paired devices (for example, on an iPhone and an Apple Watch). This property allows to filter out the devices that already contain a matching pass.
3. Once the value is fetched for a specific card app should cache primaryAccountIdentifier to avoid unnecessary MeaPushProvisioning.initializeOemTokenization calls every time when Add to Apple Wallet button should be shown or hidden.

let isPassLibraryAvailable = await MeaPushProvisioning.ApplePay.isPassLibraryAvailable();
let canAddPaymentPass = await MeaPushProvisioning.ApplePay.canAddPaymentPass();
if (isPassLibraryAvailable && canAddPaymentPass) {
try {
let tokenizationData = await MeaPushProvisioning.ApplePay.initializeOemTokenization(cardData);
if (!tokenizationData.primaryAccountIdentifier || await MeaPushProvisioning.ApplePay.canAddPaymentPassWithPrimaryAccountIdentifier(tokenizationData.primaryAccountIdentifier)) {
// TODO: Show "Add to Apple Wallet" button.
}
} catch (exception) {
// Handle error
console.log("initializeOemTokenization() error: " + exception);
}
}

Add to Apple Wallet Button

To create an Add to Apple Wallet button, use MeaPushProvisioning.ApplePay.AddPassButton control that provides wrapper for iOS PKAddPassButton class.

import MeaPushProvisioning from '@meawallet/react-native-mpp';

//...

<MeaPushProvisioning.ApplePay.AddPassButton
addPassButtonStyle = "black-outline"
onPress = { () => {
// TODO:
// Push card to Apple Wallet
} }
/>

PKAddPassButton

Caching PrimaryAccountIdentifier

App should cache primaryAccountIdentifier value for the specific card to avoid unnecessary MeaPushProvisioning.ApplePay.initializeOemTokenization calls every time when Add to Apple Wallet button should be shown or hidden.

PrimaryAccountIdentifier

Show or Hide Add to Apple Wallet Button

App is responsible to check and decide if "Add to Apple Wallet" should be shown or hidden for the user using primaryAccountIdentifier or primaryAccountNumberSuffix. Using primaryAccountNumberSuffix is useful when Customer Service API backend connection is not available. Button should be shown only when card is not added to Apple Pay already.

Use the following methods to check whether the card with specific primaryAccountIdentifier can be added to Apple Wallet:

  • MeaPushProvisioning.ApplePay.canAddPaymentPassWithPrimaryAccountIdentifier(string) (before iOS 13.4)
  • MeaPushProvisioning.ApplePay.canAddSecureElementPassWithPrimaryAccountIdentifier(string) (iOS 13.4+)

Use the following methods to check whether the card with specific primaryAccountNumberSuffix can be added to Apple Wallet:

  • MeaPushProvisioning.ApplePay.canAddPaymentPassWithPrimaryAccountNumberSuffix(string) (before iOS 13.4)
  • MeaPushProvisioning.ApplePay.canAddSecureElementPassWithPrimaryAccountNumberSuffix(string) (iOS 13.4+)

Return value indicates whether the app can add a card to Apple Pay for the provided primary account identifier. This function does not provide specific information about Apple Wallet on iPhone or Apple Watch.

Check if Card Can Be Added to Apple Wallet on iPhone or Apple Watch

info

Read further only when app needs to detect if PKPaymentPass or PKSecureElementPass can be added specifically to Apple Wallet on iPhone or Apple Watch. Use for Apple Watch only when it is paired to iPhone.

1. Use one of the methods listed above to check whether the card can be added to Apple Wallet on iPhone or Apple Watch. Return value of the function indicates if card can be added, however it does not provide specific information about Apple Wallet on iPhone or Apple Watch.
2. Detect if Apple Watch is paired with iPhone.

3. Check if card is already added to Apple Wallet on iPhone or Apple Watch:

  • Apple Wallet on iPhone:
// Before iOS 13.4
let cardExists = await MeaPushProvisioning.ApplePay.paymentPassExistsWithPrimaryAccountIdentifier("<primaryAccountIdentifier>")
let cardExists = await MeaPushProvisioning.ApplePay.paymentPassExistsWithPrimaryAccountNumberSuffix("4321")

// iOS 13.4+
let cardExists = await MeaPushProvisioning.ApplePay.secureElementPassExistsWithPrimaryAccountIdentifier("<primaryAccountIdentifier>")
let cardExists = await MeaPushProvisioning.ApplePay.secureElementPassExistsWithPrimaryAccountNumberSuffix("4321")
  • Apple Watch:
// Before iOS 13.4
let cardExists = await MeaPushProvisioning.ApplePay.remotePaymentPassExistsWithPrimaryAccountIdentifier("<primaryAccountIdentifier>")
let cardExists = await MeaPushProvisioning.ApplePay.remotePaymentPassExistsWithPrimaryAccountNumberSuffix("4321")

// iOS 13.4+
let cardExists = await MeaPushProvisioning.ApplePay.remoteSecureElementPassExistsWithPrimaryAccountIdentifier("<primaryAccountIdentifier>")
let cardExists = await MeaPushProvisioning.ApplePay.remoteSecureElementPassExistsWithPrimaryAccountNumberSuffix("4321")

Pay with Apple Pay Button

When card is added to Apple Wallet, instead of hiding Add to Apple Wallet button the app can show Pay with Apple Pay button, tapping the button can present a specific card for payment. Use PKPassLibrary.present(pass: PKSecureElementPass) to select the card for payment.

To create an Add to Pay with Apple Pay button, use MeaPushProvisioning.ApplePay.PaymentButton control that provides wrapper for iOS PKPaymentButton class.

import MeaPushProvisioning from '@meawallet/react-native-mpp';

//...

<MeaPushProvisioning.ApplePay.PaymentButton
paymentButtonType = "in-store"
addPassButtonStyle = "black"
onPress = { () => {
// ...
} }
/>

PKPaymentButton

Complete Apple Pay In-App Provisioning

For completion of provisioning React Native MPP provides showAddPaymentPassView(initializeOemTokenizationResponseData: MppInitializeOemTokenizationResponseData) method. This method exchanges Apple certificates and signature with Issuer Host and prompts the user to add pass to the Apple Wallet.

Method returns Promise that resolves to a MppPassActivationState to inform you if request has succeeded or failed.

MeaPushProvisioning.ApplePay.showAddPaymentPassView(tokenizationData)
.then((activationState)=> {
// Push Provisioning success, check `activactionState` for more info
})
.catch(error => {
// Handle error
});
info

Adding payment passes requires a special entitlement issued by Apple, see MPP SDK Installation Step 6.

In-App Verification

Apple Pay In-App Verification provides a credit or debit card issuer the means to utilize its iOS mobile app for the verification of users and activation of a payment pass previously provisioned via Apple Wallet.

Issuers can implement In-App Verification using one of the two methods:

  • Obtaining activation data with cryptographic OTP and passing to Apple Wallet
  • Server-side activation

Activation Data with Cryptographic OTP

This method uses a cryptographic value that is generated by the issuer and is validated by TSP.

1. Initiate Activation Process

Prompt the user immediately after initial login to activate a pass that is awaiting activation. Alternatively, the app can trigger a different experience if the user is deep linked from Apple Wallet for activation.

info

For more details refer to Apple Pay - In-App Verification.

2. Authenticate the Cardholder

Use the standard issuer's app authentication to verify the user.

3. Get Activation Data

Application should determine if passActivationState of a Secure Element Pass is set to REQUIRES_ACTIVATION.

Use MeaPushProvisioning.ApplePay.getActivationData() method to get activation code:

 let activationData = await MeaPushProvisioning.ApplePay.getActivationData(cardData)
4. Complete Activation

Use method MeaPushProvisioning.ApplePay.activate(secureElementPass, activationData) with activationData from previous step to activate the pass.

Server-side Activation

This method allows to activate the pass using TSP APIs.

1. Initiate activation process

This step is identical to other activation method, see Initiate activation process.

2. Authenticate the cardholder

Use the standard issuer's app authentication to verify the user.

3. Find pass with specific serial number

Use method MeaPushProvisioning.ApplePay.secureElementPassWithSerialNumber(serialNumber) to find the selected pass for activation, and determine if passActivationState of a Secure Element Pass is set to REQUIRES_ACTIVATION.

4. Complete activation

Use method MeaPushProvisioning.ApplePay.activate(secureElementPass, paymentNetwork) to activate the pass.

Handle Apple Wallet Change Notifications

Register data changed listener to refresh the state of Add to Apple Wallet button when a pass is added or removed on iPhone or Watch. These events are received and can be handled when app is in foreground.

Start listening to events.

var emitterSubscription: EmitterSubscription;
...

emitterSubscription = MeaPushProvisioning.ApplePay.registerDataChangedListener(async (data) => {
// Object data describes the changes.
// Refresh the state of the Add to Apple Wallet button here.
})

Stop listening to events.

MeaPushProvisioning.ApplePay.removeDataChangedListener(emitterSubscription);

Wallet Extensions

info

Support for Wallet Extensions (In-App Provisioning Extensions) is mandatory.

Refer to Wallet Extensions Guide for implementation details.

Google Pay

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

  • pushCard() - initiates push provisioning flow.
  • requestTokenSelectDialog - opens dialog asking user's confirmation to set the passed Google Pay token as selected (default) card in the Google Pay wallet.
  • requestTokenDeleteDialog - opens dialog asking user's confirmation to delete the passed Google Pay token from the Google Pay wallet.
  • checkWalletForCardToken - checks for Google Pay token presence and info in the active Google Pay wallet using card data. This method requires network connection.
  • checkWalletForToken - checks for Google Pay token presence and info in the active Google Pay wallet using particular token data.

Google Pay Push Provisioning API documentation:

Push Card

When MPP SDK 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(cardData, "John Doe", userAdress)
.then((pushcardInfo) => {
console.log("tokenId: " + pushcardInfo.tokenId + " network:" + pushcardInfo.cardNetwork + "last 4 digits: " + pushcardInfo.cardLastFourDigits);
// ...
})
.catch((error) => {
// handle error
});

Google Pay Result Callbacks

Google Pay push provisioning results are returned Activity.onActivityResult(int, int, Intent) method. MPP React Native module implicitly forwards these intermediate results to the MeaPushProvisioning.GooglePay.handlePushCardOnActivityResult(int, int, Intent, Activity) method, MPP Android SDK.

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: Google Pay Brand guidelines - Assets

GooglePayButton

Show or Hide Add to Google Pay Button

App is responsible to check and decide if "Add to Google Pay" should be shown or hidden for the user. Button should be shown only when card is not added to Google Pay already. MPP SDK provides the following methods to check if the specific card is already added to Google Pay wallet:

  • MeaPushProvisioning.GooglePay.checkWalletForCardToken(cardData: MppCardDataParameters) : Promise<GooglePayTokenInfo> - using card data, requires network connection.
  • MeaPushProvisioning.GooglePay.checkWalletForToken(paymentNetwork: MppPaymentNetwork, tokenId: string) : Promise<GooglePayTokenInfo> - using pre-fetched token data, does not require network connection.
  • MeaPushProvisioning.GooglePay.checkWalletForCardSuffix(cardSuffix: string) : Promise<TokenInfo[]> - using card suffix, does not require network connection.

If the card exists in Google Pay wallet, these methods return a single item or a list of GooglePayTokenInfo items that contains information about the specific Google Pay token: tokenId,tokenState, paymentNetwork and isSelectedAsDefault.
Issuer app should hide "Add to Google Pay" button when card exists in Google Pay wallet. If methods above return null or empty result, Issuer app should show "Add to Google Pay" button.

Managing Default NFC Payment App

Issuer app can check if Google Pay is set as 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 default NFC payment app:

MeaPushProvisioning.GooglePay.isDefaultPaymentApplication()
.then(isDefault => {
if (isDefault) {
// ...
}
});

Set Google Pay as default NFC payment app:

MeaPushProvisioning.GooglePay.setAsDefaultPaymentApplication(SET_DEFAULT_PAYMENTS_REQUEST_CODE)
.then(isSet => {
if (isSet) {
// ...
}
});

Getting Registered Tokens from Google Pay Wallet

There might be some use cases when Issuer app needs to get all registered tokens from Google Pay wallet, for example, yellow path use case. Method MeaPushProvisioning.GooglePay.getRegisteredTokens(...) returns list of TokenInfo items related to the active wallet.

MeaPushProvisioning.GooglePay.getRegisteredTokens()
.then((tokens) => {
// Iterate list...
tokens.forEach(token => {
// ...
});
})
.catch(error => {
// Handle error.
});

Continuing Yellow Path Through Push Provisioning

Issuer app should allow users to continue yellow path through push provisioning.

Issuer app should get the token of the selected card and check the token state. If token state matches value TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION, card provisioning has entered yellow path. Once matching GooglePayTokenInfo is available, use MeaPushProvisioning.GooglePay.tokenize(googlePayTokenInfo: GooglePayTokenInfo, cardDisplayName: string) : Promise<void> for continuing provisioning.

In general GooglePayTokenInfo of the card can be fetched using MeaPushProvisioning.GooglePay.checkWalletForCardToken(...), however for some issuers or processors backend only provides active tokens and does not provide pending tokens that have entered yellow path. See sections below for each of the cases.

Pending Tokens Available via Backend

After finding card with MeaPushProvisioning.GooglePay.checkWalletForCardToken(cardData: MppCardDataParameters) : Promise<GooglePayTokenInfo> in Google Pay wallet, check the state of the token. If token state matches TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION, card push provisioning has entered yellow path and requires additional user authentication.

Show "Add to Google Pay" button and call MeaPushProvisioning.GooglePay.tokenize(googlePayTokenInfo: GooglePayTokenInfo, cardDisplayName: string) : Promise<void> to continue push provisioning, when the button is tapped.

MeaPushProvisioning.GooglePay.checkWalletForCardToken(cardData)
.then(googlePayTokenInfo => {
if (googlePayTokenInfo.tokenState === GooglePayTokenState.TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION) {
// Card token requires additional user authentication for yellow path, show Add to Google Pay button.
// When tapping button, call MeaPushProvisioning.GooglePay.tokenize(googlePayTokenInfo, ...).
}
else {
// Token already exists in Google Pay wallet and no action required from Issuer app, hide Add to Google Pay button.
}
})
.catch(error => {
// Card token not found in Google Pay wallet, show Add to Google Pay button.
// When tapping button, call MeaPushProvisioning.GooglePay.pushCard(...).
});

Pending Tokens Not Available via Backend

Use MeaPushProvisioning.GooglePay.getRegisteredTokens(...) to get all tokens provisioned in Google Pay wallet. Iterate all the TokenInfo entities and match the selected card based on the last four digits. Once a matching token is found, check the state of the token. If token state matches TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION, card push provisioning has entered yellow path and requires additional user authentication.

Show "Add to Google Pay" button and call MeaPushProvisioning.GooglePay.tokenize(googlePayTokenInfo: GooglePayTokenInfo, cardDisplayName: string) : Promise<void> to continue push provisioning, when the button is tapped.

MeaPushProvisioning.GooglePay.getRegisteredTokens()
.then((tokens) => {
for (const tokenInfo of tokens) {
if (CARD_LAST_FOUR_DIGITS === tokenInfo.fpanLastFour ) {
if (tokenInfo.tokenState === GooglePayTokenState.TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION) {
// Card token requires additional user authentication for yellow path, show Add to Google Pay button.
// When tapping button, call MeaPushProvisioning.GooglePay.tokenize(googlePayTokenInfo, ...).
} else {
// Hide Add to Google Pay button
}

break;
}
}

})
.catch(error => {
console.log(error);
// Handle error.
});

Alternatively, use checkWalletForCardSuffix(cardSuffix: string) : Promise<TokenInfo[]> to get token(s) with matching PAN suffix.

MeaPushProvisioning.GooglePay.checkWalletForCardSuffix(CARD_LAST_FOUR_DIGITS) 
.then((tokens) => {
for (const tokenInfo of tokens) {
if (tokenInfo.tokenState == GooglePayTokenState.TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION) {
// Card token requires additional user authentication for yellow path, show Add to Google Pay button.
// When tapping button, call MeaPushProvisioning.GooglePay.tokenize(googlePayTokenInfo, ...).
} else {
// Hide Add to Google Pay button.
}
}
})
.catch(error => {
console.log(error);
// Handle error.
});

Using Tokenize

// When Add to Google Pay button tapped.
MeaPushProvisioning.GooglePay.tokenize(googlePayTokenInfo, "My Card")
.then(() => {
// ...
})
.catch(error => {
// Handle error.
});

App-to-App Verification

Issuers can implement App-to-App Verification using one of the two methods:

  • Obtaining activation code and passing to Google Wallet
  • Server-side activation

App Implementation

Issuer's app must do the following to provide app-to-app verification functionality:

1. Receive Android Intent from Google Wallet

When a user selects to verify their identity using the issuer's app, Google Wallet calls issuer's app using the package name, action and EXTRA_TEXT configured and provided through TSP. App manifest should be updated to be able to receive the Intent.

<activity android:name="AppToAppActivity">
<!-- Activity that handles APP_TO_APP actions -->
<intent-filter>
<action android:name="com.example.bank.action.APP_TO_APP"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
info
  • See React Native documentation: Handling Deep Links.
  • App-to-app verification action name varies by TSP. Consult TSP technical documentation to determine what action name should be used.
2. Authenticate the Cardholder

Use the standard issuer's app authentication to verify the user.

3. Activation

Application should determine the token in state TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION, method MeaPushProvisioning.GooglePay.getRegisteredTokens(...) can be used.

3.1. Activation Code

This method uses an activation code that is generated by the issuer and is validated by TSP.

Use MeaPushProvisioning.ApplePay.getActivationCode(...) method to get activation code and the activate on success or decline activation on error.

 MeaPushProvisioning.GooglePay.getActivationCode(cardData)
.then(activationCode => {
// Activation code received, proceed to card activation with Google Wallet.
MeaPushProvisioning.GooglePay.activate(activationCode);
})
.catch(error => {
// Activation failed, send 'declined' status to Google Wallet.
MeaPushProvisioning.GooglePay.declineActivation('declined');
});
3.2 Server-side Activation

This method allows to activate the token using TSP APIs.

// get tokenInfo by Token Unique Reference from Intent.EXTRA_TEXT opaque data received from Google Wallet.
let tokenInfo = await getTokenInfo(payload)

// activate token and return to Google Wallet.
await MeaPushProvisioning.GooglePay.activateWithTokenInfo(tokenInfo)

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.
info

Only foreground applications are notified of the data changed events. Therefore, each application should update the token statuses not only through callback, but also when the application launches or returns to the foreground.

var emitterSubscription: EmitterSubscription;

// ...

emitterSubscription = MeaPushProvisioning.GooglePay.registerDataChangedListener(() => {
// Reload data in UI
});

Stop listening data changed events by removing GooglePayDataChangedListener.

MeaPushProvisioning.GooglePay.removeDataChangedListener(emitterSubscription);

Samsung Pay

MeaPushProvisioning.SamsungPay helper interface provides the following methods to interact with Samsung Pay wallet:

  • getStatus() - checks the current status of Samsung Pay.
  • activatePay() - activates Samsung Pay app.
  • update() - updates Samsung Pay app.
  • pushCard() - pushes the card to Samsung Pay.
  • checkWalletForToken() - checks for Samsung Pay token presence and info in the Samsung Pay wallet using particular token data.
  • checkWalletForCardToken() - checks if the Samsung Pay token for the corresponding card is available in the Samsung Pay Wallet. This check requires a network call.

Samsung Pay Push Provisioning API documentation:

Set Service ID

You must pass Samsung Pay ServiceId (SID) to the SDK before using MeaPushProvisioning.SamsungPay API:

MeaPushProvisioning.SamsungPay.setServiceId("partner_app_service_id");

Get Status

The first step check Samsung Pay status on the device to determine its support for Samsung Pay. Issuer app must call this Method to check the current status of Samsung Pay before doing any operation. If the status is SAMSUNG_PAY_SETUP_NOT_COMPLETED or SAMSUNG_PAY_APP_NEED_TO_UPDATE, issuer application can activate the Samsung Pay app on the device and update it to the latest version.

MeaPushProvisioning.SamsungPay.getStatus()
.then((samsungPayStatus) => {
switch (samsungPayStatus) {
case SamsungPayStatus.SAMSUNG_PAY_READY:
// Samsung Pay is properly activated and ready to use
break;

case SamsungPayStatus.SAMSUNG_PAY_SETUP_NOT_COMPLETED:
MeaPushProvisioning.SamsungPay.activatePay();
break;

case SamsungPayStatus.SAMSUNG_PAY_APP_NEED_TO_UPDATE:
MeaPushProvisioning.SamsungPay.update();
break;

case SamsungPayStatus.SAMSUNG_PAY_NOT_SUPPORTED:
case SamsungPayStatus.SAMSUNG_PAY_UNEXPECTED_STATUS:
case SamsungPayStatus.SAMSUNG_PAY_NOT_READY:
// Not supported or unexpected error
break;
}
})
.catch(error => {
// called when the requested operation fails
});

Push Card

When MPP SDK is initialized, Issuer app can push provision card using MeaPushProvisioning.SamsungPay.pushCard(...) and MppCardDataParameters. This method checks the state of Samsung 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 Samsung Pay wallet already, it pushes the card to the Samsung Pay wallet via Samsung Push Provisioning API.

MeaPushProvisioning.SamsungPay.pushCard(cardData)
.then((pushCardInfo) => {
// success
console.log("tokenId: " + pushCardInfo.tokenId + " network:" + pushCardInfo.cardNetwork + "last 4 digits: " + pushCardInfo.cardLastFourDigits);
})
.catch((error) => {
// handle error
console.log(error);
});

Add to Samsung Pay Button

The Add to Samsung Pay button is used exclusively to initiate the Samsung Pay card provisioning flow from an Issuer app.
The "Add to Samsung Pay" buttons are available as .png and .ai images: Samsung Pay Identity Guidelines

GooglePayButton

Show or Hide Add to Samsung Pay Button

App is responsible to check and decide if "Add to Samsung Pay" should be shown or hidden for the user. Button should be shown only when card is not added to Samsung Pay already.
MPP SDK provides 2 methods to check if the corresponding card for a token is available in Samsung Pay active wallet:

  • MeaPushProvisioning.SamsungPay.checkWalletForCardToken(cardData: MppCardDataParameters) : Promise<SamsungPayTokenInfo> - using card data, requires network connection.
  • MeaPushProvisioning.SamsungPay.checkWalletForToken(tokenId: string) : Promise<SamsungPayTokenInfo> - using pre-fetched token data.

If card exists in Samsung Pay wallet, both methods return SamsungPayTokenInfo that contains information about the specific Samsung Pay token: tokenId, tokenState, paymentNetwork and isSelectedAsDefault.
Issuer app should hide "Add to Samsung Pay" button when card exists in Samsung Pay wallet. If methods above return null, Issuer app should show "Add to Samsung Pay" button.

Method MeaPushProvisioning.SamsungPay.checkWalletForCardSuffix(cardSuffix: string) : Promise<SamsungPayTokenInfo[]> can be used to get token(s) with matching PAN suffix.

MeaPushProvisioning.SamsungPay.checkWalletForCardSuffix(CARD_LAST_FOUR_DIGITS) 
.then((tokens) => {
for (const tokenInfo of tokens) {
// Hide "Add to Samsung Pay" button.
}
})
.catch((error) => {
// handle error
});

Managing Default NFC Payment App

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

MeaPushProvisioning.SamsungPay.isDefaultPaymentApplication()
.then(isDefault => {
if (isDefault) {
// ...
}
});

Set Samsung Pay as default NFC payment app:

MeaPushProvisioning.SamsungPay.setAsDefaultPaymentApplication(SET_DEFAULT_PAYMENTS_REQUEST_CODE)
.then(isSet => {
if (isSet) {
// ...
}
});

Getting Registered Tokens from Samsung Pay Wallet

There might be some use cases when Issuer app needs to get all registered tokens from Samsung Pay wallet, for example, yellow path use case. Method MeaPushProvisioning.SamsungPay.getRegisteredTokens(...) returns list of Card items related to the active wallet.

MeaPushProvisioning.SamsungPay.getRegisteredTokens() 
.then((tokens) => {
// Iterate list...
.catch((error) => {
// Handle error
});

App-to-App Verification

info

Refer to SamsungPay / App-to-App Verification for more details.

Issuers can implement App-to-App Verification using one of the two methods:

  • Obtaining activation code and passing to Samsung Pay Wallet
  • Server-side activation

App Implementation

Issuer's app must do the following to provide app-to-app verification functionality:

1. Receive Android Intent from Samsung Pay

When a user selects to verify their identity using the Issuer's App, Samsung Pay calls issuer's app using the package name, action and EXTRA_TEXT configured and provided through TSP. App manifest should be updated to be able to receive the Intent.

<activity android:name="AppToAppActivity">
<!-- Activity that handles APP_TO_APP actions -->
<intent-filter>
<action android:name="com.example.bank.action.APP_TO_APP"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
info

App-to-app verification action name varies by TSP. Consult TSP technical documentation to determine what action name should be used.

2. Authenticate the cardholder

Use the standard issuer's app authentication to verify the user.

3. Activation

Application should determine the token in state PENDING_ACTIVATION, method MeaPushProvisioning.SamsungPay.getRegisteredTokens(...) can be used.

3.1. Activation code

Application should determine the token state, method MeaPushProvisioning.SamsungPay.getRegisteredTokens(...) can be used.

Use MeaPushProvisioning.SamsungPay.getActivationCode(cardData) method to get activation code to complete the provisioning flow.

 MeaPushProvisioning.SamsungPay.getActivationCode(cardData)
.then(activationCode => {
// Activation code received, proceed to card activation with Samsung Pay Wallet.
MeaPushProvisioning.SamsungPay.activate(activationCode);
})
.catch(error => {
// Activation failed, send 'declined' status to Samsung Pay Wallet.
MeaPushProvisioning.SamsungPay.declineActivation('declined');
});
3.2. Server-side Activation

This method allows to activate the token using TSP APIs.

// get Card by Token Unique Reference from Intent.EXTRA_TEXT opaque data received from Samsung Pay Wallet.
let card = await getCard(payload)

// activate card and return to Samsung Pay Wallet.
await MeaPushProvisioning.GooglePay.activateWithCard(card)

Debug and Release mode

Samsung Pay supports both debug and release modes. More details available in the Samsung Pay SDK documentation

Third-party Wallet Providers

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.

MPP React Native enables push provisioning to both Mastercard MDES Token Connect and Visa VTS Push Provisioning using the same API.

Initialization

Before you can use MPP SDK in your application, you must initialize it MeaPushProvisioning.initialize(). Application should initialize the library only once during it's 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 the list of Token Requestors for the User.

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

  • MeaPushProvisioning.getTokenRequestors(accountRanges: string[]): Promise<MppTokenRequestor[]>: to retrieve information such as Token Requestor type, user-friendly name, available user interfaces (Android/iOS app, web).
  • getAsset(assetId: string) : Promise<MppMediaContent>: 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.

MeaPushProvisioning.getTokenRequestors(["512345678901", "512345678902", "512345678903"])
.then((tokenRequestors) => {
// Iterate token requestors
})
.catch((error) => {
// Handle error
});

Get Tokenization Receipt

When the User has selected the target Token Requestor as well as the sourcing card(s), application has to invoke getTokenizationReceipt(tokenRequestorId: string, cardData: MppCardDataParameters): Promise<TokenizationResult> method.

MeaPushProvisioning.getTokenizationReceipt("12345678901", cardData)
.then(tokenizationResult => {
// ...
})
.catch(error => {
// Handle error
});

Send User to Token Requestor (Deep-linking)

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

Additionally to receipt, getTokenizationReceipt(tokenRequestorId: string, cardData: MppCardDataParameters): Promise<TokenizationResult> 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.

MPP SDK 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 (pushAccountReceiptParameter, callbackUrlParameter, completeIssuerAppActivationParameter, completeWebsiteActivationParameter), 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.

Debugging and logging

Android

MPP SDK native logs are enabled by default in Debug mode, and available in Android Studio or via Logcat.

Removing Logs

1. Add the following lines to android/app/proguard-rules.pro file:

-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
}

2. Set minifyEnabled to true in android/app/build.gradle file:

buildTypes {
//...
release {
// ...
minifyEnabled true
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}

3. Build React Native app in release mode: Testing the release build of your app

iOS

Use setDebugLoggingEnabled() method to enable/disable native MPP SDK logging to the system logs:

MeaPushProvisioning.ApplePay.setDebugLoggingEnabled(true)

Access MPP SDK native logs when running your App in Xcode with the debugger attached, or using Console App.