The following diagram illustrates the flows of the App-to-App APIs for payment card push provisioning
Flows of push provisioning APIs
The main classes involved are:
Samsung Pay – for fetching Samsung Wallet app status and wallet information on the device.
PaymentManager – for card provisioning and invoking Favorite Cards payment functionalities.
CardManager – for payment card management.
WatchManager – for all functions related to Samsung Pay Watch.
Let’s now take a look at how each one works in the context of your bank app.
Requesting registered card list in the Samsung Pay
The'getAllCards() method of the CardManager class is used to request a list of all cards currently registered/enrolled in Samsung Wallet on the same device running the issuer’s app. To succeed, the issuer app must pass valid PartnerInfo to 'CardManager' for caller verification. 'cardFilter' narrows the card list returned by Samsung Wallet to the issuerName specified. Please be noted that getSamsungPayStatus() must be called before getAllCards(). getAllCards() could not return a cards list when getSamsungPayStatus() responds with a code other than SPAY_READY.
NoteTo get the cards list of Samsung Pay Watch, you have to use the WatchManager class instead of the CardManager class.
As of API level (SDK version) 1.4, cardFilter retrieves this information from the Samsung Pay Developers portal. Certain issuers may need to register multiple ISSUER NAME(s) with the portal, depending on their app and/or the requirements of their token service provider (TSP). The getAllCards() parameter cardFilter matches the ISSUER NAME(s) specified with those registered in the portal. Only complete matches are returned.
This method is typically called when your partner app wants to check the card status. It does not need to be called every time the partner app resumes. Therefore, you should create the card list with the 'onCreate()' method, rather than the 'onResume()' method.
The result of a getAllCards() call is delivered to GetCardListener, which provides the following events:
onSuccess() - called when the operation succeeds; provides the list of all filtered cards and their status. Card information includes cardId, cardStatus, and extra cardInfo data.
onFail() - called when the operation fails.
Here’s an example of how to use the 'getAllCards()' API method in your issuer app.
val cardFilter = Bundle()
// Since API level 1.4, cardFilter param is ignored. Partner does not need to use it here.
// It is retrieved from the Samsung Pay Developers portal
cardFilter.putString(CardManager.EXTRA_ISSUER_NAME, issuerName)
cardManager.getAllCards(null, object : GetCardListener{
override fun onSuccess(cards: MutableList<Card>?) {
// Getting card status is success
if (cards == null || cards.isEmpty()) {
Log.e(TAG, "No card is found")
return
} else {
// Perform operation with card data
for (s in cards) {
Log.d(TAG, "CardId: " + s.cardId + "CardStatus " + s.cardStatus)
// Get Extra card data
if (s.cardInfo != null) {
val cardId = s.cardId // Since API level 2.13, ID from card network.
val last4FPan = s.cardInfo.getString(CardManager.EXTRA_LAST4_FPAN)
val last4DPan = s.cardInfo.getString(CardManager.EXTRA_LAST4_DPAN)
val cardType = s.cardInfo.getString(CardManager.EXTRA_CARD_TYPE)
val cardIssuerName =
s.cardInfo.getString(CardManager.EXTRA_ISSUER_NAME)
Log.d(
TAG,
"last4FPan:$last4FPan last4DPan:$last4DPan CardId: $cardId"
)
}
}
}
}
override fun onFail(errorCode: Int, errorData: Bundle?) {
// Getting card status is failed
}
})
Getting wallet information
The SamsungPay class provides the getWalletInfo() API method, which is called to request wallet information from the Samsung Wallet app prior to calling the addCard() API, when you want to avoid duplicate provisioning. Your issuer app uses this information to uniquely identify the user and the Samsung Wallet app on a particular device (wallet device management ID, device ID, and wallet user ID).
NoteTo get wallet information of Samsung Pay Watch, you have to use the WatchManager class instead of the CardManager class.
fun getWalletInfo(List<String> keys, StatusListener callback)
The following example demonstrates how to use it.
// Set the serviceId assigned by the Samsung Pay Developers portal during service creation
val serviceId = "sampleServiceId"
val bundle = Bundle()
bundle.putString(SamsungPay.EXTRA_ISSUER_NAME, "issuer name")
bundle.putString(SamsungPay.PARTNER_SERVICE_TYPE, ServiceType.APP2APP.toString())
val pInfo = PartnerInfo(serviceId, bundle)
val samsungPay = SamsungPay(context, pInfo)
// Add bundle keys to get wallet information from Samsung Pay.
// This information can be delivered to the Partner Server for an eligibility check.
val keys = ArrayList<String>()
keys.add(SamsungPay.WALLET_USER_ID)
keys.add(SamsungPay.DEVICE_ID)
samsungPay.getWalletInfo(keys, object : StatusListener{
override fun onSuccess(status: Int, walletData: Bundle) {
// Log.d(TAG, "doWalletInfo onSuccess callback is called");
// For VISA, deviceID can be set to "clientDeviceID" as defined by VISA
val deviceId = walletData.getString(SamsungPay.DEVICE_ID)
// For VISA, walletUserId can be set to "clientWalletAccountID" as defined by VISA
val walletUserId = walletData.getString(SamsungPay.WALLET_USER_ID)
}
override fun onFail(errorCode: Int, errorData: Bundle?) {
Log.e(TAG, "onFail callback is called, errorCode: " + errorCode);
// Check the extra error codes in the errorData bundle for all the reasons in
// SamsungPay.EXTRA_ERROR_REASON, when provided
}
})
Adding a card to Samsung Pay
Your issuer app calls the 'addCard()' API method of CardManager to add a card to Samsung Wallet. By providing the required card details, your app can make it convenient and easy for users to add their bank-issued debit/credit cards to Samsung Wallet directly from your app without additional steps, like switching between apps.
NoteIf you want to add a card to Samsung Pay Watch, you have to use the 'WatchManager' class instead of the CardManager class.
For most issuers, getWalletInfo() suffices for requesting current wallet information. The response from Samsung Wallet tells the issuer app whether or not the user’s card has already been added to Samsung Wallet or is ineligible for provisioning. It is therefore recommended that you call getWalletInfo() before displaying the Add to Samsung Pay button. If the card is eligible, display the “add” button and, if the user taps it, call addCard().
ImportantRemember to obtain the governing issuer implementation guide(s) and specifications from the respective card network and implement each network’s required handling in your partner app and server
The 'addCard()' result is delivered to AddCardListener, which provides the following events:
onSuccess() - called when the operation succeeds; provides information and status regarding the added card.
onFail() - called when the operation fails; returns the error code and extra bundle data such as EXTRA_ERROR_REASON or EXTRA_REQUEST_ID (if provided).
onProgress() - called to indicate the current progress of the 'addCard()' operation; can be used to show a progress bar to the user in the issuer app. This callback is supported for TSM solution issuers in China and Spain.
Here’s an example of how to use the addCard() API method in your issuer app.
val cardType = Card.CARD_TYPE_CREDIT
val tokenizationProvider: String = AddCardInfo.PROVIDER_ABCD
// Samsung Pay does not provide detailed payload information; generate the provisioning payload in
// accordance with your card network specifications
val testPayload = "ThisIsTestPayloadCardInfo1234567890"
val cardDetail = Bundle()
cardDetail.putString(EXTRA_PROVISION_PAYLOAD, testPayload)
val addCardInfo = AddCardInfo(cardType, tokenizationProvider, cardDetail)
cardManager.addCard(addCardInfo, object : AddCardListener {
override fun onSuccess(status: Int, card: Card?) {
Log.d(TAG, "onSuccess callback is called");
}
override fun onFail(errorCode: Int, errorData: Bundle?) {
Log.d(TAG, "onFail callback is called");
// check some extra error codes in the errorData bundle
// such as SamsungPay.EXTRA_ERROR_REASON or SamsungPay.EXTRA_REQUEST_ID (if provided).
}
override fun onProgress(currentCount: Int, totalCount: Int, bundleData: Bundle?) {
Log.d(TAG,"onProgress callback is called : " + currentCount + " / " + totalCount);
}
})
Manage Your Cookies
We use cookies to improve your experience on our website and to show you relevant
advertising. Manage you settings for our cookies below.
Essential Cookies
These cookies are essential as they enable you to move around the website. This
category cannot be disabled.
Company
Domain
Samsung Electronics
.samsungdeveloperconference.com
Analytical/Performance Cookies
These cookies collect information about how you use our website. for example which
pages you visit most often. All information these cookies collect is used to improve
how the website works.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Functionality Cookies
These cookies allow our website to remember choices you make (such as your user name, language or the region your are in) and
tailor the website to provide enhanced features and content for you.
Company
Domain
LinkedIn
.ads.linkedin.com, .linkedin.com
Advertising Cookies
These cookies gather information about your browser habits. They remember that
you've visited our website and share this information with other organizations such
as advertisers.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Preferences Submitted
You have successfully updated your cookie preferences.