原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://ask.dcloud.net.cn/article/35763
iOS 离线打包原生插件另见文档 https://ask.dcloud.net.cn/article/35764


概述

云识客互联网人脸核身通过检测身份证人像照,与活体检测的人脸照做比对,判断是否是同一人,并返回身份证文字信息。包括如下功能:

1 . 身份证检测识别:扫描身份证,获取身份证照片与身份证人像,并识别身份证文字信息

2 . 活体检测:本地端动作活体检测+云端防攻击,确保当前用户是真人,防止照片欺诈,视频翻拍等问题

3 . 人脸比对:将活体照与身份证人像照进行人脸比对,返回相似度

4 . 实人认证:将姓名、身份证号、活体照送至权威机关核验,判断信息是否是一致。

5 . 刷脸登录:包括人脸注册和人脸登录两步,通过实人认证或活体检测返回人脸特征码完成人脸注册;将人脸特征码和当前登录照片调用人脸登录接口,完成人脸登录。

商户接入操作步骤

开发者在使用云识客插件(插件名:Zhiqu-ySKAuth)时,需要联系市场人员开通服务,获取appKey和secretKey值后,方可使用云识客插件。整体流程分为以下步骤:

1.联系云识客 开发者在使用云识客的插件时,可通过电话(0571-56278596)或者官网(http://www.yskplus.com)联系云识客。

2.对接 请双方商务人员完成开户。在开户过程中,商户需提供商户名称;智趣智能将提供app_key和secret_key。 友情提醒:app_key和secret_key为商户的重要身份信息,商户需要自行妥善保管。

3.开始对接 商户导入云识客的插件(插件名:Zhiqu-ySKAuth),打包编译并使用。在开发或使用插件接口时,产生疑问或出现问题,可通过微信、Email、手机联系相关技术人员,相关技术支持人员会及时处理。

4.完成以上步骤,即可开始对接联调

版本兼容

编译时候的固件版本android4.0.2(minSdkVersion 15)以上,IOS8.0以上的终端设备使用。

UI界面图

身份证OCR识别UI页面、身份识别结果页面、活体检测UI页面如下:

注:如UI界面图所示,参考调用方法,成功调用出现”身份证OCR”界面扫描身份证,OCR完成确认扫描信息后进入活体检测界面。该流程UI界面等已封装,商户可按流程完成操作无须自定义。

参数约定

  1. 是否必传:指接口的请求报文和返回报文中的参数:Y表示必传参数;N表示非必传参数;
  2. 返回结果码:表示功能调用是否成功

调用步骤

  • 引入云识客插件 const ySKAuth = uni.requireNativePlugin('Zhiqu-ySKAuth')

人脸核身全流程

  • 人脸核身全流程包括身份证OCR,活体检测,人脸比对和实人认证4项功能,其调用与回调方法为:startAuth,调用示例如下
         // 入参示例
         params: {
            appKey: '请替换自己的appKey',       //必选
            secretKey: '请替换自己的secretKey', //可选,secretKey和token二选一,建议使用secretKey
            traceId: "xxx",       //必选,商户跟踪id,请保证唯一不重复
            token:"xxx",          //可选,secretKey和token二选一
            notifyUrl: 'xxx',     //可选,异步通知地址
            extensionInfo: 'xxx', //可选,额外的异步通知信息
            isOcrFirst: true,     //可选,默认true先做ocr
            needUserGuide: true,  //可选, 默认true显示引导弹窗
            idCardOperation: {
                mode: 'FRONT_RECOGNIZE_BACK_RECOGNIZE',
                displayInfo:'1,2',
                modifyInfo:'1'
            },
            livenessOperation: {
                actionNum: 3,
                actions: '0,1,2,3,6',
                openSpeaker: true,
                realAuth: true,
                isNeedFaceCompare: true,
            }
        }   
      // 云识客全流程 
      runySKAuth() {
        var p = JSON.parse(JSON.stringify(this.params))
        ySKAuth.startAuth(p, function(ret) {
            if (!ret.resultCode) {
                console.log('result: success')
            } else {
                console.log('result: fail'+ret)
            }
        });
     }

身份证OCR

  • 身份证OCR的调用与回调方法:startOcr,调用示例如下
         // 入参示例
         params: {
            appKey: '请替换自己的appKey',       //必选
            secretKey: '请替换自己的secretKey', //可选,secretKey和token二选一,建议使用secretKey
            traceId: "xxx",       //必选,商户跟踪id,请保证唯一不重复
            token:"xxx",          //可选,secretKey和token二选一
            notifyUrl: 'xxx',     //可选,异步通知地址
            extensionInfo: 'xxx', //可选,额外的异步通知信息
            needUserGuide: true,  //可选, 默认true显示引导弹窗
            idCardOperation: {
                mode: 'FRONT_RECOGNIZE_BACK_RECOGNIZE',
                displayInfo:'1,2',
                modifyInfo:'1'
            }
        }   
       // 云识客身份证ocr
      runOcrAuth() {
            var p = JSON.parse(JSON.stringify(this.params))
            ySKAuth.startOcr(p, function(ret) {
                if (!ret.resultCode) {
                    console.log('result: success')
                } else {
                    console.log('result: fail'+ret)
                }
           });
       } 

活体检测

  • 活体检测的调用与回调方法:startLiveness,调用示例如下
         // 入参示例
         params: {
            appKey: '请替换自己的appKey',       //必选
            secretKey: '请替换自己的secretKey', //可选,secretKey和token二选一,建议使用secretKey
            traceId: "xxx",       //必选,商户跟踪id,请保证唯一不重复
            token:"xxx",          //可选,secretKey和token二选一
            notifyUrl: 'xxx',     //可选,异步通知地址
            extensionInfo: 'xxx', //可选,额外的异步通知信息
            needUserGuide: true,  //可选, 默认true显示引导弹窗
            livenessOperation: {
                actionNum: 3,
                actions: '0,1,2,3,6',
                openSpeaker: true,
                isCompare: false,
                compareImage: 'xxx', // base64格式图片
                compareImageType: "IMAGE_TYPE_ID_FACE"
            }
        }           
        // 云识客活体检测
        runLivenessAuth() {
            var p = JSON.parse(JSON.stringify(this.params))
            ySKAuth.startLiveness(p, function(ret) {
                if (!ret.resultCode) {
                    console.log('result: success')
                } else {
                    console.log('result: fail'+ret)
                }
            });
        }

刷脸登录

刷脸登录功能调用分步:

第一步:人脸注册

【场景1】:常规流程(推荐使用)

首先通过人脸注册完成第一步。

人脸注册描述:流程如图一所示:

  • 当需要人脸核身时,前端通过调用startAuth()方法完成人脸注册,并获取到人脸特征值,保存到服务端,关联到当前注册账号。
  • 当需要活体检测时,前端通过调用startLiveness()方法完成人脸注册,并获取到人脸特征值,保存到服务端,关联到当前注册账号。

刷脸注册

                                    <u>图一</u>

【场景2】:使用历史已存留的人脸照作为注册人脸照片

系统中已有用户且存有用户人脸照(人脸照片要求高清正脸),可通过人脸注册API接口完成第一步。

描述:服务端通过调用人脸注册API接口 face_feature 传入用户人脸照,获取到人脸特征值,保存到服务端,关联到当前注册账号。

第二步:刷脸登录

首先前端通过调用startLogin() 方法获取活体照,将活体照回传自己的服务端。然后服务端根据当前登录账号,获取对应的注册人脸特征值,使用人脸特征值和活体照调用云识客服务端接口face_login,根据返回相似度判断是否为同一人,流程如图二所示:

刷脸登录

                                    <u>图二</u>

接口列表说明:

接口列表

  • 刷脸登录调用与回调方法:startLogin(),调用示例如下
      // 入参示例
       params: {
        appKey: '请替换自己的appKey',       //必选
        secretKey: '请替换自己的secretKey', //可选,secretKey和token二选一
        traceId: "xxx", //必选,商户跟踪id,请保证唯一不重复
        token:"xxx",    //可选,secretKey和token二选一
        livenessOperation: {
            actionNum: 1,
            actions: '0,1,2,3'
        }
        }           
        // 云识客刷脸登陆
        startLogin(){
            var p = JSON.parse(JSON.stringify(this.params))
            ySKAuth.startLogin(p, function(ret) {
                if (!ret.resultCode) {
                    console.log('result: success')
                } else {
                    console.log('result: fail'+ret)
                }
            });
        }
  • 入参配置参数列表
参数名 是否必传 参数类型 参数说明 描述
appKey Y String 商户开户后的appKey 用于商户权限校验
secretKey N String 商户开户后的secretKey 用于通讯报文验签,secretKey和token二选一,建议使用secretKey方式
token N String 从后端获取的临时密钥 用于通讯报文验签,有实效性,必须每次调用重新获取。建议使用secretKey方式。
获取方式:Token获取方式
traceId Y String 商户接口调用跟踪号 商户跟踪号,建议唯一
notifyUrl N String 商户接收异步通知的web url 当需要接收异步通知时设定,默认不设置
extensionInfo N String 商户异步通知需要的额外信息 当需要接收异步通知且有其他额外需要添加的信息时设置,默认不设置
needUserGuide N boolean 是否显示用户使用说明窗口 当需要显示用户使用说明窗口时设置为true,默认为true(显示)
isOcrFirst Y boolean 是否先加载OCR true:先OCR后活体
false:先活体后OCR
idCardOperation Y IDCardOperation OCR功能选项 OCR功能选项封装类,字段详细见下面说明
idCardOperation.mode Y String ocr检测动作模式 正面、反面、检测、识别等功能选项。可选值见:OCR检测识别模式
idCardOperation.displayInfo N String 识别结果页允许显示信息集合 默认只显示姓名和身份证号。可选值见:OCR识别结果页显示和修改信息
idCardOperation.modifyInfo N String 识别结果页允许修改的信息集合 默认只允许修改显示姓名。可选值见:OCR识别结果页显示和修改信息
livenessOperation Y LivenessOperation 活体检测功能选项 根据业务需要设定,包括多个子参数。
livenessOperation.actionNum N int 活体动作数量 商户可以自定义,默认值为3,表示三个随机动作。动作数量不能少于1个,不能大于3个。
livenessOperation.actions N String 自定义动作,最多不超过3个,用逗号隔开 数量不能小于设置的actionNum。默认为系统支持的全部动作。可添加的动作类型见:活体检测动作类型
livenessOperation.realAuth N boolean 是否实人认证 当调用全流程(startAuth方法)时设置,默认true(实人)
livenessOperation.isNeedFaceCompare N boolean 是否进行人脸比对 当调用全流程(startAuth方法)时设置,默认true((比对)
livenessOperation.isCompare N boolean 是否需要和外部照片比对 当调用活体检测(startLiveness方法)时设置,默认false(不对比)
livenessOperation.compareImage N String 比对的外部图片 当调用活体检测(startLiveness方法),且需要和外部比对时设置,默认null
livenessOperation.compareImageType N String 比对的外部图片类型 当调用活体检测(startLiveness方法),且需要和外部比对时设置。支持的类型见:比对图片类型

OCR检测识别模式

FRONT_RECOGNIZE——正面检测识别;
FRONT_RECOGNIZE_BACK_DETECT——正面检测识别+反面检测;
FRONT_RECOGNIZE_BACK_RECOGNIZE——正面检测识别+反面检测识别;

OCR识别结果页显示和修改信息

-1——不显示或不修改所有信息;
0——身份证人像;
1——姓名;
2——公民身份证号码;
3——性别;
4——民族;
5——出生;
6——地址;
7——签发机关;
8——有效期限;

活体检测动作类型

idlivenessOperation.actions
0--眨眼;
1--微笑;
2--左转头;
3--右转头;
6--左右摇头;(刷脸登录不支持该模式)

比对图片类型

idlivenessOperation.compareImageType
活体人脸照(IMAGE_TYPE_LIVE_FACE)
证件人脸照(IMAGE_TYPE_ID_FACE)
水印人脸照(IMAGE_TYPE_WATER_FACE)

回调返回结果

success回调结果示例

  //success回调
  {
    "zqOrderId": "xxx",
    "idCardFrontInfo": {
        "name": "xxx",
        "idNo": "xxx",
        "address": "xxx",
        "birth": "xxx",
        "gender": "xxx",
        "race": "xxx",
        "cardImage": "base64格式图片",
        "faceImage": "base64格式图片"
    },
    "idCardBackInfo": {
        "issuedBy": "xxx",
        "validDate": "xxx",
        "cardImage": "base64格式图片"
    },
    "newIDCardInfo": {
        "newName": "xxx",
        "newIdNo": "xxx",
        "newGender": "xxx",
        "newBirth": "xxx",
        "newRace": "xxx",
        "newAddress": "xxx",
        "newIssuedBy": "xxx",
        "newValidDate": "xxx"
    },
    "livenessCompareInfo": {
        "livenessScore": "xxx",
        "similarity": "xxx",
        "verifyStatus": 0,
        "reason": "xxx",
        "reasonCode": 0,
        "realAuthSimilarity": 0.7,
        "liveImageFeature": "xxx",
        "faceImage": "base64格式图片"
    }
  } 

success回调参数列表

字段名称 字段描述 是否必传 备注
zqOrderId 云识客订单号 Y
idCardFrontInfo
idCardFrontInfo.idNo 居民身份证18位号码 Y
idCardFrontInfo.name 居民身份证姓名 Y
idCardFrontInfo.gender 性别 Y 男/女
idCardFrontInfo.birth 生日 Y 格式为yyyy.MM.dd
idCardFrontInfo.race 民族 Y 汉字
idCardFrontInfo.address 地址 Y
idCardFrontInfo.cardImage 证件正面图片 Y base64格式
idCardFrontInfo.faceImage 证件人像照图片 Y base64格式
idCardBackInfo
idCardBackInfo.issuedBy 居民身份证发证机关 N
idCardBackInfo.validDate 居民身份证有效期 N 两种格式。16位长度的字符串:
YYYY.MM.DD-YYYY.MM.DDYYYY.MM.DD-长期
idCardBackInfo.cardImage 证件反面图片 N base64格式
newIDCardInFo
newIDCardInFo.idNo 修改后居民身份证18位号码 N
newIDCardInFo.name 修改后居民身份证姓名 N
newIDCardInFo.gender 修改后性别 N 男/女
newIDCardInFo.birth 修改后生日 N 格式为yyyy.MM.dd
newIDCardInFo.race 修改后民族 N 汉字
newIDCardInFo.address 修改后地址 N
newIDCardInFo.issuedBy 修改后居民身份证发证机关 N
newIDCardInFo.validDate 修改后居民身份证有效期 N 两种格式。16位长度的字符串:
YYYY.MM.DD-YYYY.MM.DDYYYY.MM.DD-长期
livenessCompareInfo
livenessCompareInfo.livenessScore 活体置信度 Y 0到1之间,如何取值参见:活体置信度阈值说明
livenessCompareInfo.similarity 活体和身份证人脸照片相似度 Y 0到1之间,如何取值参见:活体和身份证人脸照片比对相似度阈值说明
livenessCompareInfo.faceImage 活体清晰照 Y base64格式
livenessCompareInfo.verifyStatus 实人认证状态 N 0:不通过
1:通过
livenessCompareInfo.reason 实人认证结果描述 N 认证通过
姓名身份证号不匹配
人脸与公安底库不一致
认证异常
livenessCompareInfo.reasonCode 实人认证失败原因编码 N 0: 姓名身份证号不匹配
1: 人脸与公安底库不一致
2: 认证异常
livenessCompareInfo.liveImageFeature 活体照的特征码 Y 当且仅当实人认证通过时不为空;(String)
人脸特征码,用于人脸登录时,解析历史用户的人脸特征。注册完成后返回,请保存至服务端
livenessCompareInfo.realAuthSimilarity 活体照与权威照片的比对相似度 N 相似度值大于0.7,认证状态通过,反之不通过

error回调结果示例

  //error回调
  {
    "zqOrderId": "xxx",
    "resultCode": 900001,
    "resultMessage": "xxx",
    "resultDetail": "xxx"
  }

error回调参数列表

字段名称 字段描述 是否必传 备注
zqOrderId 云识客订单号 Y
resultCode 结果码 Y 结果码参见:回调结果码
resultMessage 结果码描述 Y
resultDetail 结果码详情 Y

回调结果码

结果码 ErrorCode枚举 结果码描述 结果码详情
200001 LIVENESS_DETECT_RECOGNIZE_ERROR 活体检测识别失败 活体检测识别失败
200002 USER_COUNTOUT 活体错误次数超限 活体错误次数超限
300001 OCR_TIMESOUT 身份证扫描次数超限 身份证扫描次数超限
900001 PARAM_INVALID 参数无效 无效参数说明
900002 NO_NETWORK 无网络连接 无网络连接
900003 AUTH_ERROR sdk授权失败 授权错误信息
900004 USER_CANCEL 用户取消 用户取消
900005 CAMERA_ERROR 打开摄像头失败 打开摄像头失败
900006 USER_TIMEOUT 用户操作超时 用户操作超时
999999 PRO_ERROR 处理错误 处理错误

活体置信度阈值说明

误拒率(FRR) 阈值
千分之一 0.3
千分之五 0.5
百分之一 0.6
百分之三 0.7
百分之五 0.8
  • 误拒率(FRR):如千分之五,指1000次真人请求,会有5次因为活体分数低于阈值被错误拒绝;
  • 阈值:将阈值与返回的livenessScore进行比较,可以作为判断是否为活体的依据;
  • 建议商户根据自身业务场景设置阈值,一般场景设置为0.5,严格场景可设置为0.7或更高;
  • 模型升级不影响活体分数的阈值范围(云识客已经进行了归一化处理);

活体和身份证人脸照片比对相似度阈值说明

误识率(FPR) 阈值
千分之一 0.7
万分之一 0.8
十万分之一 0.9
百万分之一 0.95
  • 误识率(FPR):如千分之一,指1000次不同人的两张照片比对,会有1次因高于阈值而被识别成同一个人;
  • 阈值:将阈值与返回的similarity进行比较,可以作为判断是否为同一个人的依据;
  • 建议商户根据自身业务场景设置阈值,如一般场景设置为0.7,严格场景可设置为0.8或更高;
  • 模型升级不影响相似度阈值范围(云识客已经进行了归一化处理)

服务端对接说明

获取token API接口

功能:获取token,用于通讯报文验签,有实效性,必须每次调用重新获取,跟secretKey方式二选一。

输入:trace_id 。

输出:token。

Url: https://face.zhiquplus.com/api/faceid/1.1/{app_key}/get_token
Method: POST
Content-Type: multipart/form-data;

请求参数

字段名 必传 类型 字段说明 描述
trace_id Y String 接口唯一调用ID 接口调用的唯一标识号,长度不超过36,用于追踪订单,请保持全局唯一

返回字段

字段名 必传 类型 字段说明 描述
token Y String token

请求代码示例

def get_token():
    import uuid
    import requests
    import json

    __app_key = '351Xaxg4XfvAYxrVagDcDcJn4'
    url = "https://face.zhiquplus.com/api/faceid/1.1/{}/get_token".format(__app_key)
    param = {
        'trace_id': uuid.uuid4().hex
    }
    res = requests.post(url, data=param)
    if res.status_code == 200:
        json_data = json.loads(res.text)
        if json_data.get('success'):
            print(json_data['data'])
        else:
            print(json_data)
    else:
        print(res.text)

返回报文示例

成功请求返回值示例
{
  "success": true,
  "data": {
      "token": "40EGb6BOHs0ZJf4gKtL3Y1dwnGIHIjOB"
  }
}
失败请求返回值示例
{
    "success": false,
    "zqzn_trace_id": "388375750635421696",
    "error_code": "000001",
    "message": "PARAMS_NOT_SET_ERROR:[缺少必填参数[trace_id]]"
}

人脸注册API接口

功能:使用已保存的人脸图片提取人像特征码,保存到服务端对应的账户下,等同于SDK人脸注册获取特征码。

输入:人脸图片。

输出:特征码。

Url: https://face.zhiquplus.com/api/faceid/1.1/{app_key}/face_feature
Method: POST
Content-Type: multipart/form-data;

请求参数

字段名 必传 类型 字段说明 描述
image Y File 活体照片 见文档说明中的输入图片要求

返回字段

字段名 必传 类型 字段说明 描述
feature Y String 人脸特征码 用于人脸登录,可解析人脸特征信息。请在注册完成时保存

请求代码示例

def face_feature():
    import uuid
    import requests
    import json

    __app_key = '351Xaxg4XfvAYxrVagDcDcJn4'
    url = "https://face.zhiquplus.com/api/faceid/1.1/{}/face_feature".format(__app_key)
    param = {
        'trace_id': uuid.uuid4().hex
    }
    files = {
        'image': ('ocrb.jpg', open("D:/tmp/face/ocrb.jpg", 'rb'), 'image/jpeg')
    }
    res = requests.post(url, data=param, files=files)
    if res.status_code == 200:
        json_data = json.loads(res.text)
        if json_data.get('success'):
            print(json_data['data'])
        else:
            print(json_data)
    else:
        print(res.text)

返回报文示例

成功请求返回值示例
{
  "success": true,
  "data": {
    "feature": "lYB1Vx0j96Zx8FeY0d3E5BMNeewD9g..."
  },
  "zqzn_trace_id":"388353872072015872"
}
失败请求返回值示例
{
    "success": false,
    "zqzn_trace_id": "388375750635421696",
    "error_code": "000001",
    "message": "PARAMS_NOT_SET_ERROR:[缺少必填参数[trace_id]]"
}

刷脸登录API接口

功能:用于比对待登录人脸图片与已注册人脸特征的相似度。

输入:人脸图片、人脸特征、活体照是否需要静默活体检测。

输出:相似度、活体分数。

Url: https://face.zhiquplus.com/api/faceid/1.1/{app_key}/face_login
Method: POST
Content-Type: multipart/form-data;

请求参数

字段名 必传 类型 字段说明 描述
image1 Y File 图片1 见文档说明中的输入图片要求
image1_liveness N Int 是否需要静默活体检测 是否需要静默活体检测;
默认值为0(不检测活体)
image2_feature Y String 图片2特征

是需要静默活体检测

  • 0,不返回图片的活体检测分数,
  • 1,返回图片的活体检测分数;

返回字段

字段名 必传 类型 字段说明 描述
similarity Y Float 相似度 相似度取值范围 [0,1],保留6位小数,数值越大表示两个人脸越可能是同一个人。
image1_liveness_score N Float image1的活体分数 活体分数取值范围 [0,1],保留6位小数,数值越大表示照片是活体的可能性越大。

人脸比对相似度阈值说明

误识率(FPR) 阈值
千分之一 0.7
万分之一 0.8
十万分之一 0.9
百万分之一 0.95
  • 误识率(FPR):如千分之一,指1000次不同人的两张照片比对,会有1次因高于阈值而被识别成同一个人;
  • 阈值:将阈值与返回的similarity进行比较,可以作为判断是否为同一个人的依据;
  • 建议商户根据自身业务场景设置阈值,如一般场景设置为0.7,严格场景可设置为0.8或更高;
  • 模型升级不影响相似度阈值范围(智趣智能已经进行了归一化处理);

活体分数阈值说明

误拒率(FRR) 阈值
千分之一 0.3
千分之五 0.5
百分之一 0.6
百分之三 0.7
百分之五 0.8
  • 误拒率(FRR):如0.5%,指1000次真人请求,会有5次因为活体分数低于阈值被错误拒绝;
  • 阈值:将阈值与返回的image1_liveness_score进行比较,可以作为判断image1是否为活体的依据;
  • 建议商户根据自身业务场景设置阈值,一般场景设置为0.5,严格场景可设置为0.7或更高;
  • 模型升级不影响活体分数的阈值范围(智趣智能已经进行了归一化处理);

请求代码示例

def face_login():
    import uuid
    import requests
    import json

    __app_key = '351Xaxg4XfvAYxrVagDcDcJn4'
    url = "https://face.zhiquplus.com/api/faceid/1.1/{}/face_login".format(__app_key)
    param = {
        'trace_id': uuid.uuid4().hex,
        'image1_liveness': 0,
        'image2_feature': 'VW+2ARu7C7TFbnLARTHbPs6N...'
    }
    files = {
        'image1': ('1.jpg', open("D:/tmp/face/1.jpg", 'rb'), 'image/jpeg')
    }
    res = requests.post(url, data=param, files=files)
    if res.status_code == 200:
        json_data = json.loads(res.text)
        if json_data.get('success'):
            print(json_data['data'])
        else:
            print(json_data)
    else:
        print(res.text)

返回报文示例

成功请求返回值示例
{
  "success": true,
  "data":{
        "similarity": 0.560714,
        "image1_liveness_score": 0.860112
  },
  "zqzn_trace_id":"388353872072015872"
}
失败请求返回值示例
{
    "success": false,
    "zqzn_trace_id": "388375750635421696",
    "error_code": "000001",
    "message": "PARAMS_NOT_SET_ERROR:[缺少必填参数[trace_id]]"
}

API错误码对照表

错误码对照表中,错误码为error_code字段,错误信息为message字段;
错误信息(message)会在后端服务升级时发生变化,请以错误码(error_code)作为判断依据;

通用错误码

错误码 错误信息 错误含义
000001 PARAMS_NOT_SET_ERROR:[错误详情] 参数缺失
000002 PARAMS_CHECK_ERROR:[错误详情] 参数校验错误
001000 PROCESS_ERROR:[错误详情] 内部处理错误
002001 INVALID_APP_KEY:[错误详情] app_key无效
002002 INVALID_SERVICE_CODE:[错误详情] 服务未开通
002003 INVALID_SIGNATURE:[错误详情] 签名校验不通过
002004 INVALID_REQUEST_IP:[错误详情] 请求ip不在ip白名单列表
002005 INVALID_ACCOUNT:[错误详情] 账户未开通
002006 ACCOUNT_INSUFFICIENT_BALANCE:[错误详情] 账户余额不足或服务可用次数不足
002007 TOO_MANY_REQUESTS:[错误详情] 请求TPS超过最大限制
999999 UNKNOWN_ERROR:[错误详情] 未知错误

业务错误码

错误码 错误信息 错误含义
100004 FACE_COMP_IMAGE_NO_FACE:[错误详情] 人脸比对的图像中找不到人脸

API调用示例代码(Java)

依赖Maven包

需要在MAVENPOM文件中添加以下依赖:

  <dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpmime</artifactId>
        <version>4.5.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
 </dependencies>

测试用例

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import org.apache.http.HttpEntity;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.UUID;

/**
 * 智趣智能-人脸认证API-V1.1-单元测试用例
 */
public class ZqznAPIDemoV11 {
    //服务地址
    final static String ROOT_URL = "https://face.zhiquplus.com/api/faceid/1.1";
    //服务调用app_key,开户时分配给商户
    final static String APP_KEY = "xxx";

    /**
     * HTTP 请求处理
     */
    private JsonObject apiRequest(String url, HttpEntity reqEntity) {
        JsonObject resData = null;
        String res = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(reqEntity);
            HttpClient httpClient = HttpClients.createDefault();
            HttpEntity httpEntity = httpClient.execute(httpPost).getEntity();
            res = EntityUtils.toString(httpEntity);
        } catch (Exception e) {
            e.printStackTrace();
            //todo 调用异常:商户异常处理逻辑
        }
        if (res != null) {
            JsonObject resJson = new JsonParser().parse(res).getAsJsonObject();
            System.out.println(String.format("result:%s", res));
            if (resJson.get("success").getAsBoolean()) {
                resData = resJson.getAsJsonObject("data");
            } else {
                //todo 调用异常:商户业务处理逻辑
                String errorCode = resJson.get("error_code").getAsString();
                String message = resJson.get("message").getAsString();
                System.out.println(String.format("错误码:%s , 错误信息:%s", errorCode, message));
            }
        }
        return resData;
    }

    /**
     * 获取token
     */
    @Test
    public void test_get_token() throws IOException {
        String url = String.format("%s/%s/get_token", ROOT_URL, APP_KEY);
        //trace_id 可为商户业务系统的订单号,用于后续问题跟踪
        String traceId = UUID.randomUUID().toString();
        HttpEntity reqEntity = MultipartEntityBuilder.create()
                .addTextBody("trace_id", traceId)
                .build();
        JsonObject resData = apiRequest(url, reqEntity);
        if (resData != null) {
            //todo 调用成功:商户业务逻辑
        }
    }

    /**
     * 刷脸登录
     */
    @Test
    public void test_face_login() {
        String url = String.format("%s/%s/face_login", ROOT_URL, APP_KEY);
        //trace_id 可为商户业务系统的订单号,用于后续问题跟踪
        String traceId = UUID.randomUUID().toString();
        File image1 = new File("/tmp/face/1.jpg");
        String image2_feature = 'VW+2ARu7C7TFbnLARTHbPs6N...';
        //图片1是否检测活体
        String image1_liveness = "1";
        HttpEntity reqEntity = MultipartEntityBuilder.create()
                .addTextBody("trace_id", traceId)
                .addTextBody("image1_liveness", image1_liveness)
                .addBinaryBody("image1", image1, ContentType.create("image/jpeg"), image1.getName())
                .addTextBody("image2_feature", image2_feature)
                .build();
        JsonObject resData = apiRequest(url, reqEntity);
        if (resData != null) {
            //todo 调用成功:商户业务逻辑
        }
    }
}

API调用示例代码(PHP)

测试代码依赖composer进行包管理;在运行前先执行php composer.phar install下载依赖;

依赖Composer包

composer.json文件

{
  "require": {
    "guzzlehttp/guzzle": "~6.0"
  }
}

依赖phar包

下载guzzle-6.3.3.phar,并以include 'guzzle.phar引入;

测试用例

<?php
//for composer
//require 'vendor/autoload.php';

//for local lib
include 'guzzle.phar';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

//服务地址
$root_url = "https://face.zhiquplus.com/api/faceid/1.1";
//todo 服务调用app_key,开户时分配给商户
$app_key = 'xxx';

test();

//测试入口
function test()
{
    get_token();
    face_login();
}

/***
 * 接口调用公共方法
 * @param $url string
 * @param $multipartData  array
 * @return mixed json对象
 */
function http_request($url, $multipartData)
{
    $response = null;
    try {
        $client = new Client([
            'curl' => [CURLOPT_SSL_VERIFYPEER => false]
        ]);
        $response = $client->request('POST', $url, ['multipart' => $multipartData]);
    } catch (GuzzleException $e) {
        print($e);
        //todo 调用异常:商户异常处理逻辑
    }
    if (empty($response)) {
        //todo 调用异常:商户异常处理逻辑
        return null;
    }
    $resJsonObj = $response->getBody();
    $result = json_decode($resJsonObj, true);
    print_r($result);
    return $result;
}

/**
 * 获取token
 */
function get_token()
{
    $url = sprintf("%s/%s/get_token", $GLOBALS['root_url'], $GLOBALS['app_key']);

    $multipartData = [
        ['name' => 'trace_id', 'contents' => time()]
    ];
    $result = http_request($url, $multipartData);
    if ($result["success"]) {
        return $result["data"];
    } else {
        //todo 输入参数不正确或系统异常:商户业务处理逻辑
        echo sprintf("错误码:%s , 错误信息:%s", $result['error_code'], $result['message']);
    }
}
/**
 * 刷脸登录
 */
function face_login()
{
    $url = sprintf("%s/%s/face_login", $GLOBALS['root_url'], $GLOBALS['app_key']);
    $file1 = '/tmp/face/live1.jpg';
    $multipartData = [
        ['name' => 'trace_id', 'contents' => time()],
        ['name' => 'image1_liveness', 'contents' => '1'],
        ['name' => 'image1', 'contents' => fopen($file1, 'r'), 'filename' => basename($file1)],
        ['name' => 'image2_feature', 'contents' => 'VW+2ARu7C7TFbnLARTHbPs6N...']
    ];
    $result = http_request($url, $multipartData);
    if ($result["success"]) {
        return $result["data"];
    } else {
        //todo 输入参数不正确或系统异常:商户业务处理逻辑
        echo sprintf("错误码:%s , 错误信息:%s", $result['error_code'], $result['message']);
    }
}

?>

隐私、权限及商业化声明

1. 本插件需要申请的手机端权限列表:

相机

2. 本插件采集的手机端数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问