Skip to main content

Add to Mobile Wallet

Introduction#

Mobile wallets are a convenient way to pay with your debit cards using your smartphone. Adding a card to a Mobile Wallet (e.g. Apple Pay, Google Pay) used to require scanning a physical card with a device camera or manually typing a card number into the Wallet. By implementing the "Add to Mobile Wallet" flow described below, your end customers can add their card to a digital wallet with one tap, from within your mobile app.

Benefits#

Allowing your end customers to add their card to a digital wallet in seconds from within your app, immediately after creating a debit card (or any point thereafter), contributes to a decrease time-to-first-use and increases the potential interchange revenue by making it easier to use the card.

Customer Experience#

  1. Within your mobile app, you'll add a button that will allow your end customer to add their card to their relevant mobile wallet.
  2. The customer will review and agree to terms and conditions, and then immediately be able to use the card from within the wallet.

Pre-requisites#

  1. You’ll need to have an executed NDA with Unit.

  2. The functionality is only available for mobile applications (native iOS/Android, or using a technology like React native or Flutter)

  3. If your cards have not been previously enabled for mobile wallet support, there are a few preliminary steps Unit can help you with.

    1. Your BINs will need to be configured to allow tokenization. If this is not already complete, contact your Customer Success Manager. Setting up your BIN for tokenization can take up to 4 weeks.
    2. You’ll need to provide mobile wallet card art (see the Card Issuance Guide for more information).
  4. Your BINs will need to also be installed and configured for the mobile wallet SDK with Visa. Contact your Customer Success Manager to ensure this is configured. Setting up your BIN for SDK use takes 10-20 business days and must be complete before testing can begin.

Getting Started#

info

Contact your Customer Success Manager to begin implementation on Add to Mobile Wallet functionality, including getting your BINs configured for the mobile wallet SDK with Visa.

Compliance#

  • Deposit Agreement: If your cards already support mobile wallets, no additional language needs to be incorporated.
  • End Customer: Unit and Visa will ensure the correct terms and conditions are presented to and consented by your end customer before adding the card to their digital wallet.
  • Partner Agreements: You may need to sign agreements with each digital wallet provider, see Tech Integration details below.

Tech Integration#

  • End Customer User Interface

    • Your user interface will need to instruct an end customer to add their debit card to a mobile wallet, according to their device type (iOS or Android).
    • The correct terms for each wallet will be presented to and consented by your end customer.
  • Backend

    • Review Unit’s API documentation for Add to Mobile Wallet.
    • Contact Unit for Visa's In-App Provisioning SDK binaries, App ID
  • Sample Apps

    • Unit provides two sample apps: Android and iOS
    • Sample apps cannot be used with a simulator
    • Available upon request
  • Testing: Once Unit has confirmed your BIN is configured for SDK use at Visa,

    • Visa requires testing in production.
    • The SDK imposes a limit of 7 provisioning attempts per device in a 24 hour period. Contact your Customer Success Manager if you encounter an issue.
    • iOS apps should be distributed using TestFlight, no simulators.

iOS#

Apple Pay Prerequirements#

Request Apple Pay In-app provisioning entitlement#

  1. For each production instance of the app that will be used, get the Mobile App Name, Team ID, and Adam ID.

  2. The Mobile App Name and the Adam ID can be found in the App Store Connect after selecting one of your apps:

  3. The Team ID can be found in the Apple developer account under "Membership" section:

  4. Email applepayentitlements@apple.com to request the Apple Pay In-App Provisioning Entitlement.

    1. In the email, send Mobile App name, Team ID, and Adam ID for each production instance of the app.
    2. Apple Pay typically responds within 1 business day.

Setup your App in Apple Developer Portal once entitlement is granted by Apple#

Add the in-app provisioning entitlement#
  1. Sign in to your Apple developer account.
  2. Navigate to 'Certificates, Identifier & Profiles'.
  3. Select "Distribution" underneath the "Profiles" heading on the sidebar.
  4. Select the distribution iOS provisioning profile that will be used to deploy the app to the iTunes App Store.
  5. Select "Apple Pay In-App Provisioning Distribution" entitlement from the drop down to add the entitlement to the profile.
  6. Once the entitlement is added, follow the standard process to release the app into the App Store.
Add Wallet Capability#
  1. Sign in to your Apple developer account.
  2. Navigate to 'Certificates, Identifier & Profiles'.
  3. Select "App IDs" underneath the "Identifiers" heading on the sidebar.
  4. Select the app identifier that will be used to deploy the app to the iTunes App Store.
  5. Under "Capabilities" tab, select the "Wallet" capability:

Integration steps#

This section describes the technical steps needed to integrate with Visa's SDK and add a Unit card to the mobile Wallet.

Xcode setup verification#

Wallet Capability#

  1. Go to "Signing & Capabilities" tab of your target.
  2. Verify that Wallet capability is there.

In-App Provisioning entitlement#

  1. Open your project .entitlement file in Xcode.
  2. Add the Boolean key com.apple.developer.payment-pass-provisioning is set to 1 (true).

Add Visa SDK to your Xcode project#

  1. Drag and drop the following frameworks into the XCode project:

    • VisaPushProvisioning.xcframework
    • VisaInAppCore.xcframework
    • VisaFeatureModuleCore.xcframework
    • VisaMobileFoundation.xcframework
    • RLTMXProfiling.xcframework
    • RLTMXProfilingConnections.xcframework
  2. Select "Copy items if needed" (if not already selected) and click on "Finish".

  3. Make sure "Embed & Sign" is selected for all the above XCFrameworks.

Visa SDK Configuration#

Inside the application didFinishLaunchingWithOptions method in the AppDelegate.swift, configure VisaInAppCore as follows:

// Setup Visa SDK Configlet visaInAppConfig = VisaInAppConfig(environment: .Production, appId: "b8186bd9-fcba-b77a-11e3-1c0d2e5a3501")do {    try VisaInAppCore.configure(config: visaInAppConfig)} catch {    // handle error}

Setup the environment (.Production or .Sandbox).

Add to Wallet flow#

The following diagram demonstrates the Add to Wallet flow. Below the diagram, you will find an explanation for each step in the flow.

Step 1 - Hold a strong reference to VisaPushProvisioningInterface#
var vpInterface: VisaPushProvisioningInterface?
Step 2 - Initialize the VisaPushProvisioningInterface instance and implement the VisaPushProvisioningListener#

Initialize the VisaPushProvisioningInterface instance in the init() method of your class:

vpInterface = VisaPushProvisioningInterfaceFactory.createPushProvisioningInterface(listener: self)

Declare the VisaPushProvisioningListener methods, we will implement them later:

func initializationSuccess(pushProvisioningInterface: VisaPushProvisioningInterface, response: VPInitResponse) { }func initializationFailure(pushProvisioningInterface: VisaPushProvisioningInterface, error: VPError) { }
func supportedWalletSuccess(pushProvisioningInterface: VisaPushProvisioningInterface, response: VPSupportedWalletResponse) { }func supportedWalletFailure(pushProvisioningInterface: VisaPushProvisioningInterface, error: VPError) { }
func cardProvisioningSuccess(pushProvisioningInterface: VisaPushProvisioningInterface, response: VPCardProvisioningResponse) { }func cardProvisioningFailure(pushProvisioningInterface: VisaPushProvisioningInterface, error: VPError) { }
Step 3 - Initialize Visa SDK and get the signedNonce#

Call to initialize() method

self.vpInterface?.initialize()

Handle initialization callbacks of the VisaPushProvisioningListener

func initializationSuccess(pushProvisioningInterface: VisaPushProvisioningInterface, response: VPInitResponse) {  // Get the signedNonce  let signedNonce = response.signedNonce}
func initializationFailure (pushProvisioningInterface: VisaPushProvisioningInterface, error: VPError) {  // handle error}
Step 4 - Get wallet payload from Unit API#

Get the mobile wallet encrypted payload for a specified Unit card from Unit API. Read more details in Unit get mobile wallet payload docs.

Step 5 - Get supported wallets#

Call to getSupportedWallets(request: VPSupportedWalletRequest) method using the payload from step 4

let request = VPSupportedWalletRequest(encPayload: payload)self.vpInterface?.getSupportedWallets(request: request)

Handle getSupportedWallets callbacks of the VisaPushProvisioningListener

func supportedWalletSuccess(pushProvisioningInterface: VisaPushProvisioningInterface, response: VPSupportedWalletResponse) {  let wallet = response.wallets[0]}
func supportedWalletFailure(pushProvisioningInterface: VisaPushProvisioningInterface, error: VPError) {  // handle error}
Step 6 - Start card provisioning#

Call to startCardProvisioning(request: VPSupportedWalletRequest, initialView: UIViewController) method

// use a supported wallet to initialize the VPCardProvisioningRequestlet request = VPCardProvisioningRequest(walletCode: wallet.code, walletName: wallet.name)
// call to startCardProvisioning() with the request and a UIViewController to show the Apple Pay screen on// if your current class is a UIViewController, you can pass 'self'self.vpInterface?.startCardProvisioning(request: request, initialView: self)

Handle startCardProvisioning callbacks of the VisaPushProvisioningListener

func cardProvisioningSuccess(pushProvisioningInterface: VisaPushProvisioningInterface, response: VPCardProvisioningResponse) {  // update wallet status for Wallet  // provisioning flow completed, you can update the UI}
func cardProvisioningFailure(pushProvisioningInterface: VisaPushProvisioningInterface, error: VPError) {  // handle error}

iOS - Add to Wallet Sample App#

Steps Before running the sample app#

  1. Open the UnitAddToWalletSampleApp.xcworkspace project located in UnitAddToWalletSampleApp folder.
  2. Open UNConstants.swift file.
  3. Set the orgToken variable with your Unit organization token:
static let orgToken: String? = "v2.public..."
  1. Set the customerId variable with your Unit customer ID:
static let customerId: String? = "123456"
  1. In UnitAddToWalletSampleApp folder, run pod install in the command line.

Apple In-App Provisioning Entitlement#

Important: In order to fully demonstrate the add to wallet flow, you should set your app bundle identifier that granted access of In-App provisioning from apple. If you didn't grant it yet, you can follow the following steps to simulate the flow on a simulator:

Setup to run on a simulator#

  1. Open UnitAddToWalletSampleApp.entitlements file.
  2. Add the com.apple.developer.payment-pass-provisioning entitlement to the dictionary.
  3. Set the added entitlement type to Boolean and set its value to 1.

For example:

<dict>    <key>com.apple.developer.payment-pass-provisioning</key>    <true/>  ...</dict>

Running the sample app#

  • After running the sample app, your customer cards should appear on screen.
  • Select a card by clicking on it, and tap on "Add Selected Card To Wallet" button.
  • See the logs printed in your screen for more details.

Android#

If you elect to support Google Pay push provisioning, the following represents some of the steps that are required by Google.

Google Pay Prerequirements#

  1. Create an account in the Google Developer Portal, if one does not already exist, and make sure you have access to this link. if you don't have access, then you should request access.
  2. Ensure that you (and any mobile app providers/developers) have executed any required CTA agreements, as well as the Google NDA, via the Google Developer Portal
  3. Verify that your client BIN(s) are token eligible and set up to support the Google Pay wallet type (Unit can assist with this step)

Google's step-by-step instructions for apps that intend to use Google Pay#

Steps that are required before the start of the Visa Digital Enablement SDK integration#

Step 1: UX/branding review#

  • Optional: You may download Google's sample app to further understand the branding guidelines

  • Review and adhere to Google's branding and user experience requirements

    • Option 1: Use Unit's common Visa presentation, located in the provided zip directory under unit-common-README.md.

    • Option 2: Set the assets independently:

  • Create a slide deck of images with one screen per page of the full user journey of your app starting from the login screen. Here's an example of an app that follows the guidelines: image

  • Complete the user experience branding review with Google (watch the requirements and then fill this form) with the following information:

  • image

You should receive a response to your request within 2 business day.

Step 2: Push Provisioning API access#

Get your app's SHA256 fingerprint#
  • Press on the Gradle icon on the top right of your screen image
  • Type 'signingReport' and press enter image
  • Copy your SHA-256

Complete this form with the following information:

image

image

image

image

  • Enter your Bank Partner's name (not Unit)

You should receive a response to your request within 2 business day.

After Step 2 you should move to the Visa SDK integration steps. When you are done with the integration, complete the following steps#

Folow these steps after app development (when ready to begin testing)

Step 3: Completion of Mobile App review#

If you are using the Unit's common Visa presentation you need to get the wallets every time your app goes to the background, and then display the view according to the wallet's status (see step 4 of unit-common-README.md - located in the provided zip directory). You will need to do it for the button to always be updated according to the current Google Wallet status.

Step 4: Completion of Mobile App field testing#

Request launch approval from Google#

Once approved by Google, follow the standard process to release the app to the Google Play Store.

Steps to support Samsung Pay#

If you elect to support Samsung Pay push provisioning, the following represents some of the steps that are required by Samsung.

Steps that are required before the start of the Visa Digital Enablement SDK integration#

  1. Ensure that you have executed any required Samsung agreements

  2. Collect the 'TSP Issuer Name(s)' which are registered with Samsung

  3. Verify that your client BIN(s) are token eligible and set up to support the Samsung Pay wallet type (Unit can assist with this step)

  4. Create an account in the Samsung Developer Portal, if one does not already exist:

  5. Review all detailed tasks required for push provisioning outlined in the Samsung Developer Portal

  6. Create a New App in the Samsung Developer Portal, following their guidelines

  7. Create a New Service in the Samsung Developer Portal, following their guidelines

  8. Link the New Service with the App created in Samsung Developer Portal

  9. Copy and save the Service ID, which is used by mobile app during push provisioning

  10. Review and adhere to Samsung's branding and user experience requirements

After these steps you should move to the Visa SDK integration steps. When you are done with the integration, complete the following steps#

Folow these steps after app development (when ready to begin testing)

Complete all required steps for the activation of push provisioning as outlined in the Samsung Developer Portal, which may include the following:

  1. Whitelist and release the new Mobile App a. Navigate to Projects > App Management > App b. Add New Release Version, upload the APK file and Register
  2. Submit the release for approval in the Samsung Developer Portal Once approved by Samsung, follow the standard process to release the app to the Google Play Store.

Integration Steps#

This section describes the technical steps needed to integrate with Visa's SDK and add a Unit card to the mobile Wallet.

Prerequirements#

Before you start with the technical integration, please follow the prerequirements below:

  • The minimum supported Android SDK API version is 26.
  • The deployment target is Android SDK API version is 30.
  • The minimum supported Kotlin version is 1.5.10.
  • The minimum supported Java version is 1.8.
  • The SDK requires to use a physical Android device and not a virtual device.
  • Make sure you have the relevant wallets to which you will add cards installed on your device.

Add VDE (Visa Digital Enablement) SDK to your project#

  1. Get the push provisioning package from Unit, which consists of the following dependencies:

    • VisaPushProvisioning-3.0.0.aar
    • VisaInAppCore-3.0.0.aar
    • TMXProfiling-6.1-67.aar
    • TMXProfilingConnections-6.1-67.aar
    • samsungpaysdk-2.6.00.jar
    • play-services-tapandpay-17.0.1.aar
    • dexguard-runtime-9.0.6.aar
  2. Add the dependencies from the previous step under the libs folder of your project:

    • In Android Studio switch your folder structure from Android to Project.

    image

    • Now search for the libs folder inside the app folder.

    image

    • paste the dependencies inside the libs folder

    image

    • In case the libs folder doesn't exist you can create it:

      • Make sure the folder structure is Project (it was explained above)
      • Right click on your app name in the directory tree and go to "New" => "Directory" and name it "libs"
  3. Gradle Dependencies:

    a. Declare the following Gradle dependencies. Make sure to add the open source dependencies mentioned:

dependencies {
   // In-App Provisioning SDK   implementation files('libs/VisaPushProvisioning-3.0.0.aar')   implementation files('libs/VisaInAppCore-3.0.0.aar')   implementation files('libs/TMXProfiling-6.1-67.aar')   implementation files('libs/TMXProfilingConnections-6.1-67.aar')
   // Samsung Pay   implementation files('libs/samsungpaysdk-2.6.00.jar')
   //dexguard   implementation files ('libs/dexguard-runtime-9.0.6.aar')
   // Google Pay   implementation files('libs/play-services-tapandpay-17.0.1.aar')   implementation "com.google.android.gms:play-services-base:17.0.0"   implementation 'com.google.android.gms:play-services-instantapps:17.0.0'
   //Nimbus   implementation "com.nimbusds:nimbus-jose-jwt:9.22"
   implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
   implementation 'androidx.core:core-ktx:1.7.0'   implementation 'androidx.appcompat:appcompat:1.4.1'
   implementation 'com.squareup.retrofit2:retrofit:2.9.0'   implementation 'com.google.code.gson:gson:2.8.6'   implementation 'com.squareup.retrofit2:converter-gson:2.5.0'   implementation 'com.squareup.okhttp3:logging-interceptor:3.12.1'
   testImplementation 'junit:junit:4.13.2'   androidTestImplementation 'androidx.test.ext:junit:1.1.3'   androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
   //Kotlin Coroutines   implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2"   implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
}
  1. Additional instructions for Samsung Pay

    a. If the target device includes Android 11 and above, add the below in the app's AndroidManifest.xml file. If this is not added, the VDE SDK may return a 'NOT_INSTALLED' status.

<queries>    <package android:name="com.samsung.android.spay" /></queries>

b. Add the below in AndroidManifest.xml file, if VDE SDK has returned a 'NOT_AVAILABLE' status.

<meta-data android:name="spay_sdk_api_level" android:value="2.6" /><meta-data android:name="debug_mode" android:value="N" />

Configure VDE SDK in your custom application file#

Import the following libraries:

import com.visa.mobileEnablement.inAppCore.*import com.visa.mobileEnablement.pushProvisioning.*import androidx.lifecycle.ProcessLifecycleOwner

inside your init() configure VisaInAppCore as follows:

val visaInAppConfig = VisaInAppConfig(VisaInAppEnvironment.Production, "b8186bd9-fcba-b77a-11e3-1c0d2e5a3501")VisaInAppCore.configure(context, visaInAppConfig)//recognizes lifecycles changesProcessLifecycleOwner.get().lifecycle.addObserver(VisaInAppCoreApplicationObserver())

Setup the environment (.Production or .Sandbox).

Add to Wallet flow#

Overview#

The following diagram demonstrates the Add to Wallet flow. Below the diagram, you will find an explanation for each step in the flow.

Unit_Android_Add to_wallet_flow_diagram

Step 1 - Hold a reference to VisaPushProvisioningInterface#

var pushProvisioningInterface: VisaPushProvisioningInterface? = null

Step 2 - Initialize the VisaPushProvisioningInterface instance and implement the VisaPushProvisioningListener interface in your class#

Initialize the VisaPushProvisioningInterface instance in the init() method of your class:

//'this' is the object that implements VisaPushProvisioningListenerpushProvisioningInterface = VisaPushProvisioningInterfaceFactory.createPushProvisioningInterface(this)

Declare the VisaPushProvisioningListener methods, we will implement them later:

override fun initializationSuccess(    pushProvisioningInterface: VisaPushProvisioningInterface,    response: VPInitResponse) { }
override fun initializationFailure(    pushProvisioningInterface: VisaPushProvisioningInterface,    error: VPError) { }
override fun cardProvisioningSuccess(    pushProvisioningInterface: VisaPushProvisioningInterface,    response: VPCardProvisioningResponse) { }
override fun cardProvisioningFailure(    pushProvisioningInterface: VisaPushProvisioningInterface,    error: VPError) { }
override fun supportedWalletSuccess(    pushProvisioningInterface: VisaPushProvisioningInterface,    response: VPSupportedWalletResponse) { }
override fun supportedWalletFailure(    pushProvisioningInterface: VisaPushProvisioningInterface,    error: VPError) { }

Step 3 - Initialize Visa SDK and get the signedNonce#

Call to initialize() method

pushProvisioningInterface?.initialize()

Handle initialization callbacks of the VisaPushProvisioningListener

override fun initializationSuccess(    pushProvisioningInterface: VisaPushProvisioningInterface,    response: VPInitResponse) {    val signedNonce = response.signedNonce}
override fun initializationFailure(    pushProvisioningInterface: VisaPushProvisioningInterface,    error: VPError) {    //handle error}

Step 4 - Get wallet payload from Unit API#

Get the mobile wallet encrypted payload for a specified Unit card from Unit API. Read more details in Unit get mobile wallet payload docs.

Step 5 - Get supported wallets#

Call to getSupportedWallets(request: VPSupportedWalletRequest) method using the payload from step 4

val vpSupportedWalletRequest = VPSupportedWalletRequest(payload)pushProvisioningInterface?.getSupportedWallets(vpSupportedWalletRequest)

Handle getSupportedWallets callbacks of the VisaPushProvisioningListener

override fun supportedWalletSuccess(   pushProvisioningInterface: VisaPushProvisioningInterface,   response: VPSupportedWalletResponse) {   val wallet = response.wallets}
override fun supportedWalletFailure(   pushProvisioningInterface: VisaPushProvisioningInterface,   error: VPError) {   // handle error}

Step 6 - Start card provisioning#

Call to startCardProvisioning(context: Context, request: VPCardProvisioningRequest) method:

val vpCardProvisioningRequest = VPCardProvisioningRequest(wallet.code, wallet.name)pushProvisioningInterface?.startCardProvisioning(context, vpCardProvisioningRequest)

Handle startCardProvisioning callbacks of the VisaPushProvisioningListener

override fun cardProvisioningSuccess(    pushProvisioningInterface: VisaPushProvisioningInterface,    response: VPCardProvisioningResponse) {    // update wallet status for Wallet    // provisioning flow completed, you can update the UI}}
override fun cardProvisioningFailure(    pushProvisioningInterface: VisaPushProvisioningInterface,    error: VPError) {    // handle error}
  1. Execute the necessary agreements. The below are required, even if you already support Google Pay for manual card provisioning, to establish a relationship with you as a mobile app provider.

    1. Push Provisioning API Access Request

      1. Select "BIN Sponsor or Program Manager working on behalf of a financial company or card issuer
      2. Enter your Bank Partner's name (not Unit)
      3. Answer "Does the financial company or card issuer have a signed CTA agreement with Google?" with Yes
      4. Network will be Visa
    2. Google NDA

  2. Verify that your BIN(s) are token eligible and set up to support Google Pay. Unit can assist with this step.

  3. Create an account in the Google Developer Portal, if you do not already have one

  4. Review all detailed tasks required for push provisioning outlined in the Google Developer Portal

  5. Follow Google’s step-by-step instructions for apps that intend to use Google Pay.

    1. Review and adhere to Google’s branding and user experience requirements
    2. Complete the UX/branding review with Google
  6. When you’re ready to release to production, continue with Google’s step-by-step instructions

    1. Completion of App whitelisting
    2. Completion of App review
    3. Completion of App field testing
  7. Request launch approval from Google

  8. Once approved by Google, follow the standard process to release the app into the Google Play Store. gReport' and press enter

Android - Add to Wallet Sample App#

This sample app demonstrates how to integrate with Visa's SDK in your app.

Steps Before running the sample app#

  1. Open the project inside UnitWalletDemo folder in the Android Studio.
  2. Open UNConstants file.
  3. Set the orgToken variable with your Unit organization token:
static let orgToken: String? = "v2.public..."
  1. Set the customerId variable with your Unit customer ID:
static let customerId: String? = "123456"

Running the sample app#

  • After running the sample app, your customer cards should appear on screen.
  • Select a card by clicking on it, and tap on "Add Selected Card To Wallet" button.
  • See the logs printed in your screen for more details.