# 三、会员开卡接口
# 会员场景说明
通过刷脸会员接口识别用户会员身份后,若用户不是会员,微信支付提供“开卡组件”的能力,方便用户开通会员。
# 接入过程
# 会员功能时序图
# 公共响应参数
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
return_code | 是 | string | 错误码。公共定义见公共错误码 |
return_msg | 是 | string(128) | 对错误码的描述 |
err_code | 否 | Integer | 可为空,二级错误码,公共定义见 二级错误码 |
# 公共错误码
参数 | 错误码 | 类型 | 说明 |
---|---|---|---|
return_code | SUCCESS | string | 接口成功 |
return_code | ERROR | string | 接口失败 |
return_code | PARAM_ERROR | string | 参数错误 |
return_code | SYSTEMERROR | string | 接口返回错误 |
# 二级错误码
参数 | 错误码 | 类型 | 说明 |
---|---|---|---|
err_code | 271378620 | Interger | 刷脸服务未初始化,请调用初始化 |
err_code | 271378621 | Interger | 刷脸服务初始化中,等待500ms左右重新调用init |
# 接口调用流程
# 1、程序启动时初始化
# 程序启动时初始化initWxpayface
接口作用:对人脸SDK进行初始化
# 请求参数
除公共参数外,下方参数的代理设置可用于配置刷脸走商户内部代理。若不需要,则不用填写。
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
ip | 否 | string | HTTP代理IP或域名 |
port | 否 | string | HTTP代理端口, 须为数字 |
user | 否 | string | HTTP代理的用户名 |
passwd | 否 | string | HTTP代理的密码 |
proxy_type | 否 | int | 0:none; 1:HttpTunnel; 2:Socks5; 3:Http v2.12及以上 |
tcp_port | 否 | string | TCP的代理端口,如果TCP代理与IP代理同一端口,则无需设置v2.12及以上 |
perform_mode | 否 | string | NORMAL_PRFORM : 正常性能表现; LOW_PERFORM : 低性能表现 默认为正常性能表现 v2.13及以上 |
# 返回参数
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
return_code | 是 | string | 错误码。公共定义见 公共错误码 |
return_msg | 是 | string(128) | 对错误码的描述 |
# 请求示例
/**
* 初始化
*
*/
Map<String, String> m1 = new HashMap<>();
// m1.put("ip", "192.168.1.1"); //若没有代理,则不需要此行
// m1.put("port", "8888");//若没有代理,则不需要此行
// m1.put("user", mEtnUser.getText().toString());//若没有代理,则不需要此行
// m1.put("passwd", mEtnPassword.getText().toString());//若没有代理,则不需要此行
// m1.put("proxy_type", 1 ); //若没有代理,则不需要此行
// m1.put("perform_mode", "LOW_PERFORM");//低性能表现,默认关闭美颜等
WxPayFace.getInstance().initWxpayface(this, m1, new IWxPayfaceCallback() {
@Override
public void response(Map info) throws RemoteException {
if (info == null) {
showToast("调用返回为空, 请查看日志");
new RuntimeException("调用返回为空").printStackTrace();
return false;
}
String code = (String) info.get("return_code");
String msg = (String) info.get("return_msg");
showToast("初始化完成");
}
});
建议:1、您可以自定义一个Application,然后在自定义Application的onCreate()中调用initPayFace()完成人脸识别模块的初始化 2、您可以只在被调用人脸识别模块的activity的onCreate()中完成initPayFace()的调用
注意:目前我们没有在initPayFace()中做app保活的自启措施,所以当您的应用在启动过程中遇到重启/更新的问题,您必须重新调用initPayFace(),相信我们会在下一个最新的版本中对initPayFace()做进一步的完善。
# 2、获取数据
# 获取数据getWxpayfaceRawdata
接口作用:获取rawdata数据
# 返回参数
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
return_code | 是 | string | 错误码。公共定义见 公共错误码 |
err_code | 否 | Integer | 可为空,二级错误码,公共定义见 二级错误码 |
return_msg | 是 | string(128) | 对错误码的描述 |
rawdata | 是 | string(2048) | 初始化数据。用于接口调用, 参见: get_wxpayface_authinfo: rawdata |
# 请求示例
/**
* 获取rawdata
*
*/
WxPayFace.getInstance().getWxpayfaceRawdata(new IWxPayfaceCallback() {
@Override
public void response(final Map info) throws RemoteException {
if (info == null) {
showToast("调用返回为空, 请查看日志");
new RuntimeException("调用返回为空").printStackTrace();
return false;
}
String code = (String) info.get("return_code");
String msg = (String) info.get("return_msg");
String rawdata = info.get("rawdata");
}
});
注意:请在初始化(initWxpayface)成功后获取数据(getWxpayfaceRawdata)
# 3、获取调用凭证
# 获取调用凭证get_wxpayface_authinfo(rawdata)(获取调用凭证)
接口作用:获取调用凭证
接口地址:https://payapp.weixin.qq.com/face/get_wxpayface_authinfo
# 请求参数
除公共参数外,下方参数的代理设置可用于配置刷脸走商户内部代理。若不需要,则不用填写。
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
store_id | 是 | string(32) | 门店编号, 由商户定义, 各门店唯一。 |
store_name | 是 | string(128) | 门店名称,由商户定义。(可用于展示) |
device_id | 是 | string(32) | 终端设备编号,由商户定义。 |
attach | 否 | string | 附加字段。字段格式使用Json |
rawdata | 是 | string(2048) | 初始化数据。由微信人脸SDK的接口返回。 获取方式参见: [获取数据 getWxpayfaceRawdata](#获取数据 getWxpayfaceRawdata) [获取数据 getWxpayfaceRawdata](#获取数据 getWxpayfaceRawdata) |
appid | 是 | string(32) | 商户号绑定的公众号/小程序 appid |
mch_id | 是 | string(32) | 商户号 |
sub_appid | 否 | string(32) | 子商户绑定的公众号/小程序 appid(服务商模式) |
sub_mch_id | 否 | string(32) | 子商户号(服务商模式) |
now | 是 | int | 取当前时间,10位unix时间戳。 例如:1239878956 |
version | 是 | string | 版本号。固定为1 |
sign_type | 是 | string | 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5 |
nonce_str | 是 | string(32) | 随机字符串,不长于32位 |
sign | 是 | string | 参数签名。详见微信支付签名算法 |
# 返回参数
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
return_code | 是 | string(16) | 错误码。公共定义见 公共错误码 |
return_msg | 是 | string(128) | 对错误码的描述 |
authinfo | 是 | string(4096) | SDK调用凭证。用于调用SDK的人脸识别接口。 参见[人脸识别 getWxpayfaceCode](#人脸识别 getWxpayfaceCode) |
expires_in | 否 | int | authinfo的有效时间, 单位秒。 例如: 3600 在有效时间内, 对于同一台终端设备,相同的参数的前提下(如:相同的公众号、商户号、 门店编号等),可以用同一个authinfo,多次调用SDK的 getWxpayfaceCode 接口。 |
nonce_str | 是 | string(32) | 随机字符串 |
sign | 是 | string(32) | 响应结果签名 |
appid | 是 | string(32) | 公众号 |
mch_id | 否 | string(32) | 商户号 |
sub_appid | 否 | string(32) | 子商户公众账号ID(服务商模式) |
sub_mch_id | 是 | string(32) | 子商户号(服务商模式) |
# 请求示例
<return_code>SUCCESS</return_code>
<return_msg>请求成功</return_msg>
<nonce_str>Tivppi4UXAbgLxk8e1Sij76YdowOFFii</nonce_str>
<sign>PL0EUID6A7ICWNKHCSMQC0UIXOYNSE5B</sign>
<appid>wx31fdaErqR31</appid>
<mch_id>12345689</mch_id>
<authinfo>q3OPhFtQBf6KZGqmZhejKCRy5K/ch0kwS11YSsEj9XmUGqcsT2QPHt0Oa7xaCMCoSZTWMmShCo4dOiO5tU+OJEsvSxXzn5m3Nkh747tinNlbpJmVq1zOPj+FJNndkzanxoiAddO8p1EfrmUhJs/aNf0pDfrPoVfkAapK+ZY6blwyaDQ9bB7+KkZq29kObsXOZ3thg+bxP4RAqC0oxNS4JiyP0uA1Euzxtkc9lCTebloFied8stILrMehUKukeMGkZ1SzTyc8/HFHApzHahNPX6yD8ttzYnhe+IRMFJgpuTlIvEOYZUxenPXE1A5clrPvOBeJDszX/OvZl4fpYWPpXAcVQlw+gfYhblt+rT6ALMsD73w/rT4NRriQEEraC4Pfb5yua4qAqv4TVo04</authinfo>
<expires_in>7200</expires_in>
建议:返回的接口凭证authinfo
,可以在expires_in
指定的有效期内,同一台机具上重复使用
注意:这是一个后端调用接口,请在获取数据(getWxpayfaceRewdata)成功后获取调用凭证get_wxpayface_authinfo(rawdata)
# 4、获取用户信息
# 获取用户信息getWxpayfaceUserInfo(authinfo)
接口作用:通过人脸识别获取用户信息。
该接口与[人脸识别 getWxpayfaceCode](#人脸识别 getWxpayfaceCode)的区别:
- 无法用于订单支付;
- UI交互不同。
**适用范围:**适用于会员、推荐等场景。
# 请求参数
除公共参数外,下方参数的代理设置可用于配置刷脸走商户内部代理。若不需要,则不用填写。
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
appid | 是 | string | 商户号绑定的公众号/小程序 appid |
mch_id | 是 | string | 商户号 |
sub_appid | 否 | string(32) | 子商户绑定的公众号/小程序 appid(可不填) |
sub_mch_id | 否 | string(32) | 子商户号(非服务商模式不填) |
store_id | 是 | string | 门店编号 |
face_authtype | 是 | string | 人脸识别模式。可选值:FACEID-ONCE : 人脸识别(单次模式)FACEID-LOOP : 人脸识别(循环模式) |
authinfo | 是 | string | 调用凭证。获取方式参见: get_wxpayface_authinfo |
ask_unionid | 否 | string | 是否请求获取union_id。可选值[0:不获取;1:获取]2.12新增 |
screen_index | 否 | string | 指定刷脸界面的运行屏幕,可选值:“0”运行在默认屏幕;"1"运行在第二屏幕(副屏);"2"自动选择屏幕; "3"强制用presentation方式在第二屏幕(副屏)启动。系统要求: Android 7.1或以上(版本2.21或以上);Android 8.1或以上(版本2.13或以上) |
overlay_option | 否 | string | 指定刷脸presentation界面的层级,可选值:“0”不强制指定层级(默认);"1"强制在其他应用上层显示; |
# 返回参数
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
return_code | 是 | string | 错误码。公共定义见 公共错误码 |
err_code | 否 | Integer | 可为空,二级错误码,公共定义见 二级错误码 |
return_msg | 是 | string(128) | 对错误码的描述 |
openid | 是 | string | openid |
sub_openid | 否 | string | 子商户号下的openid(服务商模式) |
nickname | 是 | string | 微信昵称 |
token | 否 | string | 用于获取union_id,获取union_id文档2.12新增 |
unionid_code | 否 | string | 获取union_id 返回码。公共定义见公共错误码2.12新增 |
unionid_msg | 否 | string | 获取union_id 返回信息,对unionid_code返回码的描述2.12新增 |
# 请求示例
// 详细的参数配置表可见上方的“接口参数表”
Map<String, String> m1 = new HashMap<String, String>();
m1.put("appid", "填您的公众号"); // 公众号,必填
m1.put("mch_id", "填您的商户号"); // 商户号,必填
// m1.put("sub_appid", "xxxxxxxxxxxxxx"); // 子商户公众账号ID(非服务商模式不填)
// m1.put("sub_mch_id", "填您的子商户号"); // 子商户号(非服务商模式不填)
m1.put("store_id", "填您的门店编号"); // 门店编号,必填
m1.put("face_authtype", "FACEID-ONCE"); // 人脸识别模式, FACEID-ONCE`: 人脸识别(单次模式) FACEID-LOOP`: 人脸识别(循环模式), 必填
m1.put("authinfo", "填您的调用凭证"); // 调用凭证,详见上方的接口参数
// m1.put("ask_unionid", "1"); // 是否获取union_id 0:获取 1:不获取
WxPayFace.getInstance().getWxpayfaceUserInfo(m1, new IWxPayfaceCallback() {
@Override
public void response(Map info) throws RemoteException {
if (info == null) {
new RuntimeException("调用返回为空").printStackTrace();
return;
}
String code = (String) info.get("return_code"); // 错误码
Integer errcode = (Integer) info.get("err_code"); // 二级错误码
String msg = (String) info.get("return_msg"); // 错误码描述
String openid = info.get("openid").toString(); // openid
String sub_openid = "";
if (info.get("sub_openid") != null) sub_openid = info.get("sub_openid").toString(); // 子商户号下的openid(服务商模式)
String nickName = info.get("nickname").toString(); // 微信昵称
String token = "";
if (info.get("token") != null) token = info.get("token").toString(); // facesid,用户获取unionid
if (code == null || openid == null || nickName == null || !code.equals("SUCCESS")) {
new RuntimeException("调用返回非成功信息,return_msg:" + msg + " ").printStackTrace();
return ;
}
/*
获取union_id逻辑,传入参数ask_unionid为"1"时使用
String unionid_code = "";
if (info.get("unionid_code") != null) unionid_code = info.get("unionid_code").toString();
if (TextUtils.equals(unionid_code,"SUCCESS")) {
//获取union_id逻辑
} else {
String unionid_msg = "";
if (info.get("unionid_msg") != null) unionid_msg = info.get("unionid_msg").toString();
//处理返回信息
}
*/
/*
在这里处理您自己的业务逻辑
需要注意的是:
1、上述注释中的内容并非是一定会返回的,它们是否返回取决于相应的条件
2、当您确保要解开上述注释的时候,请您做好空指针的判断,不建议直接调用
*/
}
});
注意:请在获取调用凭证get_wxpayface_authinfo(rawdata)成功后调用获取用户信息getWxpayfaceUserInfo(authinfo);请不要直接在副屏presentation里调用。
# 5、调用会员开通组件
# 会员开通接口(activateWxpayfaceMember)
作用: 商户侧在人脸识别(getWxpayfaceUserInfo)后,引导用户开通会员,在用户确认意愿后调用该接口,该接口会展示微信会员开卡组件,并返回开卡结果。
支持版本: 2.23及以上
注意: 该接口调用条件是商户已在当前设备配置刷脸会员
# 接口函数
public void activateWxpayfaceMember(final Map info, final IWxPayfaceCallback wxpayfaceCallBack)
# 接口参数
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
appid | 是 | string | 商户绑定的公众号/小程序 appid |
mch_id | 是 | string | 商户号 |
store_id | 是 | string | 门店编号 |
authinfo | 是 | string | 调用凭证。获取方式参见: get_wxpayface_authinfo |
openid | 是 | string | 人脸识别接口(getWxpayfaceUserInfo)获取的openid |
# 接口返回
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
return_code | 是 | string | 错误码。公共定义见 公共错误码 |
err_code | 否 | Integer | 可为空,二级错误码,公共定义见 二级错误码 |
return_msg | 是 | string(128) | 对错误码的描述 |
# 接口错误码
错误码的公共部分,参见公共错误码, 以下为该接口独有错误码:
错误码 | 描述 | 解决方案 |
---|---|---|
PARAMS_INVALID | 传入参数错误 | 检查传参是否正确 |
MEMBER_INFO_EXP_ERROR | 用户信息过期 | 重新进行人脸识别 |
GET_MEMBER_INFO_FAIL_ERROR | 获取开通会员信息失败 | 重试 |
NOT_CONFIG_MEMBER_ERROR | 未配置会员 | 为设备配置卡包会员 |
# 实践指引
private void activateWxpayfaceMember() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("appid", "填您的公众号"); // 公众号,必填
map.put("mch_id", "填您的商户号"); // 商户号,必填
map.put("store_id", "填您的门店编号"); // 门店编号,必填
map.put("authinfo", "填您的调用凭证"); // 调用凭证,必填
map.put("openid", "填人脸识别接口获取的openid"); // openid,必填
WxPayFace.getInstance().activateWxpayfaceMember(map, new IWxPayfaceCallback() {
@Override
public void response(Map info) throws RemoteException {
if (info == null) {
new RuntimeException("调用返回为空").printStackTrace();
return;
}
String code = (String) info.get("return_code"); // 错误码
Integer errcode = (Integer) info.get("err_code"); // 二级错误码
String msg = (String) info.get("return_msg"); // 错误码描述
if (code == null || !code.equals("SUCCESS")) {
new RuntimeException("调用返回非成功信息,return_msg:" + msg + " ").printStackTrace();
return ;
}
/*
在这里处理您自己的业务逻辑:
执行到这里说明用户已经确认支付结果且成功了,此时刷脸支付界面关闭,您可以在这里选择跳转到其它界面
*/
}
});
}
# 6、释放资源
# 释放资源releaseWxpayface
接口作用:释放人脸服务,断开连接。
接口使用规范:
- 聚合支付情况下:每次启动刷脸都需要initWxpayface,刷脸结束后需要调用releaseWxpayface(释放摄像头供其他刷脸支付平台调用);
- 非聚合支付情况下:首次刷脸需要initWxpayface,刷脸结束后不需要调用releaseWxpayface,否则下次刷脸需要重新initWxpayface,影响启动耗时;初始化之后第二次刷脸可以直接调用getWxpayfaceCode启动刷脸(在保证authinfo有效的情况下)。
# 请求示例
/**
*释放资源
*
*/
WxPayFace.getInstance().releaseWxpayface(context);