Card tokenization refers to the creation of a secure digital "copy" of a preexisting card (either physical or virtual). The copy is then added to a token network, such as Apple Pay or Google Pay. In the case of Apple Pay and Google Pay, a token can be provisioned manually (i.e., a tokenization request is initiated from the Apple or Google wallet) or via push provisioning (i.e., the request is initiated from your application).
This page explains how to use the Solaris API to tokenize a customer's card using push provisioning.
To initiate push provisioning, call the respective endpoint for Apple Pay:
Retrieve the following information from Apple and provide it to Solaris via the API:
nonce: A one-time-use nonce provided by Apple. You must hex-encode this value before providing it to the API.nonce_signature: Nonce signature provided by Apple. You must hex-encode this value before providing it to the API.certificates: An array of leaf and sub-CA certificates provided by Apple. Each object contains a DER-encoded X.509 certificate, starting with the leaf and followed by the sub-CA. You must encode this value in Base64 format before providing it to the API.
The Solaris API supports in-app verification for Apple Pay using Cryptographic OTP (Method A). The process works as follows:
- Call the POST Fetch activation payload for Apple Pay in-app verification endpoint for the relevant card.
- The Solaris API will create a change request. Have the customer complete the change request following the standard process.
- The Solaris API will return an activation payload. Submit this payload in your request to the customer's Apple Wallet via the Apple Pay API. Refer to the Apple Pay developer documentation for implementation details.
View POST Fetch activation payload for Apple Pay in-app verification API reference
To initiate push provisioning, call the respective endpoint for Google Pay:
Retrieve the following information from Google and provide it to Solaris via the API:
client_wallet_account_id: Unique 24-byte identifier for each instance of a[Android user, Google account]pair wallet. The ID is computed as a keyed hash of the Android user ID and the Google account ID. The key to this hash lives on Google's servers, and the wallet ID is created during user setup as an RPC.client_device_id: Stable identifier for a physical Android device. Google refers to this attribute as a "Stable hardware ID" in their SDK documentation. The methodgetStableHardwareIddescribes how you can retrieve this value.client_app_id: Unique identifier for the client application. Use valueSolarisPushProvisioning.
The API returns a wallet_payload. Submit this to the wallet provider (Apple Pay/Google Pay) as part of a push provisioning request to their respective API. Refer to the Apple Pay/Google Pay developer documentation for more details on this process.
Unified push provisioning allows you to enable your customers to add a card to a specific Google Pay wallet on a specific Android device, and additionally saves the card to the customer's Google Account. Once saved to the account, Google can automatically re-provision the card to any new Android device the customer signs into in the future, without requiring them to add the card again manually.
Google is deprecating the standard Google Pay push provisioning endpoint ([POST /v1/cards/{card_id}/sca_push_provision/google)) at the end of 2026. You must migrate to the unified endpoint before that date.
The endpoint returns two distinct payloads:
| Payload | Field | Purpose |
|---|---|---|
| TSP OPC (opaque payment card) | opaque_payment_card | Passed to the TapAndPay SDK. Google forwards it to the Token Service Provider (Visa or Mastercard) to create a device token for contactless payments. |
| Google OPC | google_opaque_payment_card | Passed to the TapAndPay SDK. Google delivers it to its backend to save the card's FPAN to the customer's Google Account, enabling automatic re-provisioning on future devices. PGP-signed, encrypted, and Base64-encoded. |
Pre-requisites:
- Your app must include the Google Pay Push Provisioning API (TapAndPay SDK). Follow Google's setup guide to add the SDK dependency to your Android project.
- The customer must have Google Pay configured on their device. If no wallet exists, call
TapAndPay.createWallet()before proceeding. - The customer's device must be bound and the customer must have a verified mobile number,as both are required for the SCA change request process. See Device binding and Mobile number management.
- The card must be in an
ACTIVEstate in Solaris before provisioning can be initiated. - Your backend must be configured to receive
CARD_TOKEN_LIFECYCLEwebhook events.
How it works:
The flow has four phases: collecting data from the TapAndPay SDK, calling the Solaris API, the customer completing an SCA challenge, and finalizing the provisioning in the SDK.
Phase 1 — collect provisioning data from the SDK
Before calling the Solaris API, your app must retrieve four values from the TapAndPay SDK. These values identify the device, the wallet instance, and the Google Account session into which the card will be provisioned.
The referenced Google TapAndPay SDK methods are subject to change. Always verify the latest implementation details directly in the official Google Pay documentation.
Call the following SDK methods in your Android app:
TapAndPay.getActiveWalletId()→ returnswallet_idA unique 24-byte identifier for the combination of this Android user, Google account, and device. Identifies which wallet instance the card will be provisioned into.
TapAndPay.getStableHardwareId()→ returnsstable_hardware_idA stable identifier for the physical Android device. Required by certain TSPs (including Visa) during OPC generation.
GeneratePaymentCredentialsRequest→ returnsserver_session_idandtoken_requestor_idInitiates a provisioning session on Google's servers. The
server_session_idis a UUID that identifies the Google Account session and is used to generate the Google OPC. Thetoken_requestor_ididentifies the token requestor to the TSP.
Send all four values to your backend along with the Solaris card_id for the card to be provisioned.
Phase 2 — call the Solaris API
Call POST /v1/cards/{card_id}/sca_push_provision/google_unified from your backend.
Example request body
{
"wallet_id": "Rwt3tJek_k1JxivcwbPHjKDk",
"stable_hardware_id": "a1b2c3d4e5f6g7h8",
"token_requestor_id": "12345678901",
"server_session_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}Click here to view the full API reference.
Phase 3 — handle the SCA change request
This endpoint triggers the Solaris change request process. The provisioning request is not complete until the customer authorizes it via SCA.
For the full SCA change request implementation, see Strong Customer Authentication.
Once confirmed, Solaris returns 201 Created with both OPCs in the response body:
{
"opaque_payment_card": "eyJhbGciOiJBMjU2R0N...",
"google_opaque_payment_card": "LS0tLS1CRUdJTiBQR1A..."
}Phase 4 — pass the OPCs to the TapAndPay SDK
Once your backend receives the 201 response, send both payloads to your app and pass them to the TapAndPay SDK:
opaque_payment_card (TSP OPC)
Pass this to the TapAndPay SDK. Google Pay forwards it to the Token Service Provider (Visa Token Service or Mastercard Digital Enablement Service) to create a device token, enabling the card for contactless payments on this device.
google_opaque_payment_card (Google OPC)
Pass this to the TapAndPay SDK. Google delivers it to its backend to save the card number to the customer's Google Account, enabling automatic re-provisioning to any future Android devices the customer signs into.
Refer to the Google Pay Push Provisioning API reference for the specific SDK methods to use when submitting each payload.
To monitor the status of the tokenization process, subscribe to the CARD_TOKEN_LIFECYCLE webhook.
Solaris triggers this event when a token is created, updated, or deleted. When a customer successfully adds their card to a wallet (Apple Pay, Google Pay, or Samsung Pay), you receive a notification with the event type TOKEN_CREATED.
This allows you to confirm the provisioning status in your application and update the UI accordingly.
Example payload for Apple Pay:
{
"card_id": "8b48d56bdc1c091d9ab5547fe0e9511bmcrd",
"token_reference_id": "DNITHE382228352676336613",
"token_status": "ACTIVE",
"event_type": "TOKEN_CREATED",
"wallet_type": "APPLE",
"created_at": "2022-09-19T01:31:26.695Z"
}