# Prerequisites

- An [ICAO 9303](https://www.icao.int/publications/pages/publication.aspx?docnum=9303) compliant travel document to scan the NFC chip in.

#### NOTE
While any ICAO 9303 document could theoretically be scanned, the tutorials in the module assume the document is a Passport booklet.

# Integration

In your module-level `app/build.gradle`, add the Incode library for NFC alongside any required dependencies. See the [Library Dependencies section](https://developer.incode.com/docs/setup-android#dependencies) for more info.

# Usage

To add the `NfcScan` module to the flow, simply:

## 1) Create a new `NfcScan` module with its `Builder` class:

Kotlin

```kotlin
val nfcScan = NfcScan.Builder()
  .setShowNfcSymbolConfirmationScreen(true/false)
  .setProcessNfcData(true/false)
  .build()
```

```java
NfcScan nfcScan = new NfcScan.Builder()
  .setShowNfcSymbolConfirmationScreen(true/false)
  .setProcessNfcData(true/false)
  .build();
```

## 2) Add it to a `FlowConfig.Builder`:

Kotlin

```kotlin
flowConfigBuilder.addNfcScan(nfcScan)
```

```java
flowConfigBuilder.addNfcScan(nfcScan);
```

## 3) Add this callback to your `IncodeWelcome.OnboardingListener`:

Kotlin

```kotlin
override fun onNfcScanCompleted(nfcScanResult: NfcScanResult) {
  // NFC scan completed. Process result.
}
```

```java
@Override
public void onNfcScanCompleted(@NonNull NfcScanResult nfcScanResult) {
  // NFC scan completed. Process result.
}
```

# Methods for `NfcScan.Builder()`:

- `setShowNfcSymbolConfirmationScreen()`: If `true`, a screen asking the user if their document contains an NFC chip is shown. If disabled, it's recommended to handle this case yourself to prevent a user without an NFC symbol on their passport from getting stuck. Default is `true`.
- `setProcessNfcData()`: If `true`, the data read from the NFC chip is used to validate identity. How it's used depends on how the `FaceMatch` module is configured. Default is `true`.

# Returning result of the module is an `NfcScanResult` object which contains:

- `resultCode`: A `ResultCode` indicating if scanning succeeded, or a known issue caused it to not succeed. See the [Javadoc](https://incode-technologies-example-repos.github.io/Incode-Welcome-Android-example/javadoc/com/incode/welcome_sdk/results/ResultCode.html) for more info.
- `compositeCheckDigit`: A `Char` representing the digit used to check the integrity of all the data in the MRZ of the document.
- `dateOfBirth`: A `String` in "yyMMdd" format of the date of birth of the document owner.
- `dateOfBirthCheckDigit`: A `Char` representing the digit used to check the integrity of the `dateOfBirth` field.
- `dateOfExpiry`: A `String` in "yyMMdd" format of the document's expiration date.
- `dateOfExpiryCheckDigit`: A `Char` representing the digit used to check the integrity of the `dateOfExpiry` field.
- `documentCode`: A `String` representing what type of ICAO 9303 compliant document this is. For example, a passport booklet is "TD3". Can be one of: TD1-3, MRVA, or MVRB.
- `documentNumber`: A `String` representing the 9 most significant digits of the passport number, CIC, etc.
- `documentNumberCheckDigit`: A `Char` representing the digit used to check the integrity of the `documentNumber` field.
- `gender`: A `String` representing the gender of the document owner. Can be one of: `MALE`, `FEMALE`, `UNKNOWN`, or `UNSPECIFIED`.
- `issuingStateOrOrganization`: A `String` containing the 3-letter code of the authority that issued this document. For example, for US Passports, this code is: "USA".
- `nationality`: A `String` containing the 3-letter code of the document owner's nationality. For example, for UK Passports, this code is: "GBR".
- `optionalData1`: A `String` with the contents of the first optional data for TD-1 and 3 style MRZs.
- `optionalData2`: An optional `String` with the contents of the second optional data for TD-1 style MRZs only.
- `personalNumber`: A `String` with the personal number of the document owner if it's encoded in `optionalData1`.
- `personalNumberCheckDigit`: An optional `Char` representing the digit used to check the integrity of the `personalNumber` field. This is only populated if `documentCode` is "TD3".
- `primaryIdentifier`: A `String` representing the primary means of identifying the document. Typically, this is the document owner's last name.
- `secondaryIdentifier`: A `String` representing secondary means of identifying the document. Typically, this is the document owner's other names besides the last.
- `secondaryIdentifierComponents`: An `Array<String>` of all the individual names that make up the `secondaryIdentifier`. For example, if the document owner's name is "John Jacob Jingleheimer Schmidt", the `secondaryIdentifierComponents` would be this array: `["John", "Jacob", "Jingleheimer"]`.
- `faceBitmap`: A `Bitmap` of the image found on the NFC chip. See the [Android documentation](https://developer.android.com/reference/android/graphics/Bitmap) for more info.

# Face Match and NFC Scanning:

If `NfcScan.Builder().setProcessNfcData()` is set to `true`, the data read from the NFC chip will be processed on the backend and can be used in the `FaceMatch` module. Moreover, when NFC data is available on the backend, 2 new `FaceMatch.MatchTypes` become available on top of the default `ID_SELFIE` type:

- `NFC_SELFIE`: Compares the image from the NFC chip to the Selfie taken in the `SelfieScan` module.
- `NFC_3_WAY`: Compares the cropped ID image from the `IdScan` module, to the image from the NFC chip, as well as the Selfie taken in the `SelfieScan` module.

# Capturing Multiple IDs and NFC Scanning:

If your `Flow` includes capturing multiple IDs before an NFC scan is initiated, the `nfc` module is only supported for the first ID.

# Displaying the NFC Bottom Sheet on a Transparent Background

To show the NFC scanning bottom sheet on a transparent background (so your screen remains visible during the scan), use the following configuration:

Java

```java
NfcScan nfcScan = new NfcScan.Builder()
    .setShowTutorials(false)
    .setShowNfcSymbolConfirmationScreen(false)
    .setIdType(IdScan.IdType.PASSPORT) // or ID
    .setShowInitialDataConfirmationScreen(false)
    // ... other builder options as needed
    .build();
```

Kotlin

```kotlin
val nfcScan = NfcScan.Builder()
    .setShowTutorials(false)
    .setShowNfcSymbolConfirmationScreen(false)
    .setIdType(IdScan.IdType.PASSPORT) // or ID
    .setShowInitialDataConfirmationScreen(false)
    // ... other builder options as needed
    .build()
```

# License

Copyright 2026 Incode Technologies. All rights reserved.
