小程序接入说明
小程序接入流程
- 通过get_biz_token API接口,设置参数,并获取biz_token。
- 在下载中心下载身份证识别微信小程序包,解压得到 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_ocr/v1/get_biz_token
参数
参数名 | 可选/必选 | 类型 | 说明 | |
---|---|---|---|---|
sign | 必选 | String | 根据API_KEY和API_SECRET生成的签名,签名算法参见相关文档 | |
sign_version | 必选 | String | 签名算法版本,当前仅支持:hmac_sha1 | |
capture_image | 必选 | int | 0:双面,1:人像面 | |
return_url | 必选 | String | 用户完成或取消识别后网页跳转的目标URL(回调方法为get return_url?biz_token=xxx),URL限定为http或https且非内网地址 | |
notify_url | 必选 | String | 用户完成验证、取消验证、或验证超时后,由FaceID服务器请求客户服务器的URL, 我们将会把比对结果同时完整发送至您的服务器,用于对客户端的结果进行验证(回调方法为Post), URL限定为http或https且非内网地址 | |
biz_no | 可选 | String | "默认为空"。客户业务流水号,建议设置为您的业务相关的流水串号并且唯一。此字段不超过128字节 | |
idcard_threshold | 可选 | Float | 限定真是身份证阀值(推荐值0.8),如存在某一面低于设定值则重新拍摄 | |
limit_completeness | 可选 | Int | 0:身份证必须完整,1:身份证内容区域必须都在图片内,2:不做限定,如某一面不满足要求则重新拍摄 | |
limit_quality | 可选 | Float | 限定图片质量,取[0,1]区间实数,3位有效数字,一般来说质量分低于0.753则认为存在质量问题,如存在某一面低于设定值则重新拍摄 | |
limit_logic | 可选 | Int | 0:进行逻辑判断,1:不进行逻辑判断,如存在某一面低于设定值则重新拍摄 |
返回结果
字段 | 类型 | 说明 | |
---|---|---|---|
biz_token | String | 可用biz_token拼接对应身份证OCR页面URL | |
request_id | String | 用于标示本次请求的唯一的字符串,总返回该字段 | |
time_used | Int | 整个请求所花费的时间,单位为毫秒,总返回该字段 | |
error | String | 错误原因,请求调用失败时返回error字段, 该字段可能的内容参见下面的错误说明 |
错误说明
error字段可能的错误包括:
error | 说明 | HTTP状态码 |
---|---|---|
MISSING_ARGUMENTS: | 缺少某个必选参数(参数名为key) | 400 |
BAD_ARGUMENTS: | 某个参数(参数名为key)解析出错 | 400 |
AUTHORIZATION_ERROR | api_key 和 api_secret 不匹配(或sign出错) | 403 |
AUTHORIZATION_ERROR: | 鉴权失败,例如可能的原因是签名过期(EXPIRED_SIGN), 签名错误(INVALID_SIGN), API_KEY停用(API_KEY_BE_DISCONTINUED),未进行企业认证(NON_ENTERPRISE_CERTIFICATION),余额不足(BALANCE_NOT_ENOUGH), 等等 | 403 |
API_NOT_FOUND | 所调用的API不存在 | 404 |
TOO_MANY_REQUESTS | 并发数超过限制 | 429 |
INTERNAL_ERROR | 内部错误 | 500 |
示例
curl -X POST "https://openapi.faceid.com/lite_ocr/v1/get_biz_token"
-F sign=<sign>
-F sign_version=hmac_sha1
-F capture_image=<capture_image>
-F return_url=<return_url>
-F notify_url=<notify_url>
-F biz_no=<biz_no>
-F idcard_threshold=<idcard_threshold>
-F limit_completeness=<limit_completeness>
-F limit_quality=<limit_quality>
-F limit_logic=<limit_logic>
返回结果示例:成功
{
"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
下载"身份证识别微信小程序包"
下面以一个例子进行详细的说明,第一个页面(index页面)用来输入biz_token(biz_token的获取方式参见步骤1),点击确认后,会调用Face ID小程序进行验证。验证完成后,由verify.js处理回调。
下载得到的压缩包解压后得到faceid-components目录,将该目录添加至项目文件根目录。如下图所示:
在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 证书
其他说明
- 进入OCR Lite URL后,就开始进入了身份证识别的流程。
- 身份证拍摄流程中,用户按照提示,分别拍摄身份证人像面和国徽面,并进行识别。识别出错时,会提示用户,用户可以重新拍摄。
- 如果流程结束(身份证识别过程完成),或者过程中发生了不可重试的错误(例如余额不足,超过重试次数,等等),OCR Lite会跳转到用户之前定义的return url中。用户可通过get_result接口查询本次验证的详情。同时,我们还会向之前设置的notify_url发送一个post请求,包含识别结果相关信息。
- 处理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);
}
}
页面中典型错误提示和说明
错误提示 | 说明 |
---|---|
人像面识别错误,请重新拍摄 | 拍摄对应面照片未能被正常识别 |
国徽面识别错误,请重新拍摄 | 拍摄对应面照片未能被正常识别 |
第3步(可选):获取验证详细信息
API名称
get_result
说明
身份证识别流程结束后,用户服务器可以调用get_result接口,获取本次识别的详细信息。
API地址
GET https://openapi.faceid.com/lite_ocr/v1/get_result
参数
参数名 | 可选/必选 | 类型 | 说明 |
---|---|---|---|
sign | 必选 | String | 根据API_KEY和API_SECRET生成的签名,签名算法参见相关文档 |
sign_version | 必选 | String | 签名算法版本 |
biz_token | 必选 | String | get_biz_token接口返回的biz_token |
need_image | 必选 | Int | 是否需要返回身份证正反面照片及头像照片,1:返回、0:不返回 |
返回结果
字段 | 类型 | 说明 | |
---|---|---|---|
request_id | String | 用于标示本次请求的唯一的字符串,总返回该字段 | |
biz_no | String | 传入的业务流水号,原封不动地返回 | |
result_code | Int | 表示本次验证的结果状态码;开发者可结合:result_code、result_message知晓具体的结果、原因 | |
result_message | String | 开发者可通过此字段信息知晓具体的原因,具体见:result_code&result_code对照表 | |
image_frontside | String | 身份证人像面照片,Base64编码 | |
image_backside | String | 身份证国徽面照片,Base64编码 | |
name | Dict | 姓名。存在逻辑问题:姓名识别结果不合理:只有一个字/非汉字字符(允许存在“.”)(少数民族也应该是汉字,因为他们存在汉字的内容部分) | |
gender | Dict | 性别(男/女)。存在逻辑问题:性别识别结果与二代身份证号码第17位不匹配(奇数为男、偶数为女),或者男/女之外的其他值 | |
nationality | Dict | 民族(汉字)。不做逻辑判断,logic字段返回“0” | |
birth_year | Dict | 出生年份。存在逻辑问题:该结果与身份证号码7~10位不一致、若识别结果大于当前年份,或者小于1800 | |
birth_month | Dict | 出生月份。存在逻辑问题:该结果与身份证号码11~12位不一致,或者结果在1~12范围之外 | |
birth_day | Dict | 出生日。存在逻辑问题:该结果与身份证号码13~14位不一致,或识别结果在1~28/30/31(不同月份对应天数)之外 | |
idcard_number | Dict | 身份证号。注意:本字段返回的result里面如果某些字符被遮挡(internal:confidence过低)会返回“*”,此时quality=1(因为出星号,我们认为一定是存在遮挡等影戏那个识别的问题存在,或者十分模糊)。 存在逻辑问题:身份证号码规则不正确 | |
address | Dict | 住址。不做逻辑判断,logic字段返回“0” | |
portrait | Dict | 头像(在Result中返回Base64编码的String信息)。存在逻辑问题:如果没有检测到人脸,则“logic=1”,检测到人脸返回0 | |
issued_by | Dict | 签发机关。不做逻辑判断,logic字段返回0 | |
valid_date_start | Dict | 有效日期的起始时间,表示方法为8位数字,如:20150302。存在逻辑问题:有效期开始日期不存在、截止日期-开始日期<5年 | |
valid_date_end | Dict | 有效日期的结束时间,表示方法为8位数字或者汉字:长期。存在逻辑问题: 证件有效期到期时间在当前时间之前、有效期截止日期不存在或不为“长期”、截止日期-开始日期<5年 | |
+result | String | 表示以上会返回识别内容的区域才会返回的对应内容,若没有识别到,则返回空或者“null”;注意:如果没有识别出身份证,即result=2001时,或者内容字段没有识别出来,该内容字段的“result”返回空。 | |
+quality | Float | 表示该区域是否存在质量问题(存在影响识别的光斑、阴影、遮挡、污渍等),注意:存在质量问题如果是光斑,部分遮挡,也是可以识别出内容的,本字段对存在留存需求的场景提供参考。取[0,1]区间实数,3位有效数字,一般来说,这个质量分低于0.753,我们认为该区域存在质量问题。****注意:如果没有识别出身份证,即result=2001时,该内容字段的“quality”返回空。 | |
+rect | Dict | 返回字典结构,里面会包含区域的四点坐标 | |
+logic | Int | 表示该字段是否和其他某个字段存在逻辑问题;通常如果存在逻辑问题,可能是图片内容有问题,或者识别错误,但是有逻辑层的判断发现了。 0:表示正常;1:表示存在逻辑问题; | |
frontside_legality | Dict | 表示对身份证照片的五种分类的结果。它为一个结构体,包含五个key-value pair,每个key表示一种分类类型,每个value为此类型的概率值(取[0,1]区间实数,取3位有效数字,五个value总和为1)。这五个key是:ID_Photo:正式身份证照片、Temporary_ID_Photo:临时身份证照、Photocopy:正式身份证的复印件、Screen:手机或电脑屏幕翻拍的照片、Edited:用工具合成或者编辑过的身份证图片 ID_Photo_Threshold:表示判断为正式身份证照片的阈值,通常来说,如果ID_Photo的值不低于该阈值,可以认定为真实什么证的实拍 | |
frontside_completeness | Int | 表示身份证图片的完整性 0:表示身份证部分是完整的; 1:表示身份证不完整,但是内容区域全部都在图片内; 2:表示身份证不完整,且部分内容在区域外; 注意:如果没有识别出身份证,即result=2001时,此字段返回空。 | |
frontside_card_rect | Dict | 返回字典结构,里面会包含整张卡片四点坐标 | |
backside_legality | Dict | 表示对身份证照片的五种分类的结果。它为一个结构体,包含五个key-value pair,每个key表示一种分类类型,每个value为此类型的概率值(取[0,1]区间实数,取3位有效数字,五个value总和为1)。这五个key是:ID_Photo:正式身份证照片、Temporary_ID_Photo:临时身份证照、Photocopy:正式身份证的复印件、Screen:手机或电脑屏幕翻拍的照片、Edited:用工具合成或者编辑过的身份证图片 ID_Photo_Threshold:表示判断为正式身份证照片的阈值,通常来说,如果ID_Photo的值不低于该阈值,可以认定为真实什么证的实拍 | |
backside_completeness | Int | 表示身份证图片的完整性 0:表示身份证部分是完整的; 1:表示身份证不完整,但是内容区域全部都在图片内; 2:表示身份证不完整,且部分内容在区域外; 注意:如果没有识别出身份证,即result=2001时,此字段返回空。 | |
backside_card_rect | Dict | 返回字典结构,里面会包含整张卡片四点坐标 | |
ERROR | String | 发生错误后,会返回对应的错误码,具体见下面 ERROR 错误信息 |
结果码说明
result_code | result_message | 说明 |
---|---|---|
1001 | SUCCESS | 识别出身份证正反面均没有问题 |
1001 | SUCCESS_FRONTSIDE_SINGLE | 只需识别人像面时识别成功 |
1001 | SUCCESS_BACKSIDE_SINGLE | 只需识别国徽面时识别成功 |
1002 | SUCCESS_ALMOST_FRONTSIDE_SINGLE | 只需识别人像面时内容上存在没有识别出来、或者出来的内容存在逻辑问题、识别出来的内容存在质量问题 |
1002 | SUCCESS_ALMOST_BACKSIDE_SINGLE | 只需识别国徽面时内容上存在没有识别出来、或者出来的内容存在逻辑问题、识别出来的内容存在质量问题 |
1002 | SUCCESS_ALMOST_FRONTSIDE | 识别出身份证反面没有问题,身份证正面内容上存在没有识别出来、或者出来的内容存在逻辑问题、识别出来的内容存在质量问题 |
1002 | SUCCESS_ALMOST_BACKSIDE | 识别出身份证正面没有问题,身份证反面内容上存在没有识别出来、或者出来的内容存在逻辑问题、识别出来的内容存在质量问题 |
1002 | SUCCESS_ALMOST_BOTHSIDE | 识别出身份证正反面内容上均存在没有识别出来、或者出来的内容存在逻辑问题、识别出来的内容存在质量问题 |
2001 | NO_IDCARD_FRONTSIDE_SINGLE | 只需识别人像面时没有检测到人像面照片 |
2001 | NO_IDCARD_BACKSIDE_SINGLE | 只需识别国徽面时没有检测到国徽面照片 |
2001 | NO_IDCARD_FRONTSIDE | 没有检测到身份证正面照片 |
2001 | NO_IDCARD_BACKSIDE | 没有检测到身份证反面照片 |
2001 | NO_IDCARD_BOTHSIDE | 没有检测到身份证正反面照片 |
2002 | RESULT_NOT_ADEQUATE_BACKSIDE | 仅国徽面结果不满足要求 |
2002 | RESULT_NOT_ADEQUATE_FRONTSIDE | 仅人像面结果不满足要求 |
2002 | RESULT_NOT_ADEQUATE | 结果不满足要求(设定的默认标准或商户设定的判定标准) |
3100 | IDCARD_PHOTO_INVALID_SIZE | 图片大小尺寸错误 |
3100 | IDCARD_PHOTO_INVALID_FORMAT | 图片格式不正确 |
3100 | IDCARD_FRONTSIDE_BLURRED | 身份证人像面照片模糊,无法识别信息 |
4200 | SDK_TOO_OLD | SDK版本过旧,已经不被支持 |
4200 | MOBILE_PHONE_NOT_SUPPORT | 手机在不支持列表里 |
4200 | AUTHENTICATION_FAIL | 鉴权失败 |
4200 | BIZ_TOKEN_DENIED | 传入的 biz_token 不符合要求 |
5000 | REPLAY_ATTACK | 重放攻击,单次有效的签名被多次使用 |
5000 | INVALID_SIGN | 无效的签名 |
5000 | EXPIRED_SIGN | 签名过期 |
5000 | ACCOUNT_DISCONTINUED | 用户帐号已停用 |
5000 | MORE_RETRY_TIMES | 超过重试次数 |
5000 | BALANCE_NOT_ENOUGH | 余额不足 |
5000 | NON_ENTERPRISE_CERTIFICATION | 客户未进行企业认证 |
5000 | IP_NOT_ALLOWED | 不允许访问的IP |
5000 | API_KEY_BE_DISCONTINUED | api_key被停用 |
5000 | CONCURRENCY_LIMIT_EXCEEDED | 超过并发限制 |
6000 | INVALID_BUNDLE_ID | 信息验证失败,请重启程序或设备后重试 |
6000 | ILLEGAL_PARAMETER | 传入参数不合法 |
6000 | USER_CANCEL | 用户取消操作 |
6100 | 客户端上的通用错误信息,具体原因请关注返回的message信息 |
错误说明
error字段可能的错误包括:
HTTP状态码 | error | 说明 |
---|---|---|
400 | MISSING_ARGUMENTS: | 缺少某个必选参数(参数名为key) |
400 | BAD_ARGUMENTS: | 某个参数(参数名为key)解析出错 |
403 | AUTHENTICATION_ERROR | api_key和api_secret不匹配 |
403 | AUTHORIZATION_ERROR: | 鉴权失败,例如可能的原因是签名过期(EXPIRED_SIGN), 签名错误(INVALID_SIGN), API_KEY停用(API_KEY_BE_DISCONTINUED),未进行企业认证(NON_ENTERPRISE_CERTIFICATION),余额不足(BALANCE_NOT_ENOUGH), 等等 |
404 | API_NOT_FOUND | 所调用的API不存在 |
413 | Request Entity Too Large | 客户发送的请求大小超过了20MB限制或单张照片大小超过了10MB |
429 | TOO_MANY_REQUESTS | 并发数超过限制 |
500 | API_NOT_FOUND | 服务器内部错误 |
result示例
result:
{
"biz_token": "1535449056,442eabe3-38cd-4403-9b4d-08adfd9be860",
"biz_no": "",
"result_code": 1001,
"result_message": "SUCCESS",
"name": {
"result": "刘*",
"rect": {
"lb": {
"x": 229,
"y": 149
},
"lt": {
"x": 229,
"y": 112
},
"rb": {
"x": 327,
"y": 150
},
"rt": {
"x": 327,
"y": 113
}
},
"quality": 0.825,
"logic": 0
},
"gender": {
"result": "男",
"rect": {
"lb": {
"x": 229,
"y": 219
},
"lt": {
"x": 229,
"y": 188
},
"rb": {
"x": 258,
"y": 219
},
"rt": {
"x": 258,
"y": 188
}
},
"quality": 0.845,
"logic": 0
},
"nationality": {
"result": "汉",
"rect": {
"lb": {
"x": 401,
"y": 220
},
"lt": {
"x": 401,
"y": 191
},
"rb": {
"x": 430,
"y": 221
},
"rt": {
"x": 430,
"y": 191
}
},
"quality": 0.852,
"logic": 0
},
"birth_year": {
"result": "1998",
"rect": {
"lb": {
"x": 227,
"y": 281
},
"lt": {
"x": 227,
"y": 254
},
"rb": {
"x": 292,
"y": 281
},
"rt": {
"x": 292,
"y": 254
}
},
"quality": 0.851,
"logic": 0
},
"birth_month": {
"result": "10",
"rect": {
"lb": {
"x": 364,
"y": 282
},
"lt": {
"x": 364,
"y": 255
},
"rb": {
"x": 385,
"y": 282
},
"rt": {
"x": 385,
"y": 255
}
},
"quality": 0.85,
"logic": 0
},
"birth_day": {
"result": "27",
"rect": {
"lb": {
"x": 442,
"y": 282
},
"lt": {
"x": 442,
"y": 256
},
"rb": {
"x": 471,
"y": 282
},
"rt": {
"x": 471,
"y": 256
}
},
"quality": 0.855,
"logi c": 0
},
"idcard_number": {
"result": "******************",
"rect": {
"lb": {
"x": 353,
"y": 528
},
"lt": {
"x": 353,
"y": 496
},
"rb": {
"x": 820,
"y": 525
},
"rt": {
"x": 821,
"y": 494
}
},
"quality": 0.849,
"logic": 0
},
"address": {
"result": "四川省***************",
"rect": {
"lb": {
"x": 226,
"y": 398
},
"lt": {
"x": 226,
"y": 323
},
"rb": {
"x": 578,
"y": 398
},
"rt": {
"x": 578,
"y": 324
}
},
"quality": 0.861,
"logic": 0
},
"portrait": {
"result": "",
"logic": 0,
"quality": 1,
"rect": {
"lb": {
"x": 602,
"y": 442
},
"lt": {
"x": 603,
"y": 130
},
"rb": {
"x": 869,
"y": 442
},
"rt": {
"x": 873,
"y": 132
}
}
},
"issued_by": {
"result": "海淀区公安局",
"rect": {
"lb": {
"x": 269,
"y": 274
},
"lt": {
"x": 269,
"y": 254
},
"rb": {
"x": 382,
"y": 272
},
"rt": {
"x": 381,
"y": 252
}
},
"quality": 0.615,
"logic": 0
},
"valid_date_start": {
"result": "20180101",
"rect": {
"lb": {
"x": 272,
"y": 320
},
"lt": {
"x": 272,
"y": 300
},
"rb": {
"x": 472,
"y": 316
},
"rt": {
"x": 471,
"y": 296
}
},
"quality": 0.633,
"logic": 0
},
"valid_date_end": {
"result": "20230101",
"rect": {
"lb": {
"x": 272,
"y": 320
},
"lt": {
"x": 272,
"y": 300
},
"rb": {
"x": 472,
"y": 316
},
"rt": {
"x": 471,
"y": 296
}
},
"quality": 0.633,
"logic": 0
},
"frontside_legality": {
"Photocopy": 0,
"Edited": 0,
"ID_Photo": 0.975,
"Screen": 0.025,
"Temporary_ID_Photo": 0,
"ID_Photo_Threshold": 0.8
},
"frontside_completeness": 0,
"frontside_card_rect": {
"lb": {
"x": 59,
"y": 586
},
"lt": {
"x": 58,
"y": 33
},
"rb": {
"x": 920,
"y": 580
},
"rt": {
"x": 927,
"y": 43
}
},
"backside_legality": {
"Photocopy": 0,
"Edited": 0,
"ID_Photo": 0.994,
"Screen": 0.006,
"Temporary_ID_Photo": 0,
"ID_Photo_Threshold": 0.8
},
"backside_completeness": 0,
"backside_card_rect": {
"lb": {
"x": 26,
"y": 357
},
"lt": {
"x": 51,
"y": 29
},
"rb": {
"x": 606,
"y": 345
},
"rt": {
"x": 564,
"y": 16
}
},
"request_id": "1535449059,b1759a81-df3c-413d-84bc-1920c1c0e6f8",
"time_used": 80
}
当前版本
- v1.0.0