DEV Community

Cover image for How to Integrate Dojah Javascript Library into your Flutter Application using flutter_inappwebview package
mkaychuks
mkaychuks

Posted on • Edited on

How to Integrate Dojah Javascript Library into your Flutter Application using flutter_inappwebview package

Dojah uses advanced AI-powered technology to make it easy for businesses to onboard users at scale, ensuring a smooth and secure verification. Their service makes for an easy and smooth user verification (aka KYC). In this tutorial we will delve into using there service in our flutter app.

This tutorial does not cover the step by step process of setting up your account on the Dojah website or creating an App on the Dojah Sandbox, you can read more about it here.

Now to the fun part😄. Integrating Dojah KYC to your flutter app 🚀

Step 1:

create a basic flutter app and install our dependencies

flutter create my-dojah-app
cd my-dojah-app/
flutter pub add flutter_inappwebview
Enter fullscreen mode Exit fullscreen mode

Step 2.

We will also have to install permission_handler package from pub.dev. We will be using this to request camera permission.

Step 3.

In your android folder AndroidManifest.xml file /my-dojah-app/android/app/src/main/AndroidManifest.xml add this

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
//STARTS HERE
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
//ENDS HERE
<application
     ..... //other code lives here
Enter fullscreen mode Exit fullscreen mode

it will enable and give us access to our device's camera.

Step 4.

Create a file where our webview configuration and camera permission will be. You can give it any name you want. I called mine my_kyc.dart and create a StatefulWidget

Step 5.

We now need to write a function that request for permission when a user navigates to my_kyc.dart page.

import 'package:permission_handler/permission_handler.dart';


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

  @override
  State<KYCScreen> createState() => _KYCScreenState();
}

class _KYCScreenState extends State<KYCScreen> {
  bool granted = false; // JUST A FLAG TO CHECK FOR THE USER'S ANSWER

@override
  void initState() {
    super.initState();
    checkPermission(); // WE NOW CALL THE FUNCTION IN INITSTATE
  }

// THIS IS THE FUNCTION THAT CALLS FOR THE USER TO ALLOW FOR CAMERA PERMISSION.
  Future checkPermission() async {
    var status = await Permission.camera.request();
    if (!status.isGranted) {
      print("camera permission denied");
    } else {
      setState(() {
        granted = true;
      });
    }
  }
Enter fullscreen mode Exit fullscreen mode

Step 6.

Now to setting upflutter_inappwebview.

class _KYCScreenState extends State<KYCScreen> {
  /*
  .....previous code still remains.....
*/

  InAppWebViewController? _webViewController;

  InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
    crossPlatform: InAppWebViewOptions(
        clearCache: true,
        useShouldOverrideUrlLoading: true,
        mediaPlaybackRequiresUserGesture: false),
    android: AndroidInAppWebViewOptions(
      useHybridComposition: true,
    ),
    ios: IOSInAppWebViewOptions(
      allowsInlineMediaPlayback: true,
    ),
  );
Enter fullscreen mode Exit fullscreen mode

Step 7.

Setting up the Dojah Javascript Library. In our my_kyc.dart create a variable and assign the following to it. Example below..

 final data = """
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, shrink-to-fit=1"
    />
    <title>Dojah Widget Example</title>
    <style>
      @font-face {
        font-family: Athletics;
        src: url("fonts/Athletics.ttf");
      }
      * {
        font-family: Athletics, sans-serif
      }
      body {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      .paragraphText {
        font-size: 12px;
        color: #677189;
        padding: 24px 36px;
        margin-top: 0;
        margin-bottom: 0;
        background-color: #3977de05;
        text-align: center;
        line-height: 146.16%;
        border-radius: 8px;
        width: 100%;
        max-width: 268px;
      }
      button {
        margin-top: 32px;
        color: white;
        background-color: #3977de;
        padding: 14px 16px;
        border: none;
        outline: none;
        max-width: 384px;
        width: 100%;
        margin-left: auto;
        margin-right: auto;
        border-radius: 4px;
        cursor: pointer;
      }
      @media (max-width: 768px) {
        .paragraphText {
          padding: 16px;
        }
      }
    </style>
  </head>
  <body>
    <div
    style="
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      min-height: 100vh";
    "
  >
    <!-- logo goes here -->
    <img src="favicon.ico" alt="" />
    <!-- <p>Logo</p> -->
    <p
      style="
        font-size: 16px;
        color: #1b2a4e;
        font-weight: bold;
        margin-top: 48px;
        margin-bottom: 21px;
        text-align: center;
      "
    >
      Verify your identity with this Demo
    </p>
    <div>
      <p class="paragraphText">
        Your data will not be stored or retained by Dojah and will only be used
      for the purpose of demonstrating this process flow.
      </p>
    </div>

    <button id="custom-btn-connect">Custom Widget</button>
    <p
      style="
        margin-top: 16px;
        font-size: 12px;
        line-height: 17.54px;
        text-align: center;
      "
    >
      By clicking the button above, you agree to <a href="https://www.dojah.io/policy" target="_blank" rel="noopener" style="text-decoration: underline; color: #1b2a4e"> Dojah's Privacy Policy </a>
    </p>
  </div>

  <script src="https://widget.dojah.io/widget.js"></script>
  <script>
    const customOptions = {
      app_id: 'YOUR APP ID GOES HERE',
      p_key: 'YOUR PUBLIC KEY GOES HERE',
      type: 'custom',
      metadata: {
        user_id: 'YOUR USERS_ID GOES HERE',
      },
      config: {
        widget_id: "YOUR WIDGET ID GOES IN HERE"
      },
      onSuccess: function (response) {
        window.flutter_inappwebview.callHandler('onSuccessCallback', response)
      },
       onError: function (err) {
                                        window.flutter_inappwebview.callHandler('onErrorCallback', error)
                                      },
                                      onClose: function () {
                                        window.flutter_inappwebview.callHandler('onCloseCallback', 'close')
                                      }
    };
    const connectCustom = new Connect(customOptions);
    const connectBtnCustom = document.querySelector('#custom-btn-connect');
    connectBtnCustom.addEventListener('click', function () {
      connectCustom.setup();
      connectCustom.open();
    });
  </script>
</body>

</html>
                  """
Enter fullscreen mode Exit fullscreen mode

There are other parameters that you can pass to the customOptions, you can find more here.

Step 8.

Now to pull everything together. In the build function, you now do the following.

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
      ),
      body: Padding(
        padding: EdgeInsets.symmetric(vertical: 16.0),
        child: Center(
          child: InAppWebView(
            initialOptions: options,
            initialUrlRequest:
                URLRequest(url: Uri.parse("https://widget.dojah.io")),
            initialData: InAppWebViewInitialData(
              data: data, // this is the variable we have created initially
              androidHistoryUrl: Uri.parse("https://widget.dojah.io"),
              mimeType: "text/html",
              baseUrl: Uri.parse("https://widget.dojah.io"),
            ),
            onWebViewCreated: (controller) {
              _webViewController = controller;

              _webViewController?.addJavaScriptHandler(
                handlerName: 'onSuccessCallback',
                callback: (response) {
                  success(response); // this function is called on a successful verification
                },
              );
_webViewController?.addJavaScriptHandler(
                  handlerName: 'onCloseCallback',
                  callback: (response) {
                    if (response.first == 'close') {
                      Navigator.pop(context);
                    }
                  },
                );

                _webViewController?.addJavaScriptHandler(
                  handlerName: 'onErrorCallback',
                  callback: (error) {
                    // call a function that you want here
                  },
                );
            },
            androidOnPermissionRequest: (controller, origin, resources) async {
              return PermissionRequestResponse(
                  resources: resources,
                  action: PermissionRequestResponseAction.GRANT);
            },
          ),
        ),
      ),
    );
  }

  // a function that closes the webview after a successful capture
  void success(arg) {
    // what do you want the webview to do after a
    // successful verification. In my case, I want to pop the 
    //webview
    Navigator.of(context).pop;
  }
Enter fullscreen mode Exit fullscreen mode

You can write other functions for when there is an error, or a close, as seen in the snippet above.

Thanks for you time, for more information on what you can achieve with Dojah, visit there documentation page

Top comments (0)