Mobile web (H5)-mode integration

    #The Mobile Web SDK

    We provide a mobile Web SDK, which could be used in both iOS browser and android browser.


    Requirements

    • Minimum OS version supported: Android 5+, iOS 11+.
    • Permissions required: network  and camera.
    • Browser supported: iOS: Safari, Android:  recommended: chrome60+, firefox58+. For other browser in android, the behavior will be variable due to the different device.  



    #Integration Overview

    4EA5A129-6D23-4307-A548-0BA64173CEB6.png



    All h5-mode products involve 4 anticipants:

    • The merchant's server
    • The merchant's h5 page
    • ZOLOZ SaaS service
    • ZOLOZ mobile Web SDK


    The customer must fully understand the whole interaction sequence before any integration attempt.


    #Overall Sequence

    Mobile web (H5)-mode integration


    #Detailed Steps

    1. Start business. A user starts the process (e.g. eKYC process) in mobile h5.
    2. Initialize transaction. The mobile H5 sends initialization request to the merchant server.
    3. Initialize transaction. The merchant server calls ZOLOZ SaaS service to initialize the transaction of the product (such as RealId).
    4. Return initialize result and client config. ZOLOZ SaaS service completes transaction initialization and returns result as well as corresponding client configuration prepared for ZOLOZ Web SDK to the merchant server.
    5. Return initialize result and client config. The merchant server returns the initialization result and client configuration to mobile h5.
    6. Invoke with client config. The mobile h5 open ZOLOZ Web SDK url with client configuration.
    7. Capture user data and upload. ZOLOZ Web SDK starts to interact with the end-user, capture required data and then upload. There might be multiple rounds of interaction between ZOLOZ Web SDK and ZOLOZ server.
    8. Process complete. The process is completed and ZOLOZ server returns the process status to ZOLOZ Web SDK.
    9. Inform  completion with status. ZOLOZ Web SDK informs the completion of the process to the mobile h5.
    10. Inform completion. The mobile h5 informs the merchant server about the process completion.
    11. Check transaction details. The merchant server asks ZOLOZ SaaS service for transaction details.
    12. Return transaction details. ZOLOZ server returns details to the merchant server.
    13. Confirmed. The information from the mobile h5 is confirmed by the merchant server.
    14. Inform completion. The mobile h5 tells user that the  process is completed.



    #Server-side Integration

    The merchant's server need to provide proper endpoint for the merchant application to create a transaction, as well as fetch the final result of transaction. The request from the merchant application could be simply forwarded to ZOLOZ SaaS APIs.


    Similar with integrating APIs of server-mode products, ZOLOL API SDK helps a lot by easing the gateway protocol implementation. In this document we only demonstrate how to integrate with ZOLOZ API SDK.


    #1. Introduce API SDK

    Introduce the library into your project by adding following dependency in the POM file of your project

    copy
    <dependency>
        <groupId>com.zoloz.api.sdk</groupId>
        <artifactId>zoloz-api-sdk</artifactId>
        <version>0.1.0</version>
    </dependency>

    #2. Instantiate and Configure API SDK Client

    copy
    // initialize OpenApiClient
    String clientId = "<Client ID>";
    String zolozPublicKey = "<ZOLOZ's public key content encoded in base64>";
    String merchantPrivateKey = "<The merchant's private key content encoded in base64>";
    
    OpenApiClient client = new OpenApiClient();  // construct with signature and encryption by default
    client.setHostUrl("https://sg-production-api.zoloz.com");
    client.setClientId(clientId);
    client.setMerchantPrivateKey(merchantPrivateKey);
    client.setOpenApiPublicKey(zolozPublicKey);
    //client.setSigned(false);     // signature (of response) validation can be turned off
    //client.setEncrypted(false);  // encryption can be turned off

    #3. Expose Endpoint for Client Application

    copy
    @CrossOrigin
    @RestController
    public class H5ClientModeController {
    
        private static final Logger logger = LoggerFactory.getLogger(H5ClientModeController.class);
    
        @Autowired
        private OpenApiClient openApiClient;
    
        @Autowired
        private RealIdConfig realIdConfig;
    
        @RequestMapping(value = "/api/realid/h5initialize", method = RequestMethod.POST)
        public JSONObject h5RealIdInit(@RequestBody JSONObject request) {
    
            logger.info("request=" + request);
    
            String metaInfo = "MOB_H5";
    
            String businessId = "dummy_bizid_" + System.currentTimeMillis();
            String userId = "dummy_userid_" + System.currentTimeMillis();
    
            JSONObject apiReq = new JSONObject();
            apiReq.put("bizId", businessId);
            apiReq.put("flowType", "H5_REALIDLITE_KYC");
    
            if(request.getString("docType")==null){
                apiReq.put("docType", realIdConfig.getDocType());
            }else{
                apiReq.put("docType", request.getString("docType"));
            }
    
            Map<String, String> h5ModeConfig = new HashMap<>();
            if (request.getJSONObject("h5ModeConfig") != null) {
                h5ModeConfig.put("completeCallbackUrl", request.getJSONObject("h5ModeConfig").getString("completeCallbackUrl"));
                h5ModeConfig.put("interruptCallbackUrl", request.getJSONObject("h5ModeConfig").getString("interruptCallbackUrl"));
            } else {
                h5ModeConfig.put("completeCallbackUrl", "https://zasia.oss-cn-beijing.aliyuncs.com/dev/web-ekyc-realid/index.html#/result");
                h5ModeConfig.put("interruptCallbackUrl", "https://zasia.oss-cn-beijing.aliyuncs.com/dev/web-ekyc-realid/index.html#/result");
            }
    
            Map<String, String> pageConfig = new HashMap<>();
            if (request.getJSONObject("pageConfig") != null && request.getJSONObject("pageConfig").getString("urlFaceGuide") != null) {
                pageConfig.put("urlFaceGuide", request.getJSONObject("pageConfig").getString("urlFaceGuide"));
            }
    
            //apiReq.put("pages", "1");
            apiReq.put("metaInfo", metaInfo);
            apiReq.put("userId", userId);
            if(StringUtils.isNotBlank(realIdConfig.getServiceLevel())){
                apiReq.put("serviceLevel",realIdConfig.getServiceLevel());
            }
    
            apiReq.put("h5ModeConfig",h5ModeConfig);
            apiReq.put("pageConfig",pageConfig);
    
            String apiRespStr = openApiClient.callOpenApi(
                    "v1.zoloz.realid.initialize",
                    JSON.toJSONString(apiReq)
            );
            JSONObject apiResp = JSON.parseObject(apiRespStr);
            JSONObject response = new JSONObject(apiResp);
            response.put("transactionId", apiResp.getString("transactionId"));
            response.put("clientCfg", apiResp.getString("clientCfg"));
            logger.info("response=" + apiRespStr);
    
            return response;
        }
        
        @RequestMapping(value = "/api/realid/checkresult", method = RequestMethod.POST)
        public JSONObject realIdCheck(@RequestBody JSONObject request) {
    
            logger.info("request=" + request);
    
            String businessId = "dummy_bizid_" + System.currentTimeMillis();
            String transactionId = request.getString("transactionId");
            String isReturnImage = request.getString("isReturnImage");
    
            JSONObject apiReq = new JSONObject();
            apiReq.put("bizId", businessId);
            apiReq.put("transactionId", transactionId);
            apiReq.put("isReturnImage", isReturnImage);
    
            String apiRespStr = openApiClient.callOpenApi(
                    "v1.zoloz.realid.checkresult",
                    JSON.toJSONString(apiReq)
            );
    
            JSONObject apiResp = JSON.parseObject(apiRespStr);
    
            JSONObject response = new JSONObject(apiResp);
            return response;
        }
        
        


    Refer to RealId API specification for more information.


    #H5-side Integration

    #1. Invoke ZOLOZ Web SDK

    When mobile h5 get the clientcfg from server side,  mobile h5 could invoke ZOLOZ Web SDK as followed:

    copy
    var baseurl = "https://*****.html";
    var zolozurl = baseurl + "?clientcfg=encodeURIComponent(clientcfg)";
    
    // redirect the url 
    window.location.href = zolozurl;
    
    // or open in a fullscreen iframe
    <iframe src="zolozurl" allow="microphone;camera;midi;encrypted-media;" allowusermedia width="100%" height="100%"></iframe>
    • baseurl is the ZOLOZ Web SDK url;

    RealId: https://sg-production-cdn.zoloz.com/page/zoloz-realid-fe/index.html

    FaceCapture: https://sg-production-cdn.zoloz.com/page/zoloz-face-fe/index.html

    IdRecognition: https://sg-production-cdn.zoloz.com/page/zoloz-doc-fe/index.html

    • ZOLOZ server will return clientcfg to merchant server;
    • Callback url, face guide url and other parameters could be configed  in merchant init, please refer to RealId API specification for more information.


    #2. ZOLOZ Callback

    When ZOLOZ Web SDK finished, a response will be given by callbackurl or postMessage as followed:

    copy
    var callbackurl = "https://*****.html";
    var response = {
      state:'*****',        // biz state, it is parsed from clientcfg
      code:1000,                // 1000 - complete, 1003 - interrupt
      subCode:'Z****',  // Z code
      extInfo:{}                // parameters for extension
    };
    
    // callback the url if user open web sdk by redirecting
    window.location.replace = callbackurl+'?response=encodeURICompnent(JSON.stringfy(response))';
    
    // postmessage if user open web sdk in iframe
    window.parent.postMessage(response, '*');
    • callbackurl will be completeCallbackUrl if ZOLOZ Web SDK is completed, it will be interruptCallbackUrl if ZOLOZ Web SDK is interrupted. completeCallbackUrl and interruptCallbackUrl are parsed from clientcfg and they could be configed  in merchant init, please refer to RealId API specification for more information.
    • In iframe mode, user could receive the response as followed:
    copy
        window.addEventListener('message', (event) => {
          const response = event.data;
          console.log('response:', response);
        });


    #3. Customize face guide url

    A default face guide url is provided, if want to change the ui or add more language, the face guide url could be customized.


    ZOLOZ Web SDK will open the face guide url in fullscreen iframe:

    copy
    <iframe src="iframeSrc" width='100%' height='100%'/>
    • iframeSrc will be the face guide url, which is parsed from clientcfg and it could be configed in merchant init, please refer to RealId API specification for more information.


    Please post a message when click next to process the workflow:

    copy
    window.parent.postMessage('next','*');


    #Examples

    Check open-sourced examples in our Github repository: