Skip to main content
Apple Pay and Google Wallet Unified Push Provisioning (UPP) use the same endpoint. google_pay is the Legacy Google Pay integration for existing integrations. Reach out to your Imprint team to coordinate wallet enablement for your program.

Overview

Add to Wallet lets a customer provision their Imprint card into a device wallet — Apple Pay or Google Wallet — without leaving your app. The platform wallet SDK is the wallet framework the operating system provides: PassKit (PKAddPaymentPassViewController) on iOS, and the TapAndPay client on Android. Apple and Google ship it, not Imprint, and your app links it to show the native Add to Wallet sheet. Your app collects the values supplied by the platform wallet SDK, passes them to Imprint, and Imprint returns the encrypted payload the SDK needs to finish adding the card. Imprint never asks you to handle the card number. The provisioning payload is encrypted for the wallet provider, so your app acts purely as a courier between the platform wallet SDK and Imprint. What this unlocks: a customer who has just been approved for a card can tap Add to Apple Wallet in your app and start making contactless payments immediately — before the physical card arrives in the mail.

What you need

How the flow works

The critical detail: your app talks to the platform wallet SDK first. The wallet SDK produces the values Imprint needs. Only then do you call Imprint.
1

Your app asks the platform wallet to begin

The customer taps Add to Wallet. Your app starts the platform’s add-card flow (PKAddPaymentPassViewController on iOS, Google Wallet UPP through TapAndPay on Android).
2

The wallet SDK hands your app the values Imprint needs

On iOS this is a certificate chain, a nonce, and a nonce signature — a single-use handshake. On Android, Google’s payment-credentials callback supplies the active wallet ID, stable device ID, Google OPC request flag, and a server session ID when the Google OPC is requested.
3

Your app calls Imprint

POST /v2/payment_methods/{payment_method_id}/provision/{wallet}, forwarding the handshake.
4

Imprint returns an encrypted provisioning payload

Imprint validates that the payment method belongs to you, then requests the encrypted payload from the card network on your behalf.
5

Your app hands the payload back to the wallet SDK

The SDK decrypts it and adds the card. The customer sees the card appear in their wallet.
Apple Pay only: the handshake from step 2 is single-use and short-lived. You cannot cache an Imprint provisioning response and replay it later, and you cannot call Imprint with a nonce from a previous attempt. If provisioning fails, dismiss and restart PKAddPaymentPassViewController from step 1 so PassKit issues a fresh nonce.For Google Wallet UPP, call Imprint inside Google’s payment-credentials callback. If the attempt fails, start a new UPP attempt and use its callback values. Do not reuse an earlier payload or server session ID. Legacy Google Pay retries may re-send the same stable wallet_id and device_id.
In every flow the provisioning payload Imprint returns is single-use: hand it straight to the platform wallet SDK and never cache or persist it.

The endpoint

Request body options

See the API reference for the full request and response schemas.

Apple Pay (apple_pay)

Request

Take these three values from your PKAddPaymentPassViewControllerDelegate callback:
PassKit gives you certificateChain as [Data] and nonce / nonceSignature as Data. Base64-encode each one before sending it — Imprint rejects raw bytes with invalid_request. Do not otherwise transform the values.

Response

Map the payload onto PKAddPaymentPassRequest. Base64-decode each value first — Imprint returns Base64 strings, but the PassKit properties are Data. Assigning the strings without decoding hands PassKit the wrong bytes and provisioning fails.
Then pass the request to the completion handler PassKit gave you in the delegate callback.
Imprint uses elliptic-curve key exchange, so ephemeral_public_key is always the key field in the response. You do not need to handle the RSA wrappedKey variant.

Google Wallet UPP (google_wallet)

Use google_wallet for new Android integrations. Start provisioning through the TapAndPay SDK with a PaymentCredentialsGenerator, then call Imprint from inside Google’s GeneratePaymentCredentialsRequest callback. The callback tells you whether Google also needs an opaque payment card for the cardholder’s Google Account; pass that decision through rather than setting it yourself.

Inputs before Google’s callback

Build a PushTokenizeRequest and pass it to TapAndPayClient.pushTokenize. These inputs come from your app’s existing card and customer data; they are available before you call Imprint’s provisioning endpoint. Use constants from com.google.android.gms.tapandpay.TapAndPay:

Request

Google invokes PaymentCredentialsGenerator.generate(request) with a GeneratePaymentCredentialsRequest after you start pushTokenize. Read all four fields from that callback for the current attempt:
For example, inside generate(request), build the JSON body to forward through your backend:
Google generates serverSessionId for this UPP attempt and supplies it in the Android GeneratePaymentCredentialsRequest callback. It identifies the intended provisioning session for the Google opaque payment card. It is not a Lithic or Imprint response field: send the callback value unchanged as server_session_id in your request to Imprint, which forwards it to Lithic. See Google’s Google OPC specification and Lithic’s UPP request guidance. When Google supplies googleOpaquePaymentCardRequested: false, send false and omit server_session_id if Google did not supply one. Do not force the flag to true or invent a session ID. If the required wallet or device ID is missing, do not fabricate one.

Response

The Google Wallet response does not include a wallet, network, or wallet_type field. The TapAndPay request still needs the card network and its token service provider, which your app must obtain from its existing card or program configuration, not this response. In the PaymentCredentialsGenerator callback, map the response as follows:
If Google requested the additional OPC but Imprint did not return it, fail the callback; do not fall back to the device-token-only path. Keep your Imprint API key on your backend, never in the Android app, and do not log, cache, or persist either payload.
Google Wallet UPP requires Google issuer-app access and launch validation. Coordinate testing and wallet enablement with your Imprint team before release.

Google Pay Legacy (google_pay)

google_pay is the Legacy flow: it obtains the opaque payment card before starting TapAndPay push tokenization. New integrations should use google_wallet UPP.

Request

Response

opaque_payment_card is the only value that must come from this response. Build the rest of the PushTokenizeRequest from values you already have:
wallet_type is not a TokenServiceProvider. TapAndPay requires setTokenServiceProvider on every request, and its value is derived from the card network (for example a Visa card uses TOKEN_PROVIDER_VISA), not from the wallet you are provisioning into. Passing "GOOGLE_PAY" there will fail.Confirm the correct network and token service provider constants with your Imprint team during integration.

Errors

Provisioning errors use the standard Imprint error envelope described in Error handling, with a machine-readable code:
422
Do not blind-retry a failed Apple Pay call. Each PassKit nonce is single-use, so replaying the original request body fails with invalid_request — you must go back through PKAddPaymentPassViewController for a new one.Google Wallet UPP retries must restart the Google flow and use values from a new payment-credentials callback. Legacy Google Pay may re-send its stable wallet_id and device_id, but must request a fresh provisioning payload.

Not supported

Security notes

  • Provisioning payloads are encrypted for the wallet provider. Your app cannot read the card number from them, and neither can anyone intercepting them.
  • Payloads are single-use. Do not log them, cache them, or persist them.
  • Ownership is enforced server-side. Imprint verifies that the payment_method_id belongs to the program your API key is scoped to. A payment method from another program returns 404, not 403, so the endpoint does not reveal whether an unknown ID exists.
  • Keep your API key server-side. You must call this endpoint through your app’s backend proxy — your Imprint API key must never ship inside your mobile app binary.