📘 Get Started with Flutter SDK - Dojah KYC Widget

Reference : flutter_dojah_kyc Pub Dev package

Example Application: https://github.com/dojah-inc/Flutter-SDK

Installation

Step 1 : Install flutter_dojah_kyc dependency in pubspec.yaml file of your flutter project

pubspec.yaml
name: dojah_flutter
description: A new Flutter project.

publish_to: 'none'


version: 1.0.0+1

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter



  cupertino_icons: ^1.0.2
  flutter_dojah_kyc: 0.4.7

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_lints: ^1.0.0

flutter:


  uses-material-design: true

Usage

Step 2 : Create DojahKYC _dojahKYC class

main.dart

import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:flutter_dojah_kyc/flutter_dojah_kyc.dart';
import 'dart:convert';

void main() async {
  runApp(const MyApp());

// await location.requestService();

}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Demo',
        theme: ThemeData(
            // This is the theme of your application.
            //
            // Try running your application with "flutter run". You'll see the
            // application has a blue toolbar. Then, without quitting the app, try
            // changing the primarySwatch below to Colors.green and then invoke
            // "hot reload" (press "r" in the console where you ran "flutter run",
            // or simply save your changes to "hot reload" in a Flutter IDE).
            // Notice that the counter didn't reset back to zero; the application
            // is not restarted.
            //primarySwatch: Colors.blue,
            ),
        home: const HomePage());
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  
  _HomePageState createState() => _HomePageState();
}

Map<dynamic, dynamic> envVars = Platform.environment;

class _HomePageState extends State<HomePage> {
// final appId= envVars['appId']; //your application ID
// final publicKey = envVars['publicKey']; //your public key

  final appId = "6000604fb87ea60035ef41bb"; //your application ID
  final publicKey = "prod_pk_7jspvKP2FMkjkSZx1qnbgiMWy"; //your public key


  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("Dojah Widget"),
          //backgroundColor: Colors.yellow,
        ),
        body: Center(
            child: Column(children: <Widget>[
          Container(
            child: TextButton(
              child: const Text(
                'Custom Widget',
                style: TextStyle(fontSize: 20.0),
              ),
              onPressed: () {
                // final userData = {
                //   "first_name": "John",
                //   "last_name": "Doe",
                //   "dob": "1901-12-01",
                //   "residence_country": "Nigeria"
                // };

                final configObj = {


                  "widget_id": ""   //this is generated from easyonboard here https://app.dojah.io/easy-onboard
             
                };




                final metaData = {
                  "user_id": "81828289191919193882",
                };

                final govData = {
                  "bvn": "",
                  "nin": "",
                  "dl": "",
                  "mobile": ""
             };

              

                DojahKYC? _dojahKYC;

                ///Use your appId and publicKey
                _dojahKYC = DojahKYC(
                  appId: appId,
                  publicKey: publicKey,
                  type: "custom",
                  //userData: userData,
                  metaData: metaData,
                  config: configObj,
                  govData: govData,
                  // referenceId: referenceId
                );

                print(json.encode(configObj));
                print(json.encode(configObj));
                //print(userData);
                print(configObj);
                _dojahKYC.open(context,
                    onSuccess: (result) => print(result),
                    onClose: (close) => print('Widget Closed'),
                    onError: (error) => print(error));
              },
            ),
          ),
        ])));
  }
}

ParameterTypeDescription
typestringWidget Type: Values are ‘custom’, ‘verification’, ‘identification’, ‘verification’, ‘liveness’
app_idstringApplication Id, Get it from your dojah application dashboard here
p_keystringPublic Key, Get it from your dojah application dashboard here
reference_idstringReference ID, It can be passed to keep track of the verification steps (Started, Ongoing, Successful). NB: reference_id character length must be greater than 10
widget_idstringWidget ID, Get it from your Easy Onboard application dashboard here
user_dataobjectAutomatically update the user data page, and thus skip the page
gov_dataobjectAutomatically update the government data page, and thus skip the page
metadataobjectYour application’s metadata to be passed back to you via webhook, onSuccess, or onError
onSuccessfunctionThis is called when your user has successfully completed enrollment with their preferred institution. The sample response data below is passed to the widget
onErrorfunctionThis is called when your user was unable to successfully complete enrollment.
onClosefunctionThis is called when the widget is closed.

Other required installations (make sure to follow the instructions in the webview_screen documentation).

Kindly request camera permissions before launching the widget

📘 Request Camera Permission

Kindly declare and request camera permission in the main activity, at your application level - MainActivity/main.dart before launching the SDK

Android configuration

Android
// Add the camera permission: 
<uses-permission android:name="android.permission.CAMERA" />
// Add the modify audio settings permission:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

iOS configuration

iOS
permissions_path = '../ios'
pod 'Permission-Camera', :path => "#{permissions_path}/Camera"

Podfile

Podfile
Kindly include this in Podfile set up.

dart: PermissionGroup.camera PERMISSION_CAMERA=1,

dart: PermissionGroup.microphone PERMISSION_MICROPHONE=1,

dart: PermissionGroup.location PERMISSION_LOCATION=1,

infoplist

info.plist
Add the following keys to your Info.plist file, 
located in <project root>/ios/Runner/Info.plist:

NSCameraUsageDescription - 
  describe why your app needs access to the camera. This is called Privacy - Camera Usage Description in the visual editor.

NSMicrophoneUsageDescription -
  describe why your app needs access to the microphone, if you intend to record videos. This is called Privacy - Microphone Usage Description in the visual editor.

NSLocationWhenInUseUsageDescription - 
    describe why your app needs access to the location, if you intend to verify address/location. This is called Privacy - Location Usage Description in the visual editor.

Run your flutter Project

Step 3: Handle a Successful Enrollment

On successful enrollment, the _onSuccess _callback function that you supplied is called by the SDK. We then return the connected account code to your server.

Alternative configuration instead of Specifying pages Array from the SDK

The main advantage of this feature is to enable you make changes to your widget flow or configuration on Dojah Dashboard herehere instead of rebuilding or modifying the main Flutter Application.
Implementation Example

<span data-testid="SyntaxHighlighter">            
final configObj = {


"widget_id": "your widget ID",
  
  
}
</span>

Kindly use the overall status (response.status (Boolean, i.e true or false)) to ascertain if the request failed or succeeded.

📘 Webhook Notifications

You can receive the same data below (also passed to onSuccess and onError) via a webhook call.

Register your url for webhook calls here and ensure kyc.widget is the service you are subscribed to.

In Config object Kindly set webhook object value to true (Boolean)

Example : webhook : true

The Sample response data after successful verification

Response
{
    aml: {
        status: false
    },
    data: {
        id: {
            data: {
                id_url: "https://images.dojah.io/id_sample_id_1720624047.jpg",
                id_data: {
                    extras: "",
                    last_name: "John",
                    first_name: "Doe",
                    mrz_status: "",
                    date_issued: "2019-01-01",
                    expiry_date: "2020-01-01",
                    middle_name: "",
                    nationality: "Nigerian",
                    date_of_birth: "1990-01-01",
                    document_type: "National ID",
                    document_number: "123456789"
                },
                back_url: "https://images.dojah.io/id_sample_id_1720624047.jpg"
            },
            status: true,
            message: "Successfully verified your id"
        },
        email: {
            data: {
                email: "abc@gmail.com"
            },
            status: true,
            message: "abc@gmail.com validation Successful"
        },
        index: {
            data: {},
            status: true,
            message: "Successfully continued to the main checks."
        },
        selfie: {
            data: {
                selfie_url: "https://images.dojah.io/selfie_sample_image_1720624219.jpg"
            },
            status: true,
            message: "Successfully validated your liveness"
        },
        countries: {
            data: {
                country: "Nigeria"
            },
            status: true,
            message: "Successfully continued to the next step."
        },
        user_data: {
            data: {
                dob: "1990-12-03",
                last_name: "John",
                first_name: "Doe"
            },
            status: true,
            message: ""
        },
        business_id: {
            image_url: "https://images.dojah.io/selfie_sample_image_1720624219.jpg",
            business_name: "ABC Company LIMITED",
            business_type: "Business",
            business_number: "1237654",
            business_address: "",
            registration_date: ""
        },
        phone_number: {
            data: {
                phone: "234810123456"
            },
            status: true,
            message: "2348103817187 validation Successful"
        },
        business_data: {
            business_name: null,
            business_type: "BN",
            business_number: null,
            business_address: null,
            registration_date: null
        },
        government_data: {
            data: {
                bvn: {
                    entity: {
                        bvn: "222222222222",
                        nin: "",
                        email: "",
                        title: "",
                        gender: "Male",
                        customer: "6bb82c41-e15e-4308-b99d-e9640818eca9",
                        image_url: "https://images.dojah.io/id_John_Doe_1720615487.jpg",
                        last_name: "John",
                        first_name: "Doe",
                        middle_name: "Anon",
                        nationality: "",
                        name_on_card: "",
                        watch_listed: "",
                        date_of_birth: "01-Jun-1982",
                        lga_of_origin: "",
                        phone_number1: "08011111111",
                        phone_number2: "",
                        marital_status: "",
                        enrollment_bank: "",
                        state_of_origin: "",
                        level_of_account: "",
                        lga_of_residence: "",
                        enrollment_branch: "",
                        registration_date: "",
                        state_of_residence: "",
                        residential_address: ""
                    }
                },
               nin: {
                entity: {
                nin: "1234567891",
                firstname: "John",
                middlename: "Doe",
                surname: "Anon",
                maidenname: "",
                telephoneno: "0901234567",
                state: "",
                place: "",
                profession: "ZOOLOGY",
                title: "",
                height: "167",
                email: "",
                birthdate: "1960-01-01",
                birthstate: "",
                birthcountry: "Not Available",
                centralID: "",
                documentno: "",
                educationallevel: "tertiary",
                employmentstatus: "unemployed",
                othername: "",
                pfirstname: "",
                pmiddlename: "",
                psurname: "",
                nspokenlang: "YORUBA",
                ospokenlang: "",
                religion: "christianity",
                residence_Town: "",
                residence_lga: "Alimosho",
                residence_state: "Lagos",
                residencestatus: "birth",
                residence_AddressLine1: "No 2 Anon house, John does estate, Lagos state, Nigeria",
                residence_AddressLine2: "",
                self_origin_lga: "",
                self_origin_place: "",
                self_origin_state: "",
                signature: null,
                nationality: null,
                gender: "Female",
                trackingId: "",
                customer: "1234444y373737373737373737",
                image_url: "https://images.dojah.io/id_SANDBOX_1721830110.jpg"
              }
          }
            },
            status: true,
            message: ""
        },
        additional_document: [
            {
                document_url: "https://dojah-image.s3.amazonaws.com/66bcc73a4ff8e1003100454212aec768-3344-4df5-88f6-7e723c46cbb0.jpeg",
                document_type: "image"
            }
        ]
    },
    value: "123456",
    id_url: "https://images.dojah.io/id_sample_id_1720624047.jpg",
    status: true,
    id_type: "BVN",
    message: "Successfully completed the verification.",
    back_url: "https://images.dojah.io/id_sample_id_1720624047.jpg",
    metadata: {
        ipinfo: {
            as: "AS29465 MTN NIGERIA Communication limited",
            isp: "MTN NIGERIA Communication limited",
            lat: 6.4474,
            lon: 3.3903,
            org: "MTN Nigeria",
            zip: "",
            city: "Lagos",
            proxy: false,
            query: "102.89.34.49",
            mobile: true,
            status: "success",
            country: "Nigeria",
            hosting: true,
            district: "",
            timezone: "Africa/Lagos",
            region_name: "Lagos"
        },
        device_info: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
    },
    selfie_url: "https://images.dojah.io/selfie_sample_image_1720624219.jpg",
    reference_id: "DJ-31038041E0",
    verification_url: "https://app.dojah.io/verifications/bio-data/49fd74a4-8181-4ce8-a87a-0e63f7159257",
    verification_mode: "LIVENESS",
    verification_type: "RC-NUMBER",
    verification_value: "123456",
    verification_status: "Completed"
}

By Setting the user-data and country page config enable object to false, The user-data and country page will be removed. Kindly note that this customisation can be implemented only in custom widget type.

📘 How to Exclude or Skip the User data Page

Kindly pass userData inside the DojahKYC constructor class.

Example :

final userData = {  
           "first_name": "JOHN",  
           "last_name": "DOE",  
           "dob": "2022-03-12"  
          };

_dojahKYC = DojahKYC(appId: "appId",  
          publicKey: "p_key",  
          type: "custom",  
          userData: userData, 
          govData: govData, 
          config: configObj,)

📘 How to retrieve the Selfie Photo

There’s a response object that is sent to the client via the widget launcher on success or failure
selfieUrl and idUrl under selfie and id in the success response objects, which holds the final selfie capture and id capture respectively.

📘 How to Fix Android File Upload Crash

 STEP 1:


Open the AndroidManifest.xml file located in the android/app/src/main directory of your Flutter project.

Inside the &lt;application&gt; tag, add the following code:
&lt;provider android:name="androidx.core.content.FileProvider" android:authorities="com.example.dojah_kyc.flutter_inappwebview.fileprovider" android:exported="false" android:grantUriPermissions="true"&gt; &lt;meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /&gt; &lt;/provider&gt; 
Make sure to replace com.example.dojah_kyc with your application’s package name.


STEP 2: 

Create a new file named provider_paths.xml in the android/app/src/main/res/xml directory (create the xml directory if it doesn’t exist). Add the following code to the provider_paths.xml file:

&lt;paths xmlns:android="http://schemas.android.com/apk/res/android"&gt; &lt;external-path name="external_files" path="." /&gt; &lt;/paths&gt; 



STEP 3: 

Save the changes and rebuild your Flutter application.
By following these steps, you should be able to properly configure the file provider and resolve the “Couldn’t find meta-data for provider” error when selecting files with the file picker in your Flutter application on Android devices.

Webview issues and fixes

  1. if you ever experienced “Unknown feature SUPPRESS_ERROR_PAGE, webview not displaying at all on Android device,

Add this to android/build.gradle

build.gradle
allprojects {
    configurations.all {
        resolutionStrategy {
            force 'androidx.webkit:webkit:1.8.0'
        }
    }
}

Add this to dependency file

dependency_overrides:
  webview_flutter_android: 3.16.1

Issue on Github

Deployment

REMEMBER TO CHANGE THE APP ID and PUBLIC KEY WHEN DEPLOYING TO A LIVE (PRODUCTION) ENVIRONMENT

https://github.com/dojah-inc/Flutter-SDK

Example Application : https://github.com/dojah-inc/Flutter-SDK/tree/master/examples

  1. Fork it!
  2. Create your feature branch: git checkout -b feature/feature-name
  3. Commit your changes: git commit -am ‘Some commit message’
  4. Push to the branch: git push origin feature/feature-name
  5. Submit a pull request 😉😉

This project is licensed under the MIT License - see the LICENSE file for details