文档中心 > K12一脸通行解决方案IoT端侧Smile接口

封闭云端场景-人脸app接入(慎用,仅在蚂蚁同学的指导下使用)

更新时间:2021/05/06 访问次数:315

注意事项

  1. 接入方自动化测试/压测时,切记在人脸初始化时(install)把deviceNum设置成TEST,避免影响线上数据。上线时改回正式的deviceNum(参考3.1节第二步mockMerchantInfo):
merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_DEVICE_NUM, "TEST");
  1. smile版本使用4.9.3.699
  2. isv通过服务端调用刷脸接口前需要通过蚂蚁开放平台完成“刷脸付”签约(蚂蚁开放平台小程序无法签约“刷脸付”需要创建 网页&应用 去签约“刷脸付”)

   



1、整体流程

image.png

  1. 机具端业务方app启动时,调用刷脸SDK接口(getMetaInfo)获取当前刷脸所需的设备信息。getMetaInfo需要的入参包括partnerId等参数。
  2. 获取authToken:业务方app把步骤1中metaInfo上传到服务端,业务方服务端调用开放接口

   (zoloz.authentication.customer.smilepay.initialize)进行刷脸初始化和获取authToken。如果刷脸初始化成

    功,会返回刷脸调用的标识authToken(本地可保存,方便有效期内多次使用),该参数将作为下一步中进行人

    脸sdk初始化接口的入参。如果刷脸不可用,商户可对用户进行友好的提示,或者建议用户使用其他非人脸的

    支付方式(如扫码支付)。

    注:

    1)上面第1、2步主要是获取authToken,如果业务方app已获取authToken且在有效期内,第1、2步可跳过

    2)authToken有效期为24小时(时长可配置),有效期内可重复使用建议获取authToken的时机

        --未获取过authToken、或已经失效,需重新执行第1、2步获取新的authToken

        --如果机具处于联网状态,业务方app可在每次冷启动时获取最新的authToken

  1. 初始化人脸sdk:调用人脸SDK接口(install)传入partnerId、authToken、groupId、verifyMode等参数进行人脸sdk初始化。可调用脸SDK接口(register)进行初始化完成的监听。

    注:

    1)install是初始化接口,只需在业务方app刚启动人脸sdk或者人脸sdk服务端断开时调用(3.5节)

    2)对于不关心“install初始化完成时机”的场景,可以不调用register监听。

  1. 业务方app调用人脸脸SDK接口(speedyVerify)唤起人脸采集页面并进行人脸识别过程,最终返回人脸识别的结果。如果识别成功,会返回当前用户的支付宝账号信息(ftoken/uid,如果用户不存在uid,返回outerFaceId

    注意:刷脸上传时必须传入:groupId、serviceId和verifyMode三个参数

    • groupId:在入库时填写的groupId,用于指定检索学校
    • serviceId:固定为group
    • verifyMode: 固定为VerifyMode.ENCLOSED_REMOTE_VERIFY
  1. 业务方根据返回的人脸结果,执行业务逻辑。


2、依赖包和刷脸应用

1、业务方客户端需集成api**.aar文件,调用见《5、调用示例》。

2、机具上安装zoloz刷脸app(根据摄像头类型(2d或者3d)选择安装对应摄像头版本的刷脸apk)。

上述集成的aar和刷脸app从项目临客蚁上获取,由版本负责人@从彦统一管理。


3、API说明

3.1 初始化人脸sdk

 /**  * 初始化人脸应用  *  * @param params 扩展参数,参数key为:  * {@link #MERCHANT_INFO_DEVICE_NUM}, 值类型为String,必填项  * {@link ZolozConstants#KEY_MERCHANT_INFO_ISV_NAME},值类型为String,必填项  * {@link ZolozConstants#KEY_MERCHANT_INFO_PARTNER_ID},值类型为String,必填项  * {@link ZolozConstants#KEY_MERCHANT_INFO_MERCHANT_ID},值类型为String,必填项  * {@link ZolozConstants#KEY_MERCHANT_INFO_MERCHANT_NAME},值类型为String,必填项  * {@link ZolozConstants#KEY_GROUP_ID},值类型为String,必填项  * {@link ZolozConfig#KEY_VERIFY_MODE},值类型为String,必填项  * {@link ZolozConstants#KEY_AUTH_TOKEN},值类型为String,必填项  * {@link #MERCHANT_INFO_STORE_CODE}, 值类型为String,可选项  * {@link #MERCHANT_INFO_ALIPAY_STORE_CODE}, 值类型为String,可选项  * @param callback 回调接口  */  public void install(Map<String, Object> extInfo)


参数说明:

字段

参数

是否必填

具体说明

info

Map

必传参数(key定义参考ZolozConstants):
deviceNum:商户机具终端编号

partnerId:支付宝开发平台分配的isv pid
isvName:isv名称

merchantId:商户id(比如:学校:外标,景区:机构代码)
merchantName:商户name(比如:学校/景区名称)

groupID:人脸库ID

verifyMode:设置为VerifyMode.ENCLOSED_REMOTE_VERIFY

authToken:业务方授权token,调用服务端“人脸初始化”接口获取


3.2 监听初始化

 /**  * 监听初始化状态  *  * @param params 扩展用,可传空  * @param callback 回调接口  */  public void register(Map<String, Object> extInfo, InstallCallback callback) 

参数说明:

字段

参数

是否必填

具体说明

extInfo

Map

扩展用,目前未用到,可传空

callback

InstallCallback

返回install初始化成功或者失败


InstallCallback参数:

/**  * Install回调函数  */ public abstract class InstallCallback {  /**  * 初始化结果回调函数  *  * @param smile2PayResponse 回调response,{@link Smile2PayResponse}  */  public abstract void onResponse(Smile2PayResponse smile2PayResponse);  /**  * 初始化事件错误event回调  *  * @param code event code  * @param message event message  */  public void onEvent(int code, String message) {  Log.w(TAG, "onEvent(): code=" + code + ", message=" + message);  } }


onResponse回调返回smile2PayResponse,涉及的重要参数如下:

字段

类型

具体说明

code

int

取值如下:

  • Smile2PayResponse.CODE_SUCCESS: install成功
  • 其他值:失败

mExtInfo

Map<String, Object>

本地模式时,map中包括详细失败原因(FeatureResult),获取方式参考《3、调用示例》


onEvent回调code说明:

 /**  * rpc异常下载失败  */  public static final int EVENT_CODE_NET_ERROR = -1;  /**  * rpc异常下载失败  */  public static final int EVENT_CODE_SERVER_ERROR = -2;  /**  * 客户端内部错误:例如:startService失败等  */  public static final int EVENT_CODE_CLIENT_INNER_ERROR = -3;  /**  * IO异常  */  public static final int EVENT_CODE_IO_ERROR = -4;  /**  * 无存储权限  */  public static final int EVENT_CODE_NO_PERMISSION = -5;  /**  * 客户端版本过低:服务端不支持太低的特征版本号  */  public static final int EVENT_CODE_CLIENT_NOT_SUPPORT = -6;  /**  * 服务端下发的,人脸特征文件为空  */  public static final int EVENT_CODE_GROUP_ABNORMAL = -7;


3.3 获取设备信息

 /**  * 获取metaInfo  *  * @param params 扩展参数  * params参数设置同install接口  * @param metaInfoCallback 回调接口  */  public void getMetaInfo(final Map<String, Object> params,  final MetaInfoCallback metaInfoCallback)


参数说明:

字段

参数

是否必填

具体说明

info

Map

参数设置同install接口(去掉install中的authToken设置)

metaInfoCallback

MetaInfoCallback

onMetaInfo返回metaInfo和失败原因
获取失败时,metaInfo为null,extInfo包含具体失败原因


3.4 唤起刷脸

 /**  * 以去zim初始化的方式调起人脸验证  * @param params 扩展参数,参数key为:  * {@link ZolozConfig#SERVICE_ID}, 值类型为String,必填项  * {@link ZolozConfig#MERCHANT_APP_ID}, 值类型为String,必填项  * {@link ZolozConfig#KEY_VERIFY_MODE},值类型为String,必填项  * {@link ZolozConfig#SERVICE_PARAMS}, 值类型为String,选填项  * {@link ZolozConfig#SOURCE}, 值类型为String,选填项  * {@link #KEY_SMILE_MODE}, 值类型为int。用于选择刷脸模式:  * 目前值可以为{@link #SMILE_MODE_DEFAULT_DISPLAY}:主屏幕显示  * 和{@link #SMILE_MODE_EXT_DISPLAY}:副屏幕显示  * 可选项,默认值为{@link #SMILE_MODE_DEFAULT_DISPLAY}。  * @param verifyCallback 人脸验证回调接口{@link VerifyCallback}  */  public void speedyVerify(final Map<String, Object> params,  final VerifyCallback verifyCallback) 


参数说明:

字段

参数

是否必填

具体说明

serviceId

String

设置为SERVICE_ID_GROUP,定义参考:ZolozConfig.ServiceId定义

appId

String

商户开放平台上的应用id,商户指直接签约刷脸服务的商户

来自蚂蚁开发平台

verifyMode

int

设置为VerifyMode.ENCLOSED_REMOTE_VERIFY

verifyCallback

VerifyCallback

onResponse返回的结果


3.5 返回刷脸结果

verify刷脸onResponse(VerifyCallback)中返回的参数是Smile2PayResponse,定义如下:

public class Smile2PayResponse {  /**  * 人脸验证成功  */  public static final int CODE_SUCCESS = 1000;  /**  * 人脸验证过程被中断  */  public static final int CODE_INTERNAL_ERROR = 1001;  /**  * 人脸验证过程被用户取消操作  */  public static final int CODE_CANCEL_BY_USER = 1003;  /**  * 人脸验证过程,用户操作超时  */  public static final int CODE_TIMEOUT_BY_USER = 1004;  /**  * 人脸验证过程,用户重试次数过多,选择其他支付方式  */  public static final int CODE_CHOOSE_OTHER_PAYMENT = 1005;  /**  * 人脸验证失败  */  public static final int CODE_VERIFY_FAIL = 2006;   /**  * result code  */  private int mCode;  /**  * face token  */  private String mFaceToken;  /**  * sub code  */  private String mSubCode;  /**  * sub message  */  private String mSubMsg;  /**  * alipay user id  */  private String mAlipayUid;  /**  * ext info  */  private final Map<String, Object> mExtInfo = new HashMap<String, Object>();


参数说明:

字段

参数

具体说明

mCode

int

刷脸是否成功

CODE_SUCCESS:成功

CODE_CHOOSE_OTHER_PAYMENT:其他支付方式

mAlipayUid

String

支付宝uid,刷脸成功时有效

mFaceToken

String

刷脸ftoken,可用于交易,刷脸成功时有效

mSubCode
mSubMsg

String

失败详细原因,刷脸失败时有效

mExtInfo

Map<String, Object>

刷脸返回的其他信息


3.6 退出

/**  * 主动退出刷脸  *  * @param params 参考{@link CommandCode}  */ public void command(final Map<String, Object> params)


CommandCode定义如下:

public static final class CommandCode {  /**  * 退出刷脸  */  public static final int EXIT = 0; }

使用方式参考《4、调用示例》


4、调用示例

第一步:获取Zoloz实例

import com.alipay.zoloz.smile2pay.Zoloz;  mZoloz = Zoloz.getInstance(getApplicationContext());


第二步:获取设备信息

mZoloz.getMetaInfo(mockMerchantInfo1(), new MetaInfoCallback() {  // 解析zolozGetMetaInfo返回的结果,如果成功,则请求商户服务端调用人脸初始化接口  @Override  public void onMetaInfo(String metaInfo, Map<String, Object> extInfo) {  Log.d(TAG, "meta info is:" + metaInfo);  //获取metainfo成功  if (TextUtils.isEmpty(metaInfo)) {  Log.e(TAG, "metainfo is null");  } else {  Log.i("zolozTime", "smiletopay init zimid begin");  // 将metaInfo发送给商户服务端,由商户服务端发起刷脸初始化OpenAPI的调用  // 参考下面第四步  }     /**  * mock数据,真实商户请填写真实信息.  */  private Map mockMerchantInfo1() {  Map merchantInfo = new HashMap();  //以下信息请根据真实情况填写  //商户 Pid  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_MERCHANT_ID, merchantId);  // 必填项,商户名称  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_MERCHANT_NAME, merchantName);  //ISV PID  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_PARTNER_ID, partnerId);  // 必填项,ISV 名称  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_ISV_NAME, isvName);  // 必填项,逻辑库ID  merchantInfo.put(ZolozConstants.KEY_GROUP_ID, groupID);  // 必填项,比对模式  merchantInfo.put(ZolozConfig.KEY_VERIFY_MODE, verifyMode);  // 必填项,商户机具终端编号  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_DEVICE_NUM, deviceNum);   return merchantInfo; }


第三步:获取authToken

调用服务端接口zoloz.authentication.customer.smilepay.initialize 完成刷脸可用性逻辑判断及获取authToken,该接口为开放平台接口,需要商户的服务端进行调用。代码示例如下:

[注意:该接口获取的authToken有时效性,建议每24小时调用一次获取新的authToken]

//正式接入请上传metaInfo到服务端,不要忘记UrlEncode,使用服务端使用的sdk从服务端访问openapi获取zimId和zimInitClientData; AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", appId, appKey, "json", "utf-8", alipay_public_key,"RSA2");  ZolozAuthenticationCustomerSmilepayInitializeRequest request  = new ZolozAuthenticationCustomerSmilepayInitializeRequest();  // zolozGetMetaInfo接口返回的metainfo对象中加入业务参数 JSONObject zimmetainfo = JSON.parseObject(metaInfo); JSONObject merchantInfo = zimmetainfo.getJSONObject("merchantInfo"); merchantInfo.put("pay_amount", "订单金额");//可选,支付币种订单金额,值为double类型 merchantInfo.put("pay_currency", "CNY");//可选,支付币种,目前仅支持 人民币:CNY merchantInfo.put("merchantId", "2088402007521092");//商户在开放平台上的partnerId merchantInfo.put("appId", "XXXX");//商户在开放平台上的应用Id //设置需要获取authToken的标 JSONObject serviceParams = new JSONObject(); serviceParams.put("authCheck", "true"); zimmetainfo.put("serviceParams", serviceParams.toJSONString());  request.setBizContent(zimmetainfo.toJSONString());  //起一个异步线程发起网络请求 alipayClient.execute(request,new AlipayCallBack() {  @Override  public AlipayResponse onResponse(AlipayResponse response) {  if (response != null && SMILEPAY_CODE_SUCCESS.equals(response.getCode())) {  try {  ZolozAuthenticationCustomerSmilepayInitializeResponse zolozResponse  = (ZolozAuthenticationCustomerSmilepayInitializeResponse)response;   String authToken = zolozResponse.getAuthToken();  // 人脸调用  .....  } catch (Exception e) {  promptText(TXT_OTHER);  }  } else {  promptText(TXT_OTHER);  }  return null;  } });

注:接口和参数使用说明请参考OpenApi说明文档。


第四步:初始化人脸sdk

import com.alipay.zoloz.smile2pay.ZolozConstants;  mZoloz.install(mockMerchantInfo2());  /**  * mock数据,真实商户请填写真实信息.  */ private Map mockMerchantInfo2() {  Map merchantInfo = new HashMap();  //以下信息请根据真实情况填写  //商户 Pid  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_MERCHANT_ID, merchantId);  // 必填项,商户名称  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_MERCHANT_NAME, merchantName);  //ISV PID  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_PARTNER_ID, partnerId);  // 必填项,ISV 名称  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_ISV_NAME, isvName);  // 必填项,逻辑库ID  merchantInfo.put(ZolozConstants.KEY_GROUP_ID, groupID);  // 必填项,比对模式  merchantInfo.put(ZolozConfig.KEY_VERIFY_MODE, verifyMode);  // 必填项,商户机具终端编号  merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_DEVICE_NUM, deviceNum);  // 必填项,授权token  merchantInfo.put(ZolozConstants.KEY_AUTH_TOKEN, authToken);   return merchantInfo; } // 人脸初始化监听 mZoloz.register(null, new InstallCallback() {  @Overide  public void onResponse(Smile2PayResponse smileToPayResponse) {  Log.d(TAG, "register()...response");  if (smileToPayResponse != null) {  int code = smileToPayResponse.getCode();  boolean success = (Smile2PayResponse.CODE_SUCCESS == code);  if (smileToPayResponse.getExtInfo() != null) {  FeatureResult featureResult =  (FeatureResult)smileToPayResponse.getExtInfo().get(ZolozConstants.KEY_FEATURE_RESULT);  Log.d(TAG, "featureResult:" + featureResult);  }  }  }  @Override  public void onEvent(int code, String message) {  super.onEvent(code, message);  String msg = String.format("code:%d, msg:%s", code, message);  Log.i(TAG, "register.onEvent() :" + msg);  showToast(msg));  } });

人脸初始化成功后,可以执行第五步唤起人脸。

第五步:唤起刷脸

mZoloz.speedyVerify(params, new ZolozCallback() {  @Override  public void onResponse(Smile2PayResponse smileToPayResponse) {  Log.d(TAG, "verify()...response");  if (smileToPayResponse != null) {  int code = smileToPayResponse.getCode();  String uid = smileToPayResponse.getAlipayUid();  String fToken = smileToPayResponse.getFaceToken();  String msg = Smile2PayResponse.CODE_SUCCESS == code ?  "识别成功" : "识别失败";  if (CODE_SUCCESS.equalsIgnoreCase(code) && fToken != null) {  // 发起支付,参考下面第步  ...  } else {  String subMsg = smileToPayResponse.getSubMsg();  String subCode = smileToPayResponse.getSubCode();  Log.d(TAG, "verify()...response failed: code:" + code + " subCode:"  + subCode + " subMsg:" + subMsg);  }  }  } } /**  * mock数据,真实商户请填写真实信息.  */ private Map mockConfigInfo() {  Map merchantInfo = new HashMap();   merchantInfo.put(ZolozConfig.SERVICE_ID, ZolozConfig.ServiceId.SERVICE_ID_GROUP);  merchantInfo.put((ZolozConfig.KEY_VERIFY_MODE, ZolozConfig.VerifyMode.ENCLOSED_REMOTE_VERIFY);   return merchantInfo; }

拿到刷脸结果后,可以发起支付。

FAQ

关于此文档暂时还没有FAQ
返回
顶部