使用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插件模式的集成架构图如下所示。
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 App发起业务流程,例如身份验证。
- 商户Flutter App调用ZolozkitForFlutter.metaInfo属性,获取ZOLOZ原生SDK和用户设备的元信息。
- ZOLOZ Flutter插件将元信息返回给商户Flutter App。
- 商户Flutter App初始化交易信息并将元信息传递给商户服务端。
- 商户服务端获取到元信息后,调用
initialize
接口获取客户端配置信息,包括SDK连接和行为相关参数。 - ZOLOZ服务器根据元信息进行可用性检查,检查通过ZOLOZ服务器将客户端配置信息返回给商户服务端。
- 商户服务端将客户端配置信息返回给商户Flutter App。
- 商户Flutter App使用客户端配置信息启动ZOLOZ Flutter插件。
- ZOLOZ Flutter插件调用ZOLOZ原生SDK与用户交互,采集所需数据(例如人脸图片)并上传到ZOLOZ服务器进行验证。期间ZOLOZ原生SDK和ZOLOZ服务器之间可能会进行多次交互。
- ZOLOZ服务器检查上传的用户数据,并将交易状态返回给ZOLOZ Flutter插件。
如果所有检查均通过,则向ZOLOZ Flutter插件返回一个表示成功的结果码;否则该过程可能会中断,用户和ZOLOZ Flutter插件之间需要进一步交互。 - ZOLOZ Flutter插件通知商户Flutter App交易已完成。
- 商户Flutter App向商户服务端同步交易已完成,并开始对交易明细进行双重检查。
- 商户服务端调用
checkResult
接口与ZOLOZ服务器再次核对交易明细。 - ZOLOZ服务器将交易明细返回给商户服务端。
- 商户服务端过滤交易明细,并将非敏感信息返回给商户Flutter App。
说明:为了保证信息安全,采集到的人脸图片等敏感信息仅返回给商户服务端,不会返回给商户Flutter App。 - 商户Flutter App通知用户流程完成。
接入流程
服务端接入流程
前提条件
请确保已接入ZOLOZ网关,使ZOLOZ网关能够被正常调用,以便正确处理API请求和响应。接入ZOLOZ网关的操作,请参见接入ZOLOZ网关。
操作步骤
为了使商户Flutter App与商户服务端能够交互,以及商户服务端能够调用ZOLOZ API,您需要在商户服务端为商户Flutter App开放端点。本文以RealID API为例,介绍如何通过注解为商户Flutter App开放端点。
本示例仅展示商户服务端与ZOLOZ服务器交互所需的处理逻辑,在实际接入过程中,您需要根据具体业务需求来实现业务逻辑。例如:
- 调用
initialize
API时,可以保存ZOLOZ服务器返回的交易ID,便于后续查询使用。 - 调用
checkResult
API时,可以保存交易明细并对其进行脱敏,将脱敏后的信息返回给客户端。
// 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)语言特性。
操作步骤
- 导入SDK。
将ZOLOZ Flutter插件作为依赖项,添加到项目的根目录pubspec.yaml
中。
environment:
sdk: '>=2.18.5 <4.0.0'
dependencies:
flutter:
sdk: flutter
zolozkit_for_flutter: ^1.1.4
...
说明:environment.sdk为Dart语言版本,需≥2.12.0。
- 获取元信息。
使用ZolozkitForFlutter
类的计算属性MetaInfo
获取ZOLOZ原生SDK和用户设备的元信息,元信息用于后续初始化交易。
var metaInfo = await ZolozkitForFlutter.metaInfo;
- 初始化交易。
商户Flutter App向商户服务端发送包含元信息的请求来初始化交易,然后商户服务端调用initialize
API获取客户端配置并将其返回给商户Flutter App。 - 启动交易流程。
使用构建的ZLZRequest
对象调用start
方法来启动交易流程,并重写回调函数来处理交易结果。
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
方法,并根据具体的业务需求来实现相关的业务逻辑。
- 自定义配置UI(可选)。
不同的移动应用有不同的设计风格,例如标题栏风格、按钮风格等。为了更好地适应您的应用程序的风格,ZOLOZ支持对指定组件的颜色和文案进行简单的UI自定义配置。
- 配置UI并导出配置文件,操作流程请参见步骤一:配置UI并导出配置文件。
- 使用配置文件启动SDK。
将生成的配置文件与ZOLOZ Flutter插件集成,支持Android和iOS操作系统。下面为您介绍如何使用自定义UI配置文件启动ZOLOZ Flutter插件。
说明: 如果您不是客户端开发人员,请将配置文件发送给您的客户端开发人员进行配置。
- 将配置文件保存到项目的任意文件夹下,本文的保存路径为
files/UIConfig.zip
。
dependencies:
path_provider: ^2.0.15
flutter:
assets:
- files/UIConfig.zip
- 修改项目的
pubspec.yaml
文件,将自定义UI配置文件导入为assets。 - 添加以下代码启动SDK。
使用copyUIConfigFile()
将配置文件从assets中复制到App文件目录下,并在startZoloz()
中将复制的配置文件传入ZOLOZ Flutter插件中。
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");
},
);
}
- 配置多语言(可选)。
ZOLOZ门户的UI配置页面支持配置多语言,为了使ZOLOZ Flutter插件在启动时使用其中一种语言,您需要在ZLZRequest对象中为相关参数指定语言信息。ZOLOZ Flutter插件将以指定的语言读取配置文件,并将其呈现在您的应用中。
例如,您在UI配置页面添加的语言为Chinese(Simplified)(zh-CN)
,并希望ZOLOZ Flutter插件使用该语言,则需要指定ZolozkitForFlutter.zolozLocale参数的值。ZolozkitForFlutter.zolozLocale参数的取值必须为language-Country
格式。UI配置页面中提供的各个语言选项的取值,请参见语言相关的参数值格式。
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");
},
);
- 配置ProGuard(可选,仅Android硬件平台支持)。
如果您在Android应用中启用了ProGuard,为确保您的应用可以成功地调用ZOLOZ Flutter插件,需修改以下文件。
- 在
android/app/build.gradle
文件中添加以下内容。
android {
...
buildTypes {
...
release {
...
// add this line to the build.gradle file
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
}
- 在项目的
android/app/proguard-rules.pro
混淆文件中,添加以下配置。
说明:如果proguard-rules.pro
文件不存在,请先手动创建该文件。
-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 { *; }