merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_DEVICE_NUM, "TEST");
(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)install是初始化接口,只需在业务方app刚启动人脸sdk或者人脸sdk服务端断开时调用(3.5节)
2)对于不关心“install初始化完成时机”的场景,可以不调用register监听。
注意:刷脸上传时必须传入:groupId、serviceId和verifyMode三个参数
1、业务方客户端需集成api**.aar文件,调用见《5、调用示例》。
2、机具上安装zoloz刷脸app(根据摄像头类型(2d或者3d)选择安装对应摄像头版本的刷脸apk)。
上述集成的aar和刷脸app从项目临客蚁上获取,由版本负责人@从彦统一管理。
/** * 初始化人脸应用 * * @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): partnerId:支付宝开发平台分配的isv pid merchantId:商户id(比如:学校:外标,景区:机构代码) groupID:人脸库ID verifyMode:设置为VerifyMode.ENCLOSED_REMOTE_VERIFY authToken:业务方授权token,调用服务端“人脸初始化”接口获取 |
/** * 监听初始化状态 * * @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 |
取值如下:
|
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;
/** * 获取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和失败原因 |
/** * 以去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返回的结果 |
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 |
String |
失败详细原因,刷脸失败时有效 |
mExtInfo |
Map<String, Object> |
刷脸返回的其他信息 |
/** * 主动退出刷脸 * * @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、调用示例》。
import com.alipay.zoloz.smile2pay.Zoloz; mZoloz = Zoloz.getInstance(getApplicationContext());
mZoloz.getMetaInfo(mockMerchantInfo1(), new MetaInfoCallback() { // 解析zolozGetMetaInfo返回的结果,如果成功,则请求商户服务端调用人脸初始化接口 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; }
调用服务端接口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() { 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说明文档。
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() { 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); } } } 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() { 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; }
拿到刷脸结果后,可以发起支付。