Frontend Integration(H5)

For the solutionCodes that include our H5 frontend, client needs to embed our H5 Frontend into your APP first.

How To Integrate

1. Open URL in WebView

After calling the Generate URL API, there will be a url in the response body, and the App needs to open the URL in WebView.

2. Give Camera Permission

Android Webview

To allow Android Webview to visit camera, you need to override the onPermissionRequest method in your app:

private var mWebChromeClient: WebChromeClient = object : WebChromeClient() {

    override fun onPermissionRequest(request: PermissionRequest?) {

        //  IMPORTANT: Check host and adapt filter to allow camera access
        // e.g. if (request?.origin?.host == "xxx") {...}

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (context is BaseActivity) {
                if (ContextCompat.checkSelfPermission(
                        context,
                        Manifest.permission.CAMERA
                    ) == PackageManager.PERMISSION_GRANTED
                ) {
                    request?.grant(request.resources)
                } else {
                    context.requestPermission(Manifest.permission.CAMERA) { granted ->
                        if (granted) {
                            request?.grant(request.resources)
                        } else {
                            request?.deny()
                        }
                    }
                }
            }
        }
    }
}   

iOS Webview

To enable iOS Webview camera permission, you need the following adjustment:

  1. Inside info.plist file, set NSCameraUsageDescription to allow the app to access camera.
<key>NSCameraUsageDescription</key> 
<string>$(PRODUCT_NAME) need to use your rear camera</string>  
  1. Config Webview instance to allow inline media playback, disable user action for playback, enable JavaScript, and enable JavaScript to automatically open windows.
let configuration = WKWebViewConfiguration()
configuration.allowsInlineMediaPlayback = true
configuration.mediaTypesRequiringUserActionForPlayback = []
configuration.preferences.javaScriptEnabled = true
configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
self.webView = WKWebView(frame: self.view.bounds, configuration: configuration)
  1. Before entering H5 Identity Verification, check and request for camera access first.
// 请求相机权限(swift 样例代码)
// Request camera permission (in Swift)
func checkAVAuthorizationStatus(with block: @escaping((_ authed: Bool) -> Void)) {
    let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
    if authStatus == .authorized {
        block(true)
    } else if authStatus == .denied || authStatus == .restricted {
        block(false)
    } else {
        AVCaptureDevice.requestAccess(for: .video) { (result) in
            DispatchQueue.main.async {
                block(result)
            }
        }
    }
}

// Usage
// Check auth status before entering H5 Identity Verfication webpage.
self.checkAVAuthorizationStatus { authed in
  if authed {
    // Enter H5 webpage directly
  } else {
    // Logic to handle camera unauthorised.
  }
}
  1. (Optional) To avoid camera permission prompt in H5 every time.
// Make sure your ViewController inherits WKUIDelegate.
class ViewController: UIViewController, WKUIDelegate {
    ...

    // Only verified for iOS 15+
    @available(iOS 15.0, *)
    func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, type: WKMediaCaptureType, decisionHandler: @escaping (WKPermissionDecision) -> Void) {
        // NOTE: please add necessary security check like domain filter if needed.
        decisionHandler(.grant)
    }
}

self.webView.uiDelegate = self

Iframe Integration Guide

This section provides a comprehensive guide to integrating the AAI iframe into your application. It includes steps for embedding the iframe, handling events, and interpreting the event codes.


1. Enabling Iframe Mode

To enable iframe integration mode, you must configure the iframeEnabled parameter in the generateUrl API .

2. Embedding the Iframe

To integrate the iframe, include it in your HTML using the following structure:

 <iframe src="kyc-generated-url-here" allow="autoplay; camera;"></iframe>

3. Event Types and Codes

The iframe emits events to notify the parent application about workflow progress and completion. When the type is complete, the code field provides additional details about the outcome.

Below are the possible values of code and their corresponding meanings:

CodeDescription
DOCUMENT_AUTO_SCAN_TRY_COUNT_EXCEEDThe maximum number of document auto-scan attempts has been exceeded.
DOCUMENT_MANUAL_TRY_COUNT_EXCEEDThe maximum number of manual document attempts has been exceeded.
LIVENESS_TRY_COUNT_EXCEEDThe maximum number of liveness verification attempts has been exceeded.
LIVENESS_ATTACKA potential liveness attack has been detected.
SIMILARITY_FAILThe similarity check failed (e.g., face mismatch between document and liveness).

How to Use type and code

  1. Event Type (type):

    • When type is complete, the workflow has finished, and you should check the code field for details.
  2. Event Code (code):

    • Use the code value to identify the specific reason for the completion and take appropriate actions.

Example Implementation

Here is an example of how to handle type and code in your JavaScript application:

window.addEventListener('message', (event) => {
  const { type, code } = event.data;

  if (type === 'complete') {
    switch (code) {
      case 'SUCCESS':
        console.log('Ekyc complete successfuly.');
        break;
      case 'DOCUMENT_AUTO_SCAN_TRY_COUNT_EXCEED':
        console.warn('Document auto-scan try count exceeded.');
        break;
      case 'DOCUMENT_MANUAL_TRY_COUNT_EXCEED':
        console.warn('Document manual try count exceeded.');
        break;
      case 'LIVENESS_TRY_COUNT_EXCEED':
        console.warn('Liveness try count exceeded.');
        break;
      case 'LIVENESS_ATTACK':
        console.error('Liveness attack detected.');
        break;
      case 'SIMILARITY_FAIL':
        console.error('Similarity check failed.');
        break;
      default:
        console.info('Unknown completion code:', code);
        break;
    }
  }
});

Error handling

When an exception occurs blocking the process on the frontend, the frontend will be redirected to the failReturnUrl, carrying the errorCode=XXX, where the errorCode is one of the following enumerated values.

errorCodeDescription
BROWSER_ISSUENot supported due to compatibility issues
DOCUMENT_AUTO_SCAN_TRY_COUNT_EXCEEDDocument auto-scan try count exceeded the limit
DOCUMENT_MANUAL_TRY_COUNT_EXCEEDDocument manual photo try count exceeded the limit
NO_PERMISSIONNo camera permission
CAMERA_ISSUECamera issue error
RESELECT_DOC_TYPEUser clicked to reselect document type
LIVENESS_TRY_COUNT_EXCEEDLiveness detection try count exceeded the limit
NOT_SUPPORTBrowser not supported
LIVENESS_ATTACKThe liveness detection result < 50.0.

when ignoreFailWhenJump set to true, will jump to returnUrl instead.
SIMILARITY_FAILThe faceSimilarityScore < 70.0.
when ignoreFailWhenJump set to true, will jump to returnUrl instead.

Compatible Matrices

Supported browsers

Minimal browser versions with support for all features required by H5 Document Verification.

ChromeSafariEdgeOperaiOS SafariAndroid BrowserChrome for AndroidInternet Explorer
96159382158196Not supported

Sources: caniuse and WebAssembly Roadmap