> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thedecard.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Push Provisioning (Adding Cards to Apple Pay / Google Pay)

> How to let a cardholder add a DCS-issued Visa card to Apple Wallet or Google Wallet from inside the partner's app: the tokenization mental model, the commercial onboarding process, the runtime binding sequence, and the dedicated Apple and Google wallet binding REST endpoints.

## 📄 Guide

Push provisioning lets a cardholder add a DCS-issued Visa card to **Apple Wallet (iOS)** or **Google Wallet (Android)** with **a single tap inside your app**, instead of typing the card number into the wallet app. As a licensed issuer with its own BINs, DCS is the party that integrates with Apple's and Google's tokenization and provisioning authorization.

Unlike the capabilities that can only redirect the user, the DeCard-Managed model **does expose its own wallet binding REST endpoints** (`/card/v1/apple-bind-wallet` and `/card/v*/google-bind-wallet`): your app forwards the cryptographic material the wallet gives it to DCS, DCS calls Visa tokenization, and DCS returns the provisioning payload the wallet needs, which your app passes back to the system wallet to finish the job.

> **Recommendation for new Apple Pay integrations**: use [DCSProvisioningSDK](../../sdk/apple-pay/installation). The SDK uses a temporary ticket from `POST /card/v1/bind-wallet-ticket` and encapsulates the later PassKit and DCS exchange. This page keeps the underlying wallet binding REST endpoints for field reference, existing direct integrations and Google Pay integrations.

> **Prerequisite**: the user must have passed KYC and been issued a card, and you must hold that card's identifier (the last four digits of the PAN `cardMantissa` for Apple and Google V1, or `cardId` for Google V2). For the issuing flow, see [Issuing Cards](./issuing-cards).

### Mental model: tokenization

Digital wallets protect a card through **tokenization**: the real card number (PAN) is replaced by a unique digital token.

* **One token per card per device**: every "card × device" pair gets its own token, and the tokens are independent of each other.
* **End-to-end protection**: the token stands in for the real PAN at transaction time, so the plaintext PAN never reaches the merchant or the wallet.
* **Token lifecycle** (five stages): created when the card is added → activated after verification → used in place of the real PAN at transaction time → rotated periodically for security → destroyed when the card is removed.

### Two provisioning paths

| Path                    | What it is                                                                                                   | Needs the API on this page                                                        |
| :---------------------- | :----------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- |
| **Manual provisioning** | The cardholder types the card details into the Apple or Google Wallet app to add it                          | No. DCS supports this out of the box and no development is required (steps below) |
| **In-app provisioning** | The cardholder taps "add to wallet" **inside your app** and the app pushes the card into the wallet securely | **Yes.** You call the wallet binding endpoints on this page                       |

This page is about **in-app provisioning**, which requires integration work on your side and calls to the DCS wallet binding API. Manual provisioning needs no development at all (DCS supports it by default) and is done by the cardholder inside the wallet app; the steps are reproduced below so you can reuse them in your own help content.

#### Apple Pay manual provisioning (iPhone, 3 steps)

1. **Open the Wallet app**: open Wallet on the iPhone and tap "+" in the top right corner.
2. **Enter the card details**: hold the card near the iPhone to add it, or tap "Enter Card Details Manually" and follow the on-screen instructions.
3. **Verify identity**: choose a verification method when prompted (SMS or email) and enter the code to finish.

#### Google Pay manual provisioning (Android, 7 steps)

1. **Open the Google Wallet app**: the cardholder opens Google Wallet and **must be signed in to a Google account** for mobile payments to work.
2. **Start adding a card**: the cardholder taps "Add to Wallet" to begin manual provisioning.
3. **Choose the card type**: if prompted, the cardholder selects "Payment card".
4. **Enter the card details manually**: the cardholder chooses "Or enter details manually" and **types in the card number, expiry date and CVV**.
5. **Accept the terms**: the cardholder **reviews and accepts the terms and conditions**.
6. **Verify identity**: a **verification code** is sent by SMS or email for identity verification.
7. **Finish provisioning**: the cardholder enters the code and, on success, sees a confirmation in the Google Wallet app.

> The exact steps vary a little with the handset, the OS version and wallet app updates. Contact the DCS team if anything is unclear.

### The four roles

| Role                                  | Who            | Responsibility                                                                                                |
| :------------------------------------ | :------------- | :------------------------------------------------------------------------------------------------------------ |
| Partner app                           | You            | Show the "add to Apple Pay / Google Pay" button, integrate the wallet SDK, forward the cryptographic material |
| Apple Pay / Google Pay API            | Apple / Google | Perform tokenization and wallet provisioning                                                                  |
| DCS wallet binding service            | DCS            | Call Visa tokenization and return the provisioning payload the wallet needs (the API on this page)            |
| BIN Sponsor (Apple) / Issuer (Google) | DCS            | Request provisioning authorization from Apple and Google as the issuer                                        |

> On the Apple side DCS acts as the **BIN Sponsor** and the partner as the **Program Manager**; on the Google side DCS acts as the **Issuer** and the partner as the **Program Manager**.

***

## Commercial onboarding (one-off, before go-live)

Before cards can be provisioned into wallets in production, you, DCS and Apple or Google have to complete a one-off round of authorization and certification. Apple and Google run separate tracks:

### Apple Pay onboarding

| Step                     | What happens                                                                                                                                                                                                                                                                                        |
| :----------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ① Confirm roles          | Partner = Program Manager; DCS = BIN Sponsor                                                                                                                                                                                                                                                        |
| ② Partner Hub onboarding | DCS registers the partner as Program Manager in Partner Hub; the partner signs the NDA and the Program Manager agreement; DCS signs the addendum with Apple                                                                                                                                         |
| ③ Technical integration  | Manual provisioning is already supported by DCS. For a new Apple Pay integration, the partner integrates **DCSProvisioningSDK**, the backend obtains a temporary ticket, and the SDK calls DCS / Visa to provision the card. Existing direct integrations can keep using the endpoints on this page |
| ④ Lab certification      | Every Program Manager must pass Apple's **Limited Labs Certification** in its own right (book ahead; allow roughly **2–3 weeks**)                                                                                                                                                                   |
| ⑤ App release            | Once lab certification has passed and every Partner Hub review step is complete, the partner submits the app to the store for review and release                                                                                                                                                    |

### Google Pay onboarding

| Step                    | What happens                                                                                                                                                                                                                                           |
| :---------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ① Confirm roles         | DCS = Issuer; Partner = Program Manager                                                                                                                                                                                                                |
| ② Google Wallet Console | Sign the NDA; the partner registers through the issuer documentation access form; complete and submit the **Push Provisioning API Access** request (company and app details, SDK access); make sure the app is registered in the Google Wallet Console |
| ③ Technical integration | Manual provisioning is already supported by DCS; for in-app provisioning the partner integrates the **Google Pay SDK** and calls the DCS wallet binding endpoints on this page to enable "Add to Google Pay" in the app                                |
| ④ UI/UX review          | Submit the UX and branding review Google requires                                                                                                                                                                                                      |
| ⑤ Field testing         | Complete Google's field testing and meet its exit criteria before go-live                                                                                                                                                                              |
| ⑥ App release           | The partner submits the Launch Approval Form with "Program Manager" selected, then submits the app to Google Play for review                                                                                                                           |

> The screen-by-screen detail on the wallet side is governed by Apple's and Google's own issuer documentation, which this page does not reproduce. Contact the DCS team for further integration detail.

***

## Runtime provisioning flow (in-app provisioning)

Once you are integrated, every tap on "add to wallet" in your app triggers the exchange shown below. Apple is used as the example; Google works the same way and differs only in the request and response fields:

> The diagram shows the underlying direct flow. With DCSProvisioningSDK, your app hands the ticket and card parameters to the SDK, which encapsulates the exchange of PassKit device artifacts with DCS; see the [Implementation Guide](../../sdk/apple-pay/implementation).

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-push-provisioning-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=0f1fa65d68c87719157e1dadfbeb6ce5" alt="In-app provisioning sequence diagram" width="817" height="784" data-path="imgs/en/diagrams/va-push-provisioning-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-push-provisioning-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=2a39fa5805f83025517f13ee49f0a003" alt="In-app provisioning sequence diagram" width="817" height="784" data-path="imgs/en/diagrams/va-push-provisioning-dark.svg" />
</Frame>

The Apple in-app provisioning cryptographic flow in nine steps: ① the app starts provisioning → ② the wallet asks Apple for certificates and a nonce → ③ Apple returns them → ④ the wallet passes the certificates, nonce and nonce signature back to the app → ⑤ the app forwards them to the DCS wallet binding service → ⑥ DCS generates an ephemeral key pair, encrypts the payment data with a shared key derived from Apple's public key, generates the encrypted OTP, and returns the encrypted data together with the ephemeral public key → ⑦ the app sends the encrypted data, the ephemeral public key and the encrypted OTP to the wallet → ⑧ the wallet verifies the provisioning with Apple → ⑨ Apple and the payment network operator (PNO) complete standard provisioning.

Apple Pay in-app provisioning cryptographic flow:

<Frame>
  <img src="https://mintcdn.com/dcs-0bf7a937/U5My61eeN1_eDSDM/imgs/decard-managed/digitalWalletApplePay-inProvisioningFlow.png?fit=max&auto=format&n=U5My61eeN1_eDSDM&q=85&s=404c6a9ae2b43da45ae26ce0a6ddce98" alt="Apple Pay in-app provisioning cryptographic flow" width="1870" height="658" data-path="imgs/decard-managed/digitalWalletApplePay-inProvisioningFlow.png" />
</Frame>

***

## Wallet binding API

The Apple binding endpoint is `POST /card/v1/apple-bind-wallet` (it identifies the card with the last four digits of the PAN, `cardMantissa`). For Google, DCS offers **V1 and V2**; **use V2 for every new Google integration** (it identifies the card precisely with `cardId`).

| Platform | Version              | Endpoint                           | Card identifier field |
| :------- | :------------------- | :--------------------------------- | :-------------------- |
| Apple    | V1                   | `POST /card/v1/apple-bind-wallet`  | `cardMantissa`        |
| Google   | **V2 (recommended)** | `POST /card/v2/google-bind-wallet` | `cardId`              |
| Google   | V1                   | `POST /card/v1/google-bind-wallet` | `cardMantissa`        |

> **The only difference between Google V2 and V1 is how the card is identified**: V2 uses `cardId` where V1 uses `cardMantissa`. `externalUserId` is required in both versions, and every other field is identical.

### Apple Pay wallet binding

#### Request fields

| Field                     | Type      | Required | Description                                                   |
| :------------------------ | :-------- | :------- | :------------------------------------------------------------ |
| `externalUserId`          | string    | Yes      | User ID                                                       |
| `cardMantissa`            | string    | Optional | Last four digits of the PAN                                   |
| `applePublicCertificates` | string\[] | Yes      | List of Apple public key certificates, supplied by the wallet |
| `appleNonce`              | string    | Yes      | Apple nonce                                                   |
| `appleNonceSignature`     | string    | Yes      | Apple nonce signature                                         |

> The required fields are `externalUserId` / `applePublicCertificates` / `appleNonce` / `appleNonceSignature`; `cardMantissa` is optional.

#### Request example (masked)

```bash theme={null}
curl -X POST "{{dicard-server}}/card/v1/apple-bind-wallet" \
  -H "Content-Type: application/json" \
  -d '{
    "externalUserId": "<external-user-id>",
    "cardMantissa": "<last-4>",
    "applePublicCertificates": ["<apple-public-cert>"],
    "appleNonce": "<apple-nonce>",
    "appleNonceSignature": "<apple-nonce-signature>"
  }'
```

#### Response

A successful call returns the common envelope `{ code, message, messageDetail, data }` with `code = SYS_SUCCESS`. `data` holds the payload Apple Wallet needs to complete tokenization:

| `data` field         | Type / spec                        | Description                                                                                                          |
| :------------------- | :--------------------------------- | :------------------------------------------------------------------------------------------------------------------- |
| `encryptedPassData`  | string (0–8192 characters, base64) | Encrypted authentication data, containing the encrypted PAN, expiry and timestamp                                    |
| `activationData`     | string (0–8192 characters, base64) | Activation data, containing the encrypted nonce, nonceSignature and authCode                                         |
| `ephemeralPublicKey` | string (0–8192 characters, base64) | The `VISA.ECC.ePK` generated when building the MBPAD encrypted payload: an EC point on the P-256 curve, uncompressed |
| `vCardID`            | string (42 characters)             | Visa's unique card identifier, used to generate the provisioning payload                                             |

```json theme={null}
{
  "code": "SYS_SUCCESS",
  "message": "",
  "messageDetail": null,
  "data": {
    "encryptedPassData": "<base64>",
    "activationData": "<base64>",
    "ephemeralPublicKey": "<base64>",
    "vCardID": "<42-char-id>"
  }
}
```

### Google Pay wallet binding

#### Request fields

| Field              | Type   | Required (V2 / V1)           | Description                                                       |
| :----------------- | :----- | :--------------------------- | :---------------------------------------------------------------- |
| `externalUserId`   | string | Yes / Yes                    | User ID                                                           |
| `cardId`           | string | Yes / not present in V1      | Card ID (**V2 only**)                                             |
| `cardMantissa`     | string | not present in V2 / Optional | Last four digits of the PAN (**V1 only**)                         |
| `clientCustomerId` | string | Optional / Optional          | The user's Google Wallet account ID (2–36 characters)             |
| `deviceId`         | string | Optional / Optional          | The user's Android device ID, unique per device (2–24 characters) |

> Google V2 requires only `externalUserId` and `cardId`; `clientCustomerId` and `deviceId` are both optional. V1 requires only `externalUserId`.

#### Request example (V2, masked)

```bash theme={null}
curl -X POST "{{dicard-server}}/card/v2/google-bind-wallet" \
  -H "Content-Type: application/json" \
  -d '{
    "externalUserId": "<external-user-id>",
    "cardId": "<card-id>",
    "clientCustomerId": "<google-wallet-account-id>",
    "deviceId": "<android-device-id>"
  }'
```

#### Response

On success `code = SYS_SUCCESS` and `data` holds what Google Pay needs for tokenization:

| `data` field        | Type / spec            | Description                                           |
| :------------------ | :--------------------- | :---------------------------------------------------- |
| `last4`             | string (4 characters)  | Last four digits of the PAN                           |
| `opaquePaymentCard` | string                 | The opaque card data Google Pay tokenization requires |
| `vCardID`           | string (42 characters) | Visa's unique card identifier                         |

```json theme={null}
{
  "code": "SYS_SUCCESS",
  "message": "",
  "messageDetail": null,
  "data": {
    "last4": "<last-4>",
    "opaquePaymentCard": "<opaque-payment-card>",
    "vCardID": "<42-char-id>"
  }
}
```

<Warning>
  Every example value is a placeholder. **Never** put a real `externalUserId`, `cardId`, `cardMantissa`, cryptographic material, API key or secret, or any cardholder personal data into a request or a log.

  **Authentication**: the examples omit the authentication headers to keep the focus on the business fields. A real call must carry `X-DAPI-API-KEY` / `X-DAPI-SIGN` / `X-DAPI-TIMESTAMP` / `X-DAPI-NONCE` (HMAC-SHA256 signature); for the rules, see the [Authentication Guide](../../integration-resources/overview).
</Warning>

***

## Error handling

Before it can be provisioned, the card must be in a **normal, usable state**: activated, not frozen and not canceled. If the status is anything else, activate the card or lift the restriction first, then start provisioning.

| Situation                                     | What to do                                                                                                                                                                                                                                                                                             |
| :-------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `code` in the response is not `SYS_SUCCESS`   | Follow the hint in `message` and check your parameters: is `cardId` / `externalUserId` valid, is the card activated, is the cryptographic material complete                                                                                                                                            |
| Tokenization fails on the wallet side         | The risk engines built into Apple Wallet and Google Wallet can block provisioning (several attempts in quick succession, a flagged device, a mismatch between device region and card region, and so on). Ask the user to try again after **24–48 hours**; DCS cannot override a wallet's risk decision |
| Apple Pay is unavailable in the user's region | The wallet raises an iOS error, and DCS cannot work around Apple's regional restrictions                                                                                                                                                                                                               |

## Testing notes

* Push provisioning **has to be tested with production cards**: Visa provides no sandbox tokenization cards, so the full provisioning flow cannot be verified in the sandbox.
* iOS builds must be installed through **TestFlight** for testing; running straight from Xcode makes provisioning fail.

> Today, provisioning success or failure does **not** generate an extra webhook event. Treat the response from this API and from Apple or Google Wallet as authoritative. Asynchronous provisioning events would require new platform capability.

## Next steps

* [Apple Pay SDK Installation](../../sdk/apple-pay/installation) — add DCSProvisioningSDK and configure the entitlement, App Group and card profile
* [Implementation Guide](../../sdk/apple-pay/implementation) — exchange the ticket and start in-app provisioning
* [Wallet Extensions Guide](../../sdk/apple-pay/wallet-extensions) — expose the provisioning entry point inside Apple Wallet
* [Issuing Cards](./issuing-cards) — issue the card first and obtain its `cardId` / `cardMantissa`
* [Managing Cards · Overview](./overview) — freezing and unfreezing, card replacement, the state machine
* [Managing a Card's PIN](./managing-a-cards-pin) — also card management, with the PIN handled through a guidance page
* [Webhook + WebSocket notifications](../../integration-resources/webhook-websocket) — other card and transaction events; provisioning events are not among them today
