This feature needs to be enabled for your integration.
Contact your solutions engineer for info and configuration.
Starting with Android SDK version 7.15.0, you can receive real-time callbacks when the SDK successfully reads or fails to read NFC data from identity documents. This allows your app to get access to extracted NFC data (DG1 and DG2) for additional processing or analytics.
Use the NFC data listener when you need to:
Access raw NFC data (Machine Readable Zone and Face Image) for additional verification
Track NFC reading success/failure for analytics
Implement custom handling based on NFC scan results
Store NFC data in your own systems for compliance or audit purposes
Prerequisites
The listener will only receive callbacks if:
NFC reading has been enabled for your integration by Veriff
NFC reading permissions have been granted in the SDK
The end-user's document supports NFC (e-passports, some ID cards)
The device has NFC hardware capability
Add NFC data listener
Step 1: Implement the listener interface
Create a class that implements VeriffNfcDataListener:
import com.veriff.VeriffNfcDataListener
import com.veriff.NfcData
import android.util.Log
class MyNfcDataListener : VeriffNfcDataListener {
override fun onNfcDataExtracted(nfcData: NfcData) {
// Called when NFC reading succeeds
Log.d("NFC", "DG1: ${nfcData.dg1}")
Log.d("NFC", "DG2: ${nfcData.dg2}")
// Process the NFC data as needed
// Both dg1 and dg2 are Base64-encoded strings
}
override fun onNfcDataExtractionFailed() {
// Called when NFC reading fails
Log.w("NFC", "Failed to extract NFC data")
// Handle failure case
}
}import com.veriff.VeriffNfcDataListener;
import com.veriff.NfcData;
import android.util.Log;
import org.jetbrains.annotations.NotNull;
public class MyNfcDataListener implements VeriffNfcDataListener {
@Override
public void onNfcDataExtracted(@NotNull NfcData nfcData) {
// Called when NFC reading succeeds
Log.d("NFC", "DG1: " + nfcData.getDg1());
Log.d("NFC", "DG2: " + nfcData.getDg2());
// Process the NFC data as needed
// Both dg1 and dg2 are Base64-encoded strings
}
@Override
public void onNfcDataExtractionFailed() {
// Called when NFC reading fails
Log.w("NFC", "Failed to extract NFC data");
// Handle failure case
}
}Step 2: register the listener in configuration
Add the listener to your Veriff Configuration when starting the SDK:
val configuration = Configuration.Builder()
.veriffNfcDataListener(MyNfcDataListener())
.build()
val intent = Sdk.createLaunchIntent(this, sessionUrl, configuration)
startActivityForResult(intent, REQUEST_CODE_VERIFF)Configuration configuration = new Configuration.Builder()
.veriffNfcDataListener(new MyNfcDataListener())
.build(); (edited)
Intent intent = Sdk.createLaunchIntent(this, sessionUrl, configuration);
startActivityForResult(intent, REQUEST_CODE_VERIFF);NfcData object
The NfcData object contains two properties:
Property | Type | Description |
|---|---|---|
|
| DATA GROUP 1 — Machine Readable Zone Information (Base64-encoded). Contains passport number, name, birth date, nationality, etc. Follows ICAO Doc 9303, part 10, Section 4.7.1. |
|
| DATA GROUP 2 — Encoded Identification Features — Face (Base64-encoded). Contains the face image from the document in JPEG2000 format. Follows ICAO Doc 9303, part 10, Section 4.7.2. |
Note: Both fields can be null if the specific data group is not available on the document or failed to read.
Decoding NFC data
The NFC data is provided as Base64-encoded strings. To decode them back to binary data:
import java.util.Base64
override fun onNfcDataExtracted(nfcData: NfcData) {
// Decode DG1 (Machine Readable Zone)
nfcData.dg1?.let { dg1Base64 ->
val dg1Bytes = Base64.getDecoder().decode(dg1Base64)
// Process DG1 binary data
}
// Decode DG2 (Face Image)
nfcData.dg2?.let { dg2Base64 ->
val dg2Bytes = Base64.getDecoder().decode(dg2Base64)
// dg2Bytes contains JPEG2000 encoded face image
// You can save this as a file or process it further
}
}import java.util.Base64;
@Override
public void onNfcDataExtracted(@NotNull NfcData nfcData) {
// Decode DG1 (Machine Readable Zone)
if (nfcData.getDg1() != null) {
byte[] dg1Bytes = Base64.getDecoder().decode(nfcData.getDg1());
// Process DG1 binary data
}
// Decode DG2 (Face Image)
if (nfcData.getDg2() != null) {
byte[] dg2Bytes = Base64.getDecoder().decode(nfcData.getDg2());
// dg2Bytes contains JPEG2000 encoded face image
// You can save this as a file or process it further
}
}Decoding Errors
You may get errors when decoding Base64 due to:
Invalid Base64: ensure you are using
java.util.Base64, not otherBase64implementationsCharacter encoding: do not try to decode as
UTF-8string directly, DG2 is binary image data
NFCData object
The NFCData object contains two properties:
Property | Type | Description |
|---|---|---|
|
| DATA GROUP 1 — Machine Readable Zone Information (Base64-encoded). Contains passport number, name, birth date, nationality, etc. Follows ICAO Doc 9303, part 10, Section 4.7.1. |
|
| DATA GROUP 2 — Encoded Identification Features — Face (Base64-encoded). Contains the face image from the document in JPEG2000 format. Follows ICAO Doc 9303, part 10, Section 4.7.2. |
Additional info
Listener Lifecycle
Global Singleton: only one listener can be active at a time across your entire application.
Replacement: setting a new listener in a new
Configurationwill replace any previously set listener.Auto-Cleanup: the listener is automatically cleared when the SDK session ends (when the user closes the SDK or verification completes).
Threading
Callbacks are executed on the main (UI) thread. If you need to perform heavy processing, it is recommended to dispatch work to a background thread:
override fun onNfcDataExtracted(nfcData: NfcData) {
lifecycleScope.launch(Dispatchers.IO) {
// Heavy processing on background thread
processNfcData(nfcData)
}
}@Override
public void onNfcDataExtracted(@NotNull NfcData nfcData) {
new Thread(() -> {
// Heavy processing on background thread
processNfcData(nfcData);
}).start();
}Data Privacy
NFC data contains sensitive personal information:
DG1: full name, date of birth, document number, nationality
DG2: biometric face image
Ensure you:
Handle this data in compliance with GDPR, CCPA, and other privacy regulations
Implement appropriate security measures (encryption, secure storage)
Only retain data for as long as necessary
Have proper user consent mechanisms in place
FAQ
Listener is not receiving callbacks
Check NFC is enabled: verify NFC is enabled in your Veriff integration configuration and permissions have been granted
Verify document type: not all documents have NFC chips
Check device hardware: ensure the device has NFC capability (
PackageManager.FEATURE_NFC)Verify listener registration: ensure the listener is set before starting the SDK session
DG1 or DG2 is null
nullAlthough this scenario is unlikely to happen, if it occurs contact the Customer Support and your Solutions Engineer to report and troubleshoot the issue.
Changelog
Date | Description |
|---|---|
Feb 4, 2026 | FAQ > “DG1 or DG2 is |
Feb 3, 2026 | Documentation published |