SDK reference, Android SDK / Android Individual Modules

NFC Scan

The NFC Scan module reads the secure NFC chip embedded in ICAO 9303-compliant travel documents, such as e-passports. It then returns the document holder's data, including the chip's portrait image. When a flow captures multiple IDs, NFC Scan applies only to the first ID.

For an overview of this module and how it works, see NFC Scan.

How you use this module depends on your integration pattern. In Patterns 1 and 2, you add the module to a FlowConfig in code as shown on this page. In Pattern 3, you define your modules and configuration in Dashboard as a Flow or Workflow and reference it by ID with startFlow() or startWorkflow() as shown on Run Flows Configured in Dashboard.

Add NFC Scan

  1. Ensure you've declared the nfc dependency in your [module]/build.gradle.

  2. Add ID Scan, then Process ID, before NFC Scan. NFC Scan reads the chip after the document has been captured and processed.

  3. Add the module with addNfcScan(nfcScan):

    flowConfigBuilder.addNfcScan(nfcScan)
    
    flowConfigBuilder.addNfcScan(nfcScan);
    

Example

The example below adds NfcScan after the ID Scan and Process ID steps and listens for the result through onNfcScanCompleted(). It enables chip data processing. NFC Scan no longer shows the chip-symbol question.

val nfcScan = NfcScan.Builder()
    .setProcessNfcData(true)
    .build()

val flowConfig = FlowConfig.Builder()
    // ... add the ID Scan and Process ID steps first
    .addNfcScan(nfcScan)
    .build()

val onboardingListener = object : OnboardingListener() {
    override fun onNfcScanCompleted(nfcScanResult: NfcScanResult) {
        // NFC scan completed. Process the result.
    }
}

IncodeWelcome.getInstance()
    .startOnboarding(activityContext, sessionConfig, flowConfig, onboardingListener)
NfcScan nfcScan = new NfcScan.Builder()
    .setProcessNfcData(true)
    .build();

FlowConfig flowConfig = new FlowConfig.Builder()
    // ... add the ID Scan and Process ID steps first
    .addNfcScan(nfcScan)
    .build();

IncodeWelcome.OnboardingListener onboardingListener = new IncodeWelcome.OnboardingListener() {
    @Override
    public void onNfcScanCompleted(@NonNull NfcScanResult nfcScanResult) {
        // NFC scan completed. Process the result.
    }
};

IncodeWelcome.getInstance()
    .startOnboarding(activityContext, sessionConfig, flowConfig, onboardingListener);

Transparent Background Mode

To show the NFC scanning bottom sheet on a transparent background, so your screen remains visible during the scan, configure the module like this:

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

Configuration Options

Configure the module with NfcScan.Builder. The table below lists the most common options.

Setting Description
setShowNfcSymbolConfirmationScreen(Boolean) Retained for compatibility. NFC Scan no longer shows the chip-symbol question, so this option has no effect.
setProcessNfcData(Boolean) Submits the chip data to the back end for identity validation. When enabled, two additional FaceMatch.MatchType options become available beyond the default ID_SELFIE: NFC_SELFIE compares the chip portrait to the selfie, and NFC_3_WAY compares the cropped ID image, the chip portrait, and the selfie. See Face Match.
setShowTutorials(Boolean) Shows tutorials on how to scan the document.
setIdType(IdScan.IdType) Sets the document type to use for NFC scanning.
setNfcMaxRetries(Integer) Sets the maximum number of NFC scan attempts. Default: 5.
setForceNfcModule(Boolean) When true, bypasses automatic NFC skipping based on the document capability hint. Default: false. Existing scan configuration still applies.
setForceV2(Boolean) Always shows the V2 screens for this module, even when the other modules in the flow show the legacy UI. Default: false. This option is temporary and will be removed when the SDK ships V2 only.

For the complete option set, see NfcScan.Builder in API Reference.

Smart gating

When smart gating is enabled for your organization, the backend can return an NFC capability hint after the front-ID upload. In Standard and Submit Only modes, the SDK uses this hint to decide whether to start NFC Scan for the first ID. Unless an override applies, NFC Scan skips documents when the hint reports no chip or an unsupported issuer. Missing, unknown, or unrecognized hints permit an NFC attempt.

When smart gating skips NFC Scan, the SDK opens no NFC screen and starts no chip read. In Standard mode, the onNfcScanCompleted callback returns SUCCESS with isNotApplicable set to true. The SDK continues to the next module in both modes. Submit Only mode does not return module-result callbacks. Smart gating works with both legacy and V2 screens.

NFC Scan no longer shows the chip-symbol question, including when the hint is missing or unknown. setShowNfcSymbolConfirmationScreen remains available for compatibility but has no effect.

For passports, the backend chip location selects one tutorial in both UI versions:

Backend chip location Tutorial
FRONT Front cover
BACK Inner back page
DATA_PAGE Photo page
INLAY, UNKNOWN, missing, or unrecognized Front cover

Initial and retry screens use the same location and show one animation, without a slider. The retry screen keeps the Help and Try again buttons. ID cards keep their existing tutorial. setShowTutorials(false) still disables the initial tutorial.

Override smart gating

To attempt NFC even when the hint would skip it, set setForceNfcModule(true):

val nfcScan = NfcScan.Builder()
    .setForceNfcModule(true)
    .build()
NfcScan nfcScan = new NfcScan.Builder()
    .setForceNfcModule(true)
    .build();

The default is false. A server flow or workflow node can also require an NFC attempt. A local false value does not cancel a server override. For flows assembled in code, the SDK applies the override from the server configuration associated with the session, including sessions with external tokens. The override persists across sections in that session. Each workflow node uses its own setting.

This option only bypasses smart gating. It does not guarantee a chip read or change document support or hardware requirements. It is independent of setForceV2, which selects the UI version.

Result

In Standard mode, NFC Scan delivers an NfcScanResult to the onNfcScanCompleted(NfcScanResult) callback on the OnboardingListener. Key fields include:

  • isNotApplicable: true when smart gating skips NFC Scan. The result code is SUCCESS, but no chip read occurred. Defaults to false. A false value does not confirm a successful chip read.
  • compositeCheckDigit: The Machine Readable Zone (MRZ) composite check digit (DG1); < when unset.
  • dateOfBirth: The date of birth in yyMMdd format (DG1).
  • dateOfBirthCheckDigit: The check digit for the date of birth; < when unset.
  • dateOfExpiry: The document expiry date in yyMMdd format (DG1).
  • dateOfExpiryCheckDigit: The check digit for the expiration date; < when unset.
  • documentCode: The MRZ document code. One of the following: TD1, TD2, TD3, MRVA, or MRVB. The default is TD3.
  • documentNumber: The 9 most-significant digits of the document number.
  • documentNumberCheckDigit: The check digit for the document number; < when unset.
  • gender: The document holder's gender. One of the following: MALE, FEMALE, UNKNOWN, or UNSPECIFIED.
  • issuingStateOrOrganization: The issuing state or organization as a 3-letter code.
  • nationality: The document holder's nationality as a 3-letter code.
  • optionalData1: First optional data field (ID-1 and ID-3 style MRZs).
  • optionalData2: Second optional data field (ID-1 style MRZs only); may be null.
  • personalNumber: Personal number, if encoded in optionalData1.
  • personalNumberCheckDigit: The check digit for the personal number (TD3 only); may be null.
  • primaryIdentifier: The document holder's last name.
  • secondaryIdentifier: The document holder's first name.
  • secondaryIdentifierComponents: The secondary identifier split into its individual components.
  • dg1EncodedData: The Base64-encoded string of the entire MRZ (DG1).
  • faceBitmap: The document holder's face image decoded from the chip (DG2); null when unavailable.
  • dg2EncodedData: The Base64-encoded DG2 (encoded face features); null when unavailable.
  • sodEncodedData: The Base64-encoded Document Security Object (SOD); null when unavailable.
  • Fields inherited from BaseResult:
    • resultCode: The ResultCode for this result.
    • error: When resultCode is ERROR, the Throwable that caused it; otherwise, null.
    • deviceStats: The DeviceStats snapshot of the device state when the result was produced.
    • motionStatus: Device motion assessment during capture. One of the following:
      • UNCLEAR: Motion could not be determined; the default.
      • PASS: Device motion was within acceptable limits.
      • FAIL: Excessive device motion was detected.

Errors surface through OnboardingListener.onError(Throwable). If the nfc library dependency is missing when this module runs, the SDK delivers a MissingNfcDependencyException to that callback.

For the authoritative field definitions, see NfcScanResult in the Android API Reference.

Was this page helpful?