0 purchases
verifai sdk
Verifai Flutter SDK #
The official Flutter package for Verifai's mobile (iOS and Android) SDK's.
Verifai offers seamless identity verification solutions for every use case. Easy to implement and customize, while taking the highest privacy and security standards in mind. Integrates effortlessly into mobile and web applications.
Table of contents #
Getting started
Install Verifai
Add licence
Android
iOS
Usage
Core
NFC
Liveness
Customization
Core settings
Core - Instruction screens
NFC - Instruction screens
Scan help
Validators
Document Filters
Liveness checks
Support
Getting started #
If you're new to Flutter please check out their extensive guides on how to setup your environment here. Otherwise we can go right ahead and get to installing Verifai.
Install Verifai #
To integrate the sdk in your project:
flutter pub add verifai_sdk
copied to clipboard
This will add it to your pubspec.yaml, more info in the installing tab above.
Add licence #
The Verifai SDK does not work without a valid licence. The licence can be copied
from the dashboard, and has to be set with CoreApi's setLicence method, see
usage.
Licenses can be made through our dashboard. You'll have to have a solution and add an implementation for iOS and one for Android. Please ensure the identifiers are the same as the bundle identifier (iOS) and package name (Android) you're using in your apps.
An easy way to store the licence and keep it outside version control, is to copy
it in a local licence.dart file next to your main.dart. Add licence.dart to
your .gitignore file. It can look approximately like this:
var verifaiLicence = '''=== Verifai Licence file V2 ===
VQUHzC3sNld8uy8pBHMTFtLxrItlQlkL+7wX3QdVi3tFlXgxUnJhqPD510hLplCxp83o6gwOftCm
...
...
HF/w/+n6SRQso55nIQSUX8uYP8WpJVmi+Gi9aA==''';
copied to clipboard
Then import the licence variable in your main.dart like this:
import 'licence.dart';
copied to clipboard
Android #
In order for the sdk to find the native Android libraries add the Verifai maven
repository in your root build.gradle file:
allprojects {
repositories {
maven { url 'https://dashboard.verifai.com/downloads/sdk/maven/' }
}
}
copied to clipboard
To avoid conflicts between native Android runtime libraries, add the
packagingOptions code snippet in the build.gradle file of your app, not in
the root!
android {
packagingOptions {
jniLibs {
pickFirsts += ['**/*.so']
}
}
}
copied to clipboard
If you run into memory errors during the build of your app, uncomment (or if it
is not there add) the following line in your gradle.properties file:
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
copied to clipboard
iOS #
The dependencies required for iOS are all handled by Flutter. So as long as you've run flutter pub get then all the native dependencies should have been installed.
Usage #
The SDK has 3 modules:
Core: The core scanning functionality
NFC: Performs an NFC scan on the document (compatible device required)
Liveness: Performs a liveness check and optionally a face matching check
Core #
An example on how to run the most basic core functionality
import 'package:verifai_sdk/verifai_sdk.dart';
// Import licence variable stored in a local licence.dart file that is ignored by
// version control
import 'licence.dart';
// When the Core module finishes, an action is cancelled or an error is given these
// listeners will handle the returned object. The result object in the onSuccess
// listener conforms to the `CoreResult` object. The image results have been
// reworked to return something react native can understand. Read the
// documentation for more info.
// First set up the listeners, a good way of doing this is to
// define a class that extends Flutter's `ChangeNotifier`.
// In the example folder you can see an example of this.
class CoreResultImpl with ChangeNotifier implements CoreResultApi {
CoreResultImpl() {
CoreResultApi.setup(this);
}
var _data = CoreResult();
CoreResult get data => _data;
set data(CoreResult value) {
print(value.mrzData?.firstName);
print(value.mrzData?.lastName);
_data = value;
notifyListeners();
}
@override
void onSuccess(CoreResult result) {
data = result;
}
@override
void onCancelled() {
print('cancelled');
}
@override
void onError(String message) {
throw Exception(message);
}
}
// Define the Core's api implementation
var api = CoreApi();
// Set the licence (more info in the documentation)
// the `verifaiLicence` variable is defined in licence.dart as
// we talked about above
await api.setLicence(verifaiLicence);
// You can configure many aspects of the SDK, check
// our documentation or further down in this README for more
// info. First we'll just do something very simple.
api.configure(Configuration(enableVisualInspection: true));
// Start the SDK, this displays the SDK on the screen.
// The result is returned through the listeners
await api.start();
copied to clipboard
NFC #
Let's look at an example on how to run the most basic NFC functionality. The NFC module can
only be run after a scan from the Core module has been performed.
// When the Core module finishes, an action is cancelled or an error is given these
// listeners will handle the returned object. The result object in the onSuccess
// listener conforms to the `NfcResult ` object. The image results have been
// reworked to return something react native can understand. Read the
// documentation for more info.
// First set up the listeners, a good way of doing this is to
// define a class that extends Flutter's `ChangeNotifier`.
// In the example folder you can see an example of this.
class NfcResultImpl with ChangeNotifier implements NfcResultApi {
NfcResultImpl() {
NfcResultApi.setup(this);
}
var _data = NfcResult();
NfcResult get data => _data;
set data(NfcResult value) {
_data = value;
notifyListeners();
}
@override
void onSuccess(NfcResult result) {
data = result;
}
@override
void onCancelled() {
print('cancelled');
}
@override
void onError(String message) {
print(message);
throw Exception(message);
}
}
// Now we can start the NFC SDK. This will present the scanning screen. There
// are a few things we can setup while starting the NFC check to see the full
// list check out the documentation. Important: For the NFC check to work
// properly the core scan should have been performed.
var api = NfcApi();
var coreData = context.read<CoreResultImpl>().data;
if (coreData.mrzData != null) {
await api.start(NfcConfiguration(retrieveImage: true), coreData);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const NfcResult()),
);
} else {
print("No core result mrz data");
}
copied to clipboard
Liveness #
An example on how to run the most basic Liveness functionality. The Liveness
module can only be run after a scan from the Core module has been performed.
Also you need to make sure the licence has been setup by the Core before running
the Liveness module.
// When the Core module finishes or an error is given these
// listeners will handle the returned object. The result object in the onSuccess
// listener conforms to the `LivenessResult` object. The image results have been
// reworked to return something react native can understand. Read the
// documentation for more info.
// First set up the listeners, a good way of doing this is to
// define a class that extends Flutter's `ChangeNotifier`.
// In the example folder you can see an example of this.
class LivenessResultImpl with ChangeNotifier implements LivenessResultApi {
LivenessResultImpl() {
LivenessResultApi.setup(this);
}
var _data = LivenessResult();
LivenessResult get data => _data;
set data(LivenessResult value) {
_data = value;
notifyListeners();
}
@override
void onSuccess(LivenessResult result) {
data = result;
print(result.automaticChecksPassed);
print(result.successRatio);
print(result.resultList);
}
@override
void onError(String message) {
print(message);
throw Exception(message);
}
}
// Now we can start the liveness check, this shows the liveness check screen
// There are a few things we can setup while starting the liveness check to see
// the full list check out the documentation. Important: For the liveness check
// to work properly the main scan should have been performed
var api = LivenessApi();
var checks = [
LivenessCheck(type: LivenessCheckType.closeEyes, args: {"numberOfSeconds": 3}),
LivenessCheck(type: LivenessCheckType.tilt, args: {"faceAngleRequirement": 25}),
];
var image = context.read<CoreResultImpl>().data.frontImage;
if (image != null) {
checks.add(LivenessCheck(
type: LivenessCheckType.faceMatching,
args: {"documentImage": image}));
}
api.start(LivenessConfiguration(showDismissButton: true, checks: checks));
copied to clipboard
Customization #
Each module has extensive custimzation options to control the SDK's behavior.
You can customize options while scanning, scan help instruction, pre scan
instruction. You can also customize what kind of documents are allowed or filter
which options a user can choose from.
Extensive documentation on this is available in our
documentation.
Below you can find some examples on how to setup some components to give you an
idea of what you can setup.
Core settings #
The core offers several settings that allow you too better setup the SDK and
which flows a user gets.
Below is an example of the settings you can set, you can customize these to fit
your own need. For extensive explanation of what eacht setting does please check
out our documentation. You can set these values when initiating a Configuration object.
And then you can sent this object to the SDK via the CoreApi's configure method.
Configuration(
requireDocumentCopy: true,
enablePostCropping: true,
enableManual: true,
requireMrzContents: false,
requireNfcWhenAvailable: false,
readMrzContents: true,
documentFiltersAutoCreateValidators: true,
customDismissButtonTitle: null,
requireCroppedImage: true,
enableVisualInspection: true
);
copied to clipboard
Core - Instruction screens #
There are several ways of customizing the instruction screens. The easiest way
is to use our own design but customize the values yourself, place these values
inside the Configuration object:
Configuration(
enableVisualInspection: true,
instructionScreenConfiguration: InstructionScreenConfiguration(
showInstructionScreens: true,
instructionScreens: [
InstructionScreen(
screen: InstructionScreenId.mrzPresentFlowInstruction,
type: InstructionScreenType.media,
// Values for MEDIA based instruction screens
title: "Custom Instruction",
continueButtonLabel: "Let's do it!",
header: "Check out the video below",
mp4FileName: "DemoMp4", // This file needs to be available in your main bundle on the native side of things
instruction: "This is some custom instruction text that you can provide. In this example we're customizing the screen that asks if the document has an MRZ (Machine Readable Zone). So does the document have a MRZ? Answer below."
)
],
)
);
copied to clipboard
You can also use a web based instruction screen:
Configuration(
enableVisualInspection: true,
instructionScreenConfiguration: InstructionScreenConfiguration(
showInstructionScreens: true,
instructionScreens: [
InstructionScreen(
screen: InstructionScreenId.mrzPresentFlowInstruction,
type: InstructionScreenType.web,
title: "Custom web based instruction",
continueButtonLabel: "Let's do it!",
url: "https://www.verifai.com/en/support/supported-documents/
)
],
)
);
copied to clipboard
For exact options and possible values check out our documentation.
NFC - Instruction screens #
It's also possible to setup the NFC's instruction screens.
The most simple way is to use our own design but customize the values yourself,
place these values when calling the NFC module's start function:
// Setup the NFC instruction screens, check out docs for more info
NfcConfiguration(retrieveImage: true,
instructionScreenConfiguration:
NfcInstructionScreenConfiguration(showInstructionScreens: true,
instructionScreens: [
NfcInstructionScreen(
screen: NfcInstructionScreenId.nfcScanFlowInstruction,
type: InstructionScreenType.media,
title: "Custom NFC Instruction",
continueButtonLabel: "Let's do it!",
header: "Check out the video below",
mp4FileName: "DemoMp4", // This file needs to be available in your main bundle on the native side of things
instruction: "The US passport has the NFC chip in a very peculiar place. You need to open up the booklet and look for the image of a satellite looking spacecraft on the back (the voyager spacecraft). Place the top back part of your device in one swift motion on top of that spacecraft to start the NFC scan process.",
)
]
),
);
copied to clipboard
You could also use a web based instruction screen:
// Setup the NFC instruction screens, check out docs for more info
NfcConfiguration(retrieveImage: true,
instructionScreenConfiguration:
NfcInstructionScreenConfiguration(showInstructionScreens: true,
instructionScreens: [
NfcInstructionScreen(
screen: NfcInstructionScreenId.nfcScanFlowInstruction,
type: InstructionScreenType.media,
title: "Custom NFC Instruction",
continueButtonLabel: "Let's do it!",
url: "https://www.verifai.com/en/support/supported-documents/",
)
]
),
);
copied to clipboard
Scan help #
When a scan fails or if we detect the user is having difficulties scanning we
offer help screens that give more detailed information about scanning.
In the case of the Core module we also offer an optional fallback option so that
if all else fails, the user can at least take an image of the document that can
be processed manually by a human. For the scan help we let you configure the
instruction and video shown to the user. Please keep in mind the video is muted.
You can customize this screen in the following way, place these values inside the
Configuration object when setting up the Core module:
// Setup scan help, scan help in this case gets shown when scanning fails,
// check out docs for more info
Configuration(scanHelpConfiguration:
ScanHelpConfiguration(
showScanHelp: true,
customScanHelpScreenInstructions: "Our own custom instruction",
customScanHelpScreenMp4FileName: "DemoMp4"
)
);
copied to clipboard
In the NFC module we also offer scan help when an NFC scan fails. For the scan
help we let you configure the instruction and video shown to the user. Please
keep in mind the video is muted.
You can customize this screen in the following way, place these values in the NFC module's configuration:
// Setup scan help, scan help in this case gets shown when NFC scanning fails,
// check out docs for more info
NfcConfiguration(
scanHelpConfiguration:
ScanHelpConfiguration(
showScanHelp: true,
customScanHelpScreenInstructions: "Our own custom instruction",
customScanHelpScreenMp4FileName: "DemoMp4"
)
);
copied to clipboard
Validators #
Just like for the native SDK we've opened up the possibility to setup validators
via the flutter package. For an extensive explanation on what validators are
please check out our main documentation. We currently don't provide the option
to setup custom validators via the bridge. The package provides access to the
following validator types:
// Enum that describes a document Validator type
enum ValidatorType {
countryAllowlist, // Validator that only allows documents from the countries provided
countryBlocklist, // Validator that blocks the documents from the countries provided
hasMrz, // Validator that checks if document has an MRZ
documentTypes, // Validator that only validates certain document types
mrzAvailable, // Validator that requires the MRZ to be correct
nfcKeyWhenAvailable, // Validators that ensure the NFC key if available is correct
}
copied to clipboard
In the example below we setup one of each validator as an example. Please be
aware that if setup incorrectly validators can cancel each other out. Like
adding the same countries to allow and block lists.
// Example of adding validators
Configuration(
validators: [
Validator(
type: ValidatorType.countryAllowlist,
args: {
"countryList": ["NL"]
}
),
Validator(
type: ValidatorType.countryBlocklist,
args: {
"countryList": ["BE"]
}
),
Validator(
type: ValidatorType.hasMrz
),
Validator(
type: ValidatorType.documentTypes,
args: {
"validDocumentTypes": [
DocumentType.driversLicence.index,
DocumentType.passport.index
]
}
),
Validator(
type: ValidatorType.mrzAvailable
),
Validator(
type: ValidatorType.nfcKeyWhenAvailable
),
]
);
copied to clipboard
Document Filters #
We've also opened up the possibility to setup document filters via the flutter package.
Document filters allow you to cntrol which dcuments a uer can
choose when using the manual flow of the SDK. More information about this is
available in the documentation.
We provide the following document filters:
// Enum that describes document filters that filter the available documents in
// the manual document selection flow
enum DocumentFilterType {
documentTypeAllowList, // Filter that only allows certain document types
documentAllowList, // Filter that only allows documents from certain provided countries
documentBlockList, // Filter that blocks certain document countries
}
copied to clipboard
Here's an example on how to set the document filters, pass these values when configuring the core module.
// Setting document filters example
Configuration(
documentFilters: [
DocumentFilter(type: DocumentFilterType.documentAllowList,
args: {
"countryList": ["NL"]
}
),
DocumentFilter(type: DocumentFilterType.documentBlockList,
args: {
"countryList": ["BE"]
}
),
DocumentFilter(type: DocumentFilterType.documentTypeAllowList,
args: {
"validDocumentTypes": [
DocumentType.passport.index,
DocumentType.idCard.index
]
}
)
]
);
copied to clipboard
Liveness checks #
We also offer a bridge to the liveness checks tat the SDK provides. The
following Liveness checks are available:
// Enum of possible liveness checks
enum LivenessCheckType {
closeEyes, // Check where a user is asked to close their eyes for x amount of time
tilt, // Check where a user is asked to tilt their head a certain amount of degrees
speech, // Check where the user is asked to say certain words
faceMatching, // Check where the user is asked to take a selfie and the face is matched with the one on the document or NFC
}
copied to clipboard
Below you can find an example of each liveness check, you can configure the
values to match your needs or just pass an empty list and the SDK will use a
default set of checks.
You can set these values by passing them when starting the liveness check with the LivenessConfiguration object.
LivenessConfiguration(
checks: [
LivenessCheck(
type: LivenessCheckType.closeEyes,
args: {"numberOfSeconds": 3}
),
LivenessCheck(
type: LivenessCheckType.tilt,
args: {"faceAngleRequirement": 5}
),
LivenessCheck(
type: LivenessCheckType.speech,
args: {
"speechRequirement": "Apple Banana Pizza"
}
),
LivenessCheck(
type: LivenessCheckType.faceMatching,
args: {"documentImage": image}
)
]
);
copied to clipboard
Support #
For additional support remember to consult our main
documentation or reach out to us via our
support channels.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.