NAV Navbar
kotlin java
  • Verifai Android SDK (v2.1.5)
  • Implement the SDK
  • Scan modes
  • AI mode
  • Manual mode
  • Security features check
  • Visual information zone (VIZ) check
  • Additional Information
  • Handling the result
  • NFC eMRTD Check
  • Styling Verifai
  • Verifai Android SDK (v2.1.5)

    Welcome to the Verifai App implementation documentation. If you have any questions that are unanswered you can always contact our support.

    This documentation will continue to expand as we add extra services.

    Older versions

    Check the links below if you are looking for documentation of previous Verifai versions:

    Version Link
    2.0.x Documentation
    1.1.x Documentation

    Prerequisites

    Example Project

    The following GitHub repository contains an example implementation of the Verifai SDK. Go to GitHub.

    Implement the SDK

    Add dependency

    Add to project build.gradle:

    allprojects {
        repositories {
            maven { url = 'https://dashboard.verifai.com/downloads/sdk/maven' }
        }
    }
    

    Add to module build.gradle:

    dependencies {
        implementation 'com.verifai:verifai-sdk-android:2.1.5'
    }
    

    The Verifai SDK is hosted on our Maven repository. You will have to add the repository to the project build.gradle file and the dependency to the module build.gradle file.

    More information about Gradle dependencies can be found on the add build dependencies page of the Android Developer website.

    If you do not want to use our Maven repository, you can download the SDK manually from the Verifai dashboard.

    Authenticate App

    Provide licence and identifier:

    import com.verifai.Verifai
    import com.verifai.events.VerifaiLicenceListener
    import com.verifai.exceptions.fatal.LicenceNotValidException
    
    ...
    
    Verifai.configure("your_licence", "your_identifier", object : VerifaiLicenceListener {
        override fun onConfigured() {
            // Handle success
            // Verifai can now be started
        }
    
        override fun onError(e: LicenceNotValidException) {
            // Handle error
        }
    })
    
    import com.verifai.Verifai
    import com.verifai.events.VerifaiLicenceListener
    import com.verifai.exceptions.LicenceNotValidException
    
    ..
    
    Verifai.configure("your_licence", "your_identifier", new VerifaiLicenceListener() {
        @Override
        public void onConfigured() {
            // Handle success
        }
    
        @Override
        public void onError(@NotNull LicenceNotValidException e) {
            // Handle error
        }
    });
    

    Before you can start using the scanning functionality you will have to authorize your app. First you have to get a licence and identifier from the Verifai dashboard. Once you obtained a valid licence and identifier you can configure Verifai by calling the configure(…) method.

    Scan modes

    AI mode

    When starting with AI mode Verifai will recognize documents automatically and cut the document from the image.

    AI Mode

    Manual Mode

    When starting with MANUAL mode the user has to select the country, document type, model and the position of the document correctly on the screen.

    Manual Mode

    AI mode

    Before using the AI mode, Verifai has to download the neural network model to be able to recognize the identification documents.

    You can also skip to Manual mode.

    Loading the neural model

    A neural model is a trained dataset used to recognize documents on images. Before continuing you should check if the current device is supported. If the device is not supported or if you do not want to use this feature, you can skip the next few steps and start scanning immediately.

    If the device is supported and you want to use this feature you have to provide a neural model. This can be done in two ways. Either by downloading the file manually or programmatically.

    AI check

    It is possible to programmatically check if the AI mode is supported by the device, this way you can prevent downloading the neural model:

    if (Verifai.isAiModeSupported) {
        // AI mode is supported
    } else {
        // AI mode is not supported
    }
    
    if (Verifai.isAiModeSupported()) {
        // AI mode is supported
    } else {
        // AI mode is not supported
    }
    

    It is possible to programmatically check if the AI mode is supported by the device. This check could be used to skip the download of the model when it is not needed.

    Download the latest model programmatically

    Download neural model:

    val countryCodes = listOf("NL")
    val destinationDirectory: File? = null // Optional, will be downloaded to cache by default
    
    Verifai.downloadNeuralModel(this, countryCodes, destinationDirectory, object : VerifaiNeuralModelListener {
        override fun onProgress(progress: Int) {
            // Handle progress
        }
    
        override fun onInitialized() {
            // Handle success
        }
    
        override fun onError(e: Throwable) {
            // Handle error
            // Can be any one of the following
    
            // NeuralModelLoadFailedException::class
            // NeuralModelNotSupportedException::class
            // NeuralModelAlreadyUnpackingException::class
            // NeuralModelAlreadyDownloadingException::class
            // NeuralModelDownloadFailedException::class
            // NotEnoughMemoryException::class
            // LicenceNotValidException::class
    
        }
    })
    
    List<String> countryCodes = new ArrayList<String>(){{
        add("NL");
    }};
    File destinationDirectory = null; // Optional directory
    
    Verifai.downloadNeuralModel(this, countryCodes, destinationFile, new VerifaiNeuralModelListener() {
        @Override
        public void onProgress(int progress) {
            // Handle progress
        }
    
        @Override
        public void onInitialized() {
            // Handle success
        }
    
        @Override
        public void onError(@NotNull Throwable e) {
            // Handle error
        }
    });
    

    By calling downloadNeuralModel(…) the latest versions will be checked to the version of the neural model in de app cache. If the version of the previous version is not the same, then it will be overwritten.

    Providing country codes and a destination directory is optional. If not providing country codes then a neural model including all available countries will be downloaded. The destination file is the location where the compressed neural model should be stored temporarily. If not providing a destination directory the app cache will be used. The destination file will be deleted after the compressed file is uncompressed to the app cache.

    Providing a destination directory is optional. The destination file is the location where the compressed neural model should be stored temporarily. If not providing a destination directory the app cache will be used. The destination file will be deleted after the compressed file is uncompressed to the app cache.

    Cancel download

    Cancel the download.

    Verifai.cancelNeuralModelDownload()
    
    Verifai.INSTANCE.cancelNeuralModelDownload();
    

    Certain download requests can take time to finish depending on the user's internet connection. To keep you as a developer in the loop we've added progress updates that you can use to keep track download process. More on the processing state below.

    Along the same vein we also give developers control over cancelling processes when they're taking too long (for example because of a bad internet connection).

    Download manually

    Provide neural model manually:

    val inputStream = context.assets.open("verifai.package")
    
    Verifai.setNeuralModel(this, inputStream, object : VerifaiNeuralModelListener {
        override fun onProgress(progress: Int) {
            // Handle progress, on a scale from 0 to 100
        }
    
        override fun onInitialized() {
            // Handle success
        }
    
        override fun onError(e: Throwable) {
            // Handle error
        }
    })
    
    InputStream inputStream = context.getAssets().open("verifai.package");
    
    Verifai.setNeuralModel(this, inputStream, new VerifaiNeuralModelListener() {
        @Override
        public void onProgress(int progress) {
            // Handle progress, on a scale from 0 to 100
        }
    
        @Override
        public void onInitialized() {
            // Handle success
        }
    
        @Override
        public void onError(@NotNull Throwable e) {
            // Handle error
        }
    });
    

    Follow these steps to add a neural model to your app manually:

    1. Go to the Verifai dashboard
    2. Download a neural model with TensorFlow-c2 type
    3. Add the file to your app assets or an accessible location via File
    4. Create an InputStream from the asset or file and pass it to setNeuralModel(…)

    By calling setNeuralModel(…) the neural model will be cached in the app cache and then loaded. If a previous neural model exists that is not the same as the supplied one then it will be overwritten.

    Start scanning

    Start scanning

    Verifai.start(this, VerifaiScanMode.AI, object : VerifaiResultListener {
        override fun onResult(result: VerifaiResult) {
            // Handle result
        }
    
        override fun onUpdateAvailable() {
            // This will be called when there is a new version of the SDK available. The scanning will continue.
            // You could log to your central logging to be notified of outdated version.
        }
    
        override fun onError(error: Throwable) {
            // Handle errors
            when (error) {
                is FatalException -> {
                    // Verifai can not start
                }
                is CriticalException -> {
                    // AI mode will not work, you can still start the Manual mode
                }
                else -> {
                    // Network problems during scanning
                }
            }
        }
    })
    
    Verifai.start(this, VerifaiScanMode.AI, new VerifaiResultListener() {
        @Override
        public void onResult(@NotNull VerifaiResult result) {
            // Handle result
        }
    
        @Override
        public void onUpdateAvailable() {
            // This will be called when there is a new version of the SDK available. The scanning will continue.
            // You could log to your central logging to be notified of outdated version.
        }
    
        @Override
        public void onError(@NotNull Throwable e) {
            // Handle error
        }
    });
    

    You can start scanning by calling start(Context, VerifaiScanMode, VerifaiResultListener, Int?) and passing one of the two VerifaiScanMode modes. Depending on the scan mode different views will be shown. When starting with AI mode Verifai will recognize documents automatically and cut the document from the image. When starting with MANUAL mode the user has to select the country, document type and model and position the document correctly on the screen and press the capture button in order to cut it from the image. If you pass MANUAL mode then you do not have to download the neural model, documents and country codes or set the neural model. The last and optional parameter minimalDetectionTime can be set to change how long an AI scan should take in seconds (so the user can position the document correctly).

    minimalDetectionTime can also be set using Verifai.minimalDetectionTime = <Int>.

    The onResult will receive a VerifaiResult object on a succesfull scan.

    Prefetch document data

    Prefetch document data:

    val countryCodes = listOf("NL")
    
    Verifai.downloadDocuments(countryCodes, object : VerifaiDocumentsListener {
        override fun onDownloaded() {
            // Handle success
        }
    
        override fun onError(e: Throwable) {
            // Handle error
        }
    })
    
    List<String> countryCodes = new ArrayList<String>(){{
        add("NL");
    }};
    
    Verifai.downloadDocuments(countryCodes, new VerifaiDocumentsListener() {
        @Override
        public void onDownloaded() {
            // Handle success
        }
    
        @Override
        public void onError(@NotNull Throwable e) {
            // Handle error
        }
    });
    

    If your users are going to be using Verifai in situations where the internet connection is not always guaranteed, it can be useful to prefetch the document data that the AI mode uses.

    The documents contains the definitions of zones which needs to be blocked and if there is a machine readable zone present. You can pass a list of country codes to get documents for specific countries, but this is optional.

    Fetching country codes

    Download country codes:

    Verifai.downloadCountryCodes(object : VerifaiCountryCodesListener {
        override fun onDownloaded(result: List<String>) {
            // Handle result
        }
    
        override fun onError(e: Throwable) {
            // Handle error
        }
    })
    
    Verifai.downloadCountryCodes(new VerifaiCountryCodesListener() {
        @Override
        public void onDownloaded(@NotNull List<String> result) {
            // Handle result
        }
    
        @Override
        public void onError(@NotNull Throwable e) {
            // Handle error
        }
    });
    

    It is possible to download a list of supported country codes. The country codes can be used to download specific documents.

    Manual mode

    Verifai.start(this, VerifaiScanMode.MANUAL, object : VerifaiResultListener {
        override fun onResult(result: VerifaiResult) {
            // Handle result
        }
    
        override fun onUpdateAvailable() {
            // This will be called when there is a new version of the SDK available, but the scanning will continue
            // You could log to your central logging to be notified of outdated version
        }
    
        override fun onError(error: Throwable) {
            // Handle errors
            when (error) {
                is FatalException -> {
                    // Verifai has not been configured
                }
                else -> {
                    // Ignore network problems during scanning
                }
            }
        }
    })
    
    Verifai.start(this, VerifaiScanMode.MANUAL, new VerifaiResultListener() {
        @Override
        public void onResult(@NotNull VerifaiResult result) {
            // Handle result
        }
    
        @Override
        public void onUpdateAvailable() {
            // This will be called when there is a new version of the SDK available, but the scanning will continue
            // You could log to your central logging to be notified of outdated version
        }
    
        @Override
        public void onError(@NotNull Throwable e) {
            // Handle error
        }
    });
    

    The manual mode does not need any additional configuration and can start scanning immediately.

    Security features check

    The security features check is a way to validate the authenticity of a document. Many documents have very specific features that should be included on the document to prevent document forgery. These features can be checked against the document, such that the authenticity can be guaranteed.

    Security features check screenshot

    Prerequisites

    In order to start the security features check a successful scan must be performed. This scan returns a VerifaiSecurityFeaturesResult, which needs to be passed to the security features check.

    Security feature scores

    Scores are used for security features to denote how much the feature counts for when it exists, the score of the security feature. We guarantee that for every document that has security features the sum of these scores will be >=1.0. You can set a custom scoreThreshold for the flow, such that the flow will stop when this threshold has been reached.

    Example of security features

    Verifai.checkSecurityFeatures(
        context = this,
        verifaiResult = verifaiResult,
        scoreThreshold = 1f,
        listener = object : VerifaiSecurityFeaturesListener {
            override fun onResult(result: VerifaiSecurityFeaturesResult) {
                // Handle result
            }
    
            override fun onError(e: Throwable) {
                if (e is SecurityFeaturesNotFoundException) {
                    // Handle exception
                }
                if (e is SecurityFeaturesDownloadFailedException) {
                    // Handle exception
                }
                if (e is SecurityFeaturesParameterNotValidException) {
                    // Handle exception
                }
            }
        })
    

    Starting the security features check

    The security features check flow can be started by calling Verifai.checkSecurityFeatures(); which requires the following parameters:

    Property Decription Type
    context Context Context
    verifaiResult The response that was obtained earlier by performing a scan VerifaiResult
    scoreThreshold the threshold for the score. As soon as the score exceeds this threshold the flow is finished and no more security features will be checked. (default 1.0) Float
    listener The feature check result VerifaiSecurityFeaturesResult

    Checking for security features without starting flow

    It is also possible to check for the availability of security checks before starting the flow. This can be useful when communicating this to the end-user.

    Visual information zone (VIZ) check

    One of the steps of confirming the information on a eMRTD document is inspecting it's Visual information zone. The inspection zone is on the front of the document. Verifai facilitates a simple check to determine if the information on the front of the document matches the information scanned from the Machine Readable Zone.

    VIZ check screenshot

    Prerequisites

    Before starting the VIZ check a succesfull scan must be performed. This will give you the data needed to perform the VIZ check. Optionally you can also pass a VerifaiNfcResult object and send this data along to the VIZ check to check the picture.

    Example of using the VIZ check

    Verifai.checkViz(this,
        verifaiResult = result,
        verifaiNfcResult = nfcResult, 
        listener = object : VerifaiVizListener {
            override fun onResult(result: VerifaiVizResult) {
                // Handle Result
            }
    
            override fun onError(e: Throwable) {
                Verifai.logger?.log(e)
                if (e is VizNoZonesException) {
                    // Handle exception
                }
            }
    })
    

    Starting the VIZ check

    Call Verifai.checkViz() to start the VIZ check. The call needs the following parameters.

    Property Decription Type
    context Context Context
    verifaiResult The document data received from a successfull scan VerifaiResult?
    verifaiNfcResult The NFC result object (optional) VerifaiNfcResult
    listener Listener for the VIZ check, giving VerifaiVizResult VerifaiVizListener

    The VerifaiVizResult object, all properties are nullable booleans. If the boolean is null the check did not get checked.

    Property Decription Type
    passedAll Did all the checks pass? Boolean?
    passedPhoto Did photo check pass? Boolean?
    passedDateOfBirth Did date of birth check pass? Boolean?
    passedDateOfExpiry Did date of expiry check pass? Boolean?
    passedSex Did sex check pass? Boolean?
    passedIssuingCountry Did issuing country check pass? Boolean?
    passedSurname Did surname check pass? Boolean?
    passedGivenName Did given name check pass? Boolean?

    Additional Information

    Camera permission

    Verifai uses the back camera of the Android device to scan documents. Verifai will handle the permission process and prompt the user for permission when the permission is not already granted.

    Critical errors

    When an error occurs from within Verifai the onError() method is called. There are two critical errors, if one of these occurs Verifai can not continue and will finish the scanning process.

    Error Decription Type
    NotConfiguredException Verifai has not been configured Critical
    LicenceNotValidException Licence is not valid Critical
    NeuralModelNotInitializedException Neural model has not been initialized yet Critical

    Non-critical errors

    When an error occurs from within Verifai the onError() method is called. These are the non-critical errors. When one of these happens you can still continue using Verifai in your app.

    Error Decription Type
    DocumentsAlreadyDownloadingException Already downloading documents. Please wait until previous call is finished. Non-critical
    NeuralModelAlreadyDownloadingException Already downloading neural model. Please wait until previous call is finished. Non-critical
    NeuralModelAlreadyUnpackingException Neural model is already unpacking. Non-critical
    NeuralModelCurrentlyDownloadingException Currently downloading neural network. Please wait until previous call is finished. Non-critical
    NeuralModelDownloadFailedException Failed to download neural model. Non-critical
    NeuralModelLoadFailedException Failed to load neural model. Non-critical
    NeuralModelNotInitializedException Neural model is not initialized. Please call setNeuralModel(...) or downloadNeuralModel(...). Non-critical
    NeuralModelNotSupportedException Neural model not supported. Non-critical
    NeuralModelNotValidException Neural model file not valid. Non-critical
    CountryCodesAlreadyDownloadingException Already downloading country codes. Please wait until previous call is finished Non-critical

    Handling the result

    When the user has succesfully scanned a document the VerifaiResultListener.onResult() method is called. In this method a VerifaiResult object is passed, this object contains all the information about the scanned document.

    VerifaiScanMode

    The VerifaiScanMode enum is used to tell the SDK what mode to use.

    Mode Description
    VerifaiScanMode.AI When starting with AI mode Verifai will recognize documents automatically and cut the document from the image.
    VerifaiScanMode.MANUAL When starting with MANUAL mode the user has to select the country, document type and model and position the document correctly on the screen.

    VerifaiResult object

    When document scanning is completed succesfully then a VerifaiResult object will be returned. This object contains the following data:

    Property Decription Type
    frontImage Image of the front of the document, if available Bitmap
    backImage Image of the back of the document, if available Bitmap
    mrzData The MRZ data of the document if available MrzData
    documentType The document type based on what the neural network found DocumentType
    issuingCountry The issuing country based on what the neural network found (ISO 3166-1 alpha-2) String i.e. "NL"

    MrzData object

    There are several formats of MRZ. Our parser will try to guess the format and will populate MrzData field according to the format.

    format line count character count per line
    TD1 3 30
    TD2 2 36
    TD3 2 44
    MRVA 2 44
    MRVB 2 36
    Dutch Driving Licence 1 30

    There are several fields that get used. Depending of the type of MRZ it uses a different set of fields.

    field type example TD1 TD2 TD3 MRVA MRVB Dutch Driving Licence
    raw String I<NLDSPECI20142999999990<<<<<8
    6503101F2403096NLD<<<<<<<<<<<8
    DE<BRUIJN<<WILLEKE<LISELOTTE<<
    X X X X X X
    confidence Int 100 X X X X X X
    score Int 100 X X X X X X
    documentType DocumentType IDENTITY_CARD X X X X X X
    documentCode String I X X X X X X
    dateOfBirth Date Wed Mar 10 00:00:00 GMT+01:00 1965 X X X X X -
    dateOfBirthString String 650310 X X X X X -
    dateOfExpiry Date Sat Mar 09 00:00:00 GMT+01:00 2024 X X X X X -
    dateOfExpiryString String 240309 X X X X X -
    issuingCountry String NLD X X X X X X
    documentNumber String SPECI2014 X X X X X X
    optional1 String 999999990<<<<<8 X X - X X -
    sex Sex FEMALE X X X X X -
    nationality String NLD X X X X X -
    optional2 String 075405222 X - - - - -
    surname String DE BRUIJN X X X X X -
    names String WILLEKE LISELOTTE X X X X X -
    personalNumber String 999999990 - - X - - -
    chip String 1 - - - - - X
    version String 1 - - - - - X
    random String 8QJ3GL63QT6T5 - - - - - X
    documentNumberCheckDigit String 2 X X X X X -
    dateOfBirthCheckDigit String 1 X X X X X -
    dateOfExpiryCheckDigit String 6 X X X X X -
    compositeCheckDigit String 8 X X X - - -
    personalNumberCheckDigit String 8 - - X - - -
    lineCheckDigit String 3 - - - - - X
    isDocumentNumberValid Boolean true X X X X X -
    isDateOfBirthValid Boolean true X X X X X -
    isDateOfExpiryValid Boolean true X X X X X -
    isCompositeValid Boolean true X X X - - -
    isLine1LengthValid Boolean true X X X X X X
    isLine2LengthValid Boolean true X X X X X -
    isLine3LengthValid Boolean true X - - - - -
    isDocumentCodeValid Boolean true X X X X X X
    isPersonalNumberValid Boolean true - - X - - -
    isLineValid Boolean true - - - - - X
    isDutchDrivingLicenceNfcKeyValid Boolean true - - - - - X
    dutchDrivingLicenceNfcKey String 1NLD150949621118QJ3GL63QT6T5 - - - - - X
    isBiometricPassportNfcKeyValid Boolean true X X X X X -
    biometricPassportNfcKey String SPECI2014265031012403096 X X X X X -

    Possible sex in MRZ:

    Sex Value
    MALE M
    FEMALE F
    UNSPECIFIED <
    UNKNOWN

    NFC eMRTD Check

    Verifai can read and validate biometric passports. These are also known as an e-passport, ePassport or digital passport.

    All eMRTD documents are marked with the following "Chip inside" symbol.

    Chip inside symbol

    Chip inside symbol

    eMRTD Security measurements

    To check a NCF Chip, Verifai executes a lot of checks as defined below:

    Protocol Protects
    Basic Access Control Confidentiality
    Passive Authentication Authenticity
    Active Authentication Originality
    Chip Authentication Originality + confidentiality

    Security measurements:

    Basic Access Control (BAC)

    The purpose of Basic Access Control is to ensure that the we have physical access to the eMRTD. BAC prevents skimming and also eavesdropping of the communication between passport and Verifai. BAC requires the knowledge of the eMRTD holder prior to being able to read the chip. This information is retrieved from the MRZ.

    Passive Authentication (PA)

    A eMRTD contains a Document Security Object(EF.SOd), which includes the digital signature of the the issuing State and in which hash representations of the LDS contents are stored. The goal of Passive Authentication is to prove the authenticity of the data contained in the LDS.

    Passive Authentication checks:

    Active Authentication (AA)

    Active Authentication verifies that the chip is genuine. By implementing the optional Active Authentication protocol eMRTDs becomes protected against chip substitution. This is ensured by the means of a challenge-response protocol between Verifai and the eMRTD chip using asymmetric cryptography.

    Chip Authentication (CA)

    Chip Authentication also verifies that the chip is genuine. By implementing the optional Chip Authentication protocol eMRTDs becomes protected against chip substitution.

    Getting started

    Verifai.readNfc(
        this@Activity,
        mrzData,
        resultListener = object : VerifaiNfcResultListener {
            override fun onProgress(progress: Int) {
                // from 0 to 100
            }
    
            override fun onResult(result: VerifaiNfcResult) {
                // Handle result
            }
    
            override fun onError(e: Throwable) {
                if (e is NfcDisabledException) {
                    // Show enable nfc dialog
                    runOnUiThread {
                        if (!isFinishing) {
                            AlertDialog.Builder(this@ResultActivity)
                                .setTitle("NFC Disabled")
                                .setMessage("Please enable NFC.")
                                .setCancelable(false)
                                .setPositiveButton(android.R.string.ok) { dialog, which ->
                                    // ok
                                }.show()
                        }
                    }
                } else if (e is NoNfcException) {
                    // Show enable nfc dialog
                    runOnUiThread {
                        if (!isFinishing) {
                            AlertDialog.Builder(this@ResultActivity)
                                .setTitle("No NFC support")
                                .setMessage("This device does not support NFC.")
                                .setCancelable(false)
                                .setPositiveButton(android.R.string.ok) { dialog, which ->
                                    // ok
                                }.show()
                        }
                    }
                }
    
                Verifai.logger?.log(e)
            }
        })
    

    Before being able to perform an NFC check you can use the isBiometricPassportNfcKeyValid and isDutchDrivingLicenceNfcKeyValid variables from the MrzData object to check if the MRZ Data is valid for scanning the document via NFC.

    Using the Verifai.readNfc(context, mrzData) method the NFC scanning can be started. Passing the context and mrzData are required. Optionally you can also pass a VerifaiNfcResultListener() object and an downloadPhoto (default = true) boolean to the readNfc function. If downloadPhoto is set to false Verifai will not attempt to download the photo from the NFC chip, thus making the scan a lot faster.

    NFC Result

    Using the VerifaiNfcResult you can access the NFC scan result. The whole process of scanning and verifying the different elements of the document is available in this object.

    field type description
    bitmap Bitmap? The picture from the document, if requested
    mrzText String? The mrz text if it has been read from EF.DG1
    sodHashes HashMap? Hashmap containing the EF.SOd checksums
    datagroups HashMap? Hashmap containing the read data
    documentCertificate X509Certificate The certificate used to sign the chip
    signingCertificate X509Certificate The root certificate
    mrzData String? MrzData object read form the chip
    mrzMatch boolean Does the mrz from the OCR match the mrz from the card
    comSodMatch boolean Does the EF.COM from the OCR match the datagroups in EF.SOd
    bacStatus BacStatus SUCCESS, FAILED, NOT_CHECKED, RANDOM_FAILED
    activeAuthenticationStatus AaStatus SUCCESS, SIGNATURE_FAILED, FAILED, NOT_PRESENT, NOT_CHECKED
    chipAuthenticationStatus CaStatus SUCCESS, FAILED, NOT_PRESENT, NOT_CHECKED
    validDocumentSigner boolean Is the document signed by the certificate from the EF.SOd
    validCertificate boolean Is the certificate from the EF.SOd valid
    validRootCertificate RootCertificateStatus NOT_FOUND, NOT_CHECKED, VALID, INVALID, REVOKED
    scanCompleted boolean Has the whole scan process been completed?

    Originality, Authenticity and Confidentiality

    How the Originality, Authenticity and Confidentiality are defined

    method description
    originality() Did Chip Authentication and/or Active Authentication pass their checks
    authenticity() Did the document signing, certificate, root certificate and passive authentication hashes checks all pass
    confidentiality() Were the BAC and optionally the Chip Authentication successful

    Passport.LdsFile

    Each instance of the Passport.LdsFile class holds one of the files from the MRTD. LDS stands for Logical Data Structure, for more info please see ICAO doc 9303

    field type description
    data ByteArray The data read from the datagroup
    hash ByteArray Digest of the data in the datagroup
    readStatus Passport.LdsFile.ReadStatus The read status of the file

    LdsFile.ReadStatus Enum

    The read status of a MRTD file

    field type
    SUCCESS The file has been read successfully
    FAILED Reading the file failed
    NO_ACCESS The file is protected, Verifai did not gain access
    FILE_NOT_FOUND The file has not been found on the MRTD

    AaStatus Enum

    The AaStatus can be one of the following:

    field type
    SUCCESS Active authentication was performed successfully
    SIGNATURE_FAILED Unable to verify the public key on the chip
    FAILED Active authentication failed
    NOT_PRESENT Active authentication not present on the chip
    NOT_CHECKED Active authentication process hasn't been performed

    BacStatus Enum

    The BacStatus can be one of the following:

    field type
    SUCCESS Chip was accessed successfully
    FAILED Failed to gain access to chip
    NOT_CHECKED Process has not been performed yet
    RANDOM_FAILED The chip did not return a challenge

    CaStatus Enum

    The CaStatus can be one of the following:

    field type
    SUCCESS Chip authentication was performed successfully
    FAILED Chip authentication failed
    NOT_PRESENT Chip authentication not present on the chip
    NOT_CHECKED Chip authentication process hasn't been performed

    NFC Exceptions

    NFC Exceptions are passed to the onError of the VerifaiNfcResultListener.

    Error Decription Type
    NfcDisabledException The device does not have NFC enabled Critical, NFC will not work and exit
    NoNfcException The device does not have NFC Critical, NFC will not work and exit

    Styling Verifai

    Verifai will automatically adjust to the colors of your theme using the style defined in the styles.xml.

    Aditionally you can override the following colors:

    <resources>
    
        <color name="colorPrimary">#ff576d</color>
        <color name="colorPrimaryDark">@color/colorPrimary</color>
        <color name="colorAccent">@color/colorPrimary</color>
        <color name="backgroundColor">#ffffff</color>
    
        <!-- Text -->
        <color name="textColor">#222222</color>
        <color name="invertedTextColor">#eeeeee</color>
    
        <!-- Buttons -->
        <color name="affirmativeButtonBackgroundColor">#5fb500</color>
        <color name="destructiveButtonBackgroundColor">#f26522</color>
    
        <!-- View finder -->
        <color name="scanHighlightColor">@color/colorPrimary</color>
        <color name="scanHighlightTextColor">#ffffff</color>
    
        <!-- Bottom box area -->
        <color name="bottomBoxBackground">#212121</color>
        <color name="bottomBoxSubtitleTextColor">#aaaaaa</color>
        <color name="bottomBoxTitleTextColor">@color/colorPrimary</color>
        <color name="bottomBoxTextColor">@color/invertedTextColor</color>
        <color name="bottomBoxImageTintColor">@color/invertedTextColor</color>
        <color name="bottomBoxTextAreaTextColor">#ffffff</color>
        <color name="bottomBoxTextAreaBackgroundColor">#333333</color>
        <color name="bottomBoxSeparator">#333333</color>
    
        <!-- Manual -->
        <color name="selectDocumentTypeHighlightColor">@color/colorPrimary</color>
        <color name="selectDocumentTypeChevronColor">@color/invertedTextColor</color>
        <color name="selectDocumentTypePaginationCircleColor">#ffffff</color>
    
        <!-- NFC -->
        <color name="nfcProgressBarBackgroundColor">#aaaaaa</color>
        <color name="nfcProgressBarProgressColor">@color/colorPrimary</color>
    
        <!-- Blocked zone on document color in the preview -->
        <color name="blockedFieldColor">#000000</color>
    
    </resources>