Tokenization
Introduction
Tokenization is the process of replacing card sensitive information with a unique identifier called token
.
Replacing real data with these tokens minimizes the exposure of sensitive data to applications, stores and other merchants.
Tokens are meaningless outside of the specific system or merchant where they were issued,
so they cannot be used if intercepted. This makes the operation more secure and minimizes the impact of data breaches.
Tokenization is essential to the security and functionality of digital wallets.
Key Features
- Tokenize a prepaid card for secure, digital use.
- Manage the tokenization status of a card.
Prerequisites
Before integrating the Card Service, ensure you have:
- A valid Paysafe account with appropriate permissions.
- Set up instructions for Paysafe SDK Android or iOS.
To get started, initialize the CardService
instance in your app as shown below:
- Kotlin
- Swift
val cardService = Wallet.getInstance().getCardService()
import PaysafeWallet
let cardService = Wallet.instance.cardService
Tokenize a prepaid card
Tokenize a card and prepare it for securely adding it to digital wallet (e.g. Apple Wallet, Google Pay).
CardTokenizationRequest
Card Tokenization by which the client mobile application requests the needed info for card tokenization for a specific mobile wallet.
- Kotlin
- Swift
Use tokenize
method to tokenize a card by passing the card ID and a CardTokenizationRequest
object.
The response is a CardTokenization
object which contains the needed information in order specific
card to be added to Google Wallet.
val cardId = "f16ba382-eb42-481a-b08f-c57bdc9aae24"
val cardTokenizationRequest = CardTokenizationRequest(
walletType = MobileWalletType.GOOGLE_PAY,
clientDeviceId = "WNkcsfZPiKfa5PrH3jilkQYT",
clientWalletAccountId = "40exmLiWV1iV55ZVstOAiMf7"
)
val cardTokenizationResponse = cardService.tokenize(cardId, cardTokenizationRequest)
Use tokenize
method to tokenize a card by passing the card ID and a CardTokenizationRequest
object.
The response is a CardTokenization
object which contains the needed information in order specific
card to be added to Apple Wallet.
let leafCertificate = "<base64 encoded certificate>"
let subordinateCertificate = "<base64 encoded certificate>"
let nonce = "<encoded value>"
let nonceSignature = "<encoded value>"
let request = Wallet.CardTokenizationRequest(leafCertificate: leafCertificate,
subordinateCertificate: subordinateCertificate,
nonce: nonce,
nonceSignature: nonceSignature)
cardService.tokenize(cardID: "f16ba382-eb42-481a-b08f-c57bdc9aae24", request: request, completion: { result in
switch result {
case .success(let card):
// Display card
case .failure(let error):
// Handle error
}
})
Update card tokenization status
Updates card tokenization status by which tokenization can be marked as COMPLETED
. Tokenization
marked as COMPLETED
means that the given card will be not able to be tokenized for the specific
device and profile (in case of Google Pay).
Use this method when the a card is successfully added to a wallet.
- Kotlin
- Swift
Use updateTokenizationStatus
method to update the tokenization status of a card by passing the card ID and a MobileWalletTokenization
object.
The response is the updated MobileWalletTokenization
object.
val request = MobileWalletTokenization(
dpanRef = "DAPLMC00002125433c0c34a2821f4f86866e7576963baf8b",
walletId = walletId,
walletType = MobileWalletType.GOOGLE_PAY,
status = MobileWalletStatus.COMPLETED
)
val cardId = "f16ba382-eb42-481a-b08f-c57bdc9aae24"
val mobileWalletTokenization = cardService.updateTokenizationStatus(cardId, request)
Use updateTokenizationStatus
method to update the tokenization status of a card by passing the card ID and a MobileWalletTokenization
object.
The response is the updated MobileWalletTokenization
object.
let request = Wallet.MobileWalletTokenization(dpanRef: "DAPLMC00002125433c0c34a2821f4f86866e7572963baf8b",
status: .completed)
cardService.updateTokenizationStatus(cardID: "f16ba382-eb42-481a-b08f-c57bdc9aae24", request: request, completion: { result in
switch result {
case .success(let mobileWalletTokenization):
// Handle tokenization
case .failure(let error):
// Handle error
}
})
Apple card tokenization
This section includes both sequence diagrams and a technical guide outlining the process of adding a card to Apple Wallet through the In-App Provisioning flow.
Apple Wallet Requirements
- In order to enable In-App Provisioning of payment cards, you need a special entitlement. To get whitelisted to use it, contact Apple. For information on the prerequisites and required steps, please refer to Setting up Apple Pay documentation page.
This entitlement allows you to initialize and present a PKAddPaymentPassViewController object.
- Once the entitlement is approved, it needs to be configured.
- Go to Apple Developer Portal
- Certificates, Identifiers & Profiles
- Profiles
- Select the distribution iOS provisioning profile that you'll use to deploy your App to the App Store
- Edit
- Entitlements
ApplePay In-App Provisioning Distribution
- Generate
- Enable
In-App Provisioining
capability
- Go to Apple Developer Portal
- Certificates, Identifiers & Profiles
- Identifiers
- Find your App ID
- Additional Capabilities
- Enable
In-App Provisioining
capability
- Download the provisioning profile and use it
- Download the provisioning profile
- Install it (just tap on the
.mobileprofision
file when it is downloaded)
- Add your account to Xcode
- Xcode
- Preferences
- Accounts
- Add your account
- Use the selected provisioning profile
- Select a project target
- Signing & Capabilities
- Uncheck
Automatically manage signing
- Select
Provisioning Profile
Import Profile
to import the downloaded profile
Apple Wallet button
"Add to Apple Wallet" Button should only be displayed if a card does not exist in Apple Wallet on either the iPhone or Apple Watch.
- Verify device eligibility using
canAddPaymentPass()
. - Check PKPassLibrary that card does not exist in
passes()
andremoteSecureElementPasses
. - Display "Add to Apple Wallet" button using PKAddPassButton if above conditions are met.
- Tapping the button triggers In-App provisioning.
In-App provisioning
Once the user taps the 'Add to Apple Wallet' button, In-App Provisioning starts by initializing and presenting PKAddPaymentPassViewController by providing PKAddPaymentPassRequestConfiguration.
func createPaymentPassRequestConfiguration(customerInfo: Wallet.CustomerInfo, card: Wallet.Card) -> PKAddPaymentPassRequestConfiguration? {
guard let requestConfiguration = PKAddPaymentPassRequestConfiguration(encryptionScheme: .ECC_V2) else {
return nil
}
requestConfiguration.cardholderName = "\(customerInfo.firstName) \(customerInfo.lastName)"
requestConfiguration.primaryAccountSuffix = card.lastFour
// Filter the devices that already have this card provisioned, by setting requestConfiguration.primaryAccountIdentifier
requestConfiguration.paymentNetwork = card.scheme.paymentNetwork
return requestConfiguration
}
Subsequently, Apple Wallet requests creation of PKAddPaymentPassRequest through PKAddPaymentPassViewControllerDelegate. The received Apple Public Certificates, along with nonce and nonceSignature, are used to make cardService.tokenize()
request to the SDK.
Below code block demonstrates how CardTokenizationRequest is created from data returned by the delegate.
func addPaymentPassViewController(_ controller: PKAddPaymentPassViewController,
generateRequestWithCertificateChain certificates: [Data],
nonce: Data,
nonceSignature: Data,
completionHandler handler: @escaping (PKAddPaymentPassRequest) -> Void) {
let certificatesBase64EncodedString = certificates.map { $0.base64EncodedString() }
let nonceBase64EncodedString = nonce.base64EncodedString()
let nonceSignatureBase64EncodedString = nonceSignature.base64EncodedString()
guard let leafCertificate = certificatesBase64EncodedString.first,
let subordinateCertificate = certificatesBase64EncodedString.last else {
// Handle error
return
}
let tokenizationRequest = Wallet.CardTokenizationRequest(leafCertificate: leafCertificate,
subordinateCertificate: subordinateCertificate,
nonce: nonceBase64EncodedString,
nonceSignature: nonceSignatureBase64EncodedString)
Wallet.instance.cardService.tokenize(cardID: card.cardID,
request: tokenizationRequest,
completion: { result in
switch result {
case .success(let cardTokenization):
let addPaymentPassRequest = PKAddPaymentPassRequest()
addPaymentPassRequest.activationData = cardTokenization.activationData.flatMap { Data(base64Encoded: $0) }
addPaymentPassRequest.encryptedPassData = cardTokenization.encryptedPassData.flatMap { Data(base64Encoded: $0) }
addPaymentPassRequest.ephemeralPublicKey = cardTokenization.ephemeralPublicKey.flatMap { Data(base64Encoded: $0) }
handler(addPaymentPassRequest)
case .failure(let error):
// Handle error
}
})
}
Apple Wallet further forwards the encryptedPassData and ephemeralPublicKey to the PNO (Payment Network Operator) or service provider, where validation checks are conducted. The PNO validates the activationData and performs final approval checks, subsequently sending the successful activation status to Apple Wallet. PKAddPaymentPassViewControllerDelegate notifies success/failure.
func addPaymentPassViewController(
_ controller: PKAddPaymentPassViewController,
didFinishAdding pass: PKPaymentPass?,
error: (any Error)?
)
Successful activation is communicated to the SDK with cardService.updateTokenizationStatus()
which finalizes the process.
func addPaymentPassViewController(
_ controller: PKAddPaymentPassViewController,
didFinishAdding pass: PKPaymentPass?,
error: (any Error)?
) {
if let pass = pass {
let request = Wallet.MobileWalletTokenization(dpanRef: pass.deviceAccountIdentifier,
status: .completed)
Wallet.instance.cardService.updateTokenizationStatus(cardID: card.cardID,
request: request,
completion: { result in
// Handle result and refresh UI
})
} else if let error = error {
// Handle error
}
}
Google card tokenization
This section offers sequence diagrams and a detailed technical step-by-step guide for integrating card tokenization into Google Wallet using Android Push Provisioning API.
Card tokenization involves generating a secure digital replica of an existing physical or virtual card. This replica is subsequently integrated into a token network, such as Google Pay. For Google Pay, token provisioning can occur either manually, where a tokenization request is initiated from Google Wallet, or through push provisioning, where the request originates from your application.
Before initiating the card tokenization process on Google Wallet, the first step is creating a Google account if one has not already been created. After setting up your Google account, you can initiate the access request through this form, as gaining access involves submitting a request to Google Android Push Provisioning API.
After obtaining access, you can download and import the latest version of play-services-tapandpay.aar enabling you to use the TapAndPay SDK. TapAndPay SDK is a library developed by Google which streamlines the necessary calls to integrate with Google Wallet.
Google button display
The initial step is to display the Google button with the appropriate logo and dimensions. Google Pay button should be only displayed if a card does not exist in Google Pay/Wallet. Further information about this can be found in the official documentation provided by Google once access to the page is granted.
The sequence diagram below illustrates the essential checks required to initialize and display the Google button, in conjunction with the Paysafe mobile SDK, Android OS, and TapAndPay SDK.
Google button click
After completing the aforementioned steps to display and initialize the button, a subsequent click on the button will initiate one of the three specified flows below.
Push Tokenization
This flow will be initiated under two conditions: firstly, if the attempt to list tokens from TapAndPay SDK results in a failure with exception code TapAndPayStatusCode.TAP_AND_PAY_NO_ACTIVE_WALLET and secondly, if there is no match between the tokens retrieved from TapAndPay SDK and the tokens retrieved from Paysafe Mobile SDK.
The following sequence diagram outlines the necessary steps for Push Tokenization.
Manual Tokenization
This flow is initiated when listing the tokens affiliated with a particular wallet using tapAndPayClient.listTokens()
.
Upon discovering a token in the TapAndPay.TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION state related to the selected card, manual verification becomes necessary. This additional step is required to authenticate a card for a specific user.
To proceed with manual tokenization, the issuerTokenId
from the token that requires identity verification is used as tokenRefId
for the CardManualTokenizationConfiguration
object.
The following sequence diagram outlines the necessary steps for Manual Tokenization.
Create wallet
This flow is initiated when no wallet has been previously created on the device. It can be triggered either through the Push Tokenization or Manual Tokenization flows, where a call to activeWalletId and stableHardwareId may throw an exception in the absence of a wallet.
The following sequence diagram outlines the necessary steps to add a wallet to a device.