App Drop-in Setup

Integrations guide

Flutter plugin

This page sets out step-by-step instructions for setting up your App Drop-in via the Flutter plugin.

Prerequisites & configuration

You will need your:

  • fourthlineGithubToken
  • tenantId provided by your implementation manager

Check the following prerequisites and specifications for your operating system:

Android prerequisites

Android prerequisites

  • Minimum API version: 23
  • Minimum supported Android API level: 23
  • Language: The SDK is written in Kotlin but is also compatible with Java.

The plugin contains the following:

ContentDescription
Source file FourthlinePlugin.ktSubclasses the FlutterPlugin object that bridges the Flutter environment and the fourthline-scanners framework
fourthline-scanners Android libraryContains the following drop-in modules:
• Identity Verification flow
• Workflows API
• Identity data validator and zipper
fourthline-adapters-json Android libraryProvides JSON interfacing with fourthline-scanners

To resolve the dependencies on Fourthline's Android SDK, declare and authenticate in our Maven repository:

  1. Add your fourthlineGithubToken as a Gradle property for your environment.

  2. In your top-level build.gradle file, link to Fourthline's repository:

allprojects {
 repositories {
 //...
 maven {
 url = URI("https://maven.pkg.github.com/Fourthline-com/FourthlineSDK-Android")
 credentials {
 username = ""
 password = property("fourthlineGithubToken").toString()
 }
 }
 }
}
Note
Notes
Data is transferred between Flutter and our plugin API via JSON formatted Strings, both as input configuration options and payload responses.
For more information, see Flutter – Serializing JSON manually using dart:convert.
iOS prerequisites

iOS prerequisites

  • Minimum iOS version: 12
  • Minimum XCode version: 14.3
  • Minimum iOS deployment target: 12.0
  • MRZ detection in the document scanner requires minimum iOS 13.

The plugin contains the following:

ContentDescription
Source file FourthlinePlugin.swiftSubclasses the mobile FlutterPlugin object that bridges the Flutter environment and the FourthlineScanners framework
FourthlineScanners iOS frameworkContains the following drop-in modules:
• Identity Verification flow
• Workflows API
• Identity data validator and zipper
fourthline-adapters-json iOS libraryProvides JSON interfacing with FourthlineScanners
iOS frameworksProvide functionalities for FourthlineScanners:
FourthlineCore: Orchestration and analytics functionality
FourthlineVision: Document and Biometrics scanners
FourthlineNFC: NFC scanner
FourthlineKYC: Identity data management functionality
FourthlineSDK
Datadog

Before you set up the plugin, make the following preparations:

  1. In the Info.plist file, add the keys required to access the camera and NFC functionalities:
<key>NSCameraUsageDescription</key>
<string>To verify your identity, please allow us to access your camera once only.</string>
  1. Optionally, for the NFC flow, add to the Info.plist file the keys required to access the NFC functionality:
<key>NFCReaderUsageDescription</key>
<string>To read the chip in your ID document, please enable NFC.</string>

<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
 <string>A0000002471001</string>
 <string>A00000045645444C2D3031</string>
</array>
  1. Optionally, to record audio in the document and selfie videos, add to the Info.plist file the key required to access the microphone functionality:
<key>NSMicrophoneUsageDescription</key>
<string>To verify your identity, please allow access to your microphone.</string>
  1. Optionally, for the Location module, add to the Info.plist file the keys required to access the location functionality:
<key>NSLocationWhenInUseUsageDescription</key>
<string>To verify your identity, please allow access to your location.</string>

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>To verify your identity, please allow access to your location.</string>

<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dictionary>
	<key>FourthlineFullAuthorizationPurposeKey</key>
 <string>To verify your identity, your exact location is shared with us once only.</string>
</dictionary>
  1. In the XCode Signing & capabilities tab, enable the Near Field Communication Tag Reading capability.

  2. If customizing the fonts in the UI, add the font files to your project and to the projects' Info.plist:

<key>UIAppFonts</key>
	<array>
		<string>Your-Font-Medium.ttf</string>
		<string>Your-Font-Regular.ttf</string>
	</array>

Note
Notes
• Data is transferred between Flutter and our plugin API via JSON formatted Strings, both as input configuration options and payload responses. For more information, see Flutter – Serializing JSON manually using dart:convert.
• Fourthline scanners are designed to be implemented and tested on a real mobile device. Launching them on the iOS simulator throws a scanner error.

GitHub credentials

Provide your implementation manager with the GitHub usernames and email addresses of your staff who need access to our repositories.

Identity data

Configurable

If you want to receive a copy of the identity data gathered by the App Drop-in when it's uploaded to our backend (before case processing), let your implementation manager know.

Document data

Configurable

Discuss with your implementation manager what data to extract from ID document photos via optical character recognition (OCR):

Data typeDescription
MRZ dataDocument data is extracted from the MRZ only and is processed offline by the SDK.
MRZ & VIZ dataFor greater accuracy, document data is extracted from the MRZ and VIZ and processed by our AI agent in real time.

Supported devices

More information
For questions about supported devices, contact your implementation manager.


Flow

Follow these steps:

1. Set up plugin

To setup the plugin, follow these steps:

  1. Set up SSH authentication using your GitHub account with permissions for Fourthline's plugin.
    For instructions, see GitHub – Connecting to GitHub with SSH .

  2. In your pubspec.yaml file, add a dependency on this file: [email protected]:fourthline-com/fourthline_flutter.git

dependencies:
 ...
 fourthline_plugin:
 git:
 url: [email protected]:fourthline-com/fourthline_flutter.git
 version: ^1.0.0

2. Set up analytics

The FourthlineCore module collects and processes metrics.

You can set up an analytics observer for the SDK to forward Fourthline events to.

Events are only forwarded when you initialize FourthlineAnalytics by calling FourthlineAnalytics.initialize(...) and TrackingConsent is set to granted.

To set the observer, call FourthlineAnalytics.setObserver(...).

To remove the observer, call FourthlineAnalytics.removeObserver().

Example code:

import 'package:flutter/services.dart';
import 'package:fourthline/fourthline.dart';

class _ExampleWidgetState extends State<ExampleWidget> {
  StreamSubscription<dynamic>? _eventSubscription;

  @override
  void initState() {
    super.initState();

    // Start observing analytics events
    await _fourthlinePlugin.setAnalyticsObserver() ?? "Could not set analytics observer";
    
    // Start listening to the event channel
    _eventSubscription = Fourthline.analyticsEventChannel
        .receiveBroadcastStream()
        .listen(_handleAnalyticsEvent, onError: null);

  }

  @override
  void dispose() {
    // Clean up the listener when the widget is disposed
    _eventSubscription?.cancel();

    // Stop observing analytics events
    await _fourthlinePlugin.removeAnalyticsObserver() ?? "Could not remove analytics observer";

    super.dispose();
  }

  void _handleAnalyticsEvent(dynamic data) {
    // Handle the custom event
    print('Received event: $data');
  }

  // ... rest of your widget
}

Example code for tracked event:

{
  "event": string,
  "attributes": Object
}

3. Configure workflow

  1. Pass the following JSON configuration to the workflow:
{
 "configuration": WorkflowConfiguration,
 "customization": WorkflowCustomization
}

WorkflowConfiguration has the following format:

{
 "networkEnvironment": NetworkEnvironment, // To test a workflow locally use .mock, and to test workflow networking use .sandbox
 "validationCode": string, // Returned in the Create SDK session response
}

NetworkEnvironment can have the following values:

ValueDescription
productionLive environment
sandboxRemote testing environment
mockLocal testing environment with stubbed data

  1. To get the ValidationCode, make a Create SDK session request.

WorkflowCustomization is an optional field.
To customize the look and feel of the UI, see App Drop-in UI Customization.
It has the following format:

{
 "flavor": string
}

Example code:

String config = """{
 "configuration": {
 "validationCode": "123456",
 "networkEnvironment": "sandbox"
 },
 "customization": {
 "flavor": {
 "colors": $orcaColors,
 "fonts": $orcaFonts,
 "localization": $orcaLocalization,
 "layouts": $orcaLayout
 }
 }
}
""";

try {
 String result = await _fourthlinePlugin.startWorkflow(config) ?? "";
 // Client has successfully completed the workflow
 } on Exception catch (e) {
 // Extract and process the information from the error
 String? message = e.message;
 switch (e.code) {
 case "803":
 print('User canceled $message');
 break;
 case "1000":
 print('Client rejected');
 break;
 }
 };
);

If the workflow is:

  • Successful: All results are already processed and no additional response is returned.
  • Unsuccessful: The following JSON string is returned:
{
 "errorCode": number,
 "errorDescription": string
}

The following error codes are possible:

Error codeDescriptionAction
800Decoding errorCheck the errorDescription for more information.
802Invalid or missing fontCheck the errorDescription for more information.
803User canceledThe client explicitly canceled the workflow.
830JSON parse errorCheck the JSON provided.
850Incorrect configurationEnsure the workflow is configured correctly.
870Unexpected + messageInform your implementation manager immediately.
1000ClientRejectedThe client isn't eligible for the workflow.
You can't retry.
1001InvalidValidationCodeMake a new Create SDK session request.
1002Module error + messageThe client encountered an error in one of the workflow modules.
Check the message for more information.
1003ConfigurationNotSupported + messageThe workflow created using the validationCode isn't supported.
Consider updating to the latest plugin version.
1004InvalidWorkflowStatusCheck if the workflow module is already completed successfully or with an error.


4. Add data observer

To receive notifications for each data group that the SDK uploads to Fourthline and a copy of the data itself, add a data observer.

Example code:

import 'package:flutter/services.dart';
import 'package:fourthline/fourthline.dart';

class _ExampleWidgetState extends State<ExampleWidget> {
 StreamSubscription<dynamic>? _workflowDataSubscription;

 @override
 void initState() {
 super.initState();

 // Start listening to the event channel
 _workflowDataSubscription = Fourthline.workflowDataEventChannel
 .receiveBroadcastStream()
 .listen(_handleWorkflowDataEvent, onError: null);

	// Start a workflow
 }

 @override
 void dispose() {
 // Clean up the listener when the widget is disposed
 _workflowDataSubscription?.cancel();

 super.dispose();
 }
 
 void _startWorkflow() {
 String config = """{
 "configuration": {
 "validationCode": "IDV",
 "networkEnvironment": "mock"
 }
 }
 """;
 try {
 String result = await _fourthlinePlugin.startWorkflow(config) ?? "";
 } on Exception catch (e) {
 showAlertDialog("Error", e.toString());
 };
 }

 void _handleWorkflowDataEvent(dynamic data) {
 // Handle the data upload event
 print('Uploaded data: $data');
 }
}

The notifications per data type have the following JSON structure:

"idv":{
  "document":{
    "type":"string",
    "number":"string",
    "issueDate":"string", // Optional, format YYYY-MM-DD
    "expirationDate":"string", // Optional, format YYYY-MM-DD
    "images":[
      {
        "image":"string",
        "fileSide":"string",
        "isAngled":"boolean",
        "timestamp":"string", // Optional, format "YYYY-MM-dd'T'HH:mm:ssZZZZZ"
        "location":{
          "latitude":"number",
          "longitude":"number"
        }
      }
    ]
  }
}
"idv":{
  "documentVideo":{
    "url":"string",
    "duration":"string", // Default / extended
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    }
  }
}
"idv":{
  "selfie":{
    "image":"string",
    "timestamp":"string", // Optional
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    }
  }
}
"idv":{
  "selfieVideo":{
    "url":"string",
    "duration":"string", // Default / extended
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    }
  }
}

"idv":{
  "nfc":{
    "image":"string", // Optional
    "timestamp":"string",
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    },
    "mrz":"string",
    "dataGroups":[ // Optional
      {
        "groupNumber":"Int",
        "data":"string"
      }
    ]
  }
}
"idv":{
  "address":{
    "street":"string",
    "streetNumber":"Int",
    "streetNumberSuffix":"string", // Optional
    "postalCode":"string",
    "city":"string",
    "countryCode":"string",
    "region":"string" // Optional
  }
}
"idv":{
  "person":{
    "firstName":"string",
    "middleName":"string", // Optional
    "lastName":"string",
    "gender":"string",
    "nationalityCode":"string",
    "birthCountryCode":"string", // Optional
    "birthPlace":"string", // Optional
    "birthDate":"string" // Format YYYY-MM-DD
  }
}
"idv":{
  "deviceMetadata":{
    "model":"string",
    "sdkVersion":"string",
    "osVersion":"string",
    "language":"string",
    "osCompromised":"string",
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    }
  }
}

5. Delete temporary files

The plugins store some data collected during workflows (e.g. selfie and document videos) in the tmp/fourthline folder in the client's device filesystem. This is because the videos must remain available until collected, packaged into the case zipfile, and uploaded to our backend.

You must delete the temporary files when they are no longer needed, e.g. after the SDK has uploaded all data to Fourthline or immediately before the app is terminated in:

  • Android: onDestroy()
  • iOS: applicationWillTerminate

Example code:

await _fourthlinePlugin.deleteFourthlineFiles();

// Instance variable defined in your Dart class
final _fourthlinePlugin = Fourthline();
Success
Success
You have configured and set up your App Drop-in!
To integrate your solutions, see the Integration Guides.

Top of page

Accordion in HTML5