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
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
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;
});
}
}
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,
),
);
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>
"""
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;
}
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)