文档中心 > 校园产品介绍与接入指南

支付场景人脸app接入

更新时间:2020/03/09 访问次数:2289

1、快速接入

支付场景本地人脸app
主要指用户扫脸检测、活体和识别在端上进行,刷脸过程可支持短暂离线,主要是应用于K12团餐、地铁、景区等封闭式场景。

1.1 单次刷脸

单次刷脸模式是指isv每次唤起刷脸时都需调用刷脸接口(verify),刷脸完成后人脸采集页面自动退出,常用于支付和单次核身等场景。
image
流程如下:
1. isv机具端app启动时,调用刷脸SDK接口(install)传入isv和商户、gourpId信息,进行人脸和iot sdk初始化。调用register,等待初始化回调完成。register回调返回后才能进行后续刷脸。
2. 刷脸时,isv机具端app调用刷脸SDK接口(verify):
1)设备未进行iot授权,刷脸直接失败。
2)设备已授权,可正常唤起人脸采集页面并进行人脸识别过程。识别完成后返回人脸识别的结果(VerifyCallback)。如果识别成功,会返回当前用户的支付宝账号信息(ftoken/uid)、比对信息(流程图第2步)
3. 根据刷脸识别结果,isv接入方可进行相应业务逻辑(核身或者代扣)。
对于代扣,获取ftoken后调用加签接口signWithFaceToken进行签名,提交签名到isv服务端后完成支付宝代扣流程(流程图第3步)。

1.2、依赖包和刷脸应用

1、业务方客户端需集成SmileService.jar文件,调用见《5、调用示例》。
2、机具上安装zoloz刷脸app(根据摄像头类型(2d或者3d)选择安装对应摄像头版本的刷脸apk)。
上述集成的jar和刷脸app从项目临客蚁上获取,由版本负责人@从彦统一管理。

2、API说明

2.1 初始化人脸sdk

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

参数说明:

字段 参数 是否必填 具体说明
info Map 必传参数(key定义参考ZolozConstants):
_deviceNum:使用设备序列号SN,保证准确、唯一_
_isvPid:支付宝开发平台分配的isv pid_
_isvName:isv名称merchantId:商户id(比如:学校:外标,景区:机构代码)_
_merchantName:商户name(比如:学校/景区名称)_
groupID:库id

2.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 {
    /**
     * install结果回调函数
     *
     * @param smile2PayResponse     回调response,{@link Smile2PayResponse}
     */
    public abstract void onResponse(Smile2PayResponse smile2PayResponse);
}

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

字段 类型 具体说明
code int 取值如下:
Smile2PayResponse.CODE_SUCCESS: install成功
其他值:人脸库操作失败
mExtInfo Map<String, Object> 本地模式时,map中包括详细失败原因(FeatureResult),获取方式参考《5、调用示例》

2.3 唤起刷脸(本地)

2.3.1 单次刷脸

/**
     * 调起人脸验证
     *
     * @param params
     * @param verifyCallback   人脸验证回调接口{@link VerifyCallback}
     * @return
     */
    public void verify(final Map<String, Object> params,
                       final VerifyCallback verifyCallback)

参数说明:

字段 参数 是否必填 具体说明
info Map 配置参数,参考4.5.3
verifyCallback VerifyCallback onResponse返回的结果

2.3.2 配置参数Map

调用verify/detect启动刷脸时,isv可根据需要传入map配置参数。所有的配置参数定义在类**ZolozConfig**中,主要分为以下几类:

key定义 说明 具体说明
KEY_MODE***_ 业务配置 可配置刷脸模式、降级模式
KEY_ALGORITHM***_ 算法配置 可配置人脸检测/活体/比对等相关参数
KEY_FACE_SEARCH***_ 比对配置 可配置人脸比对相关参数
KEY_TASK_FLOW***_ 流程配置 可配置串并行等相关参数,目前仅支持串行,所以连续模式时,需要设置:configInfo.put(ZolozConfig.KEY_TASK_FLOW_FEATURE_POWER_MODE, PowerMode.POWER_MOD_LOW)
参考《5、示例代码》
KEY_DEVICE_SETTING***_ 相机配置 可配置相机相关参数,2D/IR摄像头时较常用
KEY_UI***_ 刷脸UI配置 可配置刷脸UI相关参数

常用参数说明

key定义 参数说明 取值说明
KEY_MODE_FACE_MODE 业务模式,根据实际应用场景设置 默认值:_FACEPAY,_其他取值参考_FaceMode_定义
KEY_SMILE_MODE 刷脸页面显示在主屏或辅屏 默认值:主屏,参考SmileMode定义
主屏:_SMILE_MODE_DEFAULT_DISPLAY_
铺屏:_SMILE_MODE_EXT_DISPLAY_
KEY_ALGORITHM_MAX_DETECT_DISTANCE 3d摄像头检测最大距离 类型:int
默认值:1000(mm)
KEY_ALGORITHM_MIN_IOD 2d摄像头检测最大距离 默认值:0.18,取值范围:0~1.0f
值越小检测距离越大
KEY_ALGORITHM_MAX_IOD 2d摄像头检测最小距离 默认值:0.45,取值范围:0~1.0f
值越小检测距离越大
KEY_FACE_SEARCH_SECURITY_LEVEL 人脸识别的阈值 类型:int
默认值:14,取值范围:0~20,
KEY_TASK_FLOW_TOYGER_POWER_MODE 串并行控制,目前仅支持串行 需设置为_POWER_MODE_LOW_

注:ZolozConfig还包括其他更多的参数,对于接入方理解起来成本比较高。为了降低理解成本,设置verify/detect接口的map参数(params)时,可根据《4、业务场景配置(本地模式)》部分直接选取适合于自己的业务场景。

2.4 返回刷脸结果

单次刷脸onResponse(VerifyCallback)和连续刷脸onFaceVerify(DetectCallback)中返回的参数是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> 本地模式时,刷脸返回的其他信息,包括刷脸比对结果(FaceVerifyResult)。获取方式参考《5、调用示例》

FaceVerifyResult说明:

字段 参数 具体说明
faceID String 人脸特征唯一标示
uid String 用户_uid_
securityLevel int 比对等级
compScore float 比对分数
compScore3D float 3D比对分数
compScoreIR float IR比对分数
extInfo Map<String, Object> 扩展用,目前为空,可忽略

2.5 中途强制退出刷脸

正常调用verify唤起刷脸过程,完成刷脸整体流程后人脸apk会自己完成关闭,无需调用该接口。如存在特殊逻辑刷脸过程中需要强制退出刷脸(如刷脸过程中判断到nfc刷卡扣款成功,需要退出人脸),则可以调用下列接口强制退出当此刷脸。

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

CommandCode定义如下:

public static final class CommandCode {
    /**
     * 退出刷脸
     */
    public static final int EXIT = 0;
    /**
     * 暂停刷脸(仅预览、不检测)
     */
    public static final int DETECT_PAUSE = 2;
    /**
     * 继续刷脸
     */
    public static final int DETECT_COTINUE = 3;
}

2.7 扫码
2.7.1 注册扫码

/**
     * 注册扫码
     *
     * @param params                暂时未用到,可传空
     * @param scanCallback          回调接口
     */
    public void register(final Map<String, Object> params,
                         final ScanCallback scanCallback)

2.7.2 停止扫码

/**
     * 注销,停止扫码
     * @param scanCallback      register设置的回调接口
     */
    public void unregister(ScanCallback scanCallback)

2.7.3 返回扫码结果

public abstract class ScanCallback {
    /**
     *  扫码服务链接成功
     */
    public static final String CODE_SUCCESS = "0";

    /**
     * 扫码成功返回的码值
     *
     * @param code     码值
     */
    public abstract void onResult(String code);
    /**
     * 扫码服务返回的状态信息
     *
     * @param eventCode event码,0:扫码服务服务链接成功,其他值为失败
     * @param eventMsg  错误描述
     */
    public abstract void onEvent(String eventCode, String eventMsg);
}

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

2.6 监听人脸服务连接状态

极端情况下,人脸app运行过程中,由于摄像头问题、算法异常等一些无法自恢复的原因,会进行kill掉刷脸进程。为了保证正常的刷脸,isv调用方需要调用此接口进行连接状态的监听,一旦断开,需要调用方再次调用register接口。代码示例参考《3、调用示例》。

/**
  * 监听人脸service
  * @param connectCallback 人脸apk连接bind/unbind回调
  */
public void setConnectCallback(ZolozConnectCallback connectCallback)

3、调用示例

第一步:获取Zoloz实例

import com.alipay.zoloz.smile2pay.Zoloz;

mZoloz = Zoloz.getInstance(getApplicationContext());

第二步:初始化人脸sdk

import com.alipay.zoloz.smile2pay.ZolozConstants;

mZoloz.install(mockMerchantInfo());
mZoloz.register(null, new InstallCallback() {
    @Overide
    public void onResponse(Smile2PayResponse smileToPayResponse) {
        Log.d(TAG, "loadFeature()...response");
        if (smileToPayResponse != null) {
            int code = smileToPayResponse.getCode();
            String msg = Smile2PayResponse.CODE_SUCCESS == code ?
                "install成功" : "install失败";
            showToast(String.format(Locale.getDefault(), "code: %s, result: %s", code, msg));
            if (smileToPayResponse.getExtInfo() != null) {
                FeatureResult featureResult =
                    (FeatureResult)smileToPayResponse.getExtInfo().get(ZolozConstants.KEY_FEATURE_RESULT);
                Log.d(TAG, "featureResult:" + featureResult);
            }
        }
    }
});

/**
 * mock数据,真实商户请填写真实信息.
 */
private Map mockMerchantInfo() {
    Map merchantInfo = new HashMap();
    // 必填项,商户机具终端编号设备SN
    merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_DEVICE_NUM, "TEST");
    // 必填项,ISV PID
    merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_ISV_PID, "TEST");
    // 必填项,ISV 名称
    merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_ISV_NAME, "TEST");
    // 必填项,商户id(如团餐场景:学校社会信用代码或者学校国标码)
    merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_MERCHANT_ID, "TEST");
    // 必填项,商户名称(如团餐场景:学校名称)
    merchantInfo.put(ZolozConstants.KEY_MERCHANT_INFO_MERCHANT_NAME, "TEST");
    // 必填项,库id
    merchantInfo.put(ZolozConstants.KEY_GROUP_ID, "TEST");

    return merchantInfo;
}

第三步:唤起刷脸

import com.alipay.zoloz.smile2pay.ZolozConfig.FaceMode;
import com.alipay.zoloz.smile2pay.verify.FaceVerifyResult;
import com.alipay.zoloz.smile2pay.verify.BehaviourLog;

/**
 * 调起刷脸
 */
mZoloz.verify(mockConfigInfo(), new VerifyCallback() {
    @Override
    public void onResponse(Smile2PayResponse smileToPayResponse) {
        Log.d(TAG, "verify()...response");
        if (smileToPayResponse != null) {
            int code = smileToPayResponse.getCode();
            String uid = smileToPayResponse.getAlipayUid();
            String msg = Smile2PayResponse.CODE_SUCCESS == code ?
                "识别成功" : "识别失败";
            BehaviourLog behaviourLog =
                (BehaviourLog)smileToPayResponse.getExtInfo().get(ZolozConstants.KEY_BEHAVIOR_LOG);
            FaceVerifyResult faceVerifyResult =
                (FaceVerifyResult)smileToPayResponse.getExtInfo().get(ZolozConstants.KEY_FACE_VERIFY_RESULT);
            // toast显示刷脸结果,isv应按照真实场景处理和显示刷脸结果
            showToast(String.format(Locale.getDefault(), "code:%s, result: %s, %s",
                                    code, msg, JSON.toJSONString(faceVerifyResult)));
            Log.d(TAG, "map:" + smileToPayResponse.getExtInfo().size());
        }
    }
});

/**
 * mock数据,真实场景请填写实际配置.
 */
private Map mockConfigInfo() {
    JSONObject configInfo = new JSONObject();
    // 必填项,模式
    configInfo.put(ZolozConfig.KEY_MODE_FACE_MODE, FaceMode.FACEPAY);

    // 可选
    //configInfo.put(ZolozConfig.KEY_FACE_SEARCH_SECURITY_LEVEL, 14);
    //configInfo.put(ZolozConfig.KEY_FACE_SEARCH_TOP_N, 2);

    // 其他可选参数参考ZolozConfig定义
    ......
        
    Map zolozConfig = new HashMap(2);
    zolozConfig.put(ZolozConfig.KEY_ZOLOZ_CONFIG, configInfo.toJSONString());
    // 显示在客显屏,默认主屏
    // zolozConfig.put(ZolozConfig.KEY_SMILE_MODE, SmileMode.SMILE_MODE_EXT_DISPLAY);

    // 设置UI config
    // JSONObject uiInfo = new JSONObject();
    // uiInfo.put(ZolozConfig.KEY_UI_SHOW_PAYMENT_CODE, true);
    // uiInfo.put(ZolozConfig.KEY_UI_PAY_AMOUNT, 20.05f);
    // uiInfo.put(ZolozConfig.KEY_UI_ENABLE_TIME_OUT, false);
    // uiInfo.put(ZolozConfig.KEY_UI_SHOW_CLOCK_TIME, true);
    // uiInfo.put(ZolozConfig.KEY_UI_CONFIRM_TEXT, "确认");
    // zolozConfig.put(ZolozConfig.KEY_UI_CONFIG, uiInfo.toJSONString());
    return zolozConfig;
}

第四步:中途强制退出刷脸

Map<String, Object> command = new HashMap<>(2);
    command.put(ZolozConfig.KEY_COMMAND_CODE, CommandCode.EXIT); // exit退出
    mZoloz.command(command);

第五步:监听人脸服务连接状态

mZoloz.setConnectCallback(new ZolozConnectCallback() {
    @Override
    public void onConnect(boolean connected, ComponentName componentName) {
        Log.d(TAG, "registerConnectCall, connected:" + connected);
        if (!connected) {
            mZoloz.register(null, new InstallCallback() {
                @Overide
                public void onResponse(Smile2PayResponse smileToPayResponse) {
                    ......
                }
            }
        }
    });

4、业务场景配置

调用verify接口启动刷脸时需要传入params参数。为了方便接入,接入方可根据自身业务场景从下面章节、选择合适的配置参数,直接copy使用即可(切记:参数值要根据实际场景进行设置)。

4.1 自由支付模式

本地人脸apk的默认的支付模式。代码示例如下:

/**
 * mock数据,真实场景请填写实际配置.
 */
private Map mockConfigInfo() {

    JSONObject configInfo = new JSONObject();
    // 必填项,模式
    configInfo.put(ZolozConfig.KEY_MODE_FACE_MODE, FaceMode.FACEPAY);
    
    // 可选
    //configInfo.put(ZolozConfig.KEY_FACE_SEARCH_SECURITY_LEVEL, 14);
    ......
    Map zolozConfig = new HashMap(2);
    zolozConfig.put(ZolozConfig.KEY_ZOLOZ_CONFIG, configInfo.toJSONString());
    
    // 显示在客显屏,默认主屏
    // zolozConfig.put(ZolozConfig.KEY_SMILE_MODE, SmileMode.SMILE_MODE_EXT_DISPLAY);
    
    // 设置UI config
    //JSONObject uiInfo = new JSONObject();
    //uiInfo.put(ZolozConfig.KEY_UI_PAY_AMOUNT, 20.05f);  <--如果需要显示金额,非必须
    //uiInfo.put(ZolozConfig.KEY_UI_SHOW_CLOCK_TIME, true);  <--如果需要显示时钟时间,非必须
    //zolozConfig.put(ZolozConfig.KEY_UI_CONFIG, uiInfo.toJSONString());
}

4.2 定额支付模式
定额模式用于消费金额固定的场景。刷脸界面调起后一直显示,直到刷脸成功。代码示例如下:

/**
 * mock数据,真实场景请填写实际配置.
 */
private Map mockConfigInfo() {
    JSONObject configInfo = new JSONObject();
    // 必填项,模式
    configInfo.put(ZolozConfig.KEY_MODE_FACE_MODE, FaceMode.FACEPAY);
    
    // 可选
    //configInfo.put(ZolozConfig.KEY_FACE_SEARCH_SECURITY_LEVEL, 14);
    ......
    Map zolozConfig = new HashMap(2);
    zolozConfig.put(ZolozConfig.KEY_ZOLOZ_CONFIG, configInfo.toJSONString());
    
    // 显示在客显屏,默认主屏
    // zolozConfig.put(ZolozConfig.KEY_SMILE_MODE, SmileMode.SMILE_MODE_EXT_DISPLAY);
    ......
    // 设置UI config
    JSONObject uiInfo = new JSONObject();
    uiInfo.put(ZolozConfig.KEY_UI_ENABLE_TIME_OUT, false); <--必须设置
    uiInfo.put(ZolozConfig.KEY_UI_PAY_AMOUNT, 20.05f);  <--金额,必须设置
    //uiInfo.put(ZolozConfig.KEY_UI_SHOW_CLOCK_TIME, true);  <--如果需要显示时钟时间,非必须
    zolozConfig.put(ZolozConfig.KEY_UI_CONFIG, uiInfo.toJSONString());
}

4.3 查询核身模式

查询模式用于非支付场景,仅用于单次身份核验。代码示例如下:

/**
 * mock数据,真实场景请填写实际配置.
 */
private Map mockConfigInfo() {
    JSONObject configInfo = new JSONObject();
     // 必填项,模式
    configInfo.put(ZolozConfig.KEY_MODE_FACE_MODE, FaceMode.ENTRANCE);
    configInfo.put(ZolozConfig.KEY_TASK_FLOW_TOYGER_POWER_MODE, PowerMode.POWER_MODE_LOW);
    
    // 可选
    //configInfo.put(ZolozConfig.KEY_FACE_SEARCH_SECURITY_LEVEL, 14);
    
    // 可选,2d摄像头时有用
    //configInfo.put(ZolozConfig.KEY_DEVICE_SETTING_SOLUTION_WIDTH, 640);
    //configInfo.put(ZolozConfig.KEY_DEVICE_SETTING_CAMERA_ID, 0);
    //configInfo.put(ZolozConfig.KEY_ALGORITHM_MIN_IOD, 0.05);
    //configInfo.put(ZolozConfig.KEY_ALGORITHM_MAX_IOD, 1.0);
    //configInfo.put(ZolozConfig.KEY_DEVICE_SETTING_IS_MIRROR, true);
    //configInfo.put(ZolozConfig.KEY_DEVICE_SETTING_ALG_ANGLE, 0);
    //configInfo.put(ZolozConfig.KEY_DEVICE_SETTING_DISPLAY_ANGLE, 0);
    //configInfo.put(ZolozConfig.KEY_DEVICE_SETTING_IS_DISPLAY_MIRROR, true);

    // 其他可选参数参考ZolozConfig定义
    ......
        
    Map zolozConfig = new HashMap(2);
    zolozConfig.put(ZolozConfig.KEY_ZOLOZ_CONFIG, configInfo.toJSONString());
    // 显示在客显屏,默认主屏
    // zolozConfig.put(ZolozConfig.KEY_SMILE_MODE, SmileMode.SMILE_MODE_EXT_DISPLAY);

    ......
    // 设置UI config
    JSONObject uiInfo = new JSONObject();
    uiInfo.put(ZolozConfig.KEY_UI_CONFIRM_TEXT, "确认");  <--必传,文本可以自定义
    //uiInfo.put(ZolozConfig.KEY_UI_COUNT_DOWN_TIME, -1);  <--确认页面是否显示,可选
    //uiInfo.put(ZolozConfig.KEY_UI_SHOW_CLOCK_TIME, true);  <--如果需要显示时钟时间,非必须
    zolozConfig.put(ZolozConfig.KEY_UI_CONFIG, uiInfo.toJSONString());
}

附录:
1.支付app与收银页面的交互可参考下图
image
如需原图可@从彦。

FAQ

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