Flutter plug-mode integration

The Flutter plugin pattern essentially employs a client/server model. ZOLOZ supplies both Flutter plugins and server-side APIs, enabling you to integrate cross-platform Flutter applications with ZOLOZ services. This document introduces the ZOLOZ Flutter plugin integration methodology, encompassing aspects such as supported products, the integration architecture, interaction sequences, and the onboarding procedure.

Products supported

The app SDK-mode integration can be applied to the following products:

  • Real ID
  • Face Capture
  • ID recognition
  • Connect

Supported Hardware Platforms

The ZOLOZ Flutter plugin offers integration services targeting mobile apps and currently does not support desktop or web platforms. The supported hardware platforms are as follows:

  • Android
  • iOS

Integration architecture

The integration architecture diagram for the ZOLOZ Flutter plugin mode is illustrated as follows.

1.png

The ZOLOZ Flutter plugin integration model consists of the following two components:

  • Client-side integration: Integrate the ZOLOZ Flutter plugin into the merchant's mobile application. The plugin invokes the native ZOLOZ iOS/Android SDKs on both iOS and Android hardware platforms respectively, utilized for gathering user data such as facial images and identity document pictures.By incorporating the ZOLOZ Flutter plugin,you can easily create a friendly interaction experience for your users in terms of:
    • Sophisticated UI design that efficiently guides users through the entire business process.
    • Employment of multiple algorithms to ensure high success rates and robust security.
    • A streamlined process where images are directly uploaded to ZOLOZ services.
  • Server-side integration: Expose endpoints on the merchant's server side for the merchant's Flutter App, enabling interaction between the Flutter App and the merchant's server. Thereafter, initialize services via ZOLOZ APIs and conduct a dual verification of authentication results.

Interaction flow

The figure below introduces the complete interaction process of starting the ZOLOZ service through the Flutter App.

image.png

  1. The user initiates a business process through the merchant's Flutter App, such as identity verification.
  2. The merchant's Flutter App invokes the ZolozkitForFlutter.metaInfo property to obtain metadata about the ZOLOZ native SDK and the user's device.
  3. The ZOLOZ Flutter plugin returns this metadata to the merchant's Flutter App.
  4. The merchant's Flutter App initializes transaction details and relays the metadata to the merchant's server.
  5. After receiving the metadata, the merchant's server calls the initialize interface to fetch client configuration information, including SDK connectivity and behavioral parameters.
  6. Based on the metadata, the ZOLOZ server conducts an availability check; if successful, it sends the client configuration details back to the merchant's server.
  7. The merchant's server then passes this client configuration information back to the merchant's Flutter App.
  8. Utilizing the client configuration information, the merchant's Flutter App launches the ZOLOZ Flutter plugin.
  9. The ZOLOZ Flutter plugin invokes the ZOLOZ native SDK to interact with the user, collecting necessary data (e.g., facial images) and uploading it to the ZOLOZ server for validation. During this process, there may be multiple interactions between the native SDK and the ZOLOZ server.
  10. The ZOLOZ server examines the uploaded user data and reports the transaction status back to the ZOLOZ Flutter plugin.

If all checks are passed successfully, a result code indicating success is returned to the ZOLOZ Flutter plugin; otherwise, the process may be interrupted, necessitating further interaction between the user and the ZOLOZ Flutter plugin.

  1. The ZOLOZ Flutter plugin notifies the merchant Flutter App that the transaction is complete.
  2. The merchant Flutter App synchronizes with the merchant server, confirming the completion of the transaction, and initiates a dual verification of the transaction details.
  3. The merchant server calls the checkResult API to verify the transaction details again with the ZOLOZ server.
  4. The ZOLOZ server returns the transaction details to the merchant server.
  5. The merchant server filters the transaction details and returns non-sensitive information to the merchant Flutter App.

Note: To ensure information security, sensitive data such as captured facial images are only returned to the merchant server and not to the merchant Flutter App.

  1. The merchant Flutter App informs the user that the process is complete.

General integration process

Server-side integration

Prerequisites

Before performing the server-side integration, follow the instructions in Interact with the ZOLOZ gateway to ensure the ZOLOZ gateway service can be invoked successfully so that API requests and responses can be handled correctly.

Procedure

To enable the your (merchant) application to interact with the your (merchant) server and the merchant server to call the ZOLOZ APIs, you must expose endpoints for the merchant application in the merchant server. The following sample code uses Real ID APIs as an example to demonstrate how to expose endpoints for the merchant application by using annotation.

Note: The sample only demonstrates the processing logic that is needed for the merchant server to interact with the ZOLOZ server. You need to implement your business logic as required, for example:

  • When implementing the initialize API, save the transaction ID that is returned by the ZOLOZ server for the later retrieving purpose.
  • When implementing the checkResult API, save the transaction details, perform desensitisation, and return the desensitised information to your client side.
copy
// Use annotation to expose endpoints for the client application to consume
@RestController
//Define the common base path for the API endpoints
@RequestMapping(value = {"/webapi"})
public class NativeClientModeController {
    
    // Auto wire the openApiClient object that is provided by ZOLOZ for calling ZOLOZ     // APIs 
    @Autowired
    private OpenApiClient openApiClient;
    
    // Define the first service to map with the API URL path
    @RequestMapping(value = {"/realid/initialize"}, method = RequestMethod.POST)
    public JSONObject realIdInit(@RequestBody JSONObject request) {

        // Step 1: instantiate the request object and provide necessary parameters
        JSONObject apiReq = new JSONObject();   
        apiReq.put("flowType", "REALIDLITE_KYC");
        // apiReq.put("...","..."); Add more request parameters as required. For more         // information about the request parameters of the Real ID initialize API, see         // the correspoding API specification in the API reference chapter.
        
        // Step 2: call the ZOLOZ API through openApiClient
        String apiRespStr = openApiClient.callOpenApi(
                "v1.zoloz.realid.initialize",
                JSON.toJSONString(apiReq)
        );

        // Step 3: process the ZOLOZ API response and construct the return object
        JSONObject apiResp = JSON.parseObject(apiRespStr);
        JSONObject response = new JSONObject(apiResp);
        response.put("rsaPubKey", openApiClient.getOpenApiPublicKey());
        // ... more codes are omitted

        // Step 4: return the service response
        return response;
    }

    // Define more services as required, for example, for Real ID, you need to define     // a service to check the transaction results
    @RequestMapping(value = "/realid/checkresult", method = RequestMethod.POST)
    public JSONObject realIdCheck(@RequestBody JSONObject request) {

        // Implement the detailed logic to create a request and handle the response
    }
}

Examples of A Minimum Merchant's Server

ZOLOZ provides sample code of a simplified merchant server for different products. The sample code includes the minimum amount of code resources that are needed to interact with the ZOLOZ SaaS environment. The code is open sourced on Github.

Note: The merchant server code needs to work together with the demo apps provided by ZOLOZ. For more information about the demo apps, see App SDK-mode integration | ZOLOZ integration Guide.

API References

For more information about the APIs that are provided for each ZOLOZ product, see:

Client-side integration

SDK requirements

ZOLOZ offers plugin integration for the Flutter platform, with supported hardware platforms being Android and iOS. Client applications must meet the following requirements:

  • The client operating system version must be Android 4.3 or later, and iOS 9 or later.
  • For Android clients, the architecture must be armeabi, arm64-v8a, or armeabi-v7a, x86 architecture is not supported.
  • The Flutter version must be 2.0.0 or higher, and the Dart version must be 2.12.0 or higher, with support for the null safety language feature.

Importing the SDK

Add the ZOLOZ Flutter plugin as a dependency in the root directory pubspec.yaml file of the project.

copy
environment:
  sdk: '>=2.18.5 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  zolozkit_for_flutter: ^1.1.4
  ...

Instructions: The environment.sdk specifies the Dart language version, which must be 2.12.0 or higher.

Obtaining Metadata

Use the computed property metaInfo of the ZolozkitForFlutter class to retrieve metadata about the ZOLOZ native SDK and the user's device. This metadata is utilized for initializing transactions subsequently.

copy
var metaInfo = await ZolozkitForFlutter.metaInfo;

Initializing Transaction

The merchant mobile app sends a request containing the metadata to the merchant server to initialize the transaction. Subsequently, the merchant server invokes the initialize API to obtain the client configuration and returns it to the merchant mobile app.

Initiating Transaction Process

Invoke the start method using the constructed ZLZRequest object to commence the transaction process, and override callback functions to handle transaction outcomes.

copy
    var publicKey = await ZolozkitForFlutter.zolozPublicKey;
    await ZolozkitForFlutter.start(
      result['clientCfg'],
      {
        publicKey: result['rsaPubKey']
      },
      (String retCode, Map<Object?, Object?>? extInfo) {
        print("onInterrupted:$retCode, $extInfo");
      },
      (String retCode, Map<Object?, Object?>? extInfo) {
        print("onComplete:$retCode, $extInfo");
      },
    );

Transaction Results Contain Result Codes indicates the Transaction Flow Status, as Follows:

  • If the end-user has completed the entire interaction process, the onComplete method is invoked. The transaction status must be synchronized with the merchant server, and a double-check mechanism should be initiated. Following this, the merchant server calls the checkResult API to fetch transaction details and returns them to the merchant mobile app.
  • If the end-user does not complete the entire interaction process, the onInterrupted method is called, and relevant business logic should be implemented based on specific business requirements.

Configuring Custom UI (Optional)

Different mobile applications have distinct design aesthetics, including title bar styles, button styles, among others. To better align with your application's style, ZOLOZ supports simple UI customization configurations for specified components such as colors and text content.

Step One: Configure UI and Export Configuration File

Configure custom UI following the native App SDK model and export the configuration file locally. For the detailed operational, please refer to Step One in Customize UI for App SDK-mode products guide.

Step Two: Launch SDK with Configuration File

Integrate the configuration file generated in Step One with the ZOLOZ Flutter plugin, supporting both Android and iOS operating systems. The following section outlines how to initiate the ZOLOZ Flutter plugin using the custom UI configuration file.

Note: If you are not a client-side developer, please forward the configuration file to your client-side development team for setup.

  1. Save the file to your project folder (in this example, the path is files/UIConfig.zip, which you can modify to another path as needed). Then, amend your project's pubspec.yaml file to import the custom UI configuration file as an asset.
copy
dependencies:
  path_provider: ^2.0.15

flutter:
  assets:
  - files/UIConfig.zip
  1. Include code to copy assets to ZOLOZ and pass the configFilePath into the ZOLOZ Flutter plugin.
copy
import 'package:path_provider/path_provider.dart';
...

  Future<String> copyUIConfigFile() async {
    var file = await rootBundle.load("files/UIConfig.zip");
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String configFilePath = "${appDocDir.path}/UIConfig.zip";
    final buffer = file.buffer;
    await File(configFilePath).writeAsBytes(
        buffer.asUint8List(file.offsetInBytes, file.lengthInBytes));
    return configFilePath;
  }

  void startZoloz() async {
    ...
    var configPath = await ZolozkitForFlutter.zolozChameleonConfigPath;
    String configFilePath = await copyUIConfigFile();
    await ZolozkitForFlutter.start(
      result['clientCfg'],
      {
        publicKey: result['rsaPubKey'], 
        configPath: configFilePath
      },
      (String retCode, Map<Object?, Object?>? extInfo) {
        print("onInterrupted:$retCode, $extInfo");
      },
      (String retCode, Map<Object?, Object?>? extInfo) {
        print("onComplete:$retCode, $extInfo");
      },
    );

  }

Configuring Multilingual Support (Optional)

The UI configuration page of the ZOLOZ portal supports configuring multiple languages. To enable the ZOLOZ Flutter plugin to utilize one of these languages upon initialization, you need to specify the language information for the relevant parameters within the ZLZRequest object. The ZOLOZ Flutter plugin will then read the configuration file in the designated language and present it within your application.

For instance, if you have added Chinese (Simplified) (zh-CN) as a language on the UI configuration page and wish for the ZOLOZ Flutter plugin to utilize this language, you must assign the value to the ZolozkitForFlutter.zolozLocale parameter accordingly.

The value of the ZolozkitForFlutter.zolozLocale parameter must adhere to the format language-Country. For the specific values corresponding to each language option provided in the UI configuration page, refer to Locale related parameter value format | ZOLOZ integration Guide.

copy
    var configPath = await ZolozkitForFlutter.zolozChameleonConfigPath;
    var publicKey = await ZolozkitForFlutter.zolozPublicKey;
    var local = await ZolozkitForFlutter.zolozLocale;

    await ZolozkitForFlutter.start(
      result['clientCfg'],
      {
        publicKey: result['rsaPubKey'],
        configPath: configFilePath,
        local: "zh-CN"
      },
      (String retCode, Map<Object?, Object?>? extInfo) {
        print("onInterrupted:$retCode, $extInfo");
      },
      (String retCode, Map<Object?, Object?>? extInfo) {
        print("onComplete:$retCode, $extInfo");
      },
    );

Configuring ProGuard (Optional, Android Platform Only)

If you have enabled ProGuard in your Android application, to ensure successful invocation of the ZOLOZ Flutter plugin within your app, you need to modify two files:

  1. Add the following content to your android/app/build.gradle file:
copy
android {
    ...
    buildTypes {
        ...
        release {
            ...
            // add this line to the build.gradle file
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"                
        }
    }        
}
  1. In the obfuscation file android/app/proguard-rules.pro of your project, add the following configurations (if the proguard-rules.pro file does not exist, create it manually):
copy
-dontwarn com.zoloz.**
-keep class okio.* { *; }
-keep class com.zoloz.zhub.** { *; }
-keep class com.alipay.zoloz.** { *; }
-keep class com.zoloz.zcore.facade.common.** { *; }
-keep class com.alipay.android.phone.zoloz.** { *; }
-keep class com.alipay.biometrics.** { *; }
-keep class com.alipay.bis.** { *; }
-keep class com.alipay.mobile.security.** { *; }
-keep class com.ap.zoloz.** { *; }
-keep class com.ap.zhubid.endpoint.** { *; }
-keep class com.zoloz.android.phone.zdoc.** { *; }
-keep class zoloz.ap.com.toolkit.** { *; }
-keep class com.zoloz.builder.** { *; }
-keep class com.ant.phone.xmedia.** { *; }

#Deeper (NearX) rules
-keep class com.alipay.alipaysecuritysdk.** { *; }
-keep class com.alipay.blueshield.** { *; }
-keep class com.alipay.deviceid.** { *; }
-keep class com.alipay.edge.** { *; }
-keep class com.alipay.softtee.NativeHelper { *; }
-keep class com.alipay.apmobilesecuritysdk.tool.si.SIUtils { *; }