Token Requestor

NFC Issuer Wallet with Mobile SDK. Mastercard MCBP 2.1 SDK and Visa VTS SDK.

Due to the rename UCP and VCP are used interchangeably.

Introduction

Token Requestor service is a set of solutions for establishing Issuer Wallet for NFC Payments. 

Issuer Wallet gives flexibility about user, cards and tokens lifecycle. It can be easily integrated within existing Mobile Banking or Payment Application. It is a full ecosystem which contains:

Issuer wallet functionalities examples:

Intro slides

Card Tokenization

MDES and VTS integration as token requestor. Issuer wallet or SDK integrated into mobile banking application. Available on all Android phones and all countries (including Huawei). Enables mobile contactless transactions using NFC interface.

• API: MDES and VTS.

• Readiness: Live.

• SDK available: Yes.

• White label solution available: Yes.

• Certification: Yes, full security and functional certification.

• Implementation time: 3 months from contracting

image-1657286927149.png

Implementation Steps

PBA.png

Architecture

MDES(1).png

image-1656856519887.54.25.png

Overview

Verestro Cloud Payments is a solution developed to facilitate adopting cloud-based payments for the Customers. VCP provides functionalities for User identification and verification, Payment Instruments digitization and User data management. Cloud payments enables a card to be digitized into a wallet application on a mobile device and used for payment without the need for a Secure Element (SE) or a Trusted Execution Environment (TEE) to protect the card’s sensitive assets, such as the keys needed for calculating the Application Cryptogram.

Master Keys for the digitized card are kept securely on remote servers(for plastic in the chip), hence the term ‘cloud-based payment,’ and a limited number of keys (where each key can only be used to perform a single transaction) are downloaded to the application.

Solution consists of:

Benefits of Payment Token

The MCBP service is an easy and secure way to replace a plastic payment card with a payment token. Recognition to the tokenization and digitization process without leaving the house, we can add our payment card to the mobile application and use only a mobile device during purchases.
The benefits of tokenization are felt by every participant in the process:
Issuer - by implementing the tokenization service, it will provide its customers with much higher and safer access to innovative payment solutions.
Card Holder - can freely use innovative payment solutions. The tokenization service will allow free and secure payments using any devices connected to the internet.

MCBP Introduction

Mastercard Cloud-Based Payments (MCBP) is technology which enables a card to be digitized into an application on a mobile device. On plastic card, Master Keys needed for calculating cryptogram are stored in the Secure Element. Using MCBP there is no need for Secure Element since keys needed for calculating the cryptogram are kept securely on remote servers, hence the term ‘cloud-based payment,’ and a limited number of keys (where each key can only be used to perform a single transaction) are downloaded to the application. VCP is solution which provides functionalities for digitization, user data management and payments needed for final Customer to adopt MCBP. 

MCBP High Level Architecture 

image-1654374212441.png

MCBP Key Components

Component Description
MPA Android Mobile Payment Application provides frontend interface to the user and uses part of Verestro Wallet SDK which is responsible for payments using HCE.
Verestro Wallet Server Provides the backend services to support Mobile Payment Application via Verestro Wallet SDK and is responsible for managing users, devices, cards, Payment Tokens and communication with MDES. Wallet Server acts as Token Requestor on behalf of Issuer in context of digitization.
Verestro Wallet SDK Provides all functionalities needed for MPA to perform all needed operations related to MCBP.

MDES

Token Service Provider which supports digitization(transforming the card into Payment Token) and is responsible for management, generation and provisioning of transaction credentials into mobile devices to enable simpler and more secure digital payment experience.
Remote Notification Service Wallet Server communicates with the MPA also using Remote Notification Service. For Android is used Firebase Cloud Messaging.
Issuer Issuer is responsible for card issuing, accepting authorization digitization requests and accepting transactions which uses token.

Description

Wallet Types 

VCP supports following wallet types which can be used in the implementation:

  • OPEN - user registers itself in the application and provides data like PAN etc.,
  • CLOSED - user data are passed automatically from Customer servers without User interaction to Wallet Server.

Implementation Models

Verestro provides two different implementation models for products: integrated and standalone version.

Integrated

In this model Customer is owner of MPA. Verestro provides Wallet SDK and Wallet Server. Customer is responsible for direct User authentication and passes the result of the authentication to Wallet SDK. Online operations which need to be performed by User using Wallet Server require valid session on Wallet Server. To obtain user online session with Wallet Server, Customer needs to pass Trusted Identity.

Standalone

In this model Verestro provides MPA, Wallet SDK and Wallet Server. Furthermore, Verestro manages direct user authentication.

Architecture

image-1654374565801.png

Server Components

Server components are applications which need to be deployed on remote server to make possible to connect them by network.

Deployment Models

Verestro offers two deployment models of server components. On-premise and SaaS.

SaaS - Server components are designed to be deploy in SaaS model. In this case everything is deployed and configured on Verestro side. Verestro is responsible for maintaining infrastructure, deploying applications and monitoring.

On-premise - Server components also can be deployed on Customer infrastructure. Applications are designed to be deployed using Kubernetes as system for automating deployment, scaling, and management of containerized applications. For more details please contact Verestro representative. 

Wallet Server

Wallet Server - is backend component which consists of few internal services which are responsible for managing users, devices, cards, Payment Tokens, transaction history. It acts as Token Requestor on behalf of Issuer and is compliant with PCI Data Security Standard.

It exposes:

Wallet Server operates with domain objects like:

image-1654374710316.png

Wallet Admin Panel

Web frontend application which is dedicated for back office to manage all User data.

Delivery 

Mobile Components

Wallet SDK

Verestro provides Software Development Kit (SDK) called Wallet SDK which can be used in Mobile Payment Application. As a company, Verestro provides many products which can be used in single application. For that reason Wallet SDK is divided into separated modules which covers different functionalities. There are two main modules dedicated for Verestro Cloud Payments: MDC SDK and VCP SDK. MDC SDK is core Verestro module responsible for user data management: authentication, payment cards management - since these are main functionalities used in every product. VCP SDK is dedicated for performing digitization and payments using Payment Token. In payment context VCP SDK wraps Mastercard Cloud Based Payment SDK.

Requirements

Wallet SDK has some mandatory requirements to make it work:

There are also some not mandatory requirements, but Customer needs to be aware of them to maintain functionalities:

Security

Wallet SDK was developed according to security requirements included in Security Guide MCBP SDK for Android. However Wallet SDK cannot guarantee full MPA protection and MPA must provide additional layer of security to protect user interface(mainy when PAN is manually entered in the application) and data processing within application. More detailed information can be found in Wallet SDK API. Moreover all sensitive data are passed as chars or bytes arrays. Wallet SDK copies the arrays and clears that copies just after processing. MPA should clear provided sensitive data immediately after passing them to Wallet SDK.

Security Checks and Data Clearing

On Wallet SDK side are performed security checks which includes static code analysis protection and dynamic analysis protection. Security checks consists of:

Security checks are performed periodically, if Wallet SDK detects any of above things all data hold by Wallet SDK will be cleared and security report will be sent to Wallet Server. MPA will be informed about such detection.

Communication with Wallet Server

Communication from genuine applications which are installed on genuine devices is accepted by the Wallet Server. Wallet SDK at the very beginning performs authentication of application and device to Wallet Server. This authentication may takes advantage of Google Play Integrity which is 3-rd party trusted side in whole authentication. Google Play Integrity verifies device and sign information about device and application. Signed data from Play Integrity are sent to the Wallet Server. Wallet Server verifies data and allow or does not allow for further communication. Application is verified according preconfigured application certificate digest used for signing application. 

Important: There is a limit of requests to Google Play Integrity API: 10 000 per day. If Customer predicts that there will be more installations per day then this limit needs to be increased during Google Project Setup.

Wallet SDK communicates with Wallet Server using TLS 1.2. Wallet SDK performs public key certificate pinning when it tries to establish connection with Wallet Server (similar with connection to MDES). Certificates for the pinning needs to be provided to SDK. Sensitive information are additionally encrypted and/or signed.

Versioning

Wallet SDK uses semantic versioning. It means that every release has own version which is MAJOR.MINOR.PATCH, where:

MAJOR versions are supported 6 months and Customer needs to migrate to new version if they want to maintain support.

Remote Notification Service

Wallet SDK is responsible for remote notification processing. However MPA is responsible for obtaining FCM registration token, handling FCM token update and receiving remote notifications. Before passing remote notification to SDK, MPA needs to verify if given message is dedicated for SDK by checking sender Id. Sender Id is configured during onboarding. Verestro will create new FCM project and provide data needed to obtain FCM token for given project. Due to observing some issues with FCM token refresh notification from FCM service, additional check of new token availability is recommended(eg. on application start). See more in Wallet SDK API. 

Access

Wallet SDK is stored as artifacts in maven repository. Access there is provided during onboarding by Verestro representative.

Configuration

Whole product has configuration which needs to be fulfilled. This configuration also consists of data which are set in MDES. More details are described in Wallet Configuration.

User Experience for Contactless Transactions

MDES offers a few options for customers for defining user experience for contactless transactions. Final option is the choice of CDCVM type (Mobile PIN, Locally-verified CDCVM) and CVM model (Always, Flexible, Card-like).

CDCVM Types

There are two types of Consumer Device Cardholder Verification Method (CDCVM) which are supported by MDES.

Mobile PIN CDCVM

A PIN value (4–8 digits) that the cardholder enters on the mobile device and that is validated online by MDES during the transaction authorization process. Since Locally-verified is mostly preferable option, Mobile PIN is out of scope.

Locally-verified CDCVM

A CDCVM entered on and validated by the consumer’s mobile device, for example system device PIN, pattern, password or biometric methods (such as fingerprint, iris or facial recognition). Swipe (slide to unlock) is not a valid cardholder verification method and must not be supported. These methods are commonly associated with a device unlock process and are validated on the cardholder’s mobile device. The payment component embedded in the Mobile Payment Application will use the outcome of this authentication process. A Locally-verified CDCVM applies to all the payment tokens of a given Mobile Payment Application instance (“Wallet-level”). In some parts of system this type is also named as Custom. 

CVM Models

For two CDCVM types customer can apply different user experience CVM Models.

Always CVM 

In this model the card profiles supplied to the SDK are configured to indicate that the mobile device supports on-device cardholder authentication. When transactions are performed on a POS supporting CDCVM, the POS will delegate cardholder authentication to the mobile device the terminal will not request an Online PIN on the terminal. In POS which does not support CDCVM cardholder authentication is required using Online PIN. This model requires the cardholder’s mobile device to authenticate the cardholder for all transactions (LVT, HVT, Transit). CDCVM can be performed using either a Mobile PIN or a Locally-verified CDCVM. MPA is expected to decline any transaction for which cardholder authentication is not performed or is unsuccessful.

Below are presented sample diagrams which show how the transactions can look like: 

Always LVT, HVT - single tap

image-1654375111845.png


Always LVT, HVT - double tap


image-1654375121955.png

Flexible CVM

In this model the card profile also indicates that the mobile device supports on device cardholder authentication Mobile PIN or Locally-verified CDCVM. However rather than applying authentication for every transaction the MPA defines flexible criteria such as allowing multiple transactions between each authentication. This criteria are often names as Lost & Stolen options or velocity checks. For transit transactions cardholder authentication is not expected.

Below are presented sample diagrams which show how the transactions can look like:

Flexible LVT

image-1654375214373.png

Flexible HVT - single tap

image-1654375231686.png

Flexible HVT, LVT with Velocity counters - double tap

image-1654375238935.png

Card-like CVM

In this model the card profiles supplied to the SDK are configured to indicate that the mobile wallet is not capable of supporting on device cardholder verification. This means that when transactions are performed with a Point of Sale (POS) terminal, the POS will treat the transaction in the same way as a card transaction. Typically this means that low value transactions (LVTs) will be processed without additional user authentication and if supported, high value transactions will require an online PIN to be provided on POS. This model is put here just for general information, however it is not preferred for issuer wallets.

Below are presented sample diagrams which show how the transactions can look like:

Card like LVT

image-1654375297218.png

Card like HVT

image-1654375302023.png


Lost & Stolen Options

The Lost & Stolen options are dedicated to control performing transactions allowed before requiring cardholder authentication. This limits fraud risk if the cardholder’s mobile device is lost or stolen. Lost & stolen options can be applied only for Flexible CDCVM. These options also are known as velocity check counters. Wallet SDK provides interface which is invoked during transaction. Transaction information like range, rich transaction type, amount are provided within this interface. MPA can implement various checks to support velocity check counters using transaction information. MPA for example can count LVT transactions and allow only some predefined number of LVT transactions without cardholder authentication.

Transit Transactions

Transit transactions are transactions with given Merchant Category Code performed e.g. on traffic gates like: underground. It is up to Customer if wants to enable such transactions or not (option selected during MDES onboarding). Transit transactions are enabled in every CVM model, however for Always CDCVM needs to be performed for every transaction, for Card-Like and Flexible CDCVM can be skipped.

Tokenization/Digitization

Tokenization is a process which enable to replace sensitive data, e.g. card number, with another string of characters - a secure payment token - as a result of which card data remains inaccessible. Payment tokens are assigned to a given device of the card owner, which means that an unauthorized person, even if he obtains the token data, will not be able to use them via another device. It is also secured inside the SDK. As a result of the tokenization process, the customer comes into possession of Transaction Credentials in a mobile application on his device.


Digitization decisions

Main processes

User and cards registration into wallet server

User with unique identifier known on issuer side is passing with cards to wallet server. After that process, device can be paired with.

Pairing device for particular user by trusted identity

Authentication of the device in context of given user. Process needed to allow access to wallet server from that particular device.

In the integrated model signed user identifier passed from issuer into wallet server via SDK is used to authenticate given user.

Digitization of the card

When device is paired user can have access to his own data: cards. After that he can digitize chosen card which was previously added into wallet server.

Digitized card profile provisioning on the device

After successful digitization, digitized card profile is delivered to device. Since only limited number of keys for transaction is delivered to the device, SDK calls replenish to cover up the number of transaction credentials.

Transaction credentials replenishment

Payment

Payment history(Optional)

It is possible to store transactions on wallet server.

Main steps and implementation

Issuer integration with MDES.

Use Cases

Version 2.1
March 2023

This section is dedicated for use cases which can be done by different API and initiated from different sources.

Wallet Server LC API Initiated

This section describes use cases which can be initiated using Wallet Server LC API. This API should be used by Customers to manage Users and cards data on Wallet Server.

User with Card Registration

User with Card Registration is process when user and cards are transferred to Wallet Server to make possible use them in different processes (e.g. digitization) later in the application. Registration needs to be done as the first step

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant Issuer
Issuer -> WS: 1. addUserWithCard(userData, cardData)
activate Issuer
activate WS
WS --> Issuer: 2. response(cardId)
deactivate WS
Issuer -> Issuer: 3. storeCardId
deactivate Issuer
@enduml

Card Reissuing

Since plastic cards have expiration date, Issuers may want to reissue them. In most cases PAN remains the same and only expiration date is extended. It is worth to mention that MDES does not check PAN expiry date for transactions performed with Payment Token. MDES offers API for Issuers where is possibility to update expiration date or even whole PAN for already provisioned Payment Tokens. In context of integration there are a few options:

All options needs to be considered individually and discussed with Verestro representative.

User Deletion

During this process all data related to given User are deleted. Payment Tokens are deleted asynchronously. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant Issuer
Issuer -> WS: 1. deleteUser(userId)
activate Issuer
activate WS
WS -> WS: 2. delete cards, devices
WS --> Issuer: 3. response
deactivate Issuer
loop All Payment Tokens for given User
WS -> MDES: 4. delete token
activate MDES
MDES --> WS: 5. response
opt
WS ->> Issuer: 6. send Payment Token event
end
deactivate WS
deactivate MDES
end
@enduml

Card Deletion

During card deletion process all data related to given card are deleted. Payment Tokens are deleted asynchronously. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
Issuer -> WS: 1. deleteCard(cardId)
activate WS
activate Issuer
WS -> WS: 2. deleteCard
WS --> Issuer: 3. response
deactivate Issuer
loop All Payment Tokens for card
WS -> MDES: 4. Delete token
activate MDES
MDES -> MDES: 5. Delete token mapping
MDES --> WS: 6. response
opt
WS ->> Issuer: 7. send Payment Token event
end
deactivate MDES
WS -> SDK: 8. deliverMessage(paymentTokenDelete)
NOTE LEFT: See: Handle Message From Server
deactivate WS
deactivate MPA
activate SDK
alt Request session if required
SDK -> MDES: 9. request session
activate MDES
MDES --> SDK: 10. response
MDES -> WS: 11. sendRemoteNotificationMessage
deactivate MDES
activate WS
WS -> SDK: 12. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
deactivate MPA
end
SDK -> MDES: 13. delete(tokenUniqueReference)
activate MDES
MDES --> SDK: 14. response
deactivate MDES
SDK -> SDK: 15. Delete transaction credentials, card profile
SDK -> MPA: 16. onPaymentInstrumentStatusChanged(id, status)
deactivate SDK
end
deactivate MPA
@enduml

Wallet SDK Initiated

Wallet SDK Setup

Setup of Wallet SDK (both modules VCP SDK and MDC SDK) is main step which needs to be made at very beginning. During setup main configuration should be provided. Moreover there is some configuration which is related with HCE payments: MPA should be registered as default application for payment (Tap & Pay) and also should implement HostApduService to emulate an NFC card inside an Android service component. Please find more details in Wallet SDK API document.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
participant MPA
participant "Wallet SDK" as SDK
MPA -> SDK: 1. MDC:setup(configuration)
activate MPA
activate SDK
SDK --> MPA: 2. result
MPA -> SDK: 3. UCP:setup(configuration)
SDK --> MPA: 4. result
deactivate MPA
deactivate SDK
@enduml

Pair Device on Wallet Server

This section describes pairing device process. Device pairing is process which authenticates device in context of given user. During this process device data and keys used in communication are exchanged with Wallet Server. To make possible device pairing, user needs to be already registered on the Wallet Server. Every device is identified by unique identifier. After every pairing device request, Wallet Server gives unique installation identifier. It means that particular installation of the application installed on particular device belongs to given User. Different Users can use same device for separate installations. If any active installation on given device already exists during pairing device, Wallet Server will delete and create new installation in context of new user. Only one active installation is possible on particular device. Device pairing is the first process which should be done after user registration. Pairing device should be done only once for individual installation.

Pair Device By Trusted Identity

In the integrated model, Trusted Identity is used to proof User authenticity. User is firstly authenticated on the Customer side. Trusted Identity should be generated on Issuer backend side and pass via Wallet SDK, since mobile environment is treated as unsecure. Algorithm of generating Trusted Identity is placed in Wallet SDK API specification.

Access to User data stored on Wallet Server is possible only when session is established. After paring device session is automatically generated for particular User. 

If previously on given device was installation which had Payment Tokens, during pairing these Payment Tokens are deleted asynchronously. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant "Issuer" as Issuer
participant "MDES" as MDES
MPA->Issuer: 1. authenticate
activate MPA
activate Issuer
Issuer->Issuer: 2. generateTrustedIdentity - signed user id
Issuer--> MPA: 3. response(trustedIdentity)
deactivate Issuer
MPA -> MPA: 4. obtainRNSToken(walletFirebase)
MPA-> SDK: 5. MDC:pairDeviceByTrustedIdentity\r(trustedIdentity, rnsRegistrationToken)
activate SDK
SDK -> SDK: 6. isDevicePaired
alt isDevicePaired=true
SDK --> MPA: 7. result
else isDevicePaired=false
SDK-> WS: 8. pairDeviceByTrustedIdentity\r(trustedIdentity, rnsRegistrationToken, deviceInfo)
activate WS
WS-> WS: 9. verify trusted identity
alt isActiveInstallationOnGivenDevice
WS -> WS: 10. deleteActiveInstallation
WS -> MDES: 11. deleteDeviceTokens
activate MDES
deactivate MDES
note left: asynchronous
end
WS -> WS: 12. createNewDeviceInstallationRecordForUser
WS --> SDK: 13. response\r (userSessionToken, installationId)
deactivate WS
SDK -> SDK: 14. store userSessionToken
SDK-->MPA: 15. result
deactivate MPA
deactivate SDK
end
@enduml

Card Digitization

Card digitization is process which allows to transform plastic card into Payment Token. To perform digitization, card data should be placed already on Wallet Server and device should be already paired. Card digitization process uses Wallet Server identifier of the card. There are two ways of performing card digitization. Usage of the API's depends on needs in given implementation.

Card Digitization Ways

Depending on implementation card can be digitized in different way using different approach. There are following ways of card digitization:

Card Digitization Ways - One Step

One step digitization is dedicated for implementations where there is no additional User authentication and there is no need to show terms and conditions before every digitization or show card art from MDES. Mostly it should be used in Issuer applications where NFC payments is added as a new functionality without additional staff which is used in dedicated wallets. Only transaction outcomes APPROVED(see APPROVED) or DECLINE(see DECLINE) are expected in this type of digitization.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant "MPA" as MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES as MDES
participant Issuer
MPA -> SDK: 1. UCP:Cards#digitize\r(paymentInstrumentId=verestroCardId, userLanguageCode, securityCode?)
activate MPA
activate SDK
SDK -> SDK: 2. isDeviceRegisteredForPayment
alt isDeviceRegisteredForPayment=false
SDK -> WS: 3. getPkCertificate
activate WS
WS -> MDES: 4. getPkCertificate
activate MDES
MDES --> WS: 5. response(pkCertificate)
WS --> SDK: 6. response(pkCertificate)
SDK -> SDK: 7. prepareDataForRegistration(pkCertificate)
SDK -> WS: 8. registerDeviceForPayment\r (paymentDeviceInfo, userSessionToken)
WS -> MDES: 9. registerMobilePaymentApplication\r (paymentDeviceInfo)
MDES --> WS: 10. response(mobileKeys,\r remoteManagementUrl)
WS --> SDK: 11. response(mobileKeys,\r remoteManagementUrl)
end
SDK -> SDK: 12. isPaymentInstrumentDigitized
alt isPaymentInstrumentDigitized=true
SDK --> MPA: 13. result
else isPaymentInstrumentDigitized=false
SDK -> WS: 14. digitizeCard\r (cardId, userSessionToken)
WS -> MDES: 15. checkEligibility(cardData, paymentAppId,\r paymentAppInstanceId)
MDES --> WS: 16. response (eligibilityReceipt)
WS -> MDES: 17. digitize(eligibilityReceipt)
MDES --> WS: 18. response
deactivate MDES
WS --> SDK: 19. response(paymentTokenInfo)
deactivate WS
SDK --> MPA: 20. result
deactivate SDK
deactivate MPA
end
deactivate SDK
deactivate MPA
note over SDK, WS #1C1E3F: See Card digitization outcome Approved or Decline diagram
@enduml

Card Digitization Ways - Multi step

Multi step digitization should be used in implementations where terms and conditions are displayed before every digitization, additional user authentication is needed or card art need to be used from MDES. Multi step digitization consists of following steps:

Digitization may finished with different outcomes(see Card Digitization Outcomes). 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
participant Issuer
MPA -> SDK: 1. UCP:Cards#checkEligibility(paymentInstrumentId=verestroCardId, locale)
activate MPA
activate SDK
SDK -> SDK: 2. isDeviceRegisteredForPayment
alt isDeviceRegisteredForPayment=false
SDK -> WS: 3. getPkCertificate
activate WS
WS -> MDES: 4. getPkCertificate
activate MDES
MDES --> WS: 5. response(pkCertificate)
WS --> SDK: 6. response(pkCertificate)
SDK -> SDK: 7. prepareDataForRegistration(pkCertificate)
SDK -> WS: 8. registerDeviceForPayment\r (paymentDeviceInfo, userSessionToken)
WS -> MDES: 9. registerMobilePaymentApplication\r (paymentDeviceInfo)
MDES --> WS: 10. response(mobileKeys,\r remoteManagementUrl)
WS --> SDK: 11. response(mobileKeys,\r remoteManagementUrl)
end
SDK -> WS: 12. checkEligibility(paymentInstrumentId,userSessionToken)
WS -> MDES: 13. checkEligibility(card)
MDES -->WS: 14. response(termsAndConditionsAssetId, eligibilityReceipt)
WS --> SDK: 15. response(termsAndConditionsAssetId, digitizationRef)
SDK --> MPA: 16. result(termsAndConditionsAssetId)
MPA -> SDK: 17. UCP:getAsset(termsAndConditionsAssetId)
SDK -> WS: 18. getAsset(termsAndConditionsAssetId)
WS -> MDES: 19. getAsset(termsAndConditionsAssetId)
MDES --> WS: 20. response(content)
deactivate MDES
WS --> SDK: 21. response(content)
deactivate WS
SDK --> MPA: 22. result
deactivate SDK
MPA -> User: 23. show T&C
deactivate MPA
User -> MPA: 24. accept
activate MPA
MPA -> SDK: 25. UCP:Cards#digitize(paymentInstrumentId, cvc?)
activate SDK
SDK -> WS: 26. digitize(digitizationRef, cvc?, userSessionToken)
activate WS
WS ->MDES: 27. digitize(eligibilityReceipt, cvc?)
activate MDES
MDES --> WS: 28. response(additionalAuthenticationRequired, authenticationMethods?, tokenInfo, productConfig)
deactivate MDES
WS --> SDK: 29. response(additionalAuthenticationRequired, authenticationMethods?, tokenInfo, productConfig)
deactivate WS
SDK --> MPA: 30. result
deactivate SDK
MPA -> User: 31. please wait
deactivate MPA
note over SDK, WS #1C1E3F: See Card digitization outcome Approved or Decline or Require Additional Authentication diagram
@enduml

Card Digitazation Outcomes

There are following digitization outcomes which should be handled differently:

APPROVED

This digitization outcome always refers to green path digitization decision. When digitization is APPROVED then profile provisioning(See Profile Provisioning) starts automatically. According to MDES architecture just after digitization Payment Token is in INACTIVE state even though does not require additional User authentication. Due that fact new flag was introduced which informs which Payment Token exactly needs to be additionally authenticated. After successful provisioning token is activated and then SDK will perform Transaction Credentials - Initial Replenishment.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES as MDES
participant Issuer
group APPROVED
MDES --> WS : 1. responseFromDigitization(APPROVED, cardDigitizationData)
activate MDES
activate WS
opt
WS ->>Issuer: 2. send Payment Token Event
end
WS --> SDK : 3. response(digitizatonData, paymentToken)
deactivate WS
activate SDK
SDK --> MPA : 4. result
activate MPA
MPA --> User : 5. result
deactivate MPA
... Profile Provisioning ...
note over MPA, MDES #1C1E3F: See Profile Provisioning diagram
... MDES Token Activation ...
SDK -> MDES: 6. notifyProvisioningResult
MDES -> MDES: 7. createTokenMapping
MDES -> WS: 8. notifyTokenUpdated(Active)
deactivate MDES
activate WS
opt
WS ->>Issuer: 9. send Payment Token Event
end
WS -> SDK: 10. deliverMessage(paymentTokenActive)
NOTE LEFT: See: Handle Message From Server
deactivate WS
SDK -> SDK: 11. updateTokenStatus
SDK -> MPA: 12. onPaymentInstrumentStatusChanged(id, status)
deactivate MPA
deactivate SDK
... Initial Replenishment ...
note over SDK, MDES #1C1E3F: Just after token activation transaction credentials initial replenishment is performed by SDK\r. See Transaction Credentials Initial Replenishment diagram
end
@enduml

DECLINE

This digitization outcome refers to red digitization decision. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES as MDES
group APPROVED
MDES --> WS : 1. responseFromDigitization(DECLINED)
activate MDES
deactivate MDES
activate WS
WS --> SDK : 2. response(error)
deactivate WS
activate SDK
SDK --> MPA : 3. result
deactivate SDK
activate MPA
MPA --> User : 4 result
deactivate MPA
@enduml

REQUIRE_ADDITIONAL_AUTHENTICATION

This digitization outcome always refers to yellow path digitization decision. When digitization is REQUIRE_ADDITIONAL_AUTHENTICATION then profile provisioning(See Profile Provisioning) starts automatically but remain INACTIVE until the User is authenticated(see Card Digitization Activation). Flag additionalAuthenticationRequired informs if additional user authentication is needed or not.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES as MDES
participant Issuer
group REQUIRE_ADDITIONAL_AUTHENTICATION
MDES --> WS : 1. responseFromDigitization(response(additionalAuthenticationRequired=true, authenticationMethods?, tokenInfo, productConfig))
activate MDES
deactivate MDES
activate WS
opt
WS ->> Issuer: 2. send Payment Token event
end
WS --> SDK : 3. response(response(additionalAuthenticationRequired=true, authenticationMethods?, tokenInfo, productConfig))
deactivate WS
activate SDK
SDK --> MPA : 4. result
deactivate SDK
activate MPA
MPA --> User : 5. result
deactivate MPA
... Profile Provisioning ...
note over MPA, MDES #1C1E3F: See Profile Provisioning diagram
... Card Digitization Activation ...
note over MPA, MDES #1C1E3F: See Card Digitization Activation diagram
end
@enduml

Card Digitization Activation

This process is applicable only if digitization has infomation that additional authentication is required. During this process User can choose one of the additional authentication methods. If user-entered authentication code is chosen then MDES will send authentication code which later should be provided by User for submission. Once user enters correct authentication code, Payment Token is activated by MDES asynchronously. After activation Wallet Server is notified that Payment Token is activated and this information is passed to Wallet SDK. After Payment Token activation, Wallet SDK start Transaction Credentials - Initial Replenishment.

NOTE: Submit authentication value is allowed only if provisioning is finished.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES as MDES
alt Just after digitization
MDES --> WS : 1. responseFromDigitization(additionalAuthenticationRequired=true, \rauthenticationMethods?, tokenInfo,productConfig)
activate MDES
activate WS
WS --> SDK : 2. response(additionalAuthenticationRequired=true, \rauthenticationMethods?, tokenInfo, productConfig)
activate SDK
SDK --> MPA: 3. result(authenticationMethods)
activate MPA
else Activation not finished after digitization
User -> MPA: 4. activate token
MPA -> SDK: 5. UCP::getAdditionalAuthenticationMethods(paymentInstrumentId)
SDK -> WS: 6. getAuthenticationMethods(cardId, userSessionToken)
WS --> SDK: 7. response(authenticationMethods)
SDK --> MPA: 8. result(authenticationMethods)
end
MPA --> User: 9. show authentication methods
User -> MPA: 10. select authentication method
MPA -> SDK: 11. UCP::submitTokenAuthenticationMethod(authenticationMethod)
deactivate MPA
SDK -> WS: 12. submitTokenAuthenticationMethod(authenticationMethod, userSessionToken)
deactivate SDK
WS -> MDES: 13. submitAuthenticationMethod(authenticationMethod)
deactivate WS
MDES -> Issuer: 14. deliverAuthCode(authCode)
deactivate MDES
activate Issuer
Issuer -> User: 15. deliver authCode
deactivate Issuer
alt Provisioning finished - onProvisioningSuccess(paymentInstrumentId) was called
User -> MPA: 16. enter authCode
NOTE LEFT: User should have possibility to enter code\n only when provisioning finished
activate MPA
MPA -> SDK: 17. UCP::submitTokenAuthenticationValue(authCode)
activate SDK
SDK -> WS: 18. submitTokenAuthenticationValue(authCode, userSessionToken)
activate WS
WS -> WS: 19. checkProvisioningStatus
WS -> MDES: 20. submitAuthenticationValue(authCode)
activate MDES
MDES -> MDES: 21. verify authCode
MDES --> WS: 22. response
WS --> SDK: 23. response
deactivate WS
SDK --> MPA: 24. response
deactivate SDK
deactivate MPA
MDES -> MDES: 25. createTokenMapping
MDES -> WS: 26. notifyTokenUpdated(Active)
deactivate MDES
activate WS
opt
WS ->>Issuer: 27. send Payment Token event
end
WS -> SDK: 28. deliverMessage(paymentTokenActive)
NOTE LEFT: See: Handle Message From Server
deactivate WS
SDK -> SDK: 29. updateTokenStatus
SDK -> MPA: 30. onPaymentInstrumentStatusChanged(id, status)
deactivate MPA
deactivate SDK
end
... Initial Replenishment ...
note over SDK, MDES #1C1E3F: Just after token activation transaction credentials initial replenishment is performed by SDK\r. See Transaction Credentials Initial Replenishment diagram
@enduml

Handle Message From Server

In whole system there are processes where server needs to send messages to the device. Wallet Server has separate component which is responsible for sending messages to the device. This component uses different channels for message delivery. There are two channels: SSE(Server Sent Events) and RNS(Remote Notification Service). When message is ready for delivery, Wallet Server uses both channels to deliver such message. In first versions of Wallet Server only RNS was used, however sometimes messages were not delivered and to improve delivery new SSE channel was introduced. This channel helps in processes which start from the device and device expects message from the server. Moreover device checks messages which are still not delivered on actions where such messages are expected. Below diagram describes how delivery message process works and how needs to be handled on MPA side.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant "MPA" as MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant "RNS" as RNS
opt
SDK -> WS: 1. callActionAfterWhichMessageIsExpected
WS --> SDK: 2. response
SDK -> WS: 3. openSSEConnection
end
WS -> WS: messageReadyForDelivery
opt If device has opened connection
WS -> SDK: 4. deliverUsingSSE
end
WS -> RNS: 5. deliverMessage
RNS --> WS: 6. response
RNS -> MPA: 7. deliverMessage
MPA -> MPA: 8. checkWalletSenderId
MPA-> SDK: 9. MDC:CloudMessage#process(pushData)
SDK -> SDK: 10. deduplicateMessage
SDK -> WS: 11. acknowledgeMessage
WS --> SDK: 12. response
SDK -> SDK: 13. processMessage
...Obtain pending messages...
MPA -> SDK: 14. someActionWhereMessageMayBeStillPending
SDK -> SDK: 15. doAction
SDK ->> WS: 16. getPendingMessages
WS --> SDK: 17. response
SDK -> SDK: do actions from 10 to 13

@enduml

Update RNS Token

Wallet Server is responsible for sending push notifications to the Wallet SDK. For that reason RNS token is passed to Wallet Server during pairing device or in some cases is obtained by SDK from MPA whenere is needed. However this token can be updated. MPA will be notified when token is being updated and then needs to obtain new RNS token and update via Wallet SDK on Wallet Server. Retrieving push notifications and RNS tokens is responsibility of the MPA.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant "Remote Notification Service" as RNS
activate RNS
RNS -> MPA: 1. onTokenRefresh
deactivate RNS
activate MPA
MPA -> MPA: 2. obtainNewToken(walletFirebase)
MPA -> SDK: 3. MDC::updateRegistrationToken(newRNSToken)
activate SDK
SDK -> WS: 4. updateRNSToken(deviceInstallationId, newRNSToken)
activate WS
WS -> WS: 5. updateRNSToken
WS --> SDK: 6. response
deactivate WS
SDK --> MPA: 7. result
deactivate SDK
deactivate MPA
deactivate RNS
@enduml

Profile Provisioning

During this process digitized card profile is delivered to the device. This process is triggered automatically after successful digitization where outcome is APPROVED or REQUIRE_ADDITIONAL_AUTHENTICATION. It is not possible to retry provisioning itself. To retry provisioning, previous token needs to be deleted and new digitization called hence when SDK reports that provisioning has failed then given token is automatically deleted and User can perform digitization once again. During process there is few point of failures and provisioning can be not finished at all. In this scenario Payment Tokens which are not provisioned for long period of time are delete by Wallet Server (see Removing Not Provisioned Tokens). From User perspective it can be good approach to treat digitization and provisioning as one process and inform User about steps(if User has to wait long time without any information then can treat this as some failure). From MPA perspective can be also good approach to wait for provisioning status as long as User stays on view dedicated to it. If User wants to cancel the process because provisioning status is not available for long period of time it is recommended to delete Payment Token(see Delete Payment Token via SDK) once User click cancel or back. Thanks to deletion, new digitization can be called and User does not have to wait until Payment Token is deleted by Wallet Server due to lack of provisioning. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES as MDES
MDES->WS: 1. sendRemoteNotificationMessage(mdesRemoteMessage)
activate MDES
deactivate MDES
activate WS
WS-> SDK: 2. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
activate SDK
SDK-> MDES: 3. provision
activate MDES
MDES --> SDK: 4. response(cardProfile)
SDK-> MDES: 5. notify provisioning result
MDES --> SDK: 6. response
deactivate MDES
SDK -> SDK: 7. store card profile
SDK -> WS: 8. confirmProvisioningStatus(SUCCESS/FAILURE)
activate WS
alt FAILURE
WS -> MDES: 9. deleteToken
activate MDES
MDES --> WS: 10. response
deactivate MDES
WS --> SDK: 11. response
SDK -> SDK: 12. deleteToken
SDK -> MPA: 13. onProvisioningFailure
activate MPA
MPA -> User: 14. please try again
deactivate MPA
else SUCCESS
WS --> SDK: 15. response
deactivate WS
SDK -> MPA: 16. onProvisioningSuccess(paymentInstrument)
deactivate SDK
activate MPA
MPA -> User: 17. card digitized successfully
deactivate MPA
end
@enduml

Getting Asset

Every field which's name consists of assetId is an identifier to some static asset. This asset can be:

There are different types of assets and multiple formats may be supported. For example a single image may be supported in various file formats or variant sizes and most appropriate format to use for a particular device.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant "MDES" as MDES
MPA -> SDK: 1. UCP::getAsset(assetId)
activate SDK
SDK -> WS: 2. getAsset(assetId)
activate WS
WS -> MDES: 3. getAsset(assetId)
activate MDES
MDES --> WS: 4. response(content)
deactivate MDES
WS --> SDK: 5. response(content)
deactivate WS
SDK --> MPA: 6. result(content)
deactivate SDK
@enduml

Transaction Credentials Replenishment

Transaction Credentials are unique per transactions keys that are used to calculate cryptograms in transactions. Each set of credentials is linked with a unique Application Transaction Counter (ATC). Each set of credentials can only be used for one transaction. There is a limit (set on MDES onboarding) of transaction credentials stored on device.

Transaction Credentials - Automatic Replenishment

After every transaction Wallet SDK checks if number of transaction credentials is below, preconfigured during SDK setup, threshold. If yes then SDK will call replenish. During replenish process transaction credentials are being delivered to mobile application.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES as MDES
SDK->SDK: 1. detectTransactionCredentialsRemainingBelowThreshold
alt Request session if required
activate SDK
SDK-> MDES: 2. requestSession
activate MDES
MDES--> SDK: 3. response
MDES-> WS: 4. sendRemoteNotificationMessage(mdesRemoteMessage)
deactivate MDES
activate WS
WS -> SDK: 5. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
end
SDK-> MDES: 6. replenish
activate MDES
MDES-> MDES: 7. checkIfPaymentTokenIsActive
MDES-->SDK: 8. response(transactionCredentials)
deactivate MDES
SDK->MPA: 9. onReplenishSuccess(paymentInstrument)
deactivate SDK
@enduml

Transaction Credentials - Initial Replenishment

Initial replenishment is process which starts directly after successful token activation. Wallet SDK is notified by Wallet Server using push notification or refreshing payment instruments. No action is needed by MPA.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES as MDES
WS -> SDK: 1. notifyTokenUpdated(Active)
activate WS
deactivate WS
activate SDK
alt Request session if required
SDK-> MDES: 2. requestSession
activate MDES
MDES--> SDK: 3. response
MDES-> WS: 4. sendRemoteNotificationMessage(mdesRemoteMessage)
deactivate MDES
activate WS
WS-> SDK: 5. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
end
SDK-> MDES: 6. replenish
activate MDES
MDES-> MDES: 7. checkIfPaymentTokenIsActive
MDES-->SDK: 8. response(transactionCredentials)
deactivate MDES
SDK -> MPA: 9. onReplenishSuccess(paymentInstrument)
deactivate SDK
@enduml

Transaction Credentials - Manual Replenishment

There are scenarios when automatic replenish is not possible (user is not able to connect with Internet) and after some number of transactions, transaction credentials number will decrease to 0. In such case MPA should handle NO_TRANSACTION_CREDENTIALS error from transaction listener, show user proper alert and call replenish method manually. MPA can also check number of transaction credentials at any other time.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES as MDES
MPA -> SDK: 1. UCP::replenishCredentials(paymentInstrumentId)
activate MPA
deactivate MPA
activate SDK
alt Request session if required
SDK-> MDES: 2. requestSession
activate MDES
MDES--> SDK: 3. response
MDES-> WS: 4. sendRemoteNotificationMessage
deactivate MDES
activate WS
WS-> SDK: 5. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
end
SDK-> MDES: 6. replenish
activate MDES
MDES-> MDES: 7. checkIfPaymentTokenIsActive
MDES-->SDK: 8. response(transactionCredentials)
deactivate MDES
SDK -> MPA: 9. onReplenishSuccess(paymentInstrument)
deactivate SDK
@enduml

Transacting

Wallet SDK provides functionalities to make contactless payments (using HCE) and e-commerce payments.

Contactless Transaction

Contactless transaction uses Android HCE. On MPA side HostApduService should be implemented. Depending on chosen CDCVM and on how transaction is started, user experience is different and MPA should interact with Wallet SDK in different way. The final decision about transaction processing belongs to MPA. Wallet SDK provides transaction information and based on that and User authentication, MPA can advise to proceed, decline or require authentication(if User should be authenticated but was not). For contactless transaction Wallet SDK provides result of transaction. This result is only from the communication between MPA and Terminal. Transaction Processing with Payment Network is done separately (see Transaction Processing). Also after every contactless transaction, Transaction Credentials Replenishment is performed automatically by SDK if needed(see Transaction Credentials - Automatic Replenishment).

NOTE: The way of authentication depends on MPA. For transaction User may also choose specific card. If no card is chosen, SDK will use the one which is set as default for contactless payments. Whenever user is authenticated or chose card for payment MPA should pass this information when onContactlessPaymentStarted is called. 

As was described above, the final decision(PROCEED, DECLINE, AUTHENTICATION_REQUIRED) for given transaction is taken on MPA side based on transaction information and User authentication. Because of that reason there could be different scenarios which may occur and transaction experience will be single or double tap.

Sample scenarios:

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "HostApduService" as HAS
participant "Wallet SDK" as SDK
participant Terminal as TER
opt User selects particular card for payment
MPA -> User: 1. showCards
activate MPA
User -> MPA: 2. selectCard
deactivate MPA
end
User -> MPA: 3. pay
User -> TER : 4. contactless 1st tap
activate TER
loop
TER -> HAS: 5. processCommandApdu(commandApdu, extras)
activate HAS
HAS -> SDK: 6. UCP::Pay#processHceApduCommand(apdu, extras)
activate SDK
group Select PPSE
SDK -> MPA: 7. onContactlessPaymentStarted()
activate MPA
MPA -> MPA: 8. checkIsUserAuthenticated
alt isAuthenticated=true
MPA -> SDK: 9. UCP::Pay#setUserAuthenticatedForPayment(paymentInstrumentId, pin?)
end
alt selectedCard == null
SDK -> SDK: 10. useDefaultPaymentInstrumentForContactless
else selectedCard != null
MPA -> SDK: 11. UCP::Pay#selectForPayment(selectedPaymentInstrumentId)
deactivate MPA
end
end
group Generate AC command
SDK -> MPA: 12. getFinalDecisionForTransaction(isUserAuthenticated,recommendedAdvice, trxInfo)
activate MPA
MPA -> MPA: 13. checkTrxAndAuthentication
MPA --> SDK: 14. result(advice)
deactivate MPA
end
SDK --> HAS: 15. responseApdu
HAS --> TER: 16. responseApdu
deactivate HAS
end
alt advice=AUTHENTICATION_REQUIRED
SDK -> MPA: 17. onAuthRequiredForContactless(paymentInstrument, trxInfo)
activate MPA
MPA -> User: 18. show authentication view with trx info
User -> MPA: 19. authenticate
User -> TER: 20. contactless 2nd tap
loop
TER -> HAS: 21. processCommandApdu(commandApdu, extras)
activate HAS
HAS -> SDK: 22. UCP::Pay#processHceApduCommand(apdu, extras)
group Select PPSE
SDK -> MPA: 23. onContactlessPaymentStarted()
MPA -> MPA: 24. checkIsUserAuthenticated
alt isAuthenticated=true
MPA -> SDK: 25. UCP::Pay#setUserAuthenticatedForPayment(paymentInstrumentId, pin?)
end
alt selectedCard == null
SDK -> SDK: 26. useDefaultPaymentInstrumentForContactless
else selectedCard != null
MPA -> SDK: 27. UCP::Pay#selectForPayment(selectedPaymentInstrumentId)
end
end
group Generate AC command
SDK -> MPA: 28. getFinalDecisionForTransaction(isUserAuthenticated=true,recommendedAdvice, trxInfo)
MPA -> MPA: 29. checkTrxAndAuthentication
MPA --> SDK: 30. result(PROCEED)
end
SDK --> HAS: 31. responseApdu
HAS --> TER: 32. responseApdu
deactivate HAS
deactivate TER
end
end
SDK -> MPA: 33. onContactlessPaymentCompleted(paymentInstrument, trxInfo, trxResult)
deactivate SDK
MPA -> User: 34. show trx info view
deactivate MPA
...Transaction Processing ...
note over HAS #1C1E3F: See Transaction Processing diagram
...Transaction Credentials Automatic Replenishment ...
note over HAS #1C1E3F: See Transaction Credentials Automatic Replenishment diagram
@enduml

E-commerce transaction

E-commerce transaction can be processed using DSRP. Every DSRP transaction has to be authenticated. Depending on implementation e-commerce payment can be preceded with one time password authentication or just device level authentication.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
box "Consumer mobile android device" #white
participant "Merchant App" as MerchantApp
participant MPA
participant "Wallet SDK" as SDK
end box
participant Merchant
participant "Wallet Server" as WS
participant MDES
participant Issuer
participant "Payment Gateway" as PG
User -> MerchantApp: 1. pay
activate MerchantApp
MerchantApp -> Merchant: 2. startTransaction
activate Merchant
Merchant --> MerchantApp: 3. response(transactionId,\r unpredictableNumber)
deactivate Merchant
MerchantApp -> MPA: 4. getDsrpData(transactionId, trxInfo)
deactivate MerchantApp
activate MPA
alt One Time Password
MPA -> User: 5. select payment instrument
User -> MPA: 6. payment instrument
MPA -> SDK: 7. UCP::requestAuthCodeForPayment(transactionId \ras authenticationRequestId)
activate SDK
SDK -> WS: 8. requestAuthenticationCodeForPayment(authenticationRequestId)
activate WS
WS -> MDES: 9. requestAuthenticationCodeForPayment(authenticationRequestId)
activate MDES
MDES -> Issuer: 10. sendAuthenticationCode
activate Issuer
Issuer --> MDES: 11. response
MDES --> WS: 12. response
deactivate MDES
WS --> SDK: 13. response
deactivate WS
SDK --> MPA: 14. result
deactivate MPA
deactivate SDK
Issuer -> User: 15. sendAuthenticationCode(authenticationCode)
deactivate Issuer
User -> MPA: 16. provide authentication code
activate MPA
MPA -> SDK: 17. UCP::validateAuthenticationCodeForPayment(authenticationCode,\r transactionId)
activate SDK
SDK -> WS: 18. validateAuthenticationCodeForPayment(authenticationCode,\r authenticationRequestId)
activate WS
WS -> MDES: 19. authenticate(authenticationCode,\r authenticationRequestId)
activate MDES
MDES --> WS: 20. response
deactivate MDES
WS -> WS: 21. createDigitalSignature(authenticationRequestId)
WS --> SDK: 22. response(digitlSignature)
deactivate WS
SDK --> MPA: 23. result(digitalSignature)
else Device Level Auth
MPA -> User: 24. show authentication view
User -> MPA: 25. authenticate
end
MPA -> SDK: 26. UCP::setUserAuthenticatedForPayment(id, pin?)
MPA -> SDK: 27. UCP::processDsrpTransaction(id, trxInfo)
SDK --> MPA: 28. result(dsrpData)
deactivate SDK
MPA --> MerchantApp: 29. result(dsrpData)
deactivate MPA
activate MerchantApp
MerchantApp -> MerchantApp: 30. encryptPaymentDataForTransit(dsrpData)
MerchantApp -> Merchant: 31. finishTransaction(encryptedPaymentData, \rdigitalSignature?, transactionId)
activate Merchant
opt
Merchant -> Merchant: 32. validateSignature
note right: this check is needed to proof that given transactionId\n\r was preceded with OTP
end
Merchant -> PG: 33. processPayment(pan, exp, cryptogram)
activate PG
PG --> Merchant: 34. response
deactivate PG
Merchant --> MerchantApp: 35. response
deactivate Merchant
MerchantApp -> User: 36. show result
deactivate MerchantApp
@enduml

Transaction Processing

Transaction Processing starts after contactless communication between terminal and MPA in case of contactless payment or after payment gateway transaction authorization initiation in case of e-commerce payment. After authorization MDES notifies Wallet Server about the result of the authorization and sends transaction information. Transaction information is sent to MPA.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant "Terminal/PG" as TER
participant "Payment Network" as PN
participant MDES
participant Issuer
TER -> PN: 1. authorizeTransaction(tokenPAN, cryptogram)
activate PN
activate TER
PN -> MDES: 2. detokenize
activate MDES
MDES -> MDES: 3. lookup token mapping
MDES --> PN: 4. response(PAN)
deactivate MDES
PN -> Issuer: 5. authorize(PAN)
activate Issuer
Issuer --> PN: 6. response
deactivate Issuer
PN --> TER: 7. response
deactivate TER
PN -> MDES: 8. storeTransactionDetails
deactivate PN
activate MDES
MDES -> WS: 9. pushTransactionDetails
deactivate MDES
activate WS
alt store transaction enabled
WS -> WS: 10. storeTransaction
end
opt
WS ->>Issuer: 11. send transaction event
end
WS -> SDK: 12. deliverMessage(trxInfo)
NOTE LEFT: See: Handle Message From Server
deactivate WS
activate SDK
SDK -> MPA: 13. onNewTransaction(trxDetails)
deactivate SDK
activate MPA
MPA -> User: 14. showSystemNotification(trxDetails)
deactivate MPA
@enduml

Setting Defaults for Payment

SDK manages default Payment Instrument for contactless payments. After digitization, if there is no default Payment Instrument, SDK sets digitized Payment Instrument after activation as default. In case where there are more than one active Payment Instruments and current default Payment Instrument is deleted or suspended, the SDK will set first active Payment Instrument as default. Default Payment Instrument can be changed at any time. Only active Payment Instrument can be set as default.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
MPA->User: 1. payment instrument list
activate MPA
User->MPA: 2. choose default for contactless payment)
MPA->SDK: 3. UCP::setDefaultForContactless(paymentInstrumentId)
activate SDK
SDK-> SDK: 4. storeDefault
SDK-->MPA: 5. result
deactivate MPA
deactivate SDK
@enduml

Login On Wallet Server

User data are protected by User session token which is issued by Wallet Server after providing authentication factor. Authentication factor is provided first in pairing device and then session is created. Since session has limited period of validity, it needs to be refreshed using login on Wallet Server methods.

Login on Wallet Server using Trusted Identity

In the Integrated implementation model User authentication doesn't occur directly on Wallet Server. Wallet Server will require User authentication when some user data will be requested. If User session token is no longer valid, SDK will return USER_UNATHORIZED error. In such case Trusted Identity needs to be prepared on Issuer server and sent via Wallet SDK in loginByTrustedIdentity method. MPA can decide whether ask User to provide authentication data or not. The latter case regards situation when user is already authenticated and Trusted Identity can be immediately returned from Issuer based on already valid session on Issuer side. During login process Wallet Server checks if given device still exists, if not then responds with CANT_FIND_DEVICE status which is interpreted on SDK side as given device is deleted and all local data stored on SDK side are cleared.

Since MDC 2.14.5 for devices which are already paired, Wallet SDK will try to asynchronously register device in new delivery message service. To make it possible CloudMessagingRegistrationProvider needs to be implemented and provided within setup. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant "Issuer" as Issuer
MPA -> SDK: 1. invoke API
activate MPA
activate SDK
SDK -> WS: 2. invoke API
activate WS
WS --> SDK: 3. response(USER_UNATHORIZED)
deactivate WS
SDK --> MPA: 4. result(USER_UNATHORIZED)
MPA->User: 5. show authenticate view
User->MPA: 6. put authentication data
MPA->Issuer: 7. authenticate
activate Issuer
Issuer -> Issuer: 8. generateTrustedIdentity - signed user id
Issuer --> MPA: 9. response(trustedIdentity)
deactivate Issuer
MPA-> SDK: 10. MDC::loginByTrustedIdentity(trustedIdentity)
SDK-> WS: 11. loginByTrustedIdentity(trustedIdentity)
alt Device not registered in new delivery message service
SDK -> MPA: 12. CloudMessagingRegistrationProvider::getRegistrationToken
SDK ->> WS: 13. registerDeviceForNewMessageDelivery(cloudMessageToken)
WS --> SDK: 14. response
end
activate WS
WS -> WS: 15. check if device exists
alt device exists
WS-> WS: 16. verify trusted identity
WS --> SDK: 17. response(userSessionToken)
SDK -> SDK: 18. store(userSessionToken)
SDK-->MPA: 19. result
MPA -> SDK: 20. invoke API
else device not exists
WS --> SDK: 21. response(CANT_FIND_DEVICE)
deactivate WS
SDK -> SDK: 22. clearAllLocalData
SDK --> MPA: 23. result(CANT_FIND_DEVICE)
deactivate MPA
deactivate SDK
... Pair device ...
note over MPA, WS #1C1E3F: See Pairing Device diagram
MPA -> SDK: 24. invoke API
end
@enduml

Getting Cards

When cards are already placed on Wallet Server, then they can be displayed to User in the application. Cards have identifiers which can be used e.g. for digitization.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
MPA->SDK: 1. MDC::getAllCards
activate MPA
activate SDK
SDK -> WS: 2. getAllCards(userSessionToken)
WS --> SDK: 3. response(userCards)
deactivate WS
SDK --> MPA: 4. result(cardList)
deactivate SDK
deactivate MPA
@enduml

Getting Payement Intruments

After digitization process, payment instrument is stored in VCP SDK module of Wallet SDK. Payment instrument in context of VCP SDK is digitized card and contains information like:

MPA can get information about all Payment Instruments from the Wallet SDK at any time. Payment instruments will be retrieved only from local storage that is part of SDK. Payment Tokens for Payment Instruments can be refreshed/pulled from Wallet Server on demand. This scenario should be considered only when User e.g. makes swipe to refresh.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant "Issuer" as IS
MPA->SDK: 1. UCP::getAllPaymentInstruments(refresh)
activate MPA
alt refresh = true
activate SDK
SDK -> WS: 2. getAllPaymentTokens(userSessionToken)
activate WS
WS -> SDK: 3. response(devicePaymentTokens)
deactivate WS
SDK -> SDK: 4. updateLocalStorage
end
SDK --> MPA: 5. result(paymentInstrumentList)
deactivate SDK
deactivate MPA
@enduml

Getting Transaction History

It is possible that transaction history will be stored on Wallet Server for infinite timeThis should be specified during onboarding. If this options is enabled, MPA can retrieve transaction history for given user and filtering. Transactions are returned in corresponding parts for better user experience. If next part is available then response from previous part contain information needed for requesting next part. MPA should check if next part is not empty and then make another request.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
loop next != null
MPA->SDK: 1. MDC::getTransactionsHistory(filters, next?)
activate MPA
activate SDK
SDK -> WS: 2. getTransactionHistory(filters, next?, userSessionToken, ...)
activate WS
WS -> SDK: 3. response(transactionHistoryList, next?)
deactivate WS
SDK --> MPA: 4. result(transactionHistoryList, next?)
deactivate SDK
deactivate MPA
end
@enduml

Payment Token Lifecycle Management via SDK

Payment Token lifecycle management can be done via SDK.

Delete Payment Token via SDK

Payment Token can be deleted using SDK. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
participant Issuer
User -> MPA: 1. Delete payment token
activate MPA
MPA -> SDK: 2. UCP::delete(paymentInstrumentId, reason)
deactivate MPA
activate SDK
SDK -> WS: 3. deletePaymentToken(userSessionToken, paymentTokenId, reason)
activate WS
WS -> MDES: 4. Delete token
activate MDES
MDES -> MDES: 5. Delete token mapping
MDES --> WS: 6. response
deactivate MDES
WS --> SDK: 7. response
opt
WS ->> Issuer: 8. send Payment Token event
end
deactivate WS
alt Request session if required
SDK -> MDES: 9. request session
activate MDES
MDES --> SDK: 10. response
MDES -> WS: 11. sendRemoteNotificationMessage
deactivate MDES
activate WS
WS -> SDK: 12. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
end
SDK -> MDES: 13. delete(tokenUniqueReference)
activate MDES
MDES --> SDK: 14. response
deactivate MDES
SDK -> SDK: 15. Delete transaction credentials, card profile
SDK -> MPA: 16. onPaymentInstrumentStatusChanged(id, status)
deactivate SDK
MPA --> User: 17. show update view
deactivate MPA
@enduml

Errors Reporting

Wallet SDK performs some security checks. When any issue is detected, Wallet SDK reports error to Wallet Server and clears own data. Also notification to MPA is called.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
SDK -> SDK: 1. detectSecurityIssue
activate SDK
SDK -> SDK: 2. clearSDKData
SDK -> WS: 3. reportSecurityIssue
activate WS
deactivate WS
deactivate SDK
SDK -> MPA: 4. onSecurityIssueAppeared(event)
activate MPA
deactivate MPA
MPA -> User: 5. show information
@enduml

Device Unpairing

Unpairing device clears all modules data and report that fact only if possible to server. If server receives this signal then removes all device data including provisioned Payment Tokens. If not then data are cleared locally only - similar like during app uninstallation. This can be used for scenario when MPA does not want to use SDK at all or for scenario when MPA supports switching between users accounts on the same installation. If MPA detects that new User is trying to log into application in case when previous had digitized cards, immediately should clear all data from previous, since SDK stores data in context of one User only. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
MPA -> SDK: 1. MDC::unpairDevice
activate MPA
activate SDK
opt
SDK -> WS: 2. unpairDevice
activate WS
WS --> SDK: 3. response
deactivate WS
end
SDK -> SDK: 4. clearAllData
SDK --> MPA: 5. result
deactivate SDK
deactivate MPA
@enduml

MDES Initiated

This section describes use cases which are initiated from MDES.

Re-digitization

Re-digitization process can be triggered by MDES for several use cases:

Token Expiry

One month before token expiry MDES will request for redigitization. 

Attribute Change

Issuer may perform an attribute change at the BIN account-range level impacting theri MDES enabled ranges. Some device tokens may need to have their data refreshed to match the new attributes.

BIN Account-Range Split

Issuer may perform a BIN account-range split. Some existing tokens may need to be updated to ensure that they are linked to the correct funding BIN account ranges internally.

PAN Update in Different Account Range

Issuer may update existing PAN with new Pan in a different BIN account range. 

For above cases:

After successful redigitization process transaction credentials replenishment is called in case where Payment Token is active.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
MDES -> WS: 1. notifyTokenUpdated(redigitize=true)
activate MDES
activate WS
WS -> MDES: 2. redigitize
MDES --> WS: 3. response
WS --> MDES: 4. response
deactivate MDES
deactivate WS
MDES->WS: 5. sendRemoteNotificationMessage(mdesRemoteMessage)
activate MDES
deactivate MDES
activate WS
WS-> SDK: 6. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
activate SDK
SDK-> MDES: 7. provision(redigitize=true)
activate MDES
MDES --> SDK: 8. response(cardProfile)
SDK-> MDES: 9. notify provisioning result(redigitize=true)
MDES --> SDK: 10. response
SDK -> WS: 11. confirmReProvisioningStatus(SUCCESS/FAILURE)
alt FAILURE
WS -> WS: 12. markRedigitizationAsFailed
note left: redigitization process will be retried after some period of time
SDK -> MPA: 13. onReProvisioningFailure(paymentInstrument)
else SUCCESS
SDK -> SDK: 14. clearTransactionCredentials
SDK -> MPA: 15. onReProvisioningSuccess(paymentInstrument)
deactivate SDK
MDES -> WS: 16. notifyTokenUpdated(redigitized=false)
deactivate MDES
activate WS
opt
WS ->> Issuer: 17. send Payment Token event
end
WS -> SDK: 18. deliverMessage(PAYMENT_TOKEN_INFO_CHANGE(redigitized=true))
NOTE LEFT: See: Handle Message From Server
deactivate WS
activate SDK
SDK -> SDK: 19. replenish
... Automatic Replenishment ...
note over SDK, MDES #1C1E3F: Just after reprovisioning transaction credentials initial replenishment is performed by SDK\r. See Transaction Credentials Initial Replenishment diagram
end
@enduml

Wallet Server Initiated

Since important processes are asynchronous in MDES and there are many point of failures, wallet server provides additional functionalities to resolve some failure scenarios by running some operations on own side.

Removing Not Provisioned Tokens

Wallet Server checks periodically DEVICE Payment Tokens and verify if provisioning is completed. These Payment Tokens which have provisioning status in progress for long period of time are deleted automatically and from User perspective process needs to be started again. By default this period is set to 1 hour but can be modified.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
WS -> WS: 1. find not provisioned payment tokens for a\r long period of time
activate WS
loop Not provisioned payment tokens for a long period of time
WS -> MDES: 2. Delete token
activate MDES
MDES -> MDES: 3. Delete token mapping
MDES --> WS: 4. response
deactivate MDES
opt
WS ->> Issuer: 5. send Payment Token event
end
WS -> SDK: 6. deliverMessage(paymentTokenDelete)
NOTE LEFT: See: Handle Message From Server
deactivate WS
activate SDK
alt Request session if required
SDK -> MDES: 7. request session
activate MDES
MDES --> SDK: 8. response
MDES -> WS: 9. sendRemoteNotificationMessage
deactivate MDES
activate WS
WS -> SDK: 10. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
end
SDK -> MDES: 11. delete(tokenUniqueReference)
activate MDES
MDES --> SDK: 12. response
deactivate MDES
SDK -> SDK: 13. Delete transaction credentials, card profile
SDK -> MPA: 14. onPaymentInstrumentStatusChanged(id, status)
deactivate SDK
end
deactivate MPA
@enduml

Wallet Server Admin API Initiated

This section describes use cases which are initiated from Wallet Server Admin Panel.

Admin Card Deletion

During this process all data related to given card are deleted. Payment Tokens are deleted asynchronously. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
participant "Admin Panel" as AP
participant Issuer
AP -> WS: 1. deleteCard(cardId)
activate WS
activate AP
WS -> WS: 2. deleteCard
WS --> AP: 3. response
deactivate AP
loop All Payment Tokens for card
WS -> MDES: 4. Delete token
activate MDES
MDES -> MDES: 5. Delete token mapping
MDES --> WS: 6. response
deactivate MDES
opt
WS ->>Issuer: 7. send Payment Token event
end
WS -> SDK: 8. deliverMessage(paymentTokenDelete)
NOTE LEFT: See: Handle Message From Server
deactivate WS
activate SDK
alt Request session if required
SDK -> MDES: 9. request session
activate MDES
MDES --> SDK: 10. response
MDES -> WS: 11. sendRemoteNotificationMessage
deactivate MDES
activate WS
WS -> SDK: 12. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
end
SDK -> MDES: 13. delete(tokenUniqueReference)
activate MDES
MDES --> SDK: 14. response
deactivate MDES
SDK -> SDK: 15. Delete transaction credentials, card profile
SDK -> MPA: 16. onPaymentInstrumentStatusChanged(id, status)
deactivate SDK
end
deactivate MPA
@enduml

Admin Device Deletion

During this process all data related to given device are deleted. Payment Tokens are deleted asynchronously. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
participant "Admin Panel" as AP
AP -> WS: 1. deleteDevice(deviceInstallationId)
activate AP
activate WS
WS --> AP: 2. response
deactivate AP
loop All Payment Tokens for given device
WS -> MDES: 3. delete token
activate MDES
MDES --> WS: 4. response
deactivate WS
deactivate MDES
end
@enduml

Admin Token Deletion

Payment Token can be deleted via admin panel. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
participant "Admin Panel" as AP
AP -> WS: 1. deletePaymentToken(paymentTokenId)
activate AP
activate WS
WS -> MDES: 2. Delete token
activate MDES
MDES -> MDES: 3. Delete token mapping
MDES --> WS: 4. response
deactivate MDES
WS --> AP: 5. response
deactivate AP
opt
WS ->> Issuer: 6. send Payment Token event
end
WS -> SDK: 7. deliverMessage(paymentTokenDeleted)
deactivate WS
activate SDK
NOTE LEFT: See: Handle Message From Server
deactivate MDES
alt Request session if required
SDK -> MDES: 8. request session
activate MDES
MDES --> SDK: 9. response
MDES -> WS: 10. sendRemoteNotificationMessage
deactivate MDES
activate WS
WS -> SDK: 11. deliverMessage(mdesRemoteMessage)
NOTE LEFT: See: Handle Message From Server
deactivate WS
end
SDK -> MDES: 12. delete(tokenUniqueReference)
activate MDES
MDES --> SDK: 13. response
deactivate MDES
SDK -> SDK: 14. Delete transaction credentials, card profile
SDK -> MPA: 15. onPaymentInstrumentStatusChanged(id, status)
deactivate SDK
MPA --> User: 16. show update view
deactivate MPA
@enduml

Admin Token Suspension

Payment Token can be suspended via admin panel.

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
participant "Admin Panel" as AP
participant Issuer
AP -> WS: 1. suspendToken(paymentTokenId)
activate WS
activate AP
WS -> MDES: 2. suspend token
activate MDES
MDES -> MDES: 3. Suspend token
MDES --> WS: 4. response
deactivate MDES
WS --> AP: 5. response
deactivate AP
opt
WS ->> Issuer: 6. send Payment Token event
end
WS -> SDK: 7. deliverMessage(paymentTokenSuspend)
NOTE LEFT: See: Handle Message From Server
deactivate WS
activate SDK
SDK -> SDK: 8. suspend
SDK -> MPA: 9. onPaymentInstrumentStatusChanged(id, status)
deactivate SDK
deactivate MPA
@enduml

Admin Token Unsuspension

Payment Token can be unsuspended via admin panel. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
participant "Admin Panel" as AP
AP -> WS: 1. unsuspendToken(paymentTokenId)
activate WS
activate AP
WS -> MDES: 2. unsuspend token
activate MDES
MDES -> MDES: 3. Unsuspend token
MDES --> WS: 4. response
deactivate MDES
WS --> AP: 5. response
deactivate AP
opt
WS ->>Issuer: 6. send Payment Token event
end
WS -> SDK: 7. deliverMessage(paymentTokenUnsuspend)
deactivate WS
activate SDK
SDK -> SDK: 8. activate
SDK -> MPA: 9. onPaymentInstrumentStatusChanged(id, status)
deactivate SDK
deactivate MPA
... Replenishment ...
note over SDK, MDES #1C1E3F: Just after token activation transaction credentials replenishment is performed by SDK\r. See Transaction Credentials Automatic Replenishment diagram
@enduml

Admin User Deletion

During this process all data related to given User are deleted. Payment Tokens are deleted asynchronously. 

@startuml
skinparam ParticipantPadding 30
skinparam BoxPadding 30
skinparam noteFontColor #FFFFFF
skinparam noteBackgroundColor #1C1E3F
skinparam noteBorderColor #1C1E3F
skinparam noteBorderThickness 1
skinparam sequence {
ArrowColor #1C1E3F
ArrowFontColor #1C1E3F
ActorBorderColor #1C1E3F
ActorBackgroundColor #FFFFFF
ActorFontStyle bold
ParticipantBorderColor #1C1E3F
ParticipantBackgroundColor #1C1E3F
ParticipantFontColor #FFFFFF
ParticipantFontStyle bold
LifeLineBackgroundColor #1C1E3F
LifeLineBorderColor #1C1E3F
}
actor User
participant MPA
participant "Wallet SDK" as SDK
participant "Wallet Server" as WS
participant MDES
participant "Admin Panel" as AP
AP -> WS: 1. deleteUser(userId)
activate AP
activate WS
WS -> WS: 2. delete cards, devices
WS --> AP: 3. response
deactivate AP
loop All Payment Tokens for given User
WS -> MDES: 4. delete token
activate MDES
MDES --> WS: 5. response
deactivate WS
deactivate MDES
end
@enduml


Summary of Changes

This section describes changes introduced in next version based on time

Version 2.0
Version 2.1

Technical Documentation VCP SDK

VCP SDK Introduction

Basic abbreviations and definitions

Field Description
CDCVM Consumer Device Cardholder Verification Method
CVM Cardholder Verification Method
Contactless

Transactions performed by tapping the mobile device on a POS, which starts data exchange. On the Android device operating system passes received data from POS to the HCE service, implemented in the MPA,
and then to VCP SDK. HCE support is required for contactless transactions

DSRP

Digital Secure Remote Payments - transactions initiated from a mobile device, engaging interaction with
the remote merchant system. HCE support is not required for DSRP transactions

FCM

Firebase Cloud Messaging

HCE Host Card Emulation
IBAN Bank Account Number
MCBP Mastercard Cloud Based Payments
MDC

Mobile Data Core. Verestro core library.

MPA

Mobile Payment Application - an application that uses VCP SDK for payments

NFC Near Field Communication
One tap

Flow in a contactless transaction, in which the consumer after authentication(using the PIN, fingerprint, etc.)
taps the device to POS to start exchanging data 

PAN Primary account number. Know as a card number. 
Payment Instrument

Model keeping all data considering entity used for payments

POS Point Of Sale
QRC

QR Code transactions - allows consumer generate QR code to present to a merchant,
who then scans it to take payment 

SUK

Single Use Key - unique credential used for single transaction 

Two tap 

Flow in a contactless transaction, in which consumer firstly taps device to POS,
authenticates(using the PIN, fingerprint, etc.), then taps to POS one more time for exchanging data

TVC Token Verification Code
EWS External Wallet Server
VCP
Verestro Cloud Payment

What is VCP SDK?

The VCP (Verestro Cloud Payments) SDK is a module for digitization, payment, and token management for available payment instruments. Usage of VCP SDK depends on Mobile DC SDK which is the core of the Verestro module. Payment instruments can be provided to VCP SDK using the Mobile DC module.payment

How VCP SDK works?

Provides methods to manage digitization using main domains:

Depending on the selected payment instrument source (Card, Iban, External Wallet Server) VCP SDK allows to digitize it and provide methods for the payment process.

Usage of the following domains depends on client requirements.

Versioning and backward compatibility

SDK version contains three digits. For example: 1.0.0.

Changes not breaking compatibility:

Technical overview

SDK Basic configuration

The minSdkVersion must be at least 23 (Android 6.0). The application must use AndroidX. 

SDK is available on the Verestro maven repository and can be configured in a project using the Gradle build system.

The username and password are provided by Verestro.

repositories{
	maven {
		credentials {
			username "<enter_username_here>"
			password "<enter_password_here>"
		}
		url "https://artifactory.upaid.pl/artifactory/libs-release-local/"


		//if the sync time takes too long, add filters to match the repository with specific modules as below
		content {
    		includeGroupByRegex "pl.upaid.*"
    		includeGroup "com.mastercard"
		}
	}
}

VCP SDK is available in two versions: debug and release.

Debug version is ended with appendix "-debug" in version name. Samples below:

For release version:

dependencies{
	implementation 'pl.upaid.module:ucpsdk:{version}'
}

For debug version:

dependencies{
	implementation 'pl.upaid.module:ucpsdk:{version}-debug'
}

Min SDK Version

The minSdkVersion must be at least 23 (Android 6.0). In case of using SDK on lower Android API version declare in the application manifest.

  <uses-sdk tools:overrideLibrary= "pl.upaid.module.ucp, 
    pl.upaid.module.mobiledc, pl.upaid.module.mcbp,
    pl.upaid.module.security, com.mastercard.mpsdk, pl.upaid.nativesecurity" />

SDK cannot be initialized on a lower Android API version, and none of the SDK methods should be used on it.


VCP SDK Size

The size of SDK is dependent on its distribution system.

The table below shows the size of the module for the ask and bundle file.

Format Size Notes
APK ~37 MB
Bundle ~7 MB

Ranged size depends on the ABI of the device.

SDK contains native libraries used by different ABI. By using a bundle only the necessary
version of the native library will be downloaded to a device.

VCP size already includes Mobile DC SDK size.

Additional information:


VCP SDK Usage

This chapter describes the structure and basic usage of VCP SDK.


Domains

Every of the described facades is divided into domains with different responsibilities. Available domains:

Every domain contains domain-related methods.


Error handling

Works like in Mobile DC SDK, but provides additional BackendException reason codes (only when Verestro Wallet Server is used) and additional exceptions for specific methods.

SDK provides errors by exceptions, which could be caught by the application and shown on UI with a detailed message.

Note: VCP SDK can throw exceptions from Mobile DC SDK as its core of the Verestro module.

Exception type Exception class Description
SDK validation ValidationException Additional reason codes for ValidationException used in Mobile DC SDK 
Backend exception BackendException

Additional reason codes for BackendException used in Mobile DC SDK.

Note: Not applicable for External Wallet Server domain 

SDK exception UcpSdkException Something went wrong on the SDK side, check the table below with possible reasons 
Process related -

As every process is different some methods could throw a specified exception

Types of possible exceptions are described in the method description

Additional BackendException reason codes:

Reason

Description

INTERNAL_ERROR

Error occurred on server

VALIDATION_ERROR

Client sent invalid data

CRYPTOGRAPHY_ERROR

Error occurred during cryptography operation

PAYMENT_CARD_PREDIGITIZE_ERROR

Predigitize of payment card failed

PAYMENT_IBAN_PREDIGITIZE_ERROR

Predigitize of payment IBAN failed

PAYMENT_CARD_DIGITIZE_ERROR

Digitize of payment card failed

PAYMENT_IBAN_DIGITIZE_ERROR

Digitize of payment IBAN failed

PAYMENT_CARD_PREDIGITIZE_NOT_EXECUTED

Predigitize for payment card must be executed

PAYMENT_IBAN_PREDIGITIZE_NOT_EXECUTED

Predigitize for payment IBAN must be executed

CLIENT_UNAUTHORIZED

Client of the API is unauthorized

USER_UNAUTHORIZED

User is unauthorized

CANT_FIND_USER

Cannot find user

CANT_FIND_DEVICE

Cannot find device

CANT_FIND_IBAN

Cannot find payment IBAN

CANT_FIND_CARD

Cannot find payment card

CANT_FIND_PAYMENT_TOKEN

Cannot find payment token

OPERATION_NOT_SUPPORTED

Requested operation is not supported

OPERATION_NOT_ALLOWED

Requested operation is not allowed

DEVICE_TEMPORARILY_LOCKED

Device is temporarily locked

DEVICE_PERMANENTLY_LOCKED

Device is permanently locked

INVALID_PAN

The PAN format is not valid, or other data associated with the PAN was incorrect or entered incorrectly

MISSING_EXPIRY_DATE

The expiry date is required for this product but was missing

PAN_INELIGIBLE

The PAN is not in an approved account range for TSP

DEVICE_INELIGIBLE

The device is not supported for use

PAN_INELIGIBLE_FOR_DEVICE

The PAN is not allowed to be provisioned to the device because of Issuer rules

IBAN_INELIGIBLE

The financial account does not have an associated account range in TSP

PARALLEL_REQUESTS_ATTEMPTS

Action is already processing. Please try again after the time included in headers 

INVALID_JWS_TOKEN Specified JWS token is invalid

Additional ValidationException reason codes:

Reason Description

INVALID_SECURITY_CODE

Security code is empty

INVALID_LANGUAGE_CODE

Language code is empty

INVALID_PAYMENT_INSTRUMENT_ID

Payment instrument id is empty

UcpSdkException reason codes:

Reason Description

PUSH_INVALID_SOURCE

Relates to push processing process. Push message should be consumed in another module

PUSH_INVALID_PUSH_CONTENT

Cannot process push message. The message is invalid or some process failed

PAYMENT_INSTRUMENT_DEFAULT_NOT_FOUND

Cannot find default PaymentInstrument

PAYMENT_INSTRUMENT_NOT_FOUND

Selected PaymentInstrument cannot be found, is not digitized or active

APPLICATION_PROCESS_NOT_KILLED

Occurs when after using the reset method, there is a try of using any of the facade methods without previously stopping the application process


Facade

The facade is an entry point to communication with VCP SDK.

Contains SDK initialization method and domains which allows for payment instrument management.


Method structure

Please read Mobile DC Documentation for details.


Multiple facade types

VCP SDK provides three public APIs with the same functionalities, the APIs are:

The difference between the APIs is a way of providing data to SDK methods and getting the results from them. Input and output as information data are the same.

This documentation presents I/O types in a Kotlin way as it’s easier to mark nullable fields (as a question mark).


HceApduService registration

To register HceApduService firstly it needs to be created a class that extends a default HostApduService. Added class needs to be added to the manifest file as a service.

Properly configured meta-data in service will also register an application as tap&pay ready.

Exemplary service below:

<service
	android:name=".WalletHceService"
	android:exported="true"
	android:permission="android.permission.BIND_NFC_SERVICE">
		
		<intent-filter>
			<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />		
		</intent-filter>
		
		<meta-data
			android:name="android.nfc.cardemulation.host_apdu_service"
			android:resource="@xml/hce_apdu_service" />
 </service>

Below listing of the default source file hce_apud_service.xml:

<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
	android:apduServiceBanner="@drawable/hce_logo"
	android:description="@string/hce_service_description"
	android:requireDeviceUnlock="false">
	<!-- If the requireDeviceUnlock is set to false, on some phones you can pay if the screen is not awake, 
    but on most devices the screen must be awake to make a payment. -->
	
	<aid-group
    	    android:category="payment"
    	    android:description="@string/aid_description">

		<!-- Following is a PPSE AID. You must always include this AID in order for payments to work-->

	 	<aid-filter android:name="325041592E5359532E4444463031" />

		<!-- Following AID list is specific to the application requirements.
	       If your application supports the type of card that these AID represents,
	       you must include those AID in your configuration file -->

		<aid-filter android:name="A0000000041010" /> <!-- Mastercard DEBIT/CREDIT -->
	    <aid-filter android:name="A0000000042203" /> <!-- Mastercard US DEBIT/CREDIT -->
	    <aid-filter android:name="A0000000043060" /> <!-- Maestro DEBIT -->
	    <aid-filter android:name="A0000000049100" /> <!-- Private label AID-->
	</aid-group>
</host-apdu-service>

Check if the application is set as default for payment.

fun isSystemDefault(): Boolean {
	val cardEmulation = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(context))
    return cardEmulation.isDefaultServiceForCategory(
        WalletHceService::class.java,
        CardEmulation.CATEGORY_PAYMENT
    )
}

Request for set your application as default for payment - will show a dialog for the user to approve the changes.

fun requestForSystemDefault() {
    val intent = Intent().apply {
        action = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT"
        putExtra("component", WalletHceService::class.java)
        putExtra("category", CardEmulation.CATEGORY_PAYMENT)
    }
    context.startActivity(intent)
}

If the application is not set as default for payment and wants to make payment from opened application needs to set the preferred service. Requires system option "On top application is the default for HCE" enabled. 

fun registerAsOnTopHceApplication() {
	val cardEmulation = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(context))
    cardEmulation.setPreferredService(
        activity, ComponentName(activity, WalletHceService::class.java)
    )
}


fun unregisterFromOnTopHceApplication() {
	val cardEmulation = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(context))
    cardEmulation.unsetPreferredService(activity)
}


Models

PaymentInstrument
Parameter Type Description
id String

Id of payment instrument. For card it is cardId, for IBAN sha256Hex.

In the context of the External Wallet Server use tokenUniqueReference from MDES

paymentTokenId String Id of payment token. Used for getting transactions history (see Mobile DC documentation) only for selected token id 
displayablePanDigits String

Token last 4 digits which can be used to display

paymentInstrumentStatus PaymentInstrumentStatus

Enum with status of payment instrument. 

contactlessSupported Boolean

Information if payment instrument supports contactless transactions. 

dsrpSupported Boolean

Information if the payment instrument supports DSRP transactions. 

qrcSupported Boolean

Information if the payment instrument supports QR transactions. 

onDeviceCvmSupported Boolean

Information about supporting CVM on device. 

credentialsCount Int

Amount of credentials that can be used for payments. 

isDefaultForContactlessPayment

Boolean

Information if payment instrument is default for contactless payments. 

isDefaultForRemotePayment Boolean

Information if payment instrument is default for remote payments. 

additionalAuthenticationRequired Boolean

Is additional authentication for payment token activation required. If true, available authentication methods can be obtained using getAdditionalAuthenticationMethods

tokenLastFourDigits String?

Payment Token last four digits. Present only when multistep digitization is used(checkEligibility and digitize called separately).

paymentInstrumentExpirationDate String?

Payment instrument expiry date in format MM/YY. Present only when multistep digitization is used(checkEligibility and digitize called separately).

paymentInstrumentLastFourDigits
String?

Payment instrument last four digits. Present only when multistep digitization is used(checkEligibility and digitize called separately).

productConfig
ProductConfig?

Payment Token configuration. Present only when multistep digitization is used(checkEligibility and digitize called separately).

provisioningStatus
String

Current state of provisioning process. One of:
IN_PROGRESS - in case of waiting for onProvisioningSuccess(),
SUCCESS - when token is provisioned.

paymentTokenExpirationDate String?

Payment token expiry date in format MM/YY. Not present when External Wallet Server is enabled.


PaymentInstrumentStatus
Field Description
INACTIVE

Payment instrument is not active, it can not be used for transactions.

The activation process depends on integration. Read the product overview for more information.

ACTIVE

Payment instrument is active and it can be used for transactions.

SUSPENDED Payment instrument is suspended.
DELETED

Payment instrument is DELETED.

UNKNOWN Payment instrument status is unknown.

AdditionalAuthenticationMethod
Parameter Type Description
id String Identifier of additional authentication method 
name String

Method name. One of:

OTP_TO_CARDHOLDER_NUMBER, OTP_TO_CARDHOLDER_EMAIL, CARDHOLDER_TO_CALL_CUSTOMER_SERVICE, CARDHOLDER_TO_VISIT_WEBSITE, CARDHOLDER_TO_USE_ISSUER_MOBILE_APPLICATION, ISSUER_TO_CALL_CARDHOLDER_NUMBER 

value String Value depends on method name. Described below. 
issuerParameters AuthMethodsIssuerParameters? Non null if method is CARDHOLDER_TO_USE_ISSUER_MOBILE_APPLICATION


Additional authentication method values:
Method Value Description
OTP_TO_CARDHOLDER_NUMBER

Masked phone number 

Text message to Account holder’s mobile phone number. The value will be the Account holder’s masked mobile phone number.
OTP_TO_CARDHOLDER_EMAIL

Masked email 

Email to Account holder’s email address. The value will be the Account holder’s masked email address.
CARDHOLDER_TO_CALL_CUSTOMER_SERVICE

Phone number 

Account holder-initiated call. The value will be the phone number for the Account holder to call Customer Service.

CARDHOLDER_TO_VISIT_WEBSITE

Website URL

Account holder to visit a website. The value will be the website URL.

CARDHOLDER_TO_USE_ISSUER_MOBILE_APPLICATION

Application name

(Conditional) Issuer’s mobile app name. The method is available for both MDES and VTS but the value will be presented only for VTS.

ISSUER_TO_CALL_CARDHOLDER_NUMBER

Masked phone number

Issuer-initiated voice call to Account holder’s phone. The value will be the Account holder’s masked voice call phone number.


AuthMethodsIssuerParameters contains the following fields:
Parameter Type Description
mdes AuthMethodsIssuerParametersMdes? Plain AuthMethodsIssuerParametersMdes object, required for MDES Payment Token
vts AuthMethodsIssuerParametersVts? Required for VTS Payment token


AuthMethodsIssuerParametersMdes contains following fields:
Parameter Type Description
android AuthMethodsIssuerParametersMdesAndroid Plain AuthMethodsIssuerParametersMdesAndroid object. Required for Android device
ios AuthMethodsIssuerParametersMdesIos Plain AuthMethodsIssuerParametersMdesIos object. Required for IOS device


AuthMethodsIssuerParametersMdesAndroid contains following fields:
Parameter Type Description
action String? Name of the action to be performed
packageName String? The package name of the issuer's mobile app
extraTextValue String? Contains the data to be passed through to the target app in the intent as an extra key/value pair with key ‘android.intent.extra.TEXT’. This is Base64-encoded data of a JSON object of the MobileAppActivationParameters. This object is not described since the whole payload is passed to the issuer app


AuthMethodsIssuerParametersMdesIos contains following fields:
Parameter Type Description
deepLinkingUrl String? The deep linking URL of the issuer’s iOS mobile app. This identifies the app that the URL will resolve to. If the app is not installed on the user’s device, this URL can be used to open a link to the appropriate iOS app store for the user to download and install the app.
extraTextValue String? Contains the data to be passed through to the target app in the deep linking URL as a query parameter. It should be appended to the deepLinkingUrl when invoked in the format: deepLinkingUrl + ‘?extraTextValue=’ + extraTextValue. This is Base64-encoded data of a JSON object of the MobileAppActivationParameters. This object is not described since the whole payload is passed to the issuer app.


AuthMethodsIssuerParametersVts contains following fields:
Parameter Type Description
android AuthMethodsIssuerParametersVtsAndroid? Plain AuthMethodsIssuerParametersVtsAndroid object.
Required for Android devices
ios AuthMethodsIssuerParametersVtsIos? Plain AuthMethodsIssuerParametersVtsIos object.
Required for IOS devices


AuthMethodsIssuerParametersVtsAndroid contains following fields:
Parameter Type Description
appId String? Unique identifier for the application within the application store.
appUrl String? URL of the application in the application store.
intentUrl String? URL of banking app designed to respond to authentication code handling.
requestPayload String? The request payload is to be sent to the banking application on behalf of Visa.
This field is opaque to wallet providers.


AuthMethodsIssuerParametersVtsIos contains following fields:
Parameter Type Description
appId String? Unique identifier for the application within the application store.
appUrl String? URL of the application in the application store.
intentUrl String? URL of banking app designed to respond to authentication code handling.
requestPayload String? The request payload is to be sent to the banking application on behalf of Visa.
This field is opaque to wallet providers.

ContactlessTransactionInformation
Parameter Type Description
currencyCode ByteArray

Code of currency, that was used in transaction. Formatted in ISO 4271.

amount ByteArray Transaction amount in bytes. Can be formatted as Int in pennies.
transactionRange ContactlessTransactionRange

Type of transaction range.

richTransactionType ContactlessRichTransactionType

Rich transaction type.

merchantAndLocation ByteArray Merchant and location data from terminal. Can be formatted as String, by using UTF_8 Charset.


ContactlessTransactionRange

Value

Description

LVT Low value transaction
HVT

High value transaction

UNKNOWN Unknown


ContactlessRichTransactionType

Value
PURCHASE
REFUND
CASH
TRANSIT
PURCHASE_WITH_CASHBACK
UNKNOWN
DsrpTransactionInfo
Parameter Type Descruption
amount Long Transaction amount
currencyCode Int

Code of currency, that was used in transaction.

countryCode Int

Code of country.

issuerCryptogramType String Cryptogram type.

TransactionAbortReason
Value Description
WALLET_CANCEL_REQUEST Indicates that the wallet has requested a transaction cancellation during payment.
CARD_ERROR

This indicates that a problem has been detected in the MChipEngine processing.

In some implementations, this can indicate badly formatted card profile data.

TERMINAL_ERROR

This indicates incorrect terminal behavior. 

NO_TRANSACTION_CREDENTIALS  There are no transaction credentials to finalize payment. The application should call replenish Credentials method to enable payment possibility.
NO_CARDS There is no active PaymentInstrument to start payment. Called when no card is added to Wallet or SDK is cleared by Security Issue (onSecurityIssueAppeared event).
TERMINAL_INACTIVITY_TIMEOUT

There is a problem with communication between the terminal and payment device.

For example, the terminal could abort communication with the mobile device for
a long period of time and then trigger a timeout.

Usually, a mobile device loses connection during payment due to a wrong or too short tap on the terminal.

The application should ignore this status as SDK waits for connection establishment and it could produce getting duplicate callbacks during payment.

Note: When user authentication is already provided it could be cleared - the application should handle card selection (if a non-default card is selected) and payment authentication again.

Note: Deprecated in 2.6.7, no longer used due to time difference between connection lost and providing result to application. Replaced by CONNECTION_LOST which works immediatelly.

CONNECTION_LOST

Connection between terminal and device is lost and payment is terminated.


NewTransaction
Field Type Description

clientTransactionId

String?

Identifier of transaction in TSP

type

String

The transaction type. One of: [UNKNOWN, PURCHASE, REFUND, PAYMENT, ATM_WITHDRAWAL, CASH_DISBURSEMENT, ATM_DEPOSIT, ATM_TRANSFER]

amountMinor

Long

The monetary amount in terms of the minor units of the currency. For example,
`EUR 2.35' will return 235, and `BHD -1.345' will return -1345

currency

String

3-digit ISO 4217 currency code

timestamp

String

The date/time when the transaction occurred. In ISO 8601 extended format

merchantName

String?

The merchant (``doing business as'') name

merchantPostalCode

String?

The postal code of the merchant

transactionCountryCode

String?

The country in which the transaction was performed. Expressed as a 3-letter (alpha-3) country code as defined in ISO 3166-1

comboCardAccountType

String?

An indicator if Credit or Debit was chosen for a tokenized combo card at the time of the transaction. One of: [UNKNOWN, CREDIT, DEBIT]

issuerResponseInformation

String?

Additional information is provided by the issuer for a declined transaction. Only returned if the transaction is declined. One of: [UNKNOWN, INVALID_CARD_NUMBER, FORMAT_ERROR, MAX_AMOUNT_EXCEEDED, EXPIRED_CARD, PIN_AUTHORIZATION_FAILED, TRANSACTION_NOT_PERMITTED, WITHDRAWL_AMOUNT_EXCEEDED, RESTRICTED_CARD, WITHDRAWL_COUNT_EXCEEDED, PIN_TRIES_NUMBER_EXCEEDED, INCORRECT_PIN, DUPLICATE_TRANSMISSION]

status

String

The authorization status of the transaction. One of: [AUTHORIZED, DECLINED, CLEARED, REVERSED]

paymentTokenId

String

Identifier of payment token in VCP


ContactlessTransactionData
Parameter Type Description
currencyNumber Int Currency number assigned to the currencyCode in ISO 4271 e.g.: for PLN is 985.
currencyCode String?

Code of currency, that was used in transaction formatted in ISO 4271. e.g.: PLN

Could be null as the terminal provides only the currencyNumber and a valid code could be not found.

amountMinor Long The monetary amount in terms of the minor units of the currency. For example, `EUR 2.35' will return 235,
transactionRange ContactlessTransactionRange

Type of transaction range.

richTransactionType ContactlessRichTransactionType

Rich transaction type.

merchantAndLocation String

Merchant and location data from terminal.

Deprecated - field shouldn't be used as it could be not configured in terminal configuration or provides invalid data.

ContactlessTransactionRange

Value

Description

LVT Low value transaction
HVT

High value transaction

UNKNOWN Unknown

ContactlessRichTransactionType

Value Description
PURCHASE
REFUND
CASH
TRANSIT
PURCHASE_WITH_CASHBACK
UNKNOWN
WITHDRAWAL
ATM_CONTACTLESS


Report
Parameter Type Description
name String Action name
description String Action details message.
isSuccess Boolean Result of action. True when action is finished successfully, false otherwise.
timestamp Long Time when the action occurred.
errorMessage String? Detailed error message when isSuccess is false.


ContactlessAdvice
Parameter Description
DECLINE

Declines a processing transaction.

When provided by SDK in getFinalDecisionForTransaction wallet should not overrule a DECLINE.

If the MPA overrules a DECLINE (and forces it into PROCEED), the transaction is likely to be declined by the issuer in the authorization response.

AUTHENTICATION_REQUIRED

An user authentication is required for transaction processing, which could be overruled on the MPA side.
When the MPA decision is AUTHENTICATION_REQUIRED, SDK will ask for user authentication in the onAuthRequiredForContactless method.

PROCEED Transaction can be processed.


ContactlessTransactionResult

Important: MPA should always refer to transaction results on the terminal.

Value Description

Is success on MPA side

AUTHORIZE_ONLINE

This indicates that the SDK returned an ARQC cryptogram using valid credentials and the POS will send the transaction online for authorization.

The SDK is not informed whether or not the issuer actually approved or declined the transaction since this information is only returned to the terminal.

Should be treated as transaction success on the MPA side.

Yes
AUTHENTICATE_OFFLINE

This indicates that the POS requested a decline (AAC) with a CDA signature.

SDK will have returned a cryptogram using valid credentials and the POS can authenticate the card offline using the CDA signature.

Typically a POS will request a decline when it simply wants to authenticate that a legitimate digital card is being used without requesting any authorization.

Should be treated as transaction success on the MPA side.

Yes
DECLINE_BY_TERMINAL

The POS has requested a decline without a CDA signature. This may correspond to a real decline by the terminal, or (in rare cases) to an online authentication request.

Paying on the terminal with offline-only network connectivity can also return this callback.

Application Cryptogram was generated with genuine credentials.

Should be treated as transaction success on the MPA side.

Yes
DECLINE_BY_CARD

The digitized card has declined the transaction. A non-exhaustive list of possible reasons may be:

  • Context mismatch between first and second tap
  • Terminal is offline-only
  • Terminal is a transit gate, and transit transactions are not allowed by the card profile
  • Transaction is international, while the card profile is domestic-only
No
WALLET_ACTION_REQUIRED

If the getFinalDecisionForTransaction returns an AUTHENTICATION_REQUIRED status then this result will be returned.

The SDK will have declined the transaction but requested that the POS should keep the context active for a subsequent tap.

If the POS does not support mobile devices then the merchant may need to repeat the transaction with the same amount so that the second tap can take place.

No


External libraries

The SDK uses several external Apache 2.0 libraries:

VCP SDK Setup

VCP SDK has to be configured every time when is used. Before VCP SDK usage Mobile DC SDK should be already configured.

setup

Synchronous. Offline.
Contains all the necessary data to configure SDK.
Should be called at the very beginning of the application lifecycle. For example in the Android Application::onCreate method.

Requires MobileDC setup() already finished

Setup methods could be called in another thread then Main to improve application start time. In case of calling setup method in another thread application must check before every SDK usage if setup method is already finished.

When SDK is integrated into the app and user can enable or disable it as a featere - the SDK setup can be ommited during Application start and loaded on demand.


Important: Before calling VCP SDK setup you must call setup from Mobile DC SDK.

Implementation of Application::on Create should be as quick as possible. Invocation time directly impacts on the performance of payment and loading first aplication screen.

Input

Parameter Type Description

Validation conditions

ucpConfiguration UcpConfiguration

VCP configuration provided in builder described below.

Not empty.


UcpConfigurationBuilder contains the following methods:

Metod Parameter Description

Validation conditions

withApplication Application Application context. Not empty
withCvmModel WalletCvmModel (enum)

Customer Verification Method: CDCVM_ALWAYS, FLEXIBLE_CDCVM, CARD_LIKE

Not empty
withUserAuthMode WalletAuthMode (enum)

User authentication mode: WALLET_PIN, CUSTOM, NONE

Contact Verestro to select proper configuration

Not empty

withUcpPaymentInstrument
EventListener

UcpPaymentInstrument
EventListener

Global listener for actions on PaymentInstrument.

Not empty
withUcpTransaction
EventListener

UcpTransactionEventListener

Deprecated - use MobileDcApiConfigurationBuilder.withOptionalMobileDcTransactionEventListener from MDC SDK instead. Global listener for actions during transaction processing

Not empty
withTransactionAcceptance
EventListener
UcpTransactionAcceptance
EventListener
Global listener which allow application take final decision about transaction acceptance during transaction Not empty
withReplenishThreshold Int

Number of credentials below which replenish process will automatically begin

Not empty
withMcbpPinningCertificates List<String>

List of public key certificates in PEM format.

Pass list with empty String if withOptionalUcpMcbpHttpExecutor mentioned below is used with custom HTTP communication.

Not empty List

withOptionalEventsReports UcpEventReportListener Global listener for most important internal SDK actions related to token management. Could be useful for logs grabbing and debugging on debug.
Optional
withOptional
ExternalWalletServer
Boolean Prepares SDK for using external wallet server. Optional
withOptional
UcpMcbpHttpExecutor
UcpMcbpHttpExecutor/
DefaultUcpMcbpHttpExecutor
Global listener for connection between SDK and MasterCards API. Could be use for adding action before connection - use DefaultUcpMcbpHttpExecutor or for completely replace this connection - use UcpMcbpHttpExecutor. Optional
withOptional
UcpReProvisionEventListener
UcpReProvisionEventListener Global listener for actions during reprovisioning. Optional
withOptional
UcpTransactionConfiguration
UcpTransactionConfiguration

Transaction configuration. Allow to enable deprecated authentication timer called when authentication is peformed.

Timer is disabled by default, usage is not recomended.

Optional
withOptionalWalletMcbpHttpExecutor Boolean

Prepares SDK for processing CMS-D HTTP requests with Wallet Server proxy.

Optional


UcpPaymentInstrumentEventListener

Contains callbacks for PaymentInstrument.

Method name Parameters

Description

onProvisioning
Success

paymentInstrument: PaymentInstrument

Method called after provisioning process. Information about PaymentInstrument activation process will be provided in onPaymentInstrumentStatusChanged callback described below

onProvisioning
Failure

errorMessage: String?,

exception: Exception?

Method called after provisioning failure. Try processing digitization again

onReplenish
Success

paymentInstrument: PaymentInstrument

numberOfTransactionCredentials: Int

Method called after successfully transaction credentials replenish. Provides information about PaymentInstrument and number of new transaction credentials.

Depending on flow is called after activation process and when requested by SDK based on replenishThreshold configuration.

Note: Replenish could be called just after transaction based on withRplenishThreshold configuration. It's recommended to not do complex process here. It could affect on next transaction processing time when multiple transactions are done in row

onReplenish
Failure

paymentInstrument: PaymentInstrument,

errorMessage: String?,

exception: Exception?

Method called after replenish failure with PaymentInstrument

Note: Replenish could be called just after transaction based on withRplenishThreshold configuration. It's recommended to not do complex process here. It could affect on next transaction processing time when multiple transactions are done in row

onPayment
Instrument
StatusChanged

newStatus: PaymentInstrument
Status

paymentInstrumentId: String

Provides information about PaymentInstrumentStatus state (check model) for selected payment instrument id

onNewTransaction

newTransaction: NewTransaction

Provides online result with details of transaction processed in VCP

Works only when application is online


UcpTransactionEventListener

Important: It's recommended to not do complex process in there callbacks. It could significantly affect on transaction processing time.

Method name Parameters

Description

onAuthRequired
ForContactless

paymentInstrument: PaymentInstrument, transactionInformation: 
ContactlessTransactionInformation
transactionData: ContactlessTransactionData

Called when user authentication is required during contactless transaction

ContactlessTransactionInformation is deprecated in version 2.2.4.

onAuthRequired
ForDsrp

paymentInstrument: PaymentInstrument, dsrpTransactionInfo: DsrpTransactionInfo

Called when user authentication is required during Dsrp transaction

onAuthTimer
Updated
secondsRemaining: Int

Called on every update of remaining time for performing transaction, as SDK starts transaction timer based on card profile configuration.
Note: Deprecated and disabled by default in version 2.6.7.

To enable use configuration avaialble in SDK setup::withOptionalUcpTransactionConfiguration.

onContactless
PaymentStarted

-

Called on very beginnging of every transaction start (SELECT_PPSE APDU command). E.g. first tap to terminal or second tap if onAuthRequiredForContactless method was called.

Locks communication until method is finished.
Method duration directly impacts on transaction time.

onContactless
Payment
Completed

paymentInstrument: PaymentInstrument
transactionInformation: ContactlessTransactionInformation

transactionResult: ContactlessTransactionResult
transactionData : ContactlessTransactionData

Called when transaction is completed with information about transaction and result.

ContactlessTransactionInformation is deprecated in version 2.2.4.

onContactless
Payment
Incident

paymentInstrument: PaymentInstrument,

exception: Exception

Called when something went wrong during transaction and Mastercard marked transaction as incident

onContactless
Payment
Aborted

paymentInstrument: PaymentInstrument?,

abortReason: TransactionAbortReason,

exception: Exception

Called when transaction is aborted during payment from some reason described in method parameter

PaymentInstrument could be null if abortReason = TransactionAbortReason.NO_CARDS is returned.


Note: SDK clears passed selected card with method selectForPayment() and authentication with setUserAuthenticatedForPayment()

onTransaction
Stopped


Method called on transaction stopped by SDK.
Deprecated in version 2.6.7, no longer used.


UcpTransactionAcceptanceEventListener

Important: It's recommended to not do complex process in there callbacks. It could significantly affect on transaction processing time.

Method name Parameters

Description

getFinal
Decision
ForTransaction

isUserAuthenticated : Boolean

recommendedAdvice : ContactlessAdvice

trasactionInformation : ContactlessTransactionInformation

transactionData : ContactlessTransactionData

Called on every transaction for the final decision about transaction processing

An application can decide based on information about authentication, transaction details like amount, currency, and transaction types

The method also provide recommended by MCBP advice  based on  transaction

ContactlessTransactionInformation is deprecated in version 2.2.4.


UcpEventReportsListener

Method name Parameters

Description

onNewReport

report: Report

Return logs related to token management.


UcpReProvisionEventListener

Called when transaction is completed with information about transaction and result.

ContactlessTransactionInformation is deprecated in version 2.2.4.

Method Name Parameters Description
onReProvisionSuccess paymentInstrument: PaymentInstrument

Method called after reProvisioning process.
Information about PaymentInstrument activation process will be provided in onPaymentInstrumentStatusChanged callback.

onReProvisionFailure

paymentInstrument : PaymentInstrument

errorMessage : String?

exception : Exception?

Method called after reProvisioning failure. Try again.


UcpMcbpHttpExecutor

Method name

Parameters

Description

execute

ucpMcbpRequestType: UcpMcbpHttpExecutorRequestType,
ucpMcbpHttpMethod:

UcpMcbpHttpMethod,
url: String,
requestData:Any,
requestProperties:

Map<String, String>

Called on every time if SDK want to connect to MasterCard and should return UcpMcbpHttpResponse.

requestData could be one of request data type: UcpMcbpRequestSessionRequestData,
UcpMcbpReplenishRequestData, UcpMcbpProvisionRequestData, UcpMcbpNotifyProvisioningResultRequestData,
UcpMcbpChangeMobilePinRequestData, UcpMcbpDeleteRequestData.

ucpMcbpHttpMethod could be one of: POST, GET.
ucpMcbpRequestType could be one of: REQUEST_SESSION, REPLENISH, PROVISION,
NOTIFY_PROVISIONING_RESULT, CHANGE_MOBILE_PIN, DELETE.


DefaultUcpMcbpHttpExecutor

Method name

Parameters

Description

execute

ucpMcbpRequestType: UcpMcbpHttpExecutorRequestType

ucpMcbpHttpMethod: UcpMcbpHttpMethod

url: String

requestData: Any

requestProperties: Map<String, String>

Called on every time if SDK want to connect to MasterCard and should return super.execute method.

requestData could be one of request data type: UcpMcbpRequestSessionRequestData,
UcpMcbpReplenishRequestData, UcpMcbpProvisionRequestData, UcpMcbpNotifyProvisioningResultRequestData,
UcpMcbpChangeMobilePinRequestData, UcpMcbpDeleteRequestData.

ucpMcbpHttpMethod could be one of: POST, GET.
ucpMcbpRequestType could be one of: REQUEST_SESSION, REPLENISH, PROVISION,
NOTIFY_PROVISIONING_RESULT, CHANGE_MOBILE_PIN, DELETE.

UcpTransactionConfiguration

Parameter

Type

Description

enableTransaction
AuthenticationTimer

Boolean

Allows to enable deprecated authentication timer.


Timer is started along setUserAuthenticatedForPayment(), result is available in onAuthTimerUpdated().

Callback samples:

UcpTransactionEventListener

// UcpTransactionEventListener comments

class BankingAppUcpTransactionEventListener : UcpTransactionEventListener {

    override fun onAuthRequiredForContactless(event: EventAuthRequiredForContactless) {
        //authorization is required for transaction, open payment screen with authorization
        //show PaymentInstrument and ContactlessTransactionData available in event object

        showPaymentScreen(event.paymentInstrument, event.transactionData)
    }


    override fun onAuthRequiredForDsrp(event: EventAuthRequiredForDsrp) {
        //authorization is required for transaction, open payment screen with authorization
        //show PaymentInstrument and DSRP transaction information available in event object

        showPaymentScreen(event.paymentInstrument, event.dsrpTransactionInfo)
    }

    override fun onAuthTimerUpdated(event: EventAuthTimerUpdated) {
        //check if user is on payment screen and update timer
        //when timer is 0, application should close payment with failure
        
		//deprcated, disabled by default, read method description how to enable
    }

    override fun onContactlessPaymentAborted(event: EventContactlessPaymentAborted) {
        //looks like payment is aborted, can provide result to payment screen 
        //and show user what is abort reason
    }

    override fun onContactlessPaymentCompleted(event: EventContactlessPaymentCompleted) {
        //payment completed, provide result to payment information
        //REMEMBER Transaction is processed on terminal and this is where 
        //you will see final transaction result
    }

    override fun onContactlessPaymentIncident(event: EventContactlessPaymentIncident) {
        //something went wrong during transaction, provide result to user
    }

    override fun onTransactionStopped() {
        //deprecated, not used anymore, 
    }
    
    override fun onContactlessPaymentStarted() {
        //Payment started or resumed after callback onAuthReqiredForContactless
        //Best place for checking if user is authenticated for payment and call
        //setUserAuthenticatedForPayment() and selectForPayment() methods if non-defaut card is selected
    }
}

UcpPaymentInstrumentEventListener

class BankingAppPaymentInstrumentEventListener : UcpPaymentInstrumentEventListener {

    override fun onNewTransaction(event: EventNewTransaction) {
        //information about new transaction processed by issuer
    }

    override fun onPaymentInstrumentStatusChanged(event: EventPaymentInstrumentStatusChanged) {
        //status of payment instrument was changed, refresh list, inform user about new status
    }

    override fun onProvisioningFailure(event: EventProvisioningFailure) {
        //provisioning failed, try again
    }

    override fun onProvisioningSuccess(event: EventProvisioningSuccess) {
        //provisioning success, wait for status and replenish changes until user can pay 
        //or provide activation method when required
    }

    override fun onReplenishFailure(event: EventReplenishFailure) {
        //transaction credentials replenish failed
    }

    override fun onReplenishSuccess(event: EventReplenishSuccess) {
        //transaction credentials replenish success
    }
}

UcpTransactionAcceptanceEventListener

class BankingAppUcpTransactionAcceptanceEventListener : UcpTransactionAcceptanceEventListener {

    //Sample implementation of transaction acceptance listener
    
	//For the scanario when authentication is required on issuer side for every transaction 
    //field even.isUserAuthenticated must be always true, otherwise 
    //ContactlessAdvice.AUTHENTICATION_REQUIRED should be returned

    override fun getFinalDecisionForTransaction(event: EventGetFinalDecision): ContactlessAdvice {

        val isScreenUnlocked = isScreenUnlocked()
        val isScreenProtectedByKeyguard = isScreenUnlocked()

        val isLvtTransaction =
            event.transactionInformation.transactionRange == ContactlessTransactionRange.LVT

        //discard all Transit transaction
        if (event.transactionInformation.richTransactionType == ContactlessRichTransactionType.TRANSIT) {
            return ContactlessAdvice.DECLINE
        }

        //allow for transaction when user is authenticated for payment and screen unlocked
        if (event.isUserAuthenticated && isScreenUnlocked) {
            return ContactlessAdvice.PROCEED
        }

        //allow for LVT transaction on unlocked screen when protected and don't require authentication
        if (isLvtTransaction && isScreenProtectedByKeyguard && isScreenUnlocked) {
            return ContactlessAdvice.PROCEED
        }

        // ...
        // much more cases

        //require authentication anyway
        return ContactlessAdvice.AUTHENTICATION_REQUIRED
    }
}

UcpEventReportsListener

class BankReportEventListener : UcpEventReportsListener {

    override fun onNewReport(report: Report) {
       //may be used for debugging SDK or gathering reports on client's app or backend
  	}
}

UcpMcbpHttpExecutor

//Use UcpMcbpHTtpExecutor as supertype if you want to replace connection
class BankUcpMcbpHttpExecutor : UcpMcbpHttpExecutor {
 
    override fun execute(
        ucpMcbpRequestType: UcpMcbpHttpExecutorRequestType,
        ucpMcbpHttpMethod: UcpMcbpHttpMethod,
        url: String,
        requestData: Any,
        requestProperties: Map<String, String>
    ): UcpMcbpHttpResponse {
 
 
        //additional action before request
 
 
        //invoke connect by custom connector
        return when (ucpMcbpRequestType) {
            UcpMcbpHttpExecutorRequestType.REQUEST_SESSION -> {
                executeRequestSession(ucpMcbpHttpMethod, url, requestData as UcpMcbpRequestSessionRequestData, 
                requestProperties)
            }
            UcpMcbpHttpExecutorRequestType.PROVISION -> {
                executeProvision(ucpMcbpHttpMethod, url, requestData as UcpMcbpProvisionRequestData, 
                requestProperties)
            }
            UcpMcbpHttpExecutorRequestType.REPLENISH -> {
                executeReplenish(ucpMcbpHttpMethod, url, requestData as UcpMcbpReplenishRequestData, 
                requestProperties)
            }
            UcpMcbpHttpExecutorRequestType.NOTIFY_PROVISIONING_RESULT -> {
                executeNotifyProvisioningResult(ucpMcbpHttpMethod, url, 
                requestData as UcpMcbpNotifyProvisioningResultRequestData, requestProperties)
            }
            UcpMcbpHttpExecutorRequestType.CHANGE_MOBILE_PIN -> {
                executeChangeMobilePin(ucpMcbpHttpMethod, url, 
                requestData as UcpMcbpChangeMobilePinRequestData, requestProperties)
            }
            UcpMcbpHttpExecutorRequestType.DELETE -> {
                executeDelete(ucpMcbpHttpMethod, url, requestData as UcpMcbpDeleteRequestData, 
                requestProperties)
            }
        }
    }
}

DefaultUcpMcbpHttpExecutor

//Use DefaultUcpMcbpHTtpExecutor as supertype if you want to only add some action before connection
class BankDefaultUcpMcbpHttpExecutor : DefaultUcpMcbpHttpExecutor() {
    override fun execute(
        ucpMcbpRequestType: UcpMcbpHttpExecutorRequestType,
        ucpMcbpHttpMethod: UcpMcbpHttpMethod,
        url: String,
        requestData: Any,
        requestProperties: Map<String, String>
    ): UcpMcbpHttpResponse {
 
        //additional action before request
 
        return super.execute(
            ucpMcbpRequestType,
            ucpMcbpHttpMethod,
            url,
            requestData,
            requestProperties
        )
    }
}

UcpReProvisionEventListener

class BankingAppUcpReProvisiongEventListener : UcpReProvisionEventListener() {
     override fun onReProvisionSuccess(event: EventReProvisionSuccess) {
     	//reProvisioning success, wait for status and replenish changes until user can pay 
  	}
 	
	override fun onReProvisionFailure(event: EventReProvisionFailure) {
       //reProvisioning failed, try again.
  	}
}

UcpTransactionConfiguration

class BankingAppUcpTransactionConfiguration : UcpTransactionConfiguration {
    override val enableTransactionAuthenticationTimer: Boolean = false
}

Sample VCP SDK setup implementation

Mobile DC setup() and VCP setup() method could be called on MainThread in Application:onCreate as blocking or another thread.
When applicaiton has multiple dependencies there is possible to call both setup() methods on another thread (MobileDC setup() method must be already finished until VCP setup() is called).
Important: In case of loading SDK on another thread and using contactless payments HostApduService must be used asynchronous way to prevet using SDK until loading is finished - check sample for method PaymentService:processHceApduCommand.

fun setup(
    application: Application,
    walletCvmModel: WalletCvmModel,
    walletAuthUserMode: WalletAuthUserMode,
    mcbpPinningCertificates: List<String>,
    replenishThreshold: Int
) {

    val ucpConfiguration = UcpConfiguration.create(
        UcpConfigurationBuilder()
            .withApplication(application)
            .withCvmModel(walletCvmModel)
            .withUserAuthMode(walletAuthUserMode)
            //marked as deprecated - see description above
            .withUcpTransactionEventListener(BankingAppUcpTransactionEventListener())
            .withUcpPaymentInstrumentEventListener(BankingAppPaymentInstrumentEventListener())
            .withMcbpPinningCertificates(mcbpPinningCertificates)
            .withUcpTransactionAcceptanceEventListener(BankingAppUcpTransactionAcceptanceEventListener())
            .withReplenishThreshold(replenishThreshold)
			.withOptionalEventsReports(BankReportEventListener())
    		.withOptionalUcpMcbpHttpExecutor(BankUcpMcbpHttpExecutor())
			//if you want to only add additional action before connection use below implementation
			//.withOptionalUcpMcbpHttpExecutor(BankDefaultUcpMcbpHttpExecutor())
			.withOptionalUcpReProvisionEventListener(BankingAppUcpReProvisionEventListener())
            //if you want to change standard transaction configuration use configuration below
            .withOptionalUcpTransactionConfiguration(BankingAppUcpTransactionConfiguration())
    )

    UcpApiKotlin().setup(ucpConfiguration)
}


reset (DEPRECATED - use restart instead)

Synchronous. Offline.
Method for resetting SDK to uninitialized state.
NOTE: According to MCBP Deployment team there is no possibility for resetting SDK without killing application process for clearing all MC SDK local variables. Please kill application process after using this method. Trying using any facade method without stopping application process will cause throwing UcpSdkException.
To avoid closing application use restart() methods.

Input

No input.


Output

No output.


Sample

Sample VCP SDK reset implementation:

fun reset() {
    UcpApiKotlin().reset()

	//Terminating JVM according to MC SDK Sample Application
    Runtime.getRuntime().exit(0);
}

restart

Synchronous. Offline.

Method for resetting SDK to uninitialized state.

Replaces reset() method which requires killing application process.

When restart finishes with error, application should repeat action.

NOTE: SDK must be already initialized to call restart() method. During restart() SDK internally initializes SDK again.

Input

No input.


Output

Success callback when SDK data is cleared and SDK is ready to use again. No any action is required to call facade methods.

Failure callback when something went wrong during restart. Application should repeat action.

Sample

Sample VCP SDK reset implementation:

UcpApiKotlin().restart({
    //restart finished with success. UCP & MDC data is cleared, SDK is now ready to use without calling MDC & UCP setup methods
}, {
    //some error occured, please repeat action
})


Cards domain

delete

Asynchronous. Online.|
Method allows delete PaymentInstument from VCP.
Payment token will be removed remote and local storage.
Result of action will be notified with onPaymentInstrumentStatusChanged.

Input

Parameter Type Description Validation conditions
paymentInstrumentId String

Id of PaymentInstrument to delete

Not empty.
reason CharArray?

Optional reason of deletion


Output

Success / failure callback

Sample

fun delete(paymentInstrumentId: String, reason: CharArray?) {
    ucpApi.cardsService
            .delete(paymentInstrumentId, reason,
                    {
                        //PaymentInstrument delete requested
                        //wait for confirmation from onPaymentInstrumentStatusChanged
                    },
                    { throwable ->
                        //Something went wrong, check excetpion with documentation
                    }
            )
}


checkEligibility

Asynchronous. Online.
Check eligibility required to process digitize.

Input

Parameter Type Description
checkEligibility CheckEligibility

CheckEligibility object

CheckEligibility

Parameter

Type

Description

paymentInstrumentId String

Identifier of payment instrument

paymentInstrumentType PaymentInstrumentType

Payment instrument type. One of: [MASTERCARD]

userLanguage String User language
userCountry String User country


Output

Success callback with CheckEligibilityResult.

CheckEligibilityResult

Parameter

Type

Description

termsAndConditionsAssetId String

Identifier of Terms and Conditions asset


Failure callback

Sample

private fun checkEligibility(
    paymentInstrumentId: String,
    paymentInstrumentType: PaymentInstrumentType,
    userLanguage: String,
    userCountry: String
) {

    ucpApi.cardsService
        .checkEligibility(
            CheckEligibility(
                paymentInstrumentId,
                paymentInstrumentType,
                userLanguage,
                userCountry
            ),
            { checkEligibilityResult ->
                //Handle result
            },
            { throwable ->
                //Something went wrong, check exception with documentation
            }
        )
}


digitize 

Asynchronous. Online.
Use only when checkEligibility method is used.
Creates payment token in VCP backend.
Expect push after successful finish and then proceed using process method in Cloud Messaging domain.


Input

Parameter Type Description Validation conditions
digitizationRequest DigitizationRequest

Plain object of DigitizationRequest

Not empty

DigitizationRequest object contains following fields:

Parameter Type Description Validation conditions
paymentInstrumentId String

Identifier of payment instrument

Not empty
paymentInstrumentType PaymentInstrumentType

Payment instrument type. One of: [MASTERCARD]

Not empty
securityCode CharArray? Optional. The CVC2 for the card to be digitized
externalPaymentTokenId String? Optional. Unique external identifier of Payment Token


Output

Success callback with DigitizationResult object

Parameter Type Description
digitizationResult DigitizationResult

Plain object of DigitizationResult


DigitizationResult contains following fields.

Parameter Type Description
paymentInstrument PaymentInstrument

Plain object of PaymentInstrument

additionalAuthenticationMethods List<AdditionalAuthenticationMethod>? All available additional authentication method
productConfig ProductConfig Plain object of ProductConfig, contains Payment Token configuration
externalPaymentTokenId String? Optional. External payment token id configured by the consumer. In case of identifier duplicate an random id is generated


ProductConfig contains following fields.

Parameter Type Description
isCoBranded Boolean Whether the product is co-branded
coBrandName String? Name of the co-branded partner
foregroundColor String Foreground color, used to overlay text on top of the card image
backgroundColor String Background color, used to overlay text on top of the card image
labelColor String? Label color of the mobile wallet entry for the card
issuerName String Name of the issuing bank
shortDescription String A short description for this product
longDescription String? A long description for this product
custoremServiceUrl String? Customer service website of the issuing bank
customerServiceEmail String? Customer service email address of issuing bank
customerServicePhoneNumber String? Customer service phone number of the issuing bank
productConfigIssuer ProductConfigIssuer? Contains one or more mobile app details that may be used to deep link from the Mobile Payment App to the issuer mobile app
onlineBankingLoginUrl String? Login URL for the issuing bank's online banking website
termsAndConditionsUrl String? URL linking to the issuing bank's terms and conditions for this product
privacyPolicyUrl String? URL linking to the issuing bank's privacy policy for this product
issuerProductConfigCode String? Freeform identifier for this product configuration as assigned by the issuer
contactName String? Name of the issuing bank
bankAppName String? Name of banking application for display
bankAppAddress String? The package name for the destination mobile application
unsupportedPresentationTypes String? The presentation types that are not supported such as "MSR" (for example). This is an advisory field to tell the wallet provider that they should not include the unsupported presentation type returned in this field in the provisioning request
unsupportedCardVerificationTypes String? The card verification types that are not supported such as "AVS" (for example). This is an advisory field to let the wallet provider know which card verification services are not supported for a given payment instrument. The wallet provider can use this information to relax any field validations on the Customer UI (such as Address)
issuerFlags List<ProductConfigIssuerFlags>? List of plain ProductConfigIssuerFlags object. Contains issuer flags
brandLogoAssetId String The Mastercard or Maestro brand logo associated with this card. Provided as an Asset ID
issuerLogoAssetId String The logo of the issuing bank. Provided as a Asset ID
coBrandLogoAssetId String? The co-brand logo (if any) for this product. Provided as an Asset ID
cardBackgroundCombinedAssetId String? The card image used to represent the digital card in the wallet. This ‘combined’ option contains the Mastercard, bank and any co-brand logos. Provided as an Asset ID
cardBackgroundAssetId String? The card image used to represent the digital card in the wallet. This ‘non-combined’ option does not contain the Mastercard, bank, or cobrand logos. Provided as an Asset ID
iconAssetId String The icon representing the primary brand(s) associated with this product. Provided as an Asset ID


ProductConfigIssuer contains following fields.

Parameter Type Description
openIssuerAndroidIntent ProductConfigOpenIssuerAndroidIntent? AndroidIntent object can be used to open the issuer mobile app
activateWithIssuerAndroidIntent ProductConfigActivateWithIssuerAndroidIntent? AndroidIntent object can be used to open the issuer mobile app
openIssuerIOSDeepLinkingUrl ProductConfigOpenIssuerIOSDeepLinkingUrl? IOSDeepLinkingUrl object can be used to open the issuer mobile app
activateWithIssuerIOSDeepLinkingUrl ProductConfigActivateWithIssuerIOSDeepLinkingUrl? IOSDeepLinkingUrl object can be used to open the issuer mobile app


ProductConfigOpenIssuerAndroidIntent contains following fields.

Parameter Type Description
action String The name of the action to be performed. This is a fully qualified name including the package name in order to create an explicit intent
packageName String The package name of the issuer’s mobile app. This identifies the app that the intent will resolve to. If the app is not installed on the user’s device, this package name can be used to open a link to the appropriate Android app store for the user to download and install the app
extraTextValue String Contains the data to be passed through to the target app in the intent as an extra key/value pair with key ‘android.intent.extra.TEXT’. This is Base64-encoded data of a JSON object


ProductConfigActivateWithIssuerAndroidIntent contains following fields.

Parameter Type Description
action String The name of the action to be performed. This is a fully qualified name including the package name in order to create an explicit intent
packageName String The package name of the issuer’s mobile app. This identifies the app that the intent will resolve to. If the app is not installed on the user’s device, this package name can be used to open a link to the appropriate Android app store for the user to download and install the app
extraTextValue String Contains the data to be passed through to the target app in the intent as an extra key/value pair with key ‘android.intent.extra.TEXT’. This is Base64-encoded data of a JSON object


ProductConfigOpenIssuerIOSDeepLinkingUrl contains following fields.

Parameter Type Description
deepLinkinUrl String The deep linking URL of the issuer’s iOS mobile app. This identifies the app that the URL will resolve to. If the app is not installed on the user’s device, this URL can be used to open a link to the appropriate iOS app store for the user to download and install the app
extraTextValue String Contains the data to be passed through to the target app in the deep linking URL as a query parameter.It should be appended to the deepLinkingUrl when invoked in the format: deepLinkingUrl + ‘?extraTextValue=’ + extraTextValue. This is Base64-encoded data of a JSON object


ProductConfigActivateWithIssuerIOSDeepLinkingUrl contains following fields.

Parameter Type Description
deepLinkingUrl String The deep linking URL of the issuer’s iOS mobile app. This identifies the app that the URL will resolve to. If the app is not installed on the user’s device, this URL can be used to open a link to the appropriate iOS app store for the user to download and install the app
extraTextValue String Contains the data to be passed through to the target app in the deep linking URL as a query parameter. It should be appended to the deepLinkingUrl when invoked in the format: deepLinkingUrl + ‘?extraTextValue=’ + extraTextValue. This is Base64-encoded data of a JSON object


ProductConfigIssuerFlags contains following fields.

Parameter Type Description
deviceBinding Boolean Device binding
cardholderVerification Boolean Whether the issuer participating in step-up flow
trustedBeneficiaryEnrollment Boolean Whether this is a trusted beneficiary enrollment
delegateAuthenticationSupported String Whether issuer supports delegated authentication


Failure callback

Sample

fun digitizeCard(digitizationRequest: DigitizationRequest) {

    ucpApi.cardsService
            .digitize( digitizationRequest,
                    { digitizationResult ->
                        //digitization success, provisioning is in progress
                        //application should listen to push message and provide content to UCP
                        //refresh you payment instrument list form Cards::getPaymentInstruments
                        //new PaymentInstrument should be visible with INACTIVE state

                        //when push processed wait for onProvisioningSuccess or Failure callback
                        //and status change
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


digitize (deprecated)

Asynchronous. Online.
Deprecated - use digitize(DigitizationGreenPath) instead.
Creates payment token in VCP backend.
Expect push after successful finish and then proceed using process method in Cloud Messaging domain.

Input

Parameter Type Description Validation conditions
paymentInstrumentId String

Identifier of payment instrument

Not empty.
userLanguage String

Language preference selected by the consumer. Formatted as an
ISO-639-1 two letter language code

Not empty.
securityCode CharArray?

Optional. The CVC2 for the card to be digitized



Output

Success / failure callback


Sample

fun digitizeCard(
        paymentInstrumentId: String,
        languageCode: String,
        securityCode: CharArray) {

    ucpApi.cardsService
            .digitize(paymentInstrumentId, languageCode, securityCode,
                    {
                        //digitization success, provisioning is in progress
                        //application should listen to push message and provide content to UCP
                        //refresh you payment instrument list form Cards::getPaymentInstruments
                        //new PaymentInstrument should be visible with INACTIVE state

                        //when push processed wait for onProvisioningSuccess or Failure callback
                        //and status change
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


digitize

Asynchronous. Online.
Creates payment token in VCP backend.
Expect push after successful finish and then proceed using process method in Cloud Messaging domain.

Input

Parameter Type Description Validation conditions
digitizationGreenPath DigitizationGreenPath

Plain object of DigitizationGreenPath

Not empty

DigitizationGreenPath contains following fields.

Parameter Type Description
paymentInstrumentId String

Identifier of payment instrument

paymentInstrumentType PaymentInstrumentType Payment instrument type. One of: [MASTERCARD]
securityCode CharArray? Optional. The CVC2 for the card to be digitized
userLanguage String User language
userCountry String User country
externalPaymentTokenId String? Optional. Unique external identifier of Payment Token

Output

Success / failure callback


Sample

fun digitizeCard(digitizationGreenPath: DigitizationGreenPath) {

    ucpApi.cardsService
            .digitize(digitizationGreenPath,
                    {
                        //digitization success, provisioning is in progress
                        //application should listen to push message and provide content to UCP
                        //refresh you payment instrument list form Cards::getPaymentInstruments
                        //new PaymentInstrument should be visible with INACTIVE state

                        //when push processed wait for onProvisioningSuccess or Failure callback
                        //and status change
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}

getAdditionalAuthenticationMethods

Asynchronous. Online.
Retrieves additional user authentication methods.

Input

Parameter Type Description Validation conditions
getAdditionalAuthenticationMethods GetAdditionalAuthenticationMethods

Plain object of GetAdditionalAuthenticationMethods

Not empty


Fields of GetAdditionalAuthenticationMethods object:

Parameter Type Description
paymentInstrumentId String Identifier of payment instrument


Output

Success callback with AdditionalAuthenticationMethods object.


Parameter Type Description
additionalAuthenticationMethods AdditionalAuthenticationMethods Object carrying list of AdditionalAuthenticationMethod


AdditionalAuthenticationMethods contains following value:

Parameter Type Description
additionalAuthenticationMethods List<AdditionalAuthenticationMethod> List of AdditionalAuthenticationMethod objects


Failure callback.

Sample

private fun getAdditionalAuthenticationMethods() {
    val getAdditionalAuthenticationMethod =
        GetAdditionalAuthenticationMethods("paymentInstrumentId")

    ucpApi
        .cardsService
        .getAdditionalAuthenticationMethods(
            getAdditionalAuthenticationMethod,
            { additionalAuthenticationMethods ->
                //Handle result
            },
            { throwable ->
                //Something went wrong, check exception with documentation
            })
}

submitTokenAuthenticationValue

Asynchronous. Online.
Submit authentication code when additional user authentication is required.

Input

Parameter Type Description
paymentInstrumentId String

Identifier of payment instrument

authenticationCode String Authentication code


Output

Success callback/failure callback.


Sample

private fun submitAuthenticationValue(paymentInstrumentId: String, authenticationCode: String) {

    ucpApi.cardsService
        .submitAuthenticationValue(
            SubmitAuthenticationValue(
                paymentInstrumentId,
                authenticationCode
            ),
            {
                //Handle success
            },
            { throwable ->
                //Something went wrong, check exception with documentation
            }
        )
}


submitTokenAuthenticationMethod

Asynchronous. Online.
Submit authentication method when additional user authentication is required.

Input

Parameter Type Description
paymentInstrumentId String

Identifier of payment instrument

authenticationMethodId String Id of authentication method. Get it when digitize method return additionalAuthenticationRequired set to true.


Output

Success callback/failure callback.


Sample

private fun submitAuthenticationMethod(paymentInstrumentId: String, authenticationMethodId: String) {

    ucpApi.cardsService
        .submitAuthenticationMethod(
            SubmitAuthenticationMethod(
                paymentInstrumentId,
                authenticationMethodId
            ),
            {
                //Handle success
            },
            { throwable ->
                //Something went wrong, check exception with documentation
            }
        )
}


getAllPaymentInstruments

Asynchronous. Online/Offline.
Method for getting all payment instruments from local or remote storage.
Local storage is always instant available and should be used to increase UX.
Use remote way when possible to keep your payment instruments always up to date.

Input

Parameter Type Description Validation conditions
refresh Boolean Refresh all PaymentInstrument objects state with remote VCP server (network and user session required)


Output

Success callback with list of PaymentInstrument objects.

Parameter Type Description
paymentInstruments List<PaymentInstrument> List of retrieved payment instruments from local or remote storage


Failure callback.

Sample

fun getAllPaymentInstrument(refresh: Boolean) {
    ucpApi.cardsService
            .getAllPaymentInstruments( refresh,
                    { paymentInstruments ->
                        //List of PaymentInstrument from local or remote storage
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


getPaymentInstrument (deprecated)

Asynchronous. Online/Offline.
Deprecated - use getAllPaymentInstruments instead.
Method for getting single PaymentInstrument from local or remote storage object based on id.
Local storage is always instant available and should be used to incerese UX.
Use remote way when possible to keep your payment instruments always up to date.


Input

Parameter Type Description Validation conditions
paymentInstrumentId String Id of instrument to retrieve Not empty
refresh Boolean Refresh selected PaymentInstrument state with remote VCP server (network required)


Output

Success callback with PaymentInstument object.

Parameter Type Description
paymentInstrument PaymentInstrument Retrieved payment instrument


Failure callback.

Sample

fun getPaymentInstrument(paymentInstrumentId: String, refresh: Boolean) {
    ucpApi.cardsService
            .getPaymentInstrument(paymentInstrumentId, refresh,
                    { paymentInstrument ->
                        //PaymentInstrument from local or remote storage
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}



IBANs domain


digitize

Asynchronous. Online.
Registers user and device if already not registered in VCP backend. Creates payment token in VCP backend.
Expect push after successfull finish and then proceed using process method in Cloud Messaging domain.


Input

Parameter Type Description Validation conditions
signedAccountInfo String

Signed AccountInfo per RFC 7519

Instruction how to sign data with JWT can be found in Data signing and encryption chapter in Mobile DC documentation

Not empty.
fcmRegistrationToken CharArray

FCM Cloud messaging registration token

Not empty.
languageCode String

Language preference selected by the consumer. Formatted as an ISO-639-1 two letter language code

Not empty.


AccountInfo:

Parameter Type Description

Validation conditions

userId String

External user id

Not empty.
iban String Bank Account Number Not empty.
countryCode String

The country of the financial account

Expressed as a 3-letter (alpha-3 country code as defined in ISO 3166-1

Not empty.


Output

Success callback. Called when device token digitization finished with success .Result contains IbanDigitizationResult object.

Note: Cloud token digitization fail doesn't affect on success/failure callback.


IbanDigitizationResult contains following fields:

Parameter Type Description
(DEPRECATED) cloudDigitizationSuccess Boolean Cloud Token Digitization Details
result CloudDigitizationResult Cloud Token Digitization Details. One of: SUCCEED, FAILED, DISABLED, UNKNOWN

Failure callback. Called when device token digitization finished with failure.


Sample

Sample generation of signedAccountInfo (see Data signing and encryption chapter in Mobile DC documentation)

class SignedAccountInfo {
    fun generate() {
        val claims = JWTClaimsSet.Builder()
            .claim("userId", "externalUserId")
            .claim("iban", "IN15HIND23467433866365")
            .claim("countryCode", "IND")
            .build()

        val signedAccountInfo = JwtGenerator.generate(claims, certificates, privateKey)
        // ...
    }


fun digitizeIban(
        signedAccountInfo: String,
        fcmRegistrationToken: CharArray,
        languageCode: String) {

    ucpApi.ibansService
            .digitize(signedAccountInfo, fcmRegistrationToken, languageCode,
                    { ibanDigitizationResult ->

                        //Device token digitization finished with success
                        //wait for onProvisioning(Success/Failure) callback and onTokenStatusChanged when success

                        val cloudDigitizationResult = ibanDigitizationResult.result

                        //check status of Cloud Token
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


createTVC

Asynchronous. Online.
Provides Transaction Verification Code required to process cloud payments.


Input

Parameter Type Description Validation conditions
signedIbanInfo String

Signed IbanInfo per RFC 7519

Instruction how to sign data with JWT can be found in Data signing and encryption chapter in Mobile DC documentation

Not empty.

IbanInfo

Parameter Type Description

Validation conditions

ibanId String

Iban id returned in addUserWithIban methdod or sha256Hex(iban)

Not empty.


Output

Success callback with Tvc object or encrypted Tvc object as String.

Parameter Type Description
plainTvc PlainTvc?

Plain PlainTvc object

encryptedTvc CharArray?

Encrypted PlainTvc object per RFC 7516

Present when client decide to encrypt data. Instruction how tu use JWE can be found in Data signing and encryption chapter in Mobile DC documentation

PlainTvc object contains following fields.

Parameter Type Description
accountNumber CharArray

Primary Account Number for the transaction – this is the Token PAN

dynamicExpiryDate CharArray

Dynamic expiration date for the token. Expressed in YYMM format

dynamicCVC CharArray Dynamic CVC


Failure callback when TVC cannot be created.

Sample

Sample generation of signedIbanInfo (see Data signing and encryption chapter in Mobile DC documentation)

class SignedIbanInfo {
    fun generate() {
        val claims = JWTClaimsSet.Builder()
            .claim("ibanId", "798c5c64d93c87b8ed7f108cde4753eb66faff760121ef2a05d0f44fb066b03b")
            .build();

        val signedIbanInfo = JwtGenerator.generate(claims, certificates, privateKey);
        // ...
    }
}


fun createTvc(signedIbanInfo: String) {
    ucpApi.ibansService
            .createTVC(signedIbanInfo, { tvc ->
                //result object could contains encrypted TVC
                val encryptedTvc: String? = tvc.encryptedTvc

                //or decrypted(plain) TVC object with parameters described in documentation
                val plainTvc = tvc.plainTvc
            }, { throwable ->
                //Something went wrong, check exception with documentation
            })
}


createPaymentData

Asynchronous. Online.
This method is responsible for creating payment data for given IBAN. Depending on configuration returned data are dedicated for payment using UCAF or TVC. Also depending on configuration payment data are returned in plain or encrypted form.

Input

Parameter Type Description Validation conditions
signedIbanInfo String

Signed IbanInfo per RFC 7519

Instruction how to sign data with JWT can be found in Data signing and encryption chapter in Mobile DC documentation

Not empty.

IbanInfo

Parameter Type Description

Validation conditions

ibanId String

Iban id returned in addUserWithIban methdod or sha256Hex(iban)

Not empty.
userId String External user id given by the client Not empty.


Output

Success callback with PaymentData object or encrypted payment data object as String.

Parameter Type Description
plainPaymentData PlainPaymentData?

Plain PlainPaymentData object

encryptedPaymentData String?

Encrypted PlainPaymentData object per RFC 7516

Present when client decide to encrypt data. Instruction how tu use JWE can be found in Data signing and encryption chapter in Mobile DC documentation


PlainPaymentData object contains following fields.

Parameter Type Description
accountNumber String

Primary Account Number for the transaction – this is the Token PAN

applicationExpiryDate String? Required only for UCAF. Application expiry date for the Token. Expressed in YYMMDD format
panSequenceNumber String? Rrquired only for UCAF. Application PAN sequence number for the Token
track2Equivalent String? Required only for UCAF. Track 2 equivalent data for the Token. Expressed according to ISO/IEC 7813, excluding start sentinel, end sentinel, and Longitudinal Redundancy Check (LRC), using hex nibble 'D' as field separator, and padded to whole bytes using one hex nibble 'F' as needed
ucafCryptogram String? Required only for UCAF. UCAF cryptogram
dynamicExpiryDate String?

Dynamic expiration date for the token. Expressed in YYMM format

dynamicCVC String? Dynamic CVC


Failure callback when PaymentData cannot be created.

Sample

Sample generation of signedIbanInfo (see Data signing and encryption chapter in Mobile DC documentation)

class SignedIbanInfo {
    fun generate() {
        val claims = JWTClaimsSet.Builder()
            .claim("ibanId", "798c5c64d93c87b8ed7f108cde4753eb66faff760121ef2a05d0f44fb066b03b")
			.claim("userId", "123")
            .build();

        val signedIbanInfo = JwtGenerator.generate(claims, certificates, privateKey);
        // ...
    }
}


fun createPaymentData(signedIbanInfo: String) {
    ucpApi.ibansService
            .createPaymentData(signedIbanInfo, { paymentData ->
                //result object could contains encrypted PaymentData
                val encryptedPaymentData: String? = paymentData.encryptedPaymentData

                //or decrypted(plain) PaymentData object with parameters described in documentation
                val plainPaymentData = paymentData.plainPaymentData
            }, { throwable ->
                //Something went wrong, check exception with documentation
            })
}


getAllPaymentInstruments

Asynchronous. Online/Offline.
Method for getting all payment instruments from local or remote storage.
Local storage is always instant available and should be used to incerese UX.
Use remote way when possible to keep your payment instruments always up to date.

Input

Parameter Type Description Validation conditions
refresh Boolean Refresh all PaymentInstrument objects state with remote VCP server (network required)

Output

Success callback with list of PaymentInstrument objects

Parameter Type Description
paymentInstruments List<PaymentInstrument> List of retrieved payment instruments


Failure callback

Sample

fun getAllPaymentInstrument(refresh: Boolean) {
    ucpApi.ibansService
            .getAllPaymentInstruments( refresh,
                    { paymentInstruments ->
                        //List of PaymentInstrument from local or remote storage
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


getPaymentInstrument(deprecated)

Asynchronous. Online/Offline.
Use getAllPaymentInstruments instead.
Method for getting single PaymentInstrument from local or remote storage object based on id.
Local storage is always instant available and should be used to incerese UX.
Use remote way when possible to keep your payment instruments always up to date. 


Input

Parameter Type Description Validation conditions
paymentInstrumentId String Id of instrument to retrieve. Not empty
refresh Boolean Refresh selected PaymentInstrument state with remote VCP server (network required)


Output

Success callback with PaymentInstument object

Parameter Type Description
paymentInstrument PaymentInstrument Retrieved payment instrument


Failure callback

Sample

fun getPaymentInstrument(paymentInstrumentId: String, refresh: Boolean) {
    ucpApi.ibansService
            .getPaymentInstrument(paymentInstrumentId, refresh,
                    { paymentInstrument ->
                        //PaymentInstrument from local or remote storage
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


delete

Asynchronous. Online.
Method allows delete PaymentInstument from VCP.
Payment token will be removed remote and local storage.
Result of action will be notified with onPaymentInstrumentStatusChanged.


Input

Parameter Type Description Validation conditions
paymentInstrumentId String

Id of PaymentInstrument to delete

Not empty.
reason CharArray?

Optional reason of deletion



Output

Success / failure callback

Sample

fun delete(paymentInstrumentId: String, reason: CharArray?) {
    ucpApi.ibansService
            .delete(paymentInstrumentId, reason,
                    {
                        //PaymentInstrument delete requested
                        //wait for confirmation from onPaymentInstrumentStatusChanged
                    },
                    { throwable ->
                        //Something went wrong, check excetpion with documentation
                    }
            )
}



Payment domain


setDefaultForContactless

Asynchronous. Offline.
Sets payment instrument as default for contactless payment.
Payment instrument set as default will be used if no other payment instrument was selected by method selectForPayment.
Default payment instrument will be used automatically after linking with PoS terminal.
Make sure PaymentInstrument status is ACTIVE. Only active payments instruments can be set as default.


Input

Parameter Type Description Validation conditions
paymentInstrumentId String

Payment instrument identity

Not empty


Output

Success / failure callback

Sample

fun setDefaultForContactless(paymentInstrument: PaymentInstrument) {

    if (paymentInstrument.status != PaymentInstrumentStatus.ACTIVE) {
        //make sure selected PaymentInstrument can be seta as default
        return
    }

    val paymentInstrumentId = paymentInstrument.id

    ucpApi.paymentService
            .setDefaultForContactless(paymentInstrumentId, {
                //success
            }, { throwable ->
                //Something went wrong, check exception with documentation
            })
}


getDefaultForContactless

Asynchronous. Offline.Provides default PaymentInstrument for contactless payment.

Throws DefaultPaymentInstrumentNotFoundException when no PaymentInstrument is set as default.


Input

No input parameters


Output

Success callback with id new default PaymentInstrument

Parameter Type Description
paymentInstrument PaymentInstrument Default Payment instrument


Failure callback.

Sample

fun getDefaultForContactless() {
    ucpApi.paymentService
            .getDefaultForContactless({ paymentInstrument ->
                // use PaymentInstrument
            }, { throwable ->
                when (throwable) {
                    is DefaultPaymentInstrumentNotFoundException -> {
                        //there is no default PaymentInstrument
                    }
                    else -> {
                        //check another exception with documentation
                    }
                }
            })
}


setDefaultForRemote (deprecated)

Asynchronous. Offline.
Sets payment instrument as default for DSRP payment.
Payment instrument set as default will be used if no other payment instrument was selected by method selectForPayment.
Default payment instrument will be used automatically to remote payments.


Input

Parameter Type Description Validation conditions
paymentInstrumentId String

Payment instrument identity

Not empty


Output

Success / failure callback

Sample

fun setDefaultForRemote(paymentInstrument: PaymentInstrument) {

    if (paymentInstrument.status != PaymentInstrumentStatus.ACTIVE
            && !paymentInstrument.dsrpSupported) {
        
        //make sure selected PaymentInstrument can be set as default
        return
    }

    val paymentInstrumentId = paymentInstrument.id

    ucpApi.paymentService
            .setDefaultForRemote(paymentInstrumentId, {
                //success
            }, { throwable ->
                //Something went wrong, check exception with documentation
            })
}


getDefaultForRemote (deprecated)

Asynchronous. Offline.
Provides default PaymentInstrument for remote payments.
Throws DefaultPaymentInstrumentNotFoundException when no PaymentInstrument is set as default.


Input

No input parameters


Output

Success callback with id new default PaymentInstrument

Parameter Type Description
paymentInstrument PaymentInstrument Default Payment instrument


Failure callback.

Sample

fun getDefaultForRemote() {
    ucpApi.paymentService
            .getDefaultForRemote({ paymentInstrument ->
                // use PaymentInstrument
            }, { throwable ->
                when (throwable) {
                    is DefaultPaymentInstrumentNotFoundException -> {
                        //there is no default PaymentInstrument
                    }
                    else -> {
                        //check another exception with documentation
                    }
                }
            })
}



selectForPayment

Asynchronous. Offline.
Sets payment instrument as primary for next incoming contactless payment.


Input

Parameter Type Description Validation conditions
paymentInstrumentd String

Payment instrument identity

Not empty


Output

Success / failure callback

Sample

Note: This is only sample payment scenation

//sample scenario of starting payment with authentication before payment

fun startPayment(paymentInstrument: PaymentInstrument) {

    //checking conditions before payment
    val isActive = paymentInstrument.status != PaymentInstrumentStatus.ACTIVE
    val isContactlessSupported = paymentInstrument.contactlessSupported
    val hasTransactionCredentials = paymentInstrument.credentialsCount > 0

    if (!isActive || !isContactlessSupported || !hasTransactionCredentials) {
        //PaymentInstrument doesn't meet requirements for payment
        return
    }
    
    //selecting PaymentInstrument to payment
    ucpApi.paymentService
            .selectForPayment(paymentInstrument.id, {
                //selection success

                //request user authentication when 
                //... authentication presented

                //use setUserAuthenticatedForPayment method

            }, { throwable ->
                //something went wrong, check exception with documentation
            })
}


setUserAuthenticatedForPayment

Asynchronous. Offline.
Sets user as authenticated to payment with provided payment instrument.

Authentication clearing depends on authentication timer configuration in UcpTransactionConfiguration:enableTransactionAuthenticationTimer.
By default timer is disabled and authentication is cancelled when user perform transaction and SDK send callback onContactlessPaymentCompleted/Aborted/Incident from UcpTransactionEventListener.
When timer is enabled authentication is cleared when auth timer finishes - it could casue problems when user start to pay just before timer finish. Authentication could be cleared by SDK during payement.

If application call setUserAuthenticatedForPayment without contactless payment context and authentication timer is disabled, authentication is never cleared by SDK. To clear authentication use abortUserAuthenticationForPayment.

UcpTransactionEventListener:onContactlessPaymentStarted is recommended place for payment authentication.


Note: User can be authenticated based on conditions like screen unlock.  Method must be called before payment in method UcpTransactionEventListener:onContactlessPaymentStarted()
Make sure that authentication on this step is done securely. Transaction information is not available on this step.

Input

Parameter Type Description Validation conditions
paymentInstrumentId String

Payment instrument identity

Not empty
pin CharArray?

PIN or null for CUSTOM WalletAuthUserMode


Output

Success / failure callback

Sample

Basic user authentication usage below, call when user is authenticated.

private fun setUserAuthenticatedForPayment(
    paymentInstrument: PaymentInstrument,
    pinProvidedByUser: CharArray
) {
    ucpApi
        .paymentService
        .setUserAuthenticatedForPayment(paymentInstrument.id, pinProvidedByUser,
            {
                //user authentication provided
                //start one tap payment or continue two tap with 2nd tap to terminal after authentication
                //listen for auth timer changes
                //user abortUserAuthentication method when transaction cancelled by user
            }, { throwable ->
                //some error, check exception
            })
}

Optional authentication before making transaction based on custom conditions.

override fun onContactlessPaymentStarted() {

    //check internal conditions
    //like user performed authentication, is logged in application, is device unlocked etc
    val isUserAuthenticated = true

    //check if use selected any token for payment and select it in UCP SDK
    //otherwise default token will be used
    if (getSelectedPaymentInstrumentId() != null) {

        ucpApi
            .paymentService
            .selectForPayment(
                paymentInstrumentId = getSelectedPaymentInstrumentId(),
                success = {
                    //token will be used for actual payment
                    //call setUserAuthenticatedForPayment here - sample below in "else" block
                },
                failure = { throwable ->
                    //something went wrong, check throwable with documentation
                }
            )
    } else {

        if (isUserAuthenticated) {
            ucpApi
                .paymentService
                .setUserAuthenticatedForPayment(
                    paymentInstrumentId = getSelectedPaymentInstrumentId(),
                    pin = null, //or pin if MobilePin is used
                    success = 
                        //user authenticated in SDK
                    }, failure = {
                        //authentication failure, check exception
                    }
                )
        }
    }
}


abortUserAuthenticationForPayment

Asynchronous. Offline.

Abort user authentication during ongoing transaction. After calling this method transaction is cancelled and timer stopped.


Input

No input parameters

Output

Success / failure callback

Sample

fun abortUserAuthenticationForPayment() {
    ucpApi
            .paymentService
            .abortUserAuthenticationForPayment(
                    {
                        //user authentication aborted
                        //listen for auth timer changes
                    },
                    { throwable ->
                        //some error, check exception
                    })
}


processHceApduCommand

Synchronous. Offline.
Processes APDU command from Point Of Sale (PoS) terminal. Returns callback APDU command to pass back to PoS.
Should be called inside registered Android Service extending HostApduService in implementation of overridden processCommandApdu method.

Input

Parameter Type Description Validation conditions
context Context

Application context, can be provided from HostApduService

Not empty
apdu ByteArray

APDU command from HostApduService::processCommandApdu method parameter

Not empty
extras Bundle?

Extras object from HostApduService::processCom mandApdu method parameter


Output

Apdu result - method called synchronous without callback

Parameter. Type Description
apdu ByteArray

APDU command to return in implementation of overridden processCommandApdu method

Sample (synchronized HostApduService)

Use this version if MobileDC:setup and UCP:setup() method is called in Application:onCreate on Main Thread.

//WalletHceService must be registerd in AndroidManifest as nfc service 
class WalletHceService : HostApduService() {

	//...
    //private val ucpApi = ..

    override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle?): ByteArray? {
        return ucpApi 
            .paymentService
            .processHceApduCommand(this, commandApdu, extras)
    }
	//..
}

Sample (aynchronous HostApduService)

Use this version if SDK is called on another thread and HostApduService can receive APDU until VCP SDK is still in loading state.

//WalletHceService must be registerd in AndroidManifest as nfc service 
class WalletHceService : HostApduService() {

	//...
    //private val ucpApi = ..
    
	override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle?): ByteArray? {

		//UcpSdkStateApplicationSingleton is sample class which keep SDK state and allow to observe when SDK load is finished
    	if (UcpSdkStateApplicationSingleton.isLoaded()) {
        	val result = processCommandApduInUcpSdk(context, commandApdu, extras)
        	sendResponseApdu(result)
    	} else {
        	sendResponseApdu(null)

        	UcpSdkStateApplicationSingleton.listenForSdkReady(
            	onSdkLoadListener = {
                	val result = processCommandApduInUcpSdk(context, commandApdu, extras)
                	sendResponseApdu(result)
            	}
        	)
    	}

    	return null
	}

	override fun onDeactivated(reason: Int) {
    	if (UcpSdkStateApplicationSingleton.isLoaded()) {
        	return ucpApi
            	.paymentService
            	.handleHceApduDeactivationEvent(reason)
    	}
	}
	
    
    private fun processCommandApduInUcpSdk(
        context: Context,
        commandApdu: ByteArray,
        extras: Bundle?
    ): ByteArray? {
        return ucpApi
            .paymentService
            .processHceApduCommand(context, commandApdu, extras)
    }
}

//sample objec which helps to listen SDK state
object UcpSdkStateApplicationSingleton : UcpSdkState {

	//flag could be synchronized
    private var isLoaded = false

    private var onSdkLoadListener: (() -> Unit)? = null

    override fun listenForSdkReady(onSdkLoadListener: () -> Unit) {
        this.onSdkLoadListener = onSdkLoadListener
        if (isLoaded) this.onSdkLoadListener?.invoke()
    }
        
	//call when SDK loading thread is finished
    //setupMdc() -> setupUcp() -> UcpSdkStateApplicationSingleton.onUcpSdkLoaded()
    override fun onUcpSdkLoaded() {
        isLoaded = true
        onSdkLoadListener?.invoke()
    }

    override fun isLoaded(): Boolean {
        return isLoaded
    }
}

replenishCredentials

Asynchronous. Online. User login session not required.
Method for manually replenishing payment credentials.
Application will receive push notification and notified about replenish process with global callback described in setup chapter. 

Input

Parameter Type Description Validation conditions
paymentInstrumentId String

Id of paymentInstrument that needs it credentials replenished

Not empty

Output

Success / failure callback

Sample

fun replenishCredentials(paymentInstrumentId: String) {
    ucpApi.paymentService
            .replenishCredentials(paymentInstrumentId,
                    {
                        //request for credentials replenish finished with success
                        //wait for push notification and pass to valid module
                        //when push processed application will be informed about replenish success/failure
                        //read chapter with setup for more information
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    })
}


restartContactlessAuthTimer

Asynchronous. Offline.
Resets auth timer during payment. After calling method auth countdown will start again with default value from card profile.
Default auth time is provided by card profile.

Input

No input parameters

Output

Success / failure callback


requestAuthenticationCodeForPayment

Asynchronous. Online.
Method dedicated for requesting authentication code for payment. Authentication code is delivered via Issuer. Only one valid Authentication Code can exist at a time for a given paymentInstrumentId and authenticationRequestId. Multiple valid codes can exist for the same token if different authenticationRequestIds are provided each in a different call. Once an Authentication Code has been generated for a given paymentInstrumentId and authenticationRequestId, it will be valid for a limited validity period, after which the code will expire. Method can be called again with the same authenticationRequestId and token unique reference , in order to trigger re-send. When an active authentication code exists for a given paymentInstrumentId and authenticationRequestId it is delivered again to the issuer. If the code has expired or the attempts has been exceeded then new code will be generated.

Input

Parameter Type Description Validation conditions
requestAuthenticationCodeForPayment RequestAuthenticationCodeForPayment

Plain RequestAuthenticationCodeForPayment object

Not empty

RequestAuthenticationCodeForPayment object contains following fields

Parameter Type Description Validation conditions
paymentInstrumentId String

Identifier of payment instrument

Not empty
authenticationRequestId String Authentication request id up to 64 alphanumeric characters long.
A new id should be used for each instance than an account holder needs to be authenticated
Not empty

Output

Success callback/failure callback.

Sample

fun requestAuthenticationCodeForPayment(requestAuthenticationCodeForPayment: RequestAuthenticationCodeForPayment) {
    ucpApi.paymentService
            .requestAuthenticationCodeForPayment( requestAuthenticationCodeForPayment,
                    { 
                        //Requesting Authentication Code went successfully.
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


validateAuthenticationCodeForPayment

Asynchronous. Online.
Method dedicated for validation of an Authentication Code generated by the requestAuthenticationCodeForPayment() method. It is given limited number of attempts to enter a correct Authentication Code(typically 3 attempts), after which the Authentication Code becomes invalid.

Input

Parameter Type Description Validation conditions
validateAuthenticationCodeForPayment ValidateAuthenticationCodeForPayment

Plain ValidateAuthenticationCodeForPayment object

Not empty

ValidateAuthenticationCodeForPayment object contains following fields

Parameter Type Description Validation conditions
paymentInstrumentId String

Identifier of payment instrument

Not empty
authenticationRequestId String Authentication request id provided to the requestAuthenticationCodeForPayment when the authentication code was requested. Not empty
authenticationCode String Authentication Code to authenticate the account holder Not empty

Output

Success callback with ValidateAuthenticationCodeForPaymentResult object.

ValidateAuthenticationCodeForPaymentResult object contains following field

Parameter Type Description
signedAuthenticationProcessData String

Signed AuthenticationProcessData per RFC 7519

AuthenticationProcessData model

Parameter Type Description
authenticationRequestId String

Authentication request id

Sample

fun validateAuthenticationCodeForPayment(validateAuthenticationCodeForPayment: ValidateAuthenticationCodeForPayment) {
    ucpApi.paymentService
            .validateAuthenticationCodeForPayment( validateAuthenticationCodeForPayment,
                    { validateAuthenticationCodeForPaymentResult ->
                        //ValidateAuthenticationCodeForPaymentResult plain object, 
                        //contains data to validate on backend
						val signedAuthenticationProcessData = ValidateAuthenticationCodeForPaymentResult
                        		.signedAuthenticationProcessData
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}

Sample verification of signedAuthenticationProcessData (see Data signing and encryption chapter in Mobile DC documentation)

class SignedAuthenticationProcessData {
    fun verifyAndGetAuthenticationRequestID() {
        val jwtClaimsSet = JWTVerifier.verify(signedAuthenticationProcessData, rsaPublicKey, 600);
        val authenticationRequestId = jwtClaimsSet.getStringClaim("authenticationRequestId")        
        // ...
    }
}


processDsrpTransaction(deprecated)


Asynchronous. Online.

Input

Parameter Type Description Validation conditions
paymentInstrumentId String

Payment instrument identity

Not empty
dsrpTransactionInfo DsrpTransactionInfo



Output

Success callback with cryptogram for payment

Failure callback


processDsrpTransaction

Asynchronous. Offline.
Method dedicated for starting DSRP transaction.
Every DSRP transaction has to be authenticated before processing.
Depending on implementation payment can be process with OTP authentication or device level authentication.


Parameter Type Description Validation conditions
processDsrpTransaction ProcessDsrpTransaction

Plain ProcessDsrpTransaction object

Not empty

ProcessDsrpTranasction object contains following fields

Parameter Type Description Validation conditions
paymentInstrumentId String

Identifier of payment instrument

Not empty
dsrpTransactionInfo DsrpTransactionInfo Plain DsrpTransactionInfo object Not empty

DsrpTransactionInfo object contains following fields

Parameter Type Description Validation conditions
amountMinor Long A long representing the transaction amount without the decimal. For instance 119.00 USD will be 11900


Not empty
currencyCode String A char (integer) representing the transaction currency code with 3 numeric digits as per ISO 4217. For instance, value will be 840 for USD. The maximum value allowed is 999. Not empty
countryCode String? A 3 digit ISO 3166 numeric country code, e.g., 826 for UK. If not sent, this value is initialized with 000.
issuer
Cryptogram
Type
DsrpIssuer
Cryptogram
Type
Enum with value represented by "UCAF" or "DE55" depending on cryptogram data format is to be used. Not empty
unpredictable
Number
Long
A long representing the random number generated by the merchant or by the Payment Gateway. The maximum value is 4,294,967,295. Not empty
transactionType
Dsrp
Transaction
Type
A type of financial transaction, one of: PURCHASE, CASH, PURCHASE_WITH_CASHBACK, REFUND
Not empty
transactionDate
Date?
A Date object indicating date of transaction.

Output

Success callback with ProcessDsrpTransactionResult object.

ProcessDsrpTransactionResult object contains following field

Parameter Type Description
transaction
Cryptogram
Data
ByteArray

A byte array containing a formatted response, either UCAF or a set of TLV data for the merchant to populate DE55 data.

pan
String

String containing the PAN of the card used.

panSequence
Number
Int

An integer value specifying the PAN Sequence Number (PSN) of the card used.

cryptogramType DsrpIssuer
Cryptogram
Type

Enum value as UCAF or DE55 depending on cryptogram data format is used.

track2Data
String

String containing the data elements of track 2 according to ISO/IEC 7813.

par
String

String representation of byte array of permanent account reference. A non-financial reference assigned to each unique PAN and used to link a Payment Account represented by that PAN to affiliated Payment Tokens.

expirationDate
String

Date in ISO-8601 (YYYY-MM-DD) format indicating expiry date of the card.

transactionId
String

Hexed byte array containing a Transaction Identifier.

Errors

DsrpPaymentException exception throwed on error in DSRP processing

DsrpPaymentException.reason Description
DSRP_INVALID_INPUT

Invalid input data.

DSRP_UNEXPECTED_DATA

Provided data is valid in context of validation, but doesn't mee

DSRP_AUTHENTICATION_REQUIRED

Authentication is not provided for DSRP payment. Authenticate and process DSRP transaction again.

DSRP_TOKEN_INACTIVE

Token used for DSRP is inactive.

DSRP_NO_TRANSACTION_CREDENTIALS

There is no transaction credentials to procees DSRP payment

DSRP_NOT_SUPPORTED_BY_CARD

DSRP is not suported by Card.

DSRP_TRANSACTION_DECLINED

Transaction is declined by Card.

DSRP_INCOMPATIBLE_PROFILE

Card profile is incomaptible with DSRP.

DSRP_WRONG_STATE

DSRP transaction is in wrong state.

DSRP_INTERNAL_ERROR

Unknowne error during DSRP processing.

Sample DSRP transaction with device level authentication

// After Merchant App delivers DSRP data application should authenticate user with device level authentication 
// and next execute setUserAuthenticationForPayment().

// Values for DsrpTransactionInfo delivered by Merchant APP 

val dsrpTransactionInfo: DsrpTransactionInfo = 
	DsrpTransactionInfo(amount, currencyCode, countryCode, issuerCryptographyType)
val processDsrpTransaction: ProcessDsrpTransaction = 
	ProcessDsrpTransaction(paymentInstrumentId, dsrpTransactionInfo)

private fun setUserAuthenticatedForPayment(
    paymentInstrumentId: String,
    pinProvidedByUser: CharArray
) {
    ucpApi
        .paymentService
        .setUserAuthenticatedForPayment(paymentInstrumentId, pinProvidedByUser,
            {
                //After succesfully authentication for payment MPA should execute processDsrpTransaction()
            }, { throwable ->
                //some error, check exception
            })
}

fun processDsrpTransaction(processDsrpTransaction : ProcessDsrpTransaction) {
    ucpApi.paymentService
            .processDsrpTransaction( processDsrpTransaction,
                    { processDsrpTranasctionResult ->
                        //DSRP transaction result with details went successfully result 
                        //should be delivered to Merchant APP
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}

Sample DSRP transaction with OTP authentication

// After Merchant App delivers DSRP data user should request authentication 
// code for payment with selected paymentInstrument.

// Values for DsrpTransactionInfo delivered by Merchant APP 

val dsrpTransactionInfo: DsrpTransactionInfo = 
		DsrpTransactionInfo(amount, currencyCode, countryCode, issuerCryptographyType)
val processDsrpTransaction: ProcessDsrpTransaction = 
		ProcessDsrpTransaction(paymentInstrumentId, dsrpTransactionInfo)

val requestAuthenticationCodeForPayment: RequestAuthenticationCodeForPayment = 
		RequestAuthenticationCodeForPayment(paymentInstrumentId, authenticationRequestId)
fun requestAuthenticationCodeForPayment(requestAuthenticationCodeForPayment) {
   		ucpApi.paymentService.requestAuthenticationCodeForPayment( requestAuthenticationCodeForPayment,
                    {
                        //When requesting went successfully User will get authentication code. 
						//In next step authentication code should be passed to MPA and application 
                        //should validate this code with validateAuthenticationCode() method
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}

val validateAuthenticationCode: ValidateAuthenticationCode = 
	ValidateAuthenticationCode(paymentInstrumentId, authenticationRequestId, authenticationCodeProvidedByUser)
fun validateAuthenticationCode(validateAuthenticationCode) {
    ucpApi.paymentService
            .validateAuthenticationCode( validateAuthenticationCode,
                    { validateAuthenticationCodeResulty ->
                        //ValidateAuthenticationCodeResult plain object
                        val signedAuthenticationProcessData = validateAuthenticationCodeResulty
                        		.signedAuthenticationProcessData

						//If validation went successfully MPA should show authentication view, 
                        //and after valid authentication MPA should execute setUserAuthenticatedForPayment()
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}

private fun setUserAuthenticatedForPayment(
    paymentInstrumentId: String,
    pinProvidedByUser: CharArray
) {
    ucpApi
        .paymentService
        .setUserAuthenticatedForPayment(paymentInstrumentId, pinProvidedByUser,
            {
                //After succesfully authentication for payment MPA should execute processDsrpTransaction()
            }, { throwable ->
                //some error, check exception
            })
}

fun processDsrpTransaction(processDsrpTransaction : ProcessDsrpTransaction) {
    ucpApi.paymentService
            .processDsrpTransaction( processDsrpTransaction,
                    { processDsrpTransactionResult ->
	                    //DSRP transaction result with details went successfully result 
                        //should be delivered to Merchant APP
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}

Sample input and output DSRP data:

Input:
amountMinor: 4321,
countryCode: 840, 
currencyCode: 840,
issuerCryptogramType: UCAF,
transactionDate: Apr 25, 2023 09:41:05, //Date() toString() format
transactionType: PURCHASE,
unpredictableNumber: 29496729

Output:
pan: 5204830959972699
track2Data: 5204830959972699D26052010000000000000
expirationDate: 2026-05-31 //YYYY-MM-DD
par: 500170A4PEV2GLWPFD00N6H5AX2YB
panSequenceNumber: 0
transactionId: df25a522a075680acbaa407fdc8a0348a321f77afa2f0231cd38f28e7ae691e2
cryptogramType: UCAF
transactionCryptogramData: 414d506a6d4a474650306149414155427768575a47674144464b553d //in Hex

Cloud messaging domain


process (deprecated in 2.6.7)

Asynchronous. Online. User login session not required.
Processes data sent by VCP backend (push notification data).
Application should check senderId in RemoteMessage object (RemoteMessage::from method) and check source in Mobile DC SDK before passing data to this method.
Method can throw InvalidPushException in case of invalid push content passed to it.
Refer Mobile DC documentation how to handle push.

Deprecated in 2.6.7, use MobileDC:CloudMessaging:process() instead.


Input

Parameter Type Description Validation conditions
pushData Map<String, String>

Data received from notification service in object RemoteMessage object

Not empty

Output

Success / failure callback. When request fails try again

Sample

//FirebaseMessagingService class from Firebase

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    super.onMessageReceived(remoteMessage)

    val senderId: String = remoteMessage.from
    val pushData = remoteMessage.data

	//check push source only when push source is uPaid sender Id

    if (isUpaidSenderId(senderId)) {

		//checking push source and passing to proper uPaid module

        mobileDcApi
            .cloudMessagingService
            .getSource(pushData, { source ->
                when (source) {
                    "UCP" -> processUcpPush(pushData)
                }
            }, {
                //some error
            })

    } else {
        //proceed push from another source
    }
}

private fun processUcpPush(pushData: Map<String, String>) {
    ucpApi
        .cloudMessagingService
        .process(pushData, {
            //push processed in Mobile DC
        }, {
            //some error
        })
}


processMcbpNotificationData

Asynchronous. Offline. 
Processes data sent by MCBP.
Application should check senderId in RemoteMessage object before passing data to VCP SDK.
Basic configuration for push processing from External Wallet Server: External Wallet Server domain.
Method can throw InvalidPushException in case of invalid push content passed to it.

Note: External Wallet Server Registration process mus be finished before push processing.


Input  

Parameter Type Description Validation conditions
encryptedPayload String

Data received from notification service in object RemoteMessage object

Not empty


Output

Success / failure callback

//FirebaseMessagingService class from Firebase


override fun onMessageReceived(remoteMessage: RemoteMessage) {
    super.onMessageReceived(remoteMessage)

    val senderId: String? = remoteMessage.from
    val pushData = remoteMessage.data

    //check push source based on senderId
    if (isMastercardSenderId(senderId)) {

        val mastercardPayload: String = readMastercardPushContent(pushData)

        ucpApi
            .cloudMessagingService
            .processMcbpNotificationData(mastercardPayload, {
                //push processed in Mcbp
            }, {
                //some error
            })
        
    } else {
        //proceed push from another source
    }
}


External Wallet Server domain

Chapter contains method for SDK when External Wallet Server is used.

Usage of method requires additional configuration with external API.


Basic MDES  cloud messaging configuration:

Environment FCM Sender Id
MTF 502118574555
PRODUCTION 993764297204


prepareRegistrationData

Asynchronous. Offline.
Method for preparing data used for activation.
Should be used before calling register method.


Input

Parameter Type Description Validation conditions
paymentAppInstanceId String Identifier for the specific Mobile Payment App instance Not empty
paymentAppProviderId String Globally unique identifier for the Wallet Provider, as assigned by MDES Not empty
publicKeyCertificate String CMS-D public key certificate in pem format Not empty
mobilePin CharArray?

Mobile PIN used to payment confirmation



Output

Success callback with PrepareRegistrationResponse object.

Parameter Type Description
publicKeyCertificateFingerprint String CMS certificate fingerprint. Used algorithm: hex(sha1(certificate.encoded))
encryptedRgk String Encrypted randomly-generated 128-bit AES key.
deviceInfo EwsDeviceInfo Device info.
deviceFingerprint String Unique device fingerprint.
encryptedPin String? Encrypted pin (if passed in input).

EwsDeviceInfo model:

Parameter Type Description
deviceName String Device model name.
formFactor String The form factor of the target provisioned device.
storageTechnology String The architecture or technology used for token storage.
osName String The name of the operating system of the target provisioned device.
osVersion String The version of the operating system of the target provisioned device.
nfcCapable Boolean

Whether the target provisioned device has NFC capability.


Failure callback

Sample

fun prepareRegistrationData(
        paymentAppInstanceId: String,
        paymentAppProviderId: String,
        publicKeyCertificate: String,
        mobilePin: CharArray?) {

    ucpApi
            .ewsService
            .prepareRegistrationData(paymentAppInstanceId,
                    paymentAppProviderId,
                    publicKeyCertificate,
                    mobilePin,
                    { prepareRegistrationResponse ->
                        //Prepared data for registration including encryptedMobilePin if mobilePin is used
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


register

Asynchronous. Online.
Method used for registration new Mobile Payment App instance with MDES for use.

Input

Parameter Type Description Validation conditions
mobileKeysetId String

Identifies the Mobile Keys used for this remote management session

Not empty
ewsMobileKeys EwsMobileKeys

Contains the mobile keys used to secure the communication during subsequent remote management sessions

Not empty
remoteManagementUrl String

The URL endpoint for subsequent remote management sessions

The Mobile Payment App must store this URL for future use in order to be able to request new remote management sessions

Not empty

EwsMobileKeys

Parameter Type Description
transportKey String

The Mobile Transport Key used to provide confidentiality of data at the transport level between the Mobile Payment App and MDES

macKey String

The Mobile MAC Key used to provide integrity of data at the transport level between the Mobile Payment App and MDES

dataEncryptionKey String

The Mobile Data Encryption Key used to encrypt any sensitive data at the data field level between the Mobile Payment App and MDES

Output

Success / failure callback

Sample

fun register(
        mobileKeysetId: String,
        ewsMobileKeys: EwsMobileKeys,
        remoteManagementUrl: String) {

    ucpApi
            .ewsService
            .register(mobileKeysetId, ewsMobileKeys, remoteManagementUrl,
                    {
                        //Device registration success 
                        //application should listen to push messages and UcpPaymentInstrumentEventListener callbacks
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation  
                    }
            )
}


activate

Asynchronous. Online.
Method to activate PaymentInstrument.
Should be used only on PaymentInstrumens which PaymentInstrumentStatus is SUSPENDED or INACTIVE.
Changes PaymentInstrumentStatus to ACTIVE, calls for transaction credentials replenish and set PaymentInstrument as default for payment when no other PaymentInstrument is available.
Method can be used when onProvisioningSuccess callback is trigerred to instantly activate card.

Input

Parameter Type Description Validation conditions
paymentInstrumentId String Id of paymentInstrument to activate. Not empty.

Output

Success / failure callback

Sample

fun activate(paymentInstrumentId: String) {
    ucpApi
		.ewsService
        .activate(paymentInstrumentId,
		{
         	//Changes PaymentInstrumentStatus to ACTIVE, set card as default for payment if another 
            //is not already setted Performing replenish, 
            //application should listen to push message with information about replenish success/failure 
        }, 
		{ throwable ->
        	//Something went wrong, check exception with documentation
        }
	)
}


suspend

Asynchronous. Offline.
Method for suspending paymentInstrument.
Changes PaymentInstrumentStatus to SUSPENDED.
Use activate method to allow payments again.

Input

Parameter Type Description Validation conditions
paymentInstrumentId String Id of paymentInstrument to suspend. Not empty.

Output

Success / failure callback

Sample

fun suspend(paymentInstrumentId: String) {
    	ucpApi
			.ewsService
            .suspend(paymentInstrumentId,
			{
           		 //Changes PaymentInstrumentStatus to SUSPENDED.
            }, 
			{ throwable ->
            	 //Something went wrong, check exception with documentation
            }
	)
}


getPaymentInstrument

Asynchronous. Offline.
Method for getting single PaymentInstrument from local storage object based on id.

Input

Parameter Type Description Validation conditions
paymentInstrumentId String

Id of paymentInstrument to get.

Not empty.

Output

Success callback with PaymentInstrument object.

Parameter Type Description
paymentInstrument PaymentInstrument Retrieved paymentInstrument


Failure callback.

Sample

fun getPaymentInstrument(paymentInstrumentId: String) {
    ucpApi.ewsService
            .getPaymentInstrument(paymentInstrumentId,
                    { paymentInstrument ->
                        //PaymentInstrument from local storage
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


getAllPaymentInstruments

Asynchronous. Offline.
Method for getting all payment instruments from local storage.

Input

No input parameters

Output

Success callback with list of PaymentInstrument objects.

Parameter Type Description
paymentInstruments List<PaymentInstrument> List of retrieved payment instruments from local storage


Failure callback.

Sample

fun getAllPaymentInstrument() {
    ucpApi.ewsService
            .getAllPaymentInstruments(
                    { paymentInstruments ->
                        //List of PaymentInstrument from local storage
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


getEncryptedPin

Asynchronous. Offline.|
Method for encrypting mobilePin. When updated on MDES call method onMobilePinChganged.

Input

Parameter Type Description Validation conditions
pin CharArray PIN to encrypt. Not empty.

Output

Success callback with encrypted mobile PIN.

Parameter Type Description
encryptedMobilePin String Hex encoded encrypted mobile PIN.


Failure callback.

Sample

fun getEncryptedPin(pin: CharArray) {
    ucpApi
            .ewsService
            .getEncryptedPin(pin, { encryptedPin ->
                //call to Wallet Server with new created encrypted mobile PIN
                //when updated call onMobilePinChanged method
            }, {
                //Something went wrong, check exception with documentation
            })
}



onMobilePinChanged

Asynchronous. Online.
Method for informing SDK about mobilePin change.
Should be used when mobilePin changed.
The result of action is deletion of existing transaction credentials and replenish.

Input

No input parameters

Output

Success / failure callback

Sample

fun reactOnMobilePinChanged() {
    ucpApi
        .ewsService
        .onMobilePinChanged(
            {
				// Informing SDK about changing mobile pin processed succesfully.
				// SDK should delete and next replenish transaction credentials. 
				// Listen for UcpPaymentInstrumentEventListener events
            }, { throwable ->
				// Something went wrong, check exception with documentation.
            })
}


delete 

Asynchronous. Online.
Method to removing PaymentInstrument.
Removed transaction credentials and PaymentInstrument from local storage and in MDES.
When success PaymentInstrument will be no longer available in getPaymentInstrument and getPaymentInstruments methods.

Input

Parameter Type Description Validation conditions
paymentInstrumentId String Id of paymentInstrument to delete. Not empty.

Output

Success / failure callback

Sample

fun delete(paymentInstrumentId: String) {
    ucpApi
            .ewsService
            .delete(paymentInstrumentId,
                    {
                        //Selected Payment instrument is removed
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}


Assets Domain


getAsset

Asynchronous. Online.
Method for getting all assets for selected assetId.

Input

Parameter Type Description Validation conditions
assetId String Id of assets to retrive Not empty

Output

Success callback with list of Assets objects.

Parameter Type Description
ucpAsset UcpAsset Plain UcpAsset object

UcpAsset object contains following field

Parameter Type Description
content List<UcpAssetContent> Plain list of UcpAssetContent objects

UcpAssetContent contains following fields.

Parameter Type Description
data String The data for this asset. Base64-encoded data, given in the format as specified in type.
type String The data MIME type. One of: application/pdf, text/plain, text/html, image/png, image/svg+xml, image/pdf.
width Long? For image assets, the width of this image. Specified in pixels.
height Long? For image assets, the width of this image. Specified in pixels.


Failure callback

Sample

fun getAsset(assetId: String) {
    ucpApi.assetsService
            .getAssets( assetId,
                    { ucpAsset ->
                        //List of assets of selected assetId
						val ucpAssetContentList = ucpAsset.content
                    },
                    { throwable ->
                        //Something went wrong, check exception with documentation
                    }
            )
}

DOCUMENT CHANGELOG

Version 2.9.5

Version 2.9.4

Version 2.8.7

Version 2.8.6

Version 2.8.5

Version 2.8.2

Version 2.7.4

Version 2.7.3

Version 2.7.1

Version 2.7.0

Version 2.6.9.2

Version 2.6.9.1 -  Hotfix possible OutOfMemoryException in MDC 2.14.7

Version 2.6.9 - don't use, could cause OOM Exception

Version 2.6.7

  • Updated Mobile DC dependency to 2.14.6

  • Added support for Mastercard India datacenter.
  • important Added new method to UcpTransactionEventListener - onContactlessPaymentStarted().
    Callback allows application to get event about new transaction and it's a best place for token selection and user authentication. Read more in Product Overview.
  • Due to adding new place for contactless payment authentiocation also updated code samples for HostApduSevice implementation and method setUserAuthenthenticatedForPayment()
  • Important CloudMessagingService:process became deprecated due to introducing delivery message from server service. Read more in Product Overview and Mobile DC specification.
  • Important Added new status AbortReason:CONNECTION_LOST for UcpTransactionEventListener:onContactlessPaymentAborted. Status TERMINAL_INACTIVITY_TIMEOUT became deprecated. Change significally improves contactless payment UX. Method works immediatelly when connection between device and terminal is lost.
  • Important Aded new optional configuration for UcpTransactionConfiguration with field enableTransactionAuthenticationTimer.
    Timer is now disabled by default, previously was always enabled and could cause problems when authentication time leading to zero and user performs transaction. It could cause clearing user authentication during processing payment on terminal. Change is related to other payments optimizations and introducing onContactlessPaymentStarted() and new AbortReason CONNECTION_LOST.
    Please align your code to new changes, enabling timer is not recommended.

Version 2.5.7

  • Updated Mobile DC dependency to 2.13.7

Version 2.5.6

Version 2.5.5

Version 2.5.3

Version 2.5.2

Version 2.5.1

Version 2.4.4

Version 2.4.3

Version 2.3.24

Version 2.3.22.2 - hotfix

Version 2.3.22

Version 2.3.21

Version 2.3.18

Version 2.3.17

Version 2.3.13

Version 2.3.12

Version 2.3.11

Version 2.3.8

Version 2.3.2

Version 2.3.1

Version 2.2.7

Version 2.2.6

Version 2.2.4

Version 2.2.3

Version 2.2.2

Version 2.2.0

Version 2.1.1

Version 2.1.0

Version 2.0.0

Version 1.0.1

Technical Documentation MDC SDK

The Mobile DC SDK is a core module dedicated to the management of users, devices, and cards in the Verestro system. To learn more about Mobile DC SDK  follow: Link to Mobile DC SDK technical documentation

Technical documentation VCP External API


Technical Documentation VCP External API

@swagger="https://services.upaidtest.pl/ucp/doc.yaml/external"

Watch integration

The Watch Payment product allows payments using Huawei smartwatches connected to Android and iOS smartphones. Payments are based on the MDES Token Requestor solution from Mastercard.
Contactless payments are possible without a constant internet connection—both on the smartphone and the smartwatch.

The core payment and token provisioning process is based on the Token Requestor product and requires an active project with Mastercard.
VCPSDK is a certified and secure product, approved by EMVCo and Mastercard, and has been launched in multiple banking and partner applications.


Introduction

The product is based on Verestro Cloud Payment solutions for NFC Issuer Wallet with Mobile SDK, Mastercard MCBP 2.1 SDK, and Visa VTS SDK.
For more details, visit: Token Requestor Page.

It is also referred to as the Token Requestor SDK.
This document describes the integration between the Mastercard MCBP 2.1 SDK for both mobile devices and Huawei Watch.


Requirements & Limitations


Architecture

watch-payment-architecture.png


Watch Connection

The communication with Huawei smartwatches is based on the WearEngine library provided by Huawei. Access to development using this library can be requested on the Huawei Developer website.

For the watch to function correctly on the device, the Huawei Health app must be installed, as it serves as an intermediary in the communication between the payment application and the smartwatch.

It is strongly recommended to keep only one active watch linked to the user's mobile application.

image.png


Watch Secure Session

During this process, the SDK establishes a secure connection between the SDK and the watch to transmit the card profile and transaction credentials.

Each data synchronization requires generating new keys on both the SDK and watch sides.
Both the sender and receiver are verified during the connection process.

image.png


Token Creation

The system uses Transaction Credentials (Payment Tokens) obtained from MDES.

Using secure channels and a certified SDK, Transaction Credentials are transferred to the watch, making it ready for contactless payments. These credentials are stored on the device, enabling payments even without a constant internet connection or a direct link to the phone.

image.png

Read more about Verestro SDK integration for tokenization:
Verestro Developer Portal.


Adding Token and Transaction Credentials to the Watch

During card digitization (payment activation), data is exchanged between devices and the MDES and Verestro servers. Transaction credentials are delivered to the devices via API and Remote Notification Service.

image.png

This process is automatic for the end user. In Quicko Wallet, contactless payment is first activated on the phone, after which the user is asked whether they want to enable payments on the smartwatch. This process can also be triggered independently, provided that the Huawei smartwatch is actively connected to the application.

image.png


Token Data Synchronization

This process ensures that all token- and payment-related data on the watch remain up to date.

There are two types of token synchronization between the MPA (Mobile Payment Application) and the watch:

MPA initiated

Watch initiated

During this proces MPA with Verestro Huawei Watch SDK manages token lifecycle in Verestro SDK and Watch.

 

image.png

Token data synchronisation MPA initiated

image.png

Token data synchronisation Watch initiated

image.png

 

Update token

image.png


Payment

This process describes the payment flow on the smartwatch.

Authentication

Transactions must be authenticated, but this does not mean that every transaction requires separate confirmation.

The application uses Consumer Device Cardholder Verification Method (CDCVM) to authenticate the user. Depending on specific circumstances, the app may request biometric authentication or a PIN.

Since the service uses on-device authentication, no additional security mechanisms need to be implemented by the integrator.


Disabling Payments

If the watch is unpaired from the phone via the Huawei Health app or the payment app, it will no longer be able to process payments.

If the watch was connected to the phone at the time of unpairing, its stored payment data will be automatically deleted.

There is no possibility to transfer payment data between devices or retain it on the watch after switching to a new phone.

Blocking payments—on both the phone and watch—is possible through the card issuer’s administrative panel.

The user can also remove the watch pairing from the mobile application, which will disable smartwatch payments.

Watch integration - API for communication between MPA and Watch

Basic information

Channel allows only to one-way communication without response. There is no response definition. Treat Response as new request without any response.

Communication is based on JSON format. Request object must contains request type and requestId. Other fields are determined by request type.

Request structure

type String Request type. Use API method name
appVersion String Current application version. Used to support backward compatibility
sdkVersion String Currently used Wearable SDK version
requestId String

Unique Id of request for matching request with response

chunk MessageChunk Optional.Allows to split the request into multiple parts to avoid 1kb limit.

Json structure:

{
    type: "EVENT_TYPE",
    appVersion: "2.0.0",
    requestId: "d516d558-f476-4e7f-b3c0-300261d37d46"
    //other fields reserved for type
}

Common models

Token

id String Payment Instrument Id

tokenType

String

Enum with value: MC

tokenExpiry

String Token expiration date in format MM/YY
tokenLastFourDigits String Token last four digits
paymentInstrumentExpirationDate String Payment instrument expiration date in format MM/YY
paymentInstrumentLastFourDigits String Payment instrument last four digits
tokenStatus String Payment token status. One of [ACTIVE, SUSPENDED, DELETED]
description String Token description
tokenVisual String Optional, visualId from DC

PaymentInstrumentStatus

paymentInstrumentId String Payment Instrument Id

status

String

Payment token status. One of [ACTIVE,  SUSPENDED, DELETED]

credentialsCount Int Transaction credentials count


MessageChunk

current Int Current chunk. Starts with 1.
total Int Number of all chunks.
data String Part of the full message.

API for communication to Watch

Method for creating secure session to transfer data betwen MPA and Watch.

Duriing this porcess SDK on Phone creates unique keys for communication then Watch creates data encryption keys.

Method should be used before evey AddTokenData and AddTokenCredentials methods

CreateSecureSesssion(

type:String,

appVersion:String,

requestId: String,

secureSessionData:String)

CreateSecureSessionResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId: String,

secureSessionData:String)

CreateSecureSessionResult(

appVersion:String,

sdkVersion:String,

type:String,

requestId:String, erorr:Error)


Errors:

Method for synchronize tokens status in version 1.0 and initialize synchronization from Watch to MPA

SyncStatus(

type:String,

appVersion:String,

requestId: String)

SyncStatusResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId:String,

pairDeviceData:String,

watchPinType:Enum<APP_PIN, WATCH_PIN, NONE>,

Deprecated("Not used in v1.1") paymentInstrumentIds : List<String>)

SyncStatusResult(

appVersion :String,

sdkVersion:String,

type:String,

requestId:String, erorr:Error)


Errors:

Method for synchronize tokens status between MPA and Watch.

Used for update  transaction credentials

SyncStatusExtended(

type:String,

appVersion:String,

requestId: String)

SyncStatusExtendedResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId:String,

chunk: MessageChunk -

ChunkedBase64 data (single json to split between next messages):

{

"paymentInstrumentStatuses":List<PaymentInstrumentStatus>

"usedCredentialsInfo":String)

}


SyncStatusExtendedResult(

appVersion :String,

sdkVersion:String,

type:String,

requestId:String, erorr:Error)


Errors:

CHUNKED_DATA_PARSE_ERROR

Method for initialize of add new Token on Watch.

Method allows to add Token details only, use AddTokenData for add token data. 

AddTokenInit(

type:String,

appVersion::String,

requestId: String,

token:Token)

AddTokenInitResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId:String)

AddTokenInitResult(

appVersion:String,

sdkVersion:String,

type:String,

requestId:String,

error:Error)


Errors:

PAYMENT_INSTRUMENT_ALREADY_EXIST, TOKEN_ADD_ERROR

Method for processing of new Token Data

When finished MPA should proceed AddTokenCreedntialsInit

AddTokenData(

type:String,

appVersion::String,

requestId: String,

paymentInstrumentId:String,

chunk:MessageChunk)


Chunked Base64 data (single json to split between next messages):
{
a:String,//paymentInstrumentId
b:String //encryptedTokenData
}

AddTokenDataResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId:String)

AddTokenDataResult(

appVersion:String,

sdkVersion:String,

type:String,

requestId:String,

error:Error)


Errors:

PAYMENT_INSTRUMENT_ALREADY_EXIST,
PAYMENT_INSTRUMENT_NOT_FOUND,
CHUNKED_DATA_PARSE_ERROR,
TOKEN_ADD_ERROR

Method for initialize of add Token Credentials on Watch.

AddTokenCredentialsInit(

type:String,

appVersion::String,

requestId: String,

paymentInstrumentId:String)

AddTokenCredentialsInitResult(

type:String,

appVersion::String,

sdkVersion:String,

requestId: String)

AddTokenCredentialsInitResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId:String,

error:Error)


Errors:

PAYMENT_INSTRUMENT_NOT_FOUND

Method for processing of add Token Credentials on Watch.

AddTokenCredentialsData(

type:String,

appVersion::String,

requestId: String,

chunk:MessageChunk)


Chunked Base64 data (single json to split between next messages):
{
a:String,//paymentInstrumentId
b:String //encryptedCredentialsData
}

AddTokenCredentialsInitResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId: String)

AddTokenCredentialsInitResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId:String,

error:Error)


Errors:

PAYMENT_INSTRUMENT_NOT_FOUND,
CHUNKED_DATA_PARSE_ERROR,
CREDENTIALS_ADD_ERROR

Method for update Token status on Watch

UpdateToken(

type:String,

requestId:String,

paymentInstrumentId:String,

status: TokenStatus(DELETED, SUSPENDED, ACTIVE)

)

UpdateTokenResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId:String)

UpdateTokenResult(

type:String,

appVersion:String,

sdkVersion:String,

requestId:String,

error:Error)


Errors:

PAYMENT_INSTRUMENT_NOT_FOUND,
TOKEN_UPDATE_ERROR

Method for displaying a list of logs on Watch

ShowLogs(

type:String,

requestId:String
)

(no response) (no response)
Method for collecting logs from Watch

DumpLogs(

type:String,

requestId:String
)

DumpLogsResult(

type:String,

requestId:String,

appVersion:String,

sdkVersion:String,

logs:List<{ time:String, message:String }>

)

DumpLogsResult(

type:String,

requestId:String,

appVersion:String,

sdkVersion:String,

error:Error
)


Errors:


Sample

//request
{
  "type": "AddTokenInit",
  "appVersion" : "2.0.0",
  "requestId": "d27978a0-5e06-4a05-aef6-b809dcffe53d",
  "token": {Token}
}
 
 
//error
{
  "type": "AddTokenInit",
  "appVersion" : "3.0.0",
  "requestId: "d27978a0-5e06-4a05-aef6-b809dcffe53d",
  "error": "PAYMENT_INSTRUMENT_ALREADY_EXIST"
}