Mobile Wallet Push Provisioning: Integration Guide
Enable an in-app "Add to Apple Pay / Google Pay / Samsung Pay" button, so a cardholder can add their card to a wallet with one tap.
Push vs. manual provisioning
- Manual / in-wallet provisioning: the cardholder opens the Wallet app and types the card in themselves. No app integration required; available once your BIN is live (or BIN go-live date identified) and all required integration steps have been completed with Spidr.
- Push provisioning (this guide): your app pushes the card credentials directly into the wallet via the wallet SDK plus the Spidr Mobile Wallet Provisioning endpoint. Requires a native app (see Prerequisites) and the steps below.
In-app vs. web provisioning
This guide covers in-app provisioning, where the cardholder taps a control inside your native mobile app. If your app is web-based, contact Spidr to scope your provisioning options.
Prerequisites
- A native mobile app (iOS and/or Android). Cross-platform frameworks like React Native or Flutter qualify as long as they bridge to the native wallet SDKs. If your app is web-based, contact Spidr to scope your provisioning options.
- Manual wallet provisioning already enabled for your BIN (push provisioning builds on it).
- Sponsor-bank Google setup complete for Google Pay (see Sponsor-bank requirement). Spidr will help coordinate this piece.
Step 1: Get developer access from the wallet providers
Request developer-program access and pull the documentation for each wallet you intend to support:
- Apple: PassKit In-App Provisioning. Demo and reference: https://applepaydemo.apple.com/in-app-provisioning · entitlement reference:
com.apple.developer.payment-pass-provisioning(in the Apple Pay & PassKit entitlements doc: https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/ApplePayandPassKitEntitlements/ApplePayandPassKitEntitlements.html) - Google: Google Wallet Push Provisioning API for Android: https://developers.google.com/pay/issuers/apis/push-provisioning/android (access is granted through your sponsor bank's issuer console)
- Samsung: Samsung Pay SDK (if in scope): https://developer.samsung.com/pay
Step 2: Integrate the wallet SDKs
Integrate each wallet's SDK in your native app:
- Apple: PassKit In-App Provisioning.
- Google: Google Pay Push Provisioning API.
- Samsung: Samsung Pay SDK.
Step 3: Obtain certificates from the wallet providers
Register your app and pull the push-provisioning certificates and keys directly in the wallet providers' developer consoles (Apple Developer, Google Pay & Wallet Console, Samsung partner dashboard). These are issued by the wallet providers; Spidr does not supply them.
Step 4: Provide your App Identifiers
So your app can be registered with the card network as an authorized token requestor, send Spidr the following per wallet:
| Wallet | Identifiers |
|---|---|
| Apple | App ID (Bundle ID); Store ID (Adam ID, from App Store Connect); App Launch URL |
| Google / Samsung | App / Package Name; Activation Action (android.intent.action.MAIN); App Launch URL |
- Identifiers must come from your production app.
- In the Samsung partner dashboard, list the Issuer as your sponsor bank, not your program.
- Allow time for an overnight network refresh after identifiers are registered.
Step 5: Call the Mobile Wallet Provisioning endpoint
CV test certificates (Apple)
When testing Apple push provisioning in the CV environment, you need to supply cert1, cert2, nonce, and nonceSignature to the POST /v1/card/{cardId}/mobileWalletProvisioning endpoint. In production these values are generated on-device by the Apple PassKit SDK during the "Add to Apple Wallet" flow, but in sandbox there is no device flow, so use the fixed test values below.
When to use these
- Apple only. Android wallets (Google Pay / Samsung Pay) do not use test certificates. For those, send
clientWalletAccountIDandclientDeviceAccountIDinstead. - CV testing only. Use these to validate your
mobileWalletProvisioningintegration before going live. In production, pass the real cert/nonce values returned by the Apple PassKit SDK; the test values will not work in production. - These same test values apply to both in-app and web push provisioning testing.
How to use them
- Confirm with your Spidr representative that Apple push provisioning is enabled for your program in sandbox.
- Call
POST /v1/card/{cardId}/mobileWalletProvisioningwithwalletType: "apple"and the four fields below in the request body. - A successful response returns the encrypted provisioning payload (
activationData,encryptedPassData,ephemeralPublicKey) that your app hands back to the Apple PassKit SDK to complete the add.
Field reference
| Field | Description |
|---|---|
cert1 | Leaf certificate (hex-encoded DER). |
cert2 | Subordinate / sub-CA certificate (hex-encoded DER). |
nonce | Hex value. Must be valid hexadecimal (even number of characters from [0-9A-Fa-f]). |
nonceSignature | Hex value, same formatting rule as nonce. |
Note:
cert1must be the leaf certificate andcert2the sub-CA certificate. Sending them in the wrong order will fail certificate-chain validation. Each value must be a single continuous hex string with no whitespace or line breaks.
Test values
{
"walletType": "apple",
"cert1": "3082028b30820231a003020102020900ab0498cd402dea45300a06082a8648ce3d0403023065310b3009060355040613025553310d300b0603550408130455746168311730150603550407130e53616c74204c616b652043697479311b3019060355040a131247616c696c656f2050726f63657373696e673111300f060355040313086a68656e736c65793020170d3139303930393135343132315a180f32393939313131303135343132315a304c310b3009060355040613025553310d300b0603550408130455746168311b3019060355040a131247616c696c656f2050726f63657373696e673111300f060355040313086a68656e736c65793059301306072a8648ce3d020106082a8648ce3d0301070342000458330ecfec33c86615ce6796e3c2bc7289fd6fa12928f37a1227a028c1ce0433d037764bd9b2f85b2bfd61c2043bf592bcf0cf1fe805df3fc3e48d393b889395a381e03081dd30090603551d1304023000301d0603551d0e04160414b3e1f6fc060b226fbae20a445ca222edff1dafd5307f0603551d2304783076a169a4673065310b3009060355040613025553310d300b0603550408130455746168311730150603550407130e53616c74204c616b652043697479311b3019060355040a131247616c696c656f2050726f63657373696e673111300f060355040313086a68656e736c6579820900ab836a9a490635a730090603551d1104023000301806092a864886f763640627040b0c09536f6d657468696e67300b0603551d0f0404030205e0300a06082a8648ce3d040302034800304502201fdd987de4044cd0d93b60613af3bc1a0efc681619e5e2839e3b7c36af05f269022100a2d7e5172d4613d99fd26684131f163d816cd6ea7309dbe8eed9e9b862f05ba5",
"cert2": "3082027230820217a003020102020900ab0498cd402dea44300a06082a8648ce3d0403023065310b3009060355040613025553310d300b0603550408130455746168311730150603550407130e53616c74204c616b652043697479311b3019060355040a131247616c696c656f2050726f63657373696e673111300f060355040313086a68656e736c65793020170d3139303930393135343035335a180f32393939313131303135343035335a304c310b3009060355040613025553310d300b0603550408130455746168311b3019060355040a131247616c696c656f2050726f63657373696e673111300f060355040313086a68656e736c65793059301306072a8648ce3d020106082a8648ce3d03010703420004ac11cb2172b8bfba429e0e9db752fc08f07954292960667a93bf25a04e7629fc66caf0ea0cda6922f5db9d34893d8bf062fe2220008caec346a06cde5bc9483aa381c63081c330090603551d1304023000301d0603551d0e04160414d212e64ef0169975f47d732f54eb282c9137ecb2307f0603551d2304783076a169a4673065310b3009060355040613025553310d300b0603550408130455746168311730150603550407130e53616c74204c616b652043697479311b3019060355040a131247616c696c656f2050726f63657373696e673111300f060355040313086a68656e736c6579820900ab836a9a490635a730090603551d1104023000300b0603551d0f0404030205e0300a06082a8648ce3d0403020349003046022100aa0317e9d00cdfa2c7fa44bb0dbb16af6f52789b2e0800cd23a62ce6bc9940dc02210085dcf171b22bb8cf109f2b89d3b8e9b86e44c3e9f73ea02efb24fa743aa547c2",
"nonce": "1ed719b5",
"nonceSignature": "40b0a7ad26e249f5807a4ff35de22cde27c3567c95f9909c5d6b02123ea60222774a87f056885e8ece8c35610054136b33d0425ab96e8910566eaa4a5155882803bb56a80e12d5f6f4881fec1175e2ae49"
}Production Validation
In production, your app collects the values returned by the wallet SDK and posts them to:
POST /v1/card/{cardId}/mobileWalletProvisioning (reference: https://docs.gospidr.com/reference/postv1cardcardidmobilewalletprovision)
Request fields
| Field | Wallet(s) | Source |
|---|---|---|
cardId (path) | all | the card to provision |
walletType (apple / google / samsung) | all | your flow |
cert1, cert2, nonce, nonceSignature | Apple | Apple PassKit SDK |
clientWalletAccountID, clientDeviceAccountID | Google / Samsung | Google / Samsung SDK |
sessionKey (optional) | all | risk/verification workflow |
Required-field rules: Apple needs cert1 + cert2 + nonce + nonceSignature; Google / Samsung need clientWalletAccountID + clientDeviceAccountID.
Response is provisioning_request_data; hand this back to the wallet SDK to complete the add:
- Apple:
activationData,encryptedPassData,ephemeralPublicKey - Google:
opaquePaymentCard - Samsung:
payload
The flow: your app gathers the wallet-provider data from the device SDK → calls the endpoint → Spidr returns the encrypted payload → your app passes it to the wallet SDK to finish provisioning → the card network creates the token and activates it on the device.
Step 6: Test, then go live
Validate the full flow in the CV (client validation) environment first; see the Getting Started with Spidr guide for a breakdown of Spidr environments. Because the entitlement and certificates apply only to your production app, end-to-end testing happens on a TestFlight/App Store (iOS) or production (Android) build.
Sponsor-bank requirement (Google Pay)
Google scopes push provisioning to the card issuer, so Google Pay requires your sponsor bank to set up an issuer profile and grant your developers access before your app can provision under it. Apple and Samsung have no equivalent bank-console step. This is a separate workstream from your app build; Spidr helps coordinate it with you and the bank.
Cardholder verification (one-time passcode)
Depending on risk, provisioning may require an extra identity verification step (a one-time passcode sent by SMS or email) before the card is added. Ensure cardholder contact details are on file so this can be delivered.
Supported card networks
Spidr supports push provisioning for Visa and Mastercard programs. (Discover support is in progress and not yet available.) The request and response fields above are supplied by the wallet SDKs and are the same regardless of your card network. A couple of network notes that apply across the board:
- Your App Identifiers are registered with the card network as the token requestor. The Bundle ID / Adam ID / Package Name and launch URL you send in Step 4 are what the network uses to recognize your app as authorized to request tokens. Provisioning requests will fail until this registration is in place, and any change to your identifiers takes time for a network refresh (typically overnight) before it's live.
- The wallet request fields are SDK-driven, not network-specific.
clientWalletAccountIDandclientDeviceAccountID(Google/Samsung) andcert1/cert2/nonce/nonceSignature(Apple) come straight from the wallet SDK. There are no additional network-side fields to collect beyond what each wallet's SDK hands you.
Updated about 1 month ago