Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
Overview
Start an integration
Funding and treasury
Treasury
Capital
Payment management
Issuing cards
    Overview
    How Issuing works
    Global availability
    Manage fraud
    Cards
    Choose your card type
    Virtual cards
    Physical cards
    Manage cards
    Digital wallets
    Replacement cards
    Card programs
    Program management
    Processor-only Issuing
    Customize your card program
    Add funds to your card program
    Credit Consumer Issuing
    Controls
    Spending controls
    Advanced fraud tools
    3DS
    Fraud challenges
    Real-time authorizations
    PIN management
    Issuing Elements
    Token Management
    Funding
    Balance
    Postfund your integration with Stripe
    Postfund your integration with Dynamic Reserves
    Purchases
    Authorizations
    Transactions
    Disputes
    Testing
    Merchant categories
    ATM Usage
    Enriched merchant data
    Issuing with Connect
    Set up an Issuing and Connect integration
    Update terms of service acceptance
    Connect funding
    Connected accounts, cardholders, and cards
    Inactive connected accounts offboarding
    Embed card management UI
    Credit
    Overview
    Set up connected accounts
    Manage credit terms
    Report other credit decisions and manage AANs
    Report required regulatory data for credit decisions
    Manage account obligations
    Test credit integration
    Additional information
    Choose a cardholder type
    Customer support for Issuing and Treasury
    Issuing watchlist
    Marketing guidance (Europe/UK)
    Product and marketing compliance guidance (US)
Global Payouts
Manage money
HomeMoney managementIssuing cards

Use digital wallets with Issuing

Learn how to use Issuing to add cards to digital wallets.

Issuing allows users to add cards to digital wallets like Apple Pay and Google Pay. Stripe supports the addition of cards through two methods:

  1. Manual Provisioning: cardholders enter their card details into a phone’s wallet application to add it to their digital wallets.
  2. Push Provisioning: mobile applications allow users to add cards to their digital wallets straight from the app.

When a card is added to a digital wallet, a tokenized representation of that card is created. Network tokens are managed separately from cards. For more information about network tokens and how they work, see Token Management.

Manual Provisioning

Cardholders can add Stripe Issuing virtual cards and physical cards to their Apple Pay, Google Pay, and Samsung Pay wallets through manual provisioning.

To do so, cardholders open the wallet app on their phone and enter their card details. Stripe then sends a 6-digit verification code to the phone_number or email of the cardholder associated with the card.

A card not supported error displays if neither field is set on the cardholder when the card was provisioned.

No code is required to implement manual provisioning, but the process to set it up can vary depending on the digital wallet provider and the country you’re based in:

US

Apple Pay wallets require approval from Apple. Check your digital wallets settings to view the status of Apple Pay in your account. You might need to submit an application before using Apple Pay.

Google Pay and Samsung Pay have no additional required steps.

EU/UK

Digital wallet integrations require additional approval from the Stripe partnership team. Get in touch with your account representative or contact Stripe for more information.

Apple Pay wallets require additional approval. Check your digital wallets settings to view the status of Apple Pay in your account. You might need to submit an application before using Apple Pay.

Push Provisioning

With push provisioning, cardholders can add their Stripe Issuing cards to their digital wallets using your app, by pressing an “add to wallet” button like the ones shown below.

Users must first complete manual provisioning steps to enable push provisioning in the US. In addition to manual provisioning approval, push provisioning requires you to integrate with the Stripe SDK.

This requires both approval processes through Stripe and code integration with the Stripe SDK for each platform you wish to support push provisioning on. Platform approvals cascade down to all of their connected accounts.

Samsung Pay push provisioning isn’t supported with our SDKs.

A black UI button that says Add to Google Wallet. There is a Google Wallet logo image to the left of the text.

Request Access

Stripe provides an SDK wrapper around a private Google library for push provisioning. To distribute your app on the Google Pay Store with push provisioning you need to:

  • Request access to Google Pay. After you complete the form, expect approval within a few hours to a day.
  • After receiving approval, download Google’s TapAndPay private SDK. The most recently tested version of the TapAndPay SDK is version 18.
  • Request access to the push provisioning API for your app. You must provide your application ID to be added to Google’s allowlist. Details on this process are available in Google’s documentation. After the process is complete, Google grants push provisioning entitlements.
  • After Google has granted push provisioning entitlements, contact Stripe with your application name, application ID, card network, and card name to complete this step.

Update your app
Client-side

  • Import Google’s private SDK.
  • Import Stripe’s SDK.
dependencies { [... your dependencies] implementation 'com.stripe:stripe-android-issuing-push-provisioning:1.2.2' }

For more context, see the code snippets and references to the sample app at each step. For this step, see how the sample app imports these SDKs.

  • Prepare your backend to create ephemeral keys for your cards. See section below.
  • Create an EphemeralKeyProvider that extends PushProvisioningEphemeralKeyProvider. As the ephemeral key provider will be passed to another activity, it also needs to implement Parcelable (see Parcelable). For more context, see how the sample app defines its EphemeralKeyProvider.
  • Implement the Add to Google Pay button according to Google’s specifications. The sample app provides an example of the button adhering to branding guidelines.

Caution

As recommended by Google, don’t require your users to install the Google Pay app, or check its existence programmatically. The app is only a frontend and you don’t need it for Google Pay to work. Users can manage their cards from within their Google settings in the “Settings” app.

Caution

Google requires that the Add to Google Pay button only displays when a card doesn’t already exist on the user’s device, and that users with cards pending verification complete the final guided activation process. Use Google’s list of checkpoints to help you verify that your implementation is correct.

To check the status of your users’ cards, use listTokens() to retrieve a list of all of your cards already present on the device. Compare the value of getFpanLastFour() on each returned object to Stripe’s last4) property of the Issued Card object for the card you want to add. Discard all non-matching objects from the response list.

  • If the resulting list is empty, it means that the card you intend to add isn’t present on the device yet. You can proceed with displaying the button as described below.
  • If the resulting list contains a TokenInfo object, check its TokenState by invoking getTokenState().
    • If the status is TOKEN_STATE_NEEDS_IDENTITY_VERIFICATION, your user has already attempted to manually add the given card to their device. Display the Add to Google Pay button, but help them to recover from this situation by wiring the onActivityResult listener to the tokenize() method as outlined in Google’s documentation.
    • If the status is anything else, the card is already present on the device. Do not display a Google Pay button.

Make sure to provide your application ID to Stripe before starting internal testing. Setup can take more than a week, and the consequences of an incomplete setup include receiving inconsistent responses to these two methods. The result of listTokens() only contains cards added after Stripe completes the setup.

  • When a user taps the button, launch Stripe’s PushProvisioningActivity using the PushProvisioningActivityStarter.
new PushProvisioningActivityStarter( this, // The Activity or Fragment you are initiating the push provisioning from new PushProvisioningActivityStarter.Args( "Stripe Card", // The name that will appear on the push provisioning UI ephemeralKeyProvider, // Your instance of EphemeralKeyProvider false // If you want to enable logs or not )).startForResult();

For more context, see how the sample app launches PushProvisioningActivity.

This prepares the push provisioning and launches the UI to add the card to the wallet. Implement the callback in your onActivityResult.

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { if (requestCode == PushProvisioningActivityStarter.REQUEST_CODE) { if (resultCode == PushProvisioningActivity.RESULT_OK) { PushProvisioningActivityStarter.Result success = PushProvisioningActivityStarter.Result.fromIntent(data); } else if (resultCode == PushProvisioningActivity.RESULT_ERROR) { PushProvisioningActivityStarter.Error error = PushProvisioningActivityStarter.Error.fromIntent(data); } } }

For more context, see how the sample app implements onActivityResult.

If the provisioning was successful, you’ll receive a PushProvisioningActivityStarter.Result containing a cardTokenId which is Google’s ID for the card in the active wallet. You can use the rest of the wallet functions with this ID.

If the provisioning encountered an error, a PushProvisioningActivityStarter.Error will be returned with a code and a message. The message is a developer-friendly text explaining the error. The code can have the following values:

EnumMeaning
USER_CANCELEDThe user canceled the provisioning.
CARD_CANCELEDThe card has been canceled or is lost or stolen and can’t be provisioned.
EPHEMERAL_KEY_ERRORThere was an error retrieving the ephemeral key.
TAP_AND_PAY_UNAVAILABLEThe TapAndPay library can’t be used, most likely because the app isn’t added to an allowlist.
NO_STABLE_HARDWARE_IDThis can happen in the development emulator. The app can’t retrieve the stable hardware ID.
NO_ACTIVE_WALLET_FOUNDNo active wallet available. Note that emulators generally don’t have Google Pay.
PUSH_PROVISIONING_ENCRYPTED_PAYLOAD_ERRORThere was an error contacting Stripe’s servers to get the encrypted payload for push provisioning.
UNKNOWN_ERRORAn unexpected error occurred. The message will have additional information.

Update your backend
Server-side

The push provisioning implementation exposes methods that expect you to communicate with your own backend to create a Stripe Ephemeral Key and return a JSON of it to your app. This key is a short-lived API credential that you can use to retrieve the encrypted card details for a single instance of a card object.

To make sure that the object returned by the Stripe API is compatible with the version of the iOS or Android SDK you’re using, the Stripe SDK lets you know what API version it prefers. You must explicitly pass this API version to our API when creating the key.

Command Line
curl
Ruby
Python
PHP
Node
Java
Go
.NET
No results
curl https://api.stripe.com/v1/ephemeral_keys \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "issuing_card"="{{ISSUING_CARD_ID}}" \ -H "Stripe-Version: {{API_VERSION}}"
{ "id": "ephkey_1G4V6eEEs6YsaMZ2P1diLWdj", "object": "ephemeral_key", "associated_objects": [ { "id": "ic_1GWQp6EESaYspYZ9uSEZOcq9", "type": "issuing.card" } ], "created": 1586556828, "expires": 1586560428, "livemode": false, "secret": "ek_test_YWNjdF8xRmdlTjZFRHelWWxwWVo5LEtLWFk0amJ2N0JOa0htU1JzEZkd2RpYkpJdnM_00z2ftxCGG" }

For more context, see how the sample backend creates a Stripe Ephemeral Key.

Testing

All testing must be done in live mode, with live Issuing cards, and on physical devices.

To build the sample app, follow the steps in the readme. You don’t need to build the app to follow the instructions above.

Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Join our early access program.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc