使用Flutter插件模式接入

Flutter插件模式即客户端/服务器模式。ZOLOZ提供了Flutter插件和服务端API,以便您将跨平台Flutter App接入ZOLOZ服务。本文从支持的产品、集成架构、交互流程和接入流程等方面对ZOLOZ Flutter插件接入模式进行介绍。

ZOLOZ Flutter插件库,请参见zolozkit_for_flutter

支持的产品

Flutter插件接入模式支持以下产品:

  • RealID
  • Face Capture
  • ID Recognition
  • Connect

支持的硬件平台

ZOLOZ Flutter插件以移动App为目标提供接入服务,目前不支持桌面和Web平台,支持的硬件平台如下:

  • Android
  • iOS

集成架构

ZOLOZ Flutter插件模式的集成架构图如下所示。

image.png

ZOLOZ Flutter插件模式集成包括以下两部分:

  • 客户端接入
    将ZOLOZ Flutter插件集成到商户Flutter App中。ZOLOZ Flutter插件在iOS和Android硬件平台分别调用ZOLOZ原生iOS SDK、Android SDK来采集用户数据,例如人脸图片、证件图片等。
    通过集成ZOLOZ Flutter插件,您可以在以下方面为终端用户提供友好的交互体验。
    • 巧妙的UI设计,能够引导用户快速完成整个业务流程。
    • 采用多种算法,保证高成功率和高安全性。
    • 接入过程简单,直接将图片上传到ZOLOZ服务即可。
  • 服务端接入
    在商户服务端为商户Flutter App开放端点,使商户Flutter App与商户服务端能够进行交互,然后通过ZOLOZ API初始化业务,并对校验结果进行双重检查。

交互流程

下图介绍了通过Flutter App启动ZOLOZ服务的完整交互流程。

使用Flutter插件模式接入
  1. 用户通过商户Flutter App发起业务流程,例如身份验证。
  2. 商户Flutter App调用ZolozkitForFlutter.metaInfo属性,获取ZOLOZ原生SDK和用户设备的元信息。
  3. ZOLOZ Flutter插件将元信息返回给商户Flutter App。
  4. 商户Flutter App初始化交易信息并将元信息传递给商户服务端。
  5. 商户服务端获取到元信息后,调用initialize接口获取客户端配置信息,包括SDK连接和行为相关参数。
  6. ZOLOZ服务器根据元信息进行可用性检查,检查通过ZOLOZ服务器将客户端配置信息返回给商户服务端。
  7. 商户服务端将客户端配置信息返回给商户Flutter App。
  8. 商户Flutter App使用客户端配置信息启动ZOLOZ Flutter插件。
  9. ZOLOZ Flutter插件调用ZOLOZ原生SDK与用户交互,采集所需数据(例如人脸图片)并上传到ZOLOZ服务器进行验证。期间ZOLOZ原生SDK和ZOLOZ服务器之间可能会进行多次交互。
  10. ZOLOZ服务器检查上传的用户数据,并将交易状态返回给ZOLOZ Flutter插件。
    如果所有检查均通过,则向ZOLOZ Flutter插件返回一个表示成功的结果码;否则该过程可能会中断,用户和ZOLOZ Flutter插件之间需要进一步交互。
  11. ZOLOZ Flutter插件通知商户Flutter App交易已完成。
  12. 商户Flutter App向商户服务端同步交易已完成,并开始对交易明细进行双重检查。
  13. 商户服务端调用checkResult接口与ZOLOZ服务器再次核对交易明细。
  14. ZOLOZ服务器将交易明细返回给商户服务端。
  15. 商户服务端过滤交易明细,并将非敏感信息返回给商户Flutter App。
    说明:为了保证信息安全,采集到的人脸图片等敏感信息仅返回给商户服务端,不会返回给商户Flutter App。
  16. 商户Flutter App通知用户流程完成。

接入流程

服务端接入流程

前提条件

请确保已接入ZOLOZ网关,使ZOLOZ网关能够被正常调用,以便正确处理API请求和响应。接入ZOLOZ网关的操作,请参见接入ZOLOZ网关

操作步骤

为了使商户Flutter App与商户服务端能够交互,以及商户服务端能够调用ZOLOZ API,您需要在商户服务端为商户Flutter App开放端点。本文以RealID API为例,介绍如何通过注解为商户Flutter App开放端点。

本示例仅展示商户服务端与ZOLOZ服务器交互所需的处理逻辑,在实际接入过程中,您需要根据具体业务需求来实现业务逻辑。例如:

  • 调用initialize API时,可以保存ZOLOZ服务器返回的交易ID,便于后续查询使用。
  • 调用checkResult API时,可以保存交易明细并对其进行脱敏,将脱敏后的信息返回给客户端。
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
    }
}

集成示例

针对不同的产品,ZOLOZ提供了一个简化版商户服务端的代码示例。代码示例中包含了与ZOLOZ SaaS环境交互所需的最基本的代码资源,且代码示例已开源,您可以在Github中获取。

注意:商户服务端代码需要与ZOLOZ提供的Demo配合使用。有关Demo的更多信息,请参见代码示例

相关API

单击下方链接,可查看ZOLOZ相关产品的服务端API。

客户端接入流程

前提条件

ZOLOZ提供插件方式接入Flutter平台,支持的硬件平台为Android和iOS,客户端必须满足以下要求:

  • 客户端操作系统版本必须为Android 4.3及以上版本,iOS 9及以上版本。
  • Android客户端的架构必须为armeabi、arm64-v8a、armeabi-v7a,不支持x86架构。
  • Flutter版本需≥2.0.0,Dart版本需≥2.12.0,支持空安全(null safety)语言特性。

操作步骤

  1. 导入SDK。
    将ZOLOZ Flutter插件作为依赖项,添加到项目的根目录pubspec.yaml中。
copy
environment:
  sdk: '>=2.18.5 <4.0.0'

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

说明:environment.sdk为Dart语言版本,需≥2.12.0。

  1. 获取元信息。
    使用ZolozkitForFlutter类的计算属性MetaInfo获取ZOLOZ原生SDK和用户设备的元信息,元信息用于后续初始化交易。
copy
var metaInfo = await ZolozkitForFlutter.metaInfo;
  1. 初始化交易。
    商户Flutter App向商户服务端发送包含元信息的请求来初始化交易,然后商户服务端调用initialize API获取客户端配置并将其返回给商户Flutter App。
  2. 启动交易流程。
    使用构建的ZLZRequest对象调用start方法来启动交易流程,并重写回调函数来处理交易结果。
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");
      },
    );

交易结果中包含标识交易流状态的结果码,具体如下:

    • 如果终端用户已完成整个交互流程,则调用onComplete方法,交易状态需要与商户服务端同步,并且需要启动双重检查。然后商户服务端调用checkResult API获取交易详情并将其返回给商户Flutter App。
    • 如果终端用户未完成整个交互流程,则调用onInterrupted方法,并根据具体的业务需求来实现相关的业务逻辑。
  1. 自定义配置UI(可选)。
    不同的移动应用有不同的设计风格,例如标题栏风格、按钮风格等。为了更好地适应您的应用程序的风格,ZOLOZ支持对指定组件的颜色和文案进行简单的UI自定义配置。
    1. 配置UI并导出配置文件,操作流程请参见步骤一:配置UI并导出配置文件
    2. 使用配置文件启动SDK。
      将生成的配置文件与ZOLOZ Flutter插件集成,支持Android和iOS操作系统。下面为您介绍如何使用自定义UI配置文件启动ZOLOZ Flutter插件。
      说明: 如果您不是客户端开发人员,请将配置文件发送给您的客户端开发人员进行配置。
      1. 将配置文件保存到项目的任意文件夹下,本文的保存路径为files/UIConfig.zip
copy
dependencies:
  path_provider: ^2.0.15

flutter:
  assets:
  - files/UIConfig.zip
      1. 修改项目的pubspec.yaml文件,将自定义UI配置文件导入为assets。
      2. 添加以下代码启动SDK。
        使用copyUIConfigFile()将配置文件从assets中复制到App文件目录下,并在startZoloz()中将复制的配置文件传入ZOLOZ Flutter插件中。
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");
      },
    );

  }
    1. 配置多语言(可选)。
      ZOLOZ门户的UI配置页面支持配置多语言,为了使ZOLOZ Flutter插件在启动时使用其中一种语言,您需要在ZLZRequest对象中为相关参数指定语言信息。ZOLOZ Flutter插件将以指定的语言读取配置文件,并将其呈现在您的应用中。
      例如,您在UI配置页面添加的语言为Chinese(Simplified)(zh-CN),并希望ZOLOZ Flutter插件使用该语言,则需要指定ZolozkitForFlutter.zolozLocale参数的值。ZolozkitForFlutter.zolozLocale参数的取值必须为language-Country格式。UI配置页面中提供的各个语言选项的取值,请参见语言相关的参数值格式
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");
      },
    );
  1. 配置ProGuard(可选,仅Android硬件平台支持)。
    如果您在Android应用中启用了ProGuard,为确保您的应用可以成功地调用ZOLOZ Flutter插件,需修改以下文件。
    1. android/app/build.gradle文件中添加以下内容。
copy
android {
    ...
    buildTypes {
        ...
        release {
            ...
            // add this line to the build.gradle file
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"                
        }
    }        
}
    1. 在项目的android/app/proguard-rules.pro混淆文件中,添加以下配置。
      说明:如果proguard-rules.pro文件不存在,请先手动创建该文件。
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)相关
-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 { *; }