# Apple Wallet ID

Apple Wallet verification lets a user share approved identity attributes from a supported credential in Apple Wallet instead of photographing a physical document. The Incode iOS SDK presents Apple's system authorization sheet, sends the encrypted Wallet response to Incode for validation, and then continues the onboarding flow.

Apple Wallet ID is available for:

- iOS 16.0 or later. Some credentials may require a newer iOS version.
- An Incode iOS SDK version that supports Apple Wallet identity verification.

<Callout icon="⚠️" theme="warn">
  ### Warning

  Incode must enable and configure Apple Wallet for your account through Dashboard. Apple Wallet cannot currently be enabled or configured through a code-defined SDK flow.
</Callout>

***

## How It Works

Apple Wallet appears as one option in the [ID Capture](/sdk-reference/module-id-scan/) module's document chooser. The integration is chooser-based:

1. Your app initializes the iOS SDK and starts a session.
2. The ID Capture module shows any configured physical-capture and file-upload choices immediately.

   At the same time, the SDK checks with PassKit whether Apple Wallet is available on the device. If it is, the chooser adds **Apple Wallet** as an option. If it isn't, the existing choices stay the same.
3. The user selects **Apple Wallet**.
4. The SDK requests a one-time challenge from Incode. The challenge lists the fields configured in Dashboard.
5. Apple shows the system authorization sheet. The user reviews the requested information and authorizes with Face ID or Touch ID.
6. PassKit returns an encrypted response. The SDK sends this response to Incode without inspecting it.
7. Incode decrypts and validates the response on the server. ID Capture completes, and onboarding continues.

The host app doesn't receive raw Wallet identity attributes through a client callback. Results stay part of the Incode session and its configured verification flow. The back end determines requested identity fields through the one-time challenge; the SDK doesn't choose them.

***

## Prerequisites

Before integrating Apple Wallet, confirm all of the following:

| Requirement       | Details                                                                                                                                                                                                                                                                                                                                                                                           |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Incode enablement | Incode has enabled Apple Wallet for the account and environment.                                                                                                                                                                                                                                                                                                                                  |
| SDK               | An Incode SDK version that supports Apple Wallet identity verification.                                                                                                                                                                                                                                                                                                                           |
| Device            | An eligible iPhone with a supported identity credential in Apple Wallet.                                                                                                                                                                                                                                                                                                                          |
| OS                | The SDK generally supports iOS 13.0 and newer, but Apple Wallet identity verification requires iOS 16.0 or newer. The [credential itself](#apple-credential-availability) may require a newer iOS version. The current implementation uses PassKit APIs available from iOS 16.0 and a driver's-license descriptor. The supported scope is a mobile driver's license (mDL) or equivalent state ID. |
| App ID            | Apple has granted Verify with Wallet access for the exact bundle ID.                                                                                                                                                                                                                                                                                                                              |
| Signing           | The installed build uses a provisioning profile containing both identity-presentment entitlements.                                                                                                                                                                                                                                                                                                |
| Merchant ID       | The app entitlement, SDK configuration, and Incode environment use the same merchant ID.                                                                                                                                                                                                                                                                                                          |
| Privacy           | `NSIdentityUsageDescription` is present in the host app's `Info.plist`.                                                                                                                                                                                                                                                                                                                           |
| Flow or Workflow  | The ID document chooser is enabled and Digital IDs with the Apple Wallet method are configured in Dashboard.                                                                                                                                                                                                                                                                                      |

### Apple Credential Availability

Apple controls the minimum device and OS for each credential, and these requirements can change. Verify them on Apple's [Verify with Wallet](https://developer.apple.com/wallet/get-started-with-verify-with-wallet/) page before planning a rollout.

| Credential                                   | Apple Minimum on iPhone                    | Incode iOS Scope    |
| -------------------------------------------- | ------------------------------------------ | ------------------- |
| Supported US driver's licenses and state IDs | iPhone 8 or later<br />iOS 16.5 and newer  | Supported mDL scope |
| California driver's license or state ID      | iPhone XS or later<br />iOS 17.5 and newer | Supported mDL scope |
| Puerto Rico driver's license or ID           | iPhone XS or later<br />iOS 18.1 and newer | Supported mDL scope |
| Japan My Number Card                         | iPhone XS or later<br />iOS 18.5 and newer | Coming Soon         |
| Digital ID created from a US passport        | iPhone 11 or later<br />iOS 26.1 and newer | Coming Soon         |
| Other national ID or PID credentials         | Varies by issuer and region                | Coming Soon         |

Passport-derived Digital ID and national ID support require additional PassKit descriptors and corresponding Incode back-end validation.

***

## Set Up Apple Wallet ID

Complete the following steps in order.

### Configure Incode

Apple Wallet configuration is server-driven. Ask Incode Support to configure the following for each environment:

- Enable Digital IDs and the **Apple Wallet** method for ID Capture.
- Enable the identity fields required by the use case.
- Configure the merchant ID and server-side identity certificate used to validate the encrypted response.
- Confirm that the merchant ID belongs to the same environment used by the SDK session.

| Configuration Source               | Apple Wallet Enablement                                                   | Requested Fields                                            |
| ---------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Dashboard-defined Flow or Workflow | Enable Digital IDs and the `APPLE_WALLET` method in the ID Capture module | Returned with the one-time Wallet challenge after selection |
| Code-defined flow                  | Not supported in the initial version                                      | Not supported in the initial version                        |

The Flow or Workflow response supplies enablement but intentionally does not include [requested fields](#requested-fields). The one-time back-end challenge is the authoritative source for requested fields. The public `addIdScan()` [API](/sdk-reference/module-id-scan/#add-id-capture) doesn't expose Apple Wallet enablement or requested-field settings. This avoids a second client-side configuration that could conflict with the back-end challenge.

<Callout icon="❗" theme="error">
  ### Warning

  Do not copy a merchant ID from a sample or another environment. A mismatch between the app, provisioning profile, and Incode server configuration prevents the Wallet response from being validated.
</Callout>

### Configure the Host App

#### Apple Developer Account

Follow Apple's [environment configuration](https://developer.apple.com/documentation/passkit/configuring-your-environment-for-the-verify-with-wallet-api) process.

1. Request access to Verify with Wallet for your exact bundle ID. Entitlement approval is granted per bundle ID.
2. Create or select the merchant ID coordinated with Incode.
3. Create the required Identity Access Certificate in coordination with Incode's server configuration.
4. Add **In App Identity Presentment** to the App ID.
5. Add **In App Identity Presentment Merchant IDs** and select the merchant ID.
6. Generate and install a new provisioning profile.

#### Entitlements

The app target must contain both identity-presentment entitlements. Include only document types and elements Apple approved for the app. This example shows a typical US mDL subset; replace the merchant placeholder with the value supplied for your environment.

```xml
<key>com.apple.developer.in-app-identity-presentment</key>
<dict>
    <key>document-types</key>
    <array>
        <string>us-drivers-license</string>
    </array>
    <key>elements</key>
    <array>
        <string>given-name</string>
        <string>family-name</string>
        <string>portrait</string>
        <string>address</string>
        <string>issuing-authority</string>
        <string>document-expiration-date</string>
        <string>document-number</string>
        <string>driving-privileges</string>
        <string>age</string>
        <string>date-of-birth</string>
        <string>document-issue-date</string>
    </array>
</dict>
<key>com.apple.developer.in-app-identity-presentment.merchant-identifiers</key>
<array>
    <string>merchant.your-company.identity</string>
</array>
```

The Apple Pay entitlement `com.apple.developer.in-app-payments` does **not** replace the identity-presentment merchant entitlement.

#### Privacy Usage Description

Add a user-facing explanation to the host app's `Info.plist`. Calling the Wallet identity API without this key causes iOS to terminate the app.

```xml
<key>NSIdentityUsageDescription</key>
<string>We use information from your ID in Apple Wallet to verify your identity.</string>
```

#### Merchant Configuration

Set the merchant ID on the shared manager before starting the onboarding session.

```swift
IncdOnboardingManager.shared.appleWalletMerchantID = "merchant.your-company.identity"
```

The value must exactly match an entry in `com.apple.developer.in-app-identity-presentment.merchant-identifiers` and the merchant configured by Incode for the active environment.

### Enable Apple Wallet in ID Capture

Configure Apple Wallet in Dashboard for the specific Flow or Workflow where it should be offered.

1. Open the [ID Capture](/dashboard-platform-administration/id-capture-dashboard/) module in the Flow or Workflow.
2. Keep the ID document chooser enabled.
3. Turn on **_Enable Digital ID upload_**.
4. Enable the `APPLE_WALLET` method.
5. Select the identity fields required by the use case.

The SDK does not expose a corresponding code-defined setting. When the chooser opens, it performs a general driver's-license availability check. Physical-capture and file-upload choices remain usable while the check runs. Apple Wallet appears only when PassKit confirms that the device has a requestable mDL. The availability check does not pre-validate every Dashboard-configured field, because those fields arrive later with the one-time challenge.

***

## Requested Fields

Every requested field must satisfy three conditions:

1. The field is enabled in the ID Capture configuration.
2. The SDK maps it to an Apple `PKIdentityElement`.
3. The host app's Apple entitlement and provisioning profile authorize the corresponding element.

Dashboard exposes the following choices. Challenge values are shown for troubleshooting only; integrators do not pass them through a public SDK API.

| Dashboard Field    | Challenge Value        | `PKIdentityElement` Mapping | Availability                                     |
| ------------------ | ---------------------- | --------------------------- | ------------------------------------------------ |
| Given name         | `given_name`           | `.givenName`                | iOS 16.0 and newer                               |
| Family name        | `family_name`          | `.familyName`               | iOS 16.0 and newer                               |
| Date of birth      | `birth_date`           | `.dateOfBirth`              | iOS 16.0 and newer                               |
| License number     | `document_number`      | `.documentNumber`           | iOS 16.0 and newer                               |
| Expiry date        | `expiry_date`          | `.documentExpirationDate`   | iOS 16.0 and newer                               |
| Portrait photo     | `portrait`             | `.portrait`                 | iOS 16.0 and newer                               |
| Issue date         | `document_issue_date`  | `.documentIssueDate`        | iOS 16.0 and newer                               |
| Issuing country    | `issuing_country`      | `.issuingAuthority`         | iOS 16.0 and newer                               |
| Issuing authority  | `issuing_authority`    | `.issuingAuthority`         | iOS 16.0 and newer                               |
| Driving privileges | `driving_privileges`   | `.drivingPrivileges`        | iOS 16.0 and newer                               |
| Full address       | `resident_address`     | `.address`                  | iOS 16.0 and newer                               |
| City               | `resident_city`        | `.address`                  | iOS 16.0 and newer                               |
| State/Province     | `resident_state`       | `.address`                  | iOS 16.0 and newer                               |
| Postal code        | `resident_postal_code` | `.address`                  | iOS 16.0 and newer                               |
| Age 18+            | `age_over_18`          | `.age(atLeast: 18)`         | Final validation in progress; iOS 16.0 and newer |
| Age 21+            | `age_over_21`          | `.age(atLeast: 21)`         | Final validation in progress; iOS 16.0 and newer |
| Gender             | `sex`                  | `.sex`                      | iOS 17.2 and newer                               |
| Height             | `height`               | `.height`                   | iOS 26.0 and newer                               |
| Nationality        | `nationality`          | `.nationality`              | iOS 26.4 and newer                               |

Both issuing-country and issuing-authority requests map to PassKit's `.issuingAuthority` element, and all four resident-address choices map to PassKit's single `.address` element. Unknown, unsupported, or OS-unavailable fields are logged and skipped. If no supported elements remain, the SDK shows the generic Wallet retry screen after the user selects Apple Wallet.

The client uses Apple's privacy-preserving threshold elements for `age_over_18` and `age_over_21`, but their final end-to-end validation is still in progress. A threshold request can fall back to the age element when the issuer does not provide that threshold. Confirm the resulting data and retention behavior for your environment before relying on a threshold-only use case. The SDK marks requested elements with Apple's `mayStore` intent. Make sure the fields you request and the retention described in your privacy policy match your approved use case.

***

## Sequence Diagram

The Wallet challenge is fetched after the user selects Apple Wallet. The SDK drives the PassKit authorization sheet, and the returned encrypted response is validated server-side.

```mermaid
sequenceDiagram
    autonumber
    participant App as Client app
    participant SDK as Incode SDK
    participant BE as Incode back-end
    participant Wallet as Apple Wallet (PassKit)

    App->>SDK: Start Flow or Workflow
    Note over App,SDK: SDK initialization and onboarding start
    SDK->>Wallet: Check driver's-license availability
    Wallet-->>SDK: Available / not available
    SDK-->>App: Render document chooser
    Note over App,SDK: Apple Wallet appears only when PassKit confirms availability
    App->>SDK: User selects Apple Wallet
    SDK->>BE: Request one-time challenge
    BE-->>SDK: nonce, merchantId, requestedFields
    SDK->>Wallet: Present authorization sheet (requested elements)
    Wallet->>Wallet: User authorizes with Face ID / Touch ID
    Wallet-->>SDK: Encrypted identity response (opaque)
    SDK->>BE: Send encrypted response for validation
    BE-->>SDK: Return verification result
    SDK-->>App: Continue onboarding
```

On cancellation, the user returns to the chooser. On failure, the SDK shows its generic Wallet retry screen. On success, the encrypted response is validated and onboarding continues.

***

## Cancellation and Errors

The current integration does not expose a Wallet-specific public error callback. Errors remain inside the chooser experience so the user can retry or select document capture instead.

| Situation                                             | SDK Behavior                                                                                     | What To Check                                                                                                                                 |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| User cancels Apple's authorization sheet              | Returns to the document chooser without reporting an error                                       | No action required                                                                                                                            |
| Apple Wallet option is absent                         | Other choices stay visible during the check; Wallet is added only after PassKit confirms support | Incode enablement<br />Dashboard document-chooser setting<br />iOS 16.0 or newer<br />Signed entitlements<br />A compatible mDL on the device |
| Availability changes after the chooser is shown       | PassKit can reject the request, and the SDK shows its generic retry screen                       | Device and credential eligibility<br />Whether another identity request is active                                                             |
| App terminates with an entitlement error              | iOS rejects the PassKit call                                                                     | Bundle ID approval<br />Signed entitlements<br />Regenerated provisioning profile                                                             |
| App terminates with a privacy usage-description error | iOS rejects the PassKit call                                                                     | Add `NSIdentityUsageDescription` to the host app                                                                                              |
| `appleWalletMerchantID` is missing                    | The SDK shows its generic Wallet retry screen                                                    | Set `IncdOnboardingManager.shared.appleWalletMerchantID` before starting onboarding                                                           |
| Merchant or challenge validation fails                | The SDK shows its generic Wallet retry screen                                                    | Confirm the merchant ID matches the entitlement and the Incode environment<br />Confirm network access                                        |
| A requested field is logged as unsupported            | The SDK skips that field and continues                                                           | Verify Dashboard field, device OS, and SDK build against the field table                                                                      |
| Every requested field is unsupported                  | The SDK shows the generic Wallet retry screen after challenge creation                           | Configure at least one supported, entitled field                                                                                              |
| Encrypted response validation or upload fails         | The SDK shows its generic Wallet retry screen                                                    | Confirm Incode environment enablement and merchant/certificate configuration with Support                                                     |

When contacting Support, include:

- SDK version
- App bundle ID
- iOS/device version
- Incode session identifier
- Approximate timestamp
- Whether the failure occurred before or after Apple's authorization sheet

Do not include raw identity data.

***

## External References

- [Get started with Verify with Wallet](https://developer.apple.com/wallet/get-started-with-verify-with-wallet/)
- [Configure your environment for the Verify with Wallet API](https://developer.apple.com/documentation/passkit/configuring-your-environment-for-the-verify-with-wallet-api)
- [PKIdentityAuthorizationController](https://developer.apple.com/documentation/passkit/pkidentityauthorizationcontroller)

<br />
