Skip to main content

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:

val cardService = Wallet.getInstance().getCardService()

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.

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)

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).

note

Use this method when the a card is successfully added to a wallet.

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)

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

  1. 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.

  1. 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
  1. 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
  1. Download the provisioning profile and use it
  • Download the provisioning profile
  • Install it (just tap on the .mobileprofision file when it is downloaded)
  1. Add your account to Xcode
  • Xcode
  • Preferences
  • Accounts
  • Add your account
  1. 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() and remoteSecureElementPasses.
  • Display "Add to Apple Wallet" button using PKAddPassButton if above conditions are met.
  • Tapping the button triggers In-App provisioning.
Display Apple Wallet ButtonDisplay Apple Wallet ButtonDisplay Apple Wallet ButtonDisplay Apple Wallet Button

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
}
}
In-App Provisioning FlowIn-App Provisioning FlowIn-App Provisioning FlowIn-App Provisioning Flow

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.

Display google button flowDisplay google button flowDisplay google button flowDisplay google button flow

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.

Push tokenization flowPush tokenization flowPush tokenization flowPush tokenization flow

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.

Manual tokenization flowManual tokenization flowManual tokenization flowManual tokenization flow

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.

Create wallet flowCreate wallet flowCreate wallet flowCreate wallet flow