Add a card to a digital wallet
Last updated: April 7, 2025
You can enable cardholders to add cards to their Apple or Google wallet with push provisioning in your mobile app or the Apple Wallet app, using the Card Management Android or iOS SDK.
Push provisioning means the cardholder does not have to enter the card details manually. It involves multiple parties including you, Checkout.com, the card scheme, and the wallet provider.
Information
To enable and onboard for push provisioning, contact your Account Manager. Your Account Manager collects your configuration requirements and shares your unique issuer ID.
You must:
- Complete your Issuing onboarding.
- Integrate the Card Management Android SDK or iOS SDK.
- Ensure you import the Android additional libraries or iOS dependencies and libraries.
- Ensure you're using the SDK's
CheckoutCardManagement
library.
- Create or receive your private/public key pair.
- Add your testing device to the device allowlist.
- Implement the push-provisioning prerequisites.
Note
If you attempt push provisioning without completing your Issuing or push-provisioning onboarding, your app intentionally crashes.
Push provisioning requires a private/public key pair, which can be generated by either Checkout.com or you.
- Private key – You use this to sign the JSON Web Token (JWT).
- Public key – The server uses this to verify the OpenID access token provided by the issuer's identity provider (IdP). This ensures that the JWT was signed with the private key that corresponds to the public key.
Example –ABCDOEFGHIJKLMNOPqRsTu+VWx1Yzabc+DEfGhIj2kl/mN3opQr4STUV5wx6Y78z
If Checkout.com generates the key pair, we securely share the private key with you. If you generate the key pair, share it with Checkout.com through a safe store.
To generate the key pair, run the following command, providing your issuer ID from your push-provisioning onboarding:
1$ openssl ecparam -name prime256v1 -genkey -noout -out is_cko_{Issuer_id}-jwt-priv-key.pem23$ openssl ec -in is_cko_cko-jwt-priv-key.pem -pubout > is_cko_{Issuer_id}-jwt-pub-key.pem
Checkout.com recommends testing push provisioning on a physical device. You must add your testing device to the allowlist for your platform:
Retrieve your SHA-256 fingerprint:
- Open Android Studio and go to the Gradle tab.
- Select the Execute Gradle Task icon.
- In the modal that appears, enter
gradle signinReport
, and then press Enter. - Copy the SHA-256 value from the report output.
Complete the Push Provisioning API Access Request form as follows:
- Company name – Enter Checkout.com.
- Google Wallet use case – Select Payments card.
- Option which best describes your company – Select Card Issuer.
- App package name – Enter [your.app.package]. For example,
com.checkout.levant
. - App package environment – Select Production.
- Fingerprints – Enter your SHA-256 fingerprint.
- Target launch date – Enter a date in the future, in
MM/DD/YYYY
format. - Network – Select Mastercard as the card scheme.
Implement the required push-provisioning prerequisites for your platform:
You must request access to the Android Push Provisioning API.
Once you have completed the setup, the flow for the cardholder to add their card to their wallet is as follows:
- Authenticate the cardholder.
- Retrieve the cardholder's cards.
- Configure push provisioning.
- Provide a JSON Web Token.
- If you're provisioning from within your app, verify the cards' digitization status.
- Provision the card.
You are responsible for performing Strong Customer Authentication (SCA) on the cardholder for each session where they use functionality provided by the SDK. This applies to both the sandbox and production SDK environments.
Pass an access token that your app receives from your authentication back end.
1val token = "{Access_token}"2cardManager.logInSession(token)
Once you’ve authenticated the cardholder and your app, call the cardManager.getCards()
method to retrieve a list of their cards:
1cardManager.getCards { result: Result<List<Card>> ->2result.onSuccess {3// You receive a list of the cardholder's cards that you can display in your UI4// Returned card details include the last four digits of the PAN, expiry date, cardholder name, card status, and card ID5}.onFailure {6// If something goes wrong, you receive an error with more information7}8}
- Call the
checkoutCardManager.configurePushProvisioning()
method:
1checkoutCardManager.configurePushProvisioning(2activity = {Activity_to_handle_the_provisioning_outcome},3cardholderId = "{Dd_of_cardholder_performing_operation}",4configuration = ProvisioningConfiguration(/* */),5completionHandler = { result: Result<Unit> -> /* Callback after the operation is complete*/ })
- Provide a
ProvisioningConfiguration
object to the SDK as follows:
1ProvisioningConfiguration(issuerID, // Your unique issuer identifier from Checkout.com2serviceRSAExponent, // As a bytearray object3serviceRSAModulus, // As a bytearray object4serviceURL, // The URL of the D1 Service Server5digitalCardURL) // The URL for the digital card operation
issuerID
– Provide your issuer ID from your push-provisioning onboarding.serviceRSAExponent
andserviceRSAModulus
– To retrieve these values from the Public Key Privacy Enhanced Mail (PEM) file, run the following command:
1openssl rsa -pubin -inform PEM -text -noout < pubkey.pem
serviceURLString
– Provide the following URL:https://client-api.d1.thalescloud.io/
.digitalServiceURLString
– Provide the following URL:https://hapi.dbp.thalescloud.io/mg/tpc
.
Information
For more information on the ProvisioningConfiguration
object fields, see Thales D1 Developer Portal – Initial Setup.
Provide a unique JSON Web Token (JWT) for every provisioning call for each device or app. Ensure the token is supported in your back end. The token format must be unique and differ from all other tokens the SDK consumes.
Information
For more information, see Thales D1 Developer Portal – SDK Login.
For full guidance on generating JWTs, see Thales D1 Developer Portal – Backend Authorization.
Do not use any mobile end examples from this guidance in the production environment.
To generate the token, provide the following properties and sign it using your private key:
Token property | Description | Generated token |
---|---|---|
string | The token scope: |
string |
string | The unique identifier for the cardholder. |
string |
| The date and time when you want the token issued, in UTC. |
|
URL | The token issuer, including your Checkout.com issuer ID from onboarding: |
URL |
URL | The token audience, including your Checkout.com issuer ID: |
URL |
| The date and time when the token expires, in UTC. |
|
string | The token key identifier: |
string |
alg
is the encryption algorithm used. This can be one of: ES256
or RS256
.
1Header:2{3"alg" : "ES256",4"kid" : "d1api-{Your_Checkout.com_client_name}-01"5}67Payload:8{9"aud" : "https://client-api.d1.thalescloud.io/oidc/\{issuerId}",10"scope" : "thales:d1",11"iss" : "https://bpsd1-demo-a2oidc.d1-dev.thalescloud.io/oidc/\{issuerId}",12"exp" : "2025-01-31T10:20:30.456",13"sub" : "crh_d3ozhf43pcq2xbldn2g45qnb44",14"iat" : "2025-01-31T10:20:30.456"15}1617Signature18{Signature generated using your private key and hash function}
If you're provisioning from within your app, call the card.getDigitizationState()
method to verify the digitization status of the cardholder's cards.
Note
If the cardholder has multiple cards, call this method for each card synchronously. If you attempt asynchronous calls, each new execution overrides the previous one.
1card.getDigitizationState(token: "{JWT_generated_for_operation}",2completionHandler: "Completion handler that returns the digitization result ((CheckoutCardManager.CardDigitizationResult) -> Void)")
Cards can have the following digitization statuses:
Digitization status | Description |
---|---|
| The card is digitized on all associated devices. |
| The card is digitized on some but not all associated devices, or is not digitized on any associated devices. NoteIf you continue to receive this status after the card is added to the wallet, check that your app is correctly configured on the Token Service Provider (TSP) portal. |
| Prompt the cardholder to activate the card to enable digitization on their device. |
| The card is being digitized. |
- Call the
card.provision()
method:
1card.provision(2activity = {Activity_to_handle_the_provisioning_outcome},3token = "{JWT_generated_for_operation}",4completionHandler = { result: Result<Unit> -> /* Callback after the operation is complete*/5}6)
- Handle the push-provisioning response in the same activity you used for the
card.provision
method:
1// Required to handle the card result2override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {3super.onActivityResult(requestCode, resultCode, data)4card.handleCardResult(requestCode, resultCode, data)5}
Information
If you have integration questions or issues, contact your issuing representative or [email protected].
You can only test push provisioning in the SDK's production environment.
If you receive the following ERROR_CORE
authorization failure, ensure your testing device date is in the future:
1ERROR_CORE [20001] (3) (401) {"error_reference":"TCsTqQepR8w4GRVnTVS7jlC1cTrk772v","securityEvent":true}
You may receive an API_UNAVAILABLE error code or message from Google Pay. For example:
1AppsFilter: interaction: PackageSetting{ba9eff6 com.google.android.gms.tapandpay.issuer.devapp.littlebear/10337} -> PackageSetting{6e03871 com.checkout.levant/10405} BLOCKED23API: TapAndPay.TAP_AND_PAY_API is not available on this device. Connection failed with: ConnectionResult{statusCode=API_UNAVAILABLE, resolution=null, message=null}
This could be for the following reasons:
- During testing, you did not add your device to the Google allowlist.
- In production, your cardholder does not have Google Wallet installed. Prompt them to install the app via the Play Store.