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.
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.
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.
import { MppCardDataParameters } from '@meawallet/react-native-mpp';
// ...
const cardId = "<value>";
const cardSecret = "<value>";
const cardParams = MppCardDataParameters.withCardSecret(cardId, cardSecret);
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);
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));
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.
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
} }
/>
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.
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
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 = { () => {
// ...
} }
/>
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
});
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.
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
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
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
Refer to Google Pay - App-to-App Verification with Activation Code for more details.
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>
- 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.
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:
- Samsung Pay SDK download
- Samsung Pay SDK - Push Provisioning
- App to App card enrollment integration guide
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
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
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>
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.