The following diagram illustrates the flows of the App-to-App APIs for payment card push provisioning and opening Favorite Cards from an issuer app integrated with the Samsung Pay SDK.
The main classes involved are:
Samsung Pay
PaymentManager
CardManager
WatchManager
Let’s now take a look at how each one works in the context of your bank app.
The'getAllCards() method of the CardManager class is used to request a list of all cards currently registered/enrolled in Samsung Pay 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 Pay 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.
'getAllCards()
getSamsungPayStatus()
getAllCards()
SPAY_READY
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.
cardFilter
ISSUER NAME(s)
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:
GetCardListener
onSuccess()
onFail()
Here’s an example of how to use the 'getAllCards()' API method in your issuer app.
Bundle cardFilter = new 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(cardFilter, new GetCardListener() { @Override public void onSuccess(List<Card> cards){ // 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 (Card s:cards) { Log.d(TAG,"CardId: "+ s.getCardId()+"CardStatus "+s.getCardStatus()); // Get Extra card data if (s.getCardInfo() != null) { String cardId = s.getCardId(); // Since API level 2.13, ID from card network. String last4FPan = s.getCardInfo().getString(CardManager.EXTRA_LAST4_FPAN); String last4DPan = s.getCardInfo().getString(CardManager.EXTRA_LAST4_DPAN); String cardType = s.getCardInfo().getString(CardManager.EXTRA_CARD_TYPE); String cardIssuerName = s.getCardInfo().getString(CardManager.EXTRA_ISSUER_NAME); Log.d(TAG,"last4FPan:"+last4FPan+" last4DPan:"+ last4DPan + " CardId: "+ cardId); } } } } @Override public void onFail(int error, Bundle errorData) { // Getting card status is failed } });
The SamsungPay class provides the getWalletInfo() API method, which is called to request wallet information from the Samsung Pay 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 Pay app on a particular device (wallet device management ID, device ID, and wallet user ID).
SamsungPay
getWalletInfo()
addCard()
void 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 String serviceId = "sampleServiceId"; Bundle bundle = new Bundle(); bundle.putString(SamsungPay.EXTRA_ISSUER_NAME,"issuer name"); bundle.putString(SamsungPay.PARTNER_SERVICE_TYPE,SamsungPay.ServiceType.APP2APP.toString()); PartnerInfo pInfo = new PartnerInfo(serviceId, bundle); SamsungPay samsungPay = new 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. ArrayList<String> keys = new ArrayList<>(); keys.add(SamsungPay.WALLET_USER_ID); keys.add(SamsungPay.DEVICE_ID); samsungPay.getWalletInfo(keys, new StatusListener() { @Override public void onSuccess ( int status, Bundle walletData){ // Log.d(TAG, "doWalletInfo onSuccess callback is called"); // For VISA, deviceID can be set to "clientDeviceID" as defined by VISA String deviceId = walletData.get(SamsungPay.DEVICE_ID); // For VISA, walletUserId can be set to "clientWalletAccountID" as defined by VISA String walletUserId = walletData.get(SamsungPay.WALLET_USER_ID); } @Override public void onFail ( int errorCode, Bundle errorData){ 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 } }
Your issuer app calls the 'addCard()' API method of CardManager to add a card to Samsung Pay. 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 Pay directly from your app without additional steps, like switching between apps.
For most issuers, getWalletInfo() suffices for requesting current wallet information. The response from Samsung Pay tells the issuer app whether or not the user’s card has already been added to Samsung Pay 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().
The 'addCard()' result is delivered to AddCardListener, which provides the following events:
AddCardListener
EXTRA_ERROR_REASON
EXTRA_REQUEST_ID
onProgress()
Here’s an example of how to use the addCard() API method in your issuer app.
String cardType = Card.CARD_TYPE_CREDIT; String tokenizationProvider = AddCardInfo.PROVIDER_ABCD; // Samsung Pay does not provide detailed payload information; generate the provisioning payload in // accordance with your card network specifications String testPayload = "ThisIsTestPayloadCardInfo1234567890"; Bundle cardDetail = new Bundle(); cardDetail.putString(AddCardInfo.EXTRA_PROVISION_PAYLOAD, testPayload); AddCardInfo addCardInfo = new AddCardInfo(cardType, tokenizationProvider, cardDetail); cardManager.addCard(addCardInfo, new AddCardListener() { @Override public void onSuccess(int status, Card card) { Log.d(TAG, "onSuccess callback is called"); } @Override public void onFail(int error, Bundle errorData ) { 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 public void onProgress(int currentCount, int totalCount, Bundle bundleData) { Log.d(TAG,"onProgress callback is called : " + currentCount + " / " + totalCount); } });