小程序接入说明
小程序接入流程
- 通过get_biz_token API接口,设置参数,并获取biz_token。
- 在下载中心下载KYC验证微信小程序包,解压得到 faceid-components文件夹。将faceid-components文件夹添加至项目文件根目录。在需要引用组件的页面进行集成。请参见下文详细介绍。
- 验证流程结束后,可以通过get_result接口获取本次验证流程的详细信息。
下面对各个步骤进行详细的说明
第1步:获取biz_token
API名称
Get_biz_token
说明
客户服务器端通过此接口可以获得一个biz_token(biz_token唯一且只能使用一次,有效期为1小时,但是您可以在1天内对该结果进行查询)。该请求是POST方法,参数中要包括用户后续验证的相关信息。
API地址
POST https://openapi.faceid.com/lite/v1/get_biz_token
参数
参数名 | 可选/必选 | 类型 | 说明 |
---|---|---|---|
sign | 必选 | String | 根据API_KEY和API_SECRET生成的签名,签名算法参见相关文档 |
sign_version | 必选 | String | 签名算法版本,当前仅支持:hmac_sha1 |
return_url | 必选 | String | 流程结束后跳转到客户定义的页面,必须以http或者https开头,对微信小程序来说,该参数不起作用 |
notify_url | 必选 | String | 流程结束后,FaceID会通知客户服务器,post请求到该url,必须以http或者https开头, post的参数名是data,data的值是一个json字符串,内容包括:biz_token, error_code,error_msg。biz_token是get_biz_token接口获得的,error_code和error_msg参见后文详述 |
biz_no | 可选 | String | "默认为空"。客户业务流水号,建议设置为您的业务相关的流水串号并且唯一。此字段不超过128字节 |
comparison_type | 必选 | Int | 本次验证服务的类型。 0:表示活体照片和上传照片进行比对(人脸比对)。 1:表示活体照片和参考数据进行比对(KYC验证) |
group | 可选 | Int | 对于comparison_type为1时有效,支持0和1,默认值为0,表示身份证信息是通过下面的参数获得的;如果设为1,表示身份证信息是通过身份证OCR识别获取的,不需要下面的idcard_name和idcard_number参数 |
idcard_name | 条件必选 | String | 姓名。当comparison_type=1, 并且group=0时,必须传入此字段 |
idcard_number | 条件必选 | String | 身份证号。当comparison_type=1, 并且group=0时,必须传入该字段 |
idcard_threshold | 可选 | Float | 当group=1时该参数有效。表示身份证识别的阈值,支持0~1之间的小数,默认值为0.8。如果ID_Photo分数大于该阈值,则继续进行人脸识别流程。如果ID_Photo值小于该阈值,则认为是非法身份证,提示用户重新拍摄 |
idcard_retry_time | 可选 | Int | 当group=1时有效。表示身份证OCR重新拍摄的最大次数。默认值为3,即人像面和国徽面分别有3次重新拍摄的机会。用户可以通过该参数设置为1~5 |
idcard_side | 可选 | Int | 表示是否身份证OCR时是两面都拍摄,还是只拍摄人像面。支持0和1,默认值是0,表示拍摄双面;如果设为1,表示只拍摄人像面 |
liveness_type | 必选 | String | 表示活体检测的类型,当前仅支持:video_number |
security_level | 可选 | Int | 表示对比对结果的严格程度限制,默认值为2,可以根据您的场景,选择相应的安全规则,越严格,准确性要求越高,通过率也会相应下降。支持:1(宽松),2(常规),3(严格) |
liveness_preferences | 可选 | Int | 1:默认值,表示视频活体采用宽松模式(4个数字对3个就能通过); 2:表示视频活体采用严格模式(4个数字完全正确才通过) |
liveness_retry_count | 可选 | Int | 当视频验证出错时,视频允许上传最大重试次数,默认为3次,用户可以通过该参数设置为1~5 |
uuid | 条件必选 | String | 当comparison_type=0时,该字段用于标志本次识别对应的用户的唯一ID,要求不长于128字节。建议对来自同一用户的比对请求使用同样的ID |
image_ref1 | 条件必选 | File | 由您自己提供的参照人脸照片,File类型。当comparison_type=0时,必选。 |
image_ref2 | 可选 | File | 由您自己提供的参照人脸照片,File类型 |
返回结果
字段 | 类型 | 说明 |
---|---|---|
biz_token | String | 生成的biz_token,该字段后续用于调用小程序。请求调用成功时会返回biz_token字段 |
request_id | String | 用于标示本次请求的唯一的字符串,总返回该字段 |
time_used | Int | 整个请求所花费的时间,单位为毫秒,总返回该字段 |
error | String | 错误原因,请求调用失败时返回error字段, 该字段可能的内容参见下面的错误说明 |
错误说明
error字段可能的错误包括:
HTTP状态码 | error | 说明 |
---|---|---|
400 | MISSING_ARGUMENTS: | 缺少某个必选参数(参数名为key) |
400 | BAD_ARGUMENTS: | 某个参数(参数名为key)解析出错 |
403 | AUTHORIZATION_ERROR: | 鉴权失败,例如可能的原因是签名过期(EXPIRED_SIGN), 签名错误(INVALID_SIGN), API_KEY停用(API_KEY_BE_DISCONTINUED),未进行企业认证(NON_ENTERPRISE_CERTIFICATION),余额不足(BALANCE_NOT_ENOUGH), 等等 |
429 | CONCURRENCY_LIMIT_EXCEEDED | 请求超过并发 |
500 | INTERNAL_ERROR | 内部错误 |
413 | Request Entity Too Large | 客户发送的请求大小超过了20MB限制 |
示例
示例:仅做KYC验证,不做身份证OCR
curl -X POST "https://openapi.faceid.com/lite/v1/get_biz_token"
-F sign=<sign>
-F sign_version=hmac_sha1
-F return_url=<return_url>
-F notify_url=<notify_url>
-F liveness_type=video_number
-F comparison_type=1
-F idcard_name=<姓名>
-F idcard_number=<18位身份号>
返回结果示例:成功
{
"request_id": "1462257147,3149525e-2c24-4862-8e9f-92040595f0a4",
"time_used": 5,
"biz_token":"1462257147,34fb21937e47ae719f11cbc719615687",
}
返回结果示例:return_url没填导致的错误
{
"request_id": "1461740007,71eeb124-08f0-47b3-8fc8-ac048cfa1372",
"time_used": 4,
"error": "MISSING_ARGUMENTS:return_url",
}
第2步:下载小程序包,并集成
下载地址:https://faceid.com/faceopen/pages/sdk_download
下载"KYC验证微信小程序包"
下面以一个例子进行详细的说明,第一个页面(index页面)用来输入biz_token(biz_token的获取方式参见步骤1),点击确认后,会调用Face ID小程序进行验证。验证完成后,由verify.js处理回调。
下载得到的压缩包解压后得到faceid-components幕布,将该目录添加至项目文件根目录。如下图所示:
在index/index.json文件中增加以下配置:
{
"usingComponents": {
"base": "../../faceid-components/components/base/base",
"modal": "../../faceid-components/components/modal/modal"
}
}
- 在index/index.js中处理输入token提交的逻辑,示例代码如下:
Page({
data: {
},
onLoad: function () {
},
formSubmitProd: function (e) {
const {token} = e.detail.value;
if (!token) {
this.modal.showModal({
message: 'token不能为空'
});
return;
}
wx.navigateTo({
url: `../verify/verify?token=${token}`
});
},
})
- 在verify/verify.json文件中增加以下配置:
{
"usingComponents": {
"faceid-verify": "../../faceid-components/components/index/index"
}
}
- 在verify/verify.wxml中定义传递的参数和回调函数,参见:
<!--pages/verify/verify.wxml-->
<faceid-verify token="{{token}}" bind:onFinish="onFinish"/>
- 在verify/verify.js中完成回调函数, status是状态信息,包括"complete"和”tokenError", 建议当status为complete时调用第3步get_result接口获取进一步信息;为tokenError时调用第1步get_biz_token接口重新申请token
// 定义验证流程结束的回调函数
onFinish: function (e) {
console.log(e.detail);
const {token,status} = e.detail;
wx.showModal({
title: '验证流程结束',
content: token + ',' + status,
success: function () {
wx.navigateBack();
}
});
注意:正式环境需要在微信公众平台配置小程序的服务器域名 将https://openapi.faceid.com 添加到服务器域名列表中,测试环境可以打开微信开发者工具内 不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书
其他说明
- 进入FaceID 小程序后,就开始进入了FaceID 验证的流程。如果之前设置了group为1,会先进入身份证OCR流程,否则直接进入活体验证和比对流程。
- 身份证拍摄流程中,用户按照提示,分别拍摄身份证人像面和国徽面,并进行识别。识别出错时,会提示用户,用户可以重新拍摄。重新拍摄的最大次数限制由之前设置的idcard_retry_time定义,默认值为3。一般的身份证识别错误是由于阴影,暗光,模糊等造成,也可能是由于系统认为当前证件是假证,翻拍证件,等等。所有错误提示参见下表。
- 处理notify的示例代码如下:
public class ParamController {
/**
* notify_url 使用 JavaSpring MVC 框架接受post过来的表单参数
*/
@RequestMapping(method = RequestMethod.POST, value = "/notify")
@ResponseBody
public String toNotify(HttpServletRequest request){
//获取notify过来的json
String data = request.getParameter("data");
System.out.println(String.format("%s",data));
return String.format("%s",data);
}
}
页面中典型错误提示和说明
错误提示 | 说明 |
---|---|
无效请求,或当前请求已过期 | Token过期,或者无效token |
识别错误,请正对身份证重新拍摄 | 可能原因是身份证拍摄模糊,阴影,暗光,证件有逻辑错误(例如性别字段和身份证号矛盾) |
身份证人像面找不到人脸,请正对身份证重新拍摄 | 身份证人像面识别过程中无法找到人脸,或者有多张人脸 |
非身份证人像面,请正对身份证重新拍摄 | 系统识别不是当前照片不是身份证人像面 |
非身份证国徽面,请正对身份证重新拍摄 | 系统识别不是当前照片不是身份证国徽面 |
视频中没有检测到人脸,请重试 | 活体验证过程中,录入的视频中找不到人脸 |
视频过长,请重试 | 活体验证过程中,录入的视频过大(最大值为20M) |
视频质量太差,请重试 | 活体验证过程中,录入的视频质量太差,无法进行识别 |
未通过念数字识别,请重试 | 活体验证过程未数字语音识别 |
没有声音,请重试 | 活体验证过程中,录入的视频没有声音,可能的原因是用户手机中未开启该浏览器的语音权限 |
视频格式无法识别,请重试 | 活体验证过程中,录入的视频格式无法识别 |
第3步(可选):获取验证详细信息
API名称
get_result
说明
验证流程结束后,用户服务器可以调用get_result接口,获取本次验证的详细信息。
API地址
GET https://openapi.faceid.com/lite/v1/get_result
参数
参数名 | 可选/必选 | 类型 | 说明 |
---|---|---|---|
sign | 必选 | String | 根据API_KEY和API_SECRET生成的签名,签名算法参见相关文档 |
sign_version | 必选 | String | 签名算法版本,当前仅支持:hmac_sha1 |
biz_token | 必选 | String | get_biz_token接口返回的biz_token |
verbose | 可选 | Int | 表示返回数据的详细程度,取值如下: 0:仅返回结论; 1:默认值,返回结论与摘要信息 |
返回结果
字段 | 类型 | 说明 |
---|---|---|
request_id | String | 用于标示本次请求的唯一的字符串,总返回该字段 |
time_used | Int | 整个请求所花费的时间,单位为毫秒,总返回该字段 |
error | String | 错误原因,请求调用失败时返回error字段, 该字段可能的内容参见下面的错误说明 |
biz_token | String | 传入的biz_token,原样返回 |
biz_no | String | 之前在get_biz_token中设置的biz_no字段,如果没有设置,返回为空字符串 |
result_code | Int | 结果码 |
result_message | String | 结果信息 |
action | String | 当前该字段为空列表 |
images | Json | 字段如下: image_best: 活体检测获得的最优照片,base64编码。该照片会和参考数据照片或者用户上传的上传照片进行比对。 idcard_frontside: OCR识别的身份证人像面照片,base64编码。 idcard_backside: OCR识别的身份证国徽面照片,base64编码。 idcard_portrait: OCR识别的身份证人像抠图,base64编码 |
idcard_result | Json | 身份证OCR返回的信息,该字段的详细信息参见下文示例 |
verification | Json | 人脸比对的详细结果,可能的字段如下: - idcard: Json类型, 表示活体照片和参考数据比对的结果,具体包括以下字段: -- confidence: 比对结果的置信度,Float类型,取值[0,100],数字越大表示风险越小。 -- thresholds: 一组用于参考的置信度阈值,Json类型,包含三个字段,均为Float类型、取值[0,100]: --- 1e-3: 误识率为千分之一的置信度阈值; --- 1e-4: 误识率为万分之一的置信度阈值; --- 1e-5: 误识率为十万分之一的置信度阈值; --- 1e-6: 误识率为百万分之一的置信度阈值; - ref1: Json类型,表示活体照片和image_ref1的比对结果,字段和上面的相同。 - ref2: Json类型,表示活体照片和image_ref2的比对结果,字段和上面的相同。 |
结果码说明
result_code | result_message | 说明 |
---|---|---|
1000 | SUCCESS | 待比对照片与参考数据照片或上传照片对比是同一个人 |
2000 | PASS_LIVING_NOT_THE_SAME | 待比对照片与参考数据照片或上传照片对比不是同一个人 |
3000 | NO_ID_CARD_NUMBER | 无此身份证号 |
3000 | ID_NUMBER_NAME_NOT_MATCH | 身份证号和姓名不相符 |
3000 | NO_ID_PHOTO | 无法获取参考照片 |
3000 | DATA_SOURCE_ERROR | 参考数据错误 |
3100 | IDCARD_PHOTO_FRONTSIDE | 身份证人像面识别错误(可能是拍摄模糊,阴影,暗光)或者有逻辑错误(例如性别和身份证号不匹配) |
3100 | IDCARD_BACKSIDE_BLURRED | 身份证国徽面识别错误(可能是拍摄模糊,阴影,暗光)或者有逻辑错误(例如性别和身份证号不匹配) |
3100 | NO_FACE_FOUND_IDCARD | 身份证人像面找不到人脸 |
3100 | IDCARD_PHOTO_NOTFRONTSIDE | 非身份证人像面 |
3100 | IDCARD_PHOTO_NOTBACKSIDE | 非身份证国徽面 |
3200 | FAIL_OCR_FAKE_IDCARD | 假证 |
4100 | FAIL_LIVING_FACE_ATTACK | 云端活体验证失败 |
4100 | CHANGE_FACE_ATTACK | 活体验证视频中发生了换脸攻击(视频中不是同一个人) |
4200 | NO_FACE_FOUND | 活体验证视频中没有检测到人脸 |
4200 | FACE_QUALITY_TOO_LOW | 活体验证视频中质量太差 |
4200 | INVALID_VIDEO_DURATION | 活体验证视频中长度不符合要求(2s~20s) |
4200 | VIDEO_TOO_LARGE | 活体验证视频过大 |
4200 | SR_ERROR | 活体验证视频中,用户读数语音不符合要求 |
4200 | NOT_SYNCHRONIZED | 活体验证视频中,用户读数唇语不符合要求 |
4200 | NO_AUDIO | 活体验证视频无声音 |
4200 | VIDEO_FORMAT_UNSUPPORTED | 活体验证视频格式无法识别 |
4200 | LIP_VOICE_NOT_SYNC | 活体验证视频中语音唇语不同步 |
4200 | VIDEO_OK | 活体验证视频可用 |
4200 | VIDEO_MANY_TIMES | 活体验证视频上传超过阈值(默认为3,get_biz_token接口中liveness_retry_count参数可以设置) |
4200 | VIDEO_INTERNAL_ERROR | 活体验证内部错误 |
5000 | NON_ENTERPRISE_CERTIFICATION | 客户未进行企业认证 |
5000 | BALANCE_NOT_ENOUGH | 余额不足 |
5000 | ACCOUNT_DISABLED | 账户已停用 |
6000 | USER_CANCEL | 用户主动退出流程 |
9000 | ==LIVING_NOT_START== | 验证流程尚未开始 |
错误说明
error字段可能的错误包括:
error | 说明 | HTTP状态码 |
---|---|---|
MISSING_ARGUMENTS: | 缺少某个必选参数(参数名为key) | 400 |
BAD_ARGUMENTS: | 某个参数(参数名为key)解析出错 | 400 |
BIZ_TOKEN_USED | biz_token 已使用 | 400 |
AUTHORIZATION_ERROR: | 鉴权失败,例如可能的原因是签名过期(EXPIRED_SIGN), 签名错误(INVALID_SIGN), API_KEY停用(API_KEY_BE_DISCONTINUED),未进行企业认证(NON_ENTERPRISE_CERTIFICATION),余额不足(BALANCE_NOT_ENOUGH), 等等 | 403 |
DATA_DESTROYED | 超过可查询时间或超过最多可查询次数 | 403 |
TOO_MANY_REQUESTS | 请求超过并发 | 429 |
INTERNAL_ERROR | 内部错误 | 500 |
idcard_result示例
idcard_result: {
"name": "张三",
"idcard_number": "XXXXXX",
"gender": "男",
"nationality": "汉",
"birth_year": "1996",
"birth_month": "3",
"birth_day": "10",
"address": "北京市海淀区XXXXX",
"issued_by": "北京市公安局海淀分局",
"valid_date_start": "20150516",
"valid_date_end": "20350516",
"frontside_legality": {
"Photocopy": 0, ## 该照片为复印件的概率
"Edited": 0, ## 该照片为用工具合成或者编辑过的身份证图片的概率
"ID_Photo": 1, ## 该照片为正式身份证照片的概率
"Screen": 0, ## 该照片为手机或电脑屏幕翻拍照片的概率
"Temporary_ID_Photo": 0, ## 该照片为临时身份证照片的概率
"ID_Photo_Threshold": 0.8 ## 判断为真实身份证的阈值,如果ID_Photo大于该阈值,则可以认为该身份证为真实身份证
},
"backside_legality": {
"Photocopy": 0,
"Edited": 0,
"ID_Photo": 0.999,
"Screen": 0.001,
"Temporary_ID_Photo": 0,
"ID_Photo_Threshold": 0.8
},
"frontside_completeness": 0, ## 完整程度,0表示完整; 1表示身份证不完整,但是内容区域全部都在图片内; 2表示身份证不完整,且部分内容在区域外
"backside_completeness": 0,
"image_portrait": "XXXXXX" ## 身份证头像抠图(base64编码结果)
}
verification示例
KYC验证(comparison_type=1), 未传image_ref
"verification": {
"idcard": { ## 活体照片和参考数据比对结果
"confidence": 86.4735,
"thresholds": {
"1e-3": 62.168713,
"1e-4": 69.31534,
"1e-5": 74.39926,
"1e-6": 78.038055
}
}
}
KYC验证(comparison_type=1), 传入了image_ref1
"verification": {
"idcard": { ## 活体照片和参考数据比对结果
"confidence": 86.4735,
"thresholds": {
"1e-3": 62.168713,
"1e-4": 69.31534,
"1e-5": 74.39926,
"1e-6": 78.038055
}
},
"ref1": { ## 活体照片和上传照片比对结果
"confidence": 86.4735,
"thresholds": {
"1e-3": 62.168713,
"1e-4": 69.31534,
"1e-5": 74.39926,
"1e-6": 78.038055
}
}
}
人脸比对(comparison_type=0), 传入了image_ref1, image_ref2
"verification": {
"ref1": { ## 活体照片和上传照片1的比对结果
"confidence": 86.4735,
"thresholds": {
"1e-3": 62.168713,
"1e-4": 69.31534,
"1e-5": 74.39926,
"1e-6": 78.038055
},
"ref2": { ## 活体照片和上传照片2的比对结果
"confidence": 86.4735,
"thresholds": {
"1e-3": 62.168713,
"1e-4": 69.31534,
"1e-5": 74.39926,
"1e-6": 78.038055
}
}
}
}
当前版本
- v1.0.0
历史版本
- v0.1.0 文档