# 慧眼个人认证

# 业务介绍

移动端实名验证产品,主要的应用在 H5/Android/IOS 场景中,提供了四大功能:

  • 通过用户输入的手机号码,验证手机号码是否正确。
  • 通过用户传入的身份证正反面,结构化识别卡片证件照。
  • 通过用户新录制一个视频,来进行活体检测的判断。Android/IOS 通过活体认证并解析出人脸图片。H5 通过录制视频或者拍摄视频来进行活体检测来解析出人脸图片。
  • 通过用户传入的视频、身份信息,综合对比核验用户身份。

交互流程:

全流程/快速验证:用户在获取认证入口选择进行全流程场景或快速验证场景,验证手机号码,传入姓名身份证号、进行 OCR 识别,识别成功完成验证。全流程和快速验证唯一不一样的是信息的存储和人工审核,快速验证信息不进行存储,也不会出现人工审核;

二次验证:用户第一次通过全流程个人认证后,进行第二次验证,填写第一次认证时的姓名和身份证,进行活体检测和人脸比对,比对成功完成验证,快速验证不支持二次验证;

这里为了方便您的理解,请点击如下链接查看演示:

H5认证流程说明

Android/IOS认证流程说明

# 获取token

根据传入的核验信息生成token

# 一、请求说明

# 二、请求参数

名称 类型 是否必须 描述
authScene String 业务场景(详情见字段解释)
runEnv String 运行环境(详情见字段解释)
notifyUrl String 服务器通知地址(点我查看详细使用)
realname String 姓名
idcard String 证件号
mobile String 手机号
successUrl String h5成功页面,不可携带请求参数(点我查看详细使用)
errorUrl String h5失败页面,不可携带请求参数(点我查看详细使用)
validMobile Boolean 是否验证 Mobile
collectIdPhoto Boolean 是否ocr验证
  • 字段解释

  • authScene 场景类型介绍

类型字段 介绍
FULL 完整流程 首次验证或重新验证 验证成功保存或更新信息
FAST 快速验证 同完整认证流程 区别:1 验证成功不保存信息 2 不出现人工审核
SECOND 二次验证 需要之前已经进行过验证
  • runEnv 运行环境类型介绍
类型字段 介绍
SDK_ANDROID 以SDK运行 支持Android
SDK_IOS 以SDK运行,支持IOS
H5 H5运行,支持大多数手机浏览器

请求示例:

https://eapi.spiderid.cn/openapi/verification?
authScene=XXX
&runEnv=XXX
&<[公共请求参数]>

# 三、响应参数

data 结果信息 类型 描述
authToken String 认证Token
expireTime Long 过期时间毫秒数
h5Url String 如果运行环境是 H5,认证流程页面入口URL

# 四、成功示例

JSON示例

{
   "code": 0,
    "requestId":"f1205...",
    "message": "success",
    "data": {
        "authToken":"8a17dc9c2dc1a32a1fbd61baa34da096cfdbc45732a149d2957066f40211da67",
        "expireTime":1597390941250,
        "h5Url":"http://h5api.spiderid.cn/auth/8a17dc9c2dc1a32a1fbd61baa34da096cfdbc45732a149d2957066f40211da67"
    }
}

# 五、失败示例

JSON示例

{
  "code": 10005,
  "requestId":"f1205...",
  "message": "请求参数(idcard)身份证格式不合法,请参考API文档"
}

# 获取验证状态

根据token验证状态

# 一、请求说明

# 二、请求参数

名称 类型 是否必须 描述
authToken String 认证token

请求示例:

https://eapi.spiderid.cn/openapi/verification?
token=XXX
&<[公共请求参数]>

# 三、响应参数

data 结果信息 类型 描述
status String 认证状态 (详情见字段解释)
incorrect Integer 返回码 (详情见字段解释)
message String 对返回码的描述
  • 字段解释

  • status 认证状态介绍

字段 状态介绍
CREATE 未认证
ACTION 认证中
OVER 完成认证
INVALID 已失效
  • incorrect 返回码介绍
字段 状态介绍
100 成功
101 认证记录不存在
102 二次认证前需要先进行完整流程
103 姓名与预留的证件号不一致

# 四、成功示例

JSON示例

{
   "code": 0,
    "requestId":"f1205...",
    "message": "success",
    "data": {
        "status":"CREATE",
        "incorrect":100,
        "message":"成功"
    }
}

# 五、失败示例

JSON示例

{
  "code": 10001,
  "requestId":"f1205...",
  "message": "系统错误"
}

# 获取验证结果

根据token获取验证结果,状态为OVER时,才能获取到认证结果。

# 一、请求说明

# 二、请求参数

名称 类型 是否必须 描述
authToken String 认证token

请求示例:

https://eapi.spiderid.cn/openapi/verification?
token=XXX
&<[公共请求参数]>

# 三、响应参数

data 结果信息 类型 描述
incorrect Integer 返回码 (详情见字段解释)
message String 对状态码的描述
verifyStatus String 验证状态 (详情见字段解释)
faceScore Double 人脸对比分数
faceScoreMsg String 人脸对比分数参考消息
livenessScore Double H5活体分数
livenessMsg String H5活体分数参考消息
realname String 姓名
mobile String 手机号
idcard String 身份证号
sex String 性别
nation String 民族
birthDate String 出生日期
address String 出生地
issueUint String 签发机关
validDate String 有效期
idFacePhotoUri String 身份证人像面照片
idEmblemPhotoUri String 身份证国徽面照片
videoUri String 视频文件
livenessPhoto String 活体照片
remark String 审核意见
  • 字段解释

  • status 认证状态介绍

字段 状态介绍
CREATE 未认证
ACTION 认证中
OVER 完成认证
INVALID 已失效
  • incorrect 返回码介绍
字段 状态介绍
100 成功
101 认证记录不存在
102 认证状态非法
103 人工审核认证失败

# 四、成功示例

JSON示例

{
   "code": 0,
    "requestId":"f1205...",
    "message": "success",
    "data": {
        "verifyStatus":"OVER",
        "faceScore":0.89,
        "faceScoreMsg":"系统判断为同一人",
        "livenessScore":0.99,
        "livenessMsg":"检测成功",
        "realname":"xxx",
        "mobile":"xxx",
        "idcard":"xxx",
        "sex":"男",
        "nation":"汉",
        "birthDate":"1993年12月3日",
        "address":"xxx",
        "issueUint":"南京市公安局浦口分局",
        "validDate":"20180716-20280716",
        "idFacePhotoUri":"xxx",
        "idEmblemPhotoUri":"xxx",
        "videoUri":"xxx",
        "livenessPhoto":"xxx",
        "incorrect":100,
        "message":"成功"
    }
}

# 五、失败示例

JSON示例

{
  "code": 10001,
  "requestId":"f1205...",
  "message": "系统错误"
}

# SDK 请求示例

# 获取token

        //提供的url
        String url = "http://eapi.spiderid.cn/openapi/verification";
        //您的appKey
        String appkey = "XXX";
        //您的appSecret
        String secretKey = "XXX";

        //1.原客户端
        ApiClient apiClient = new DefaultApiClient(url, appkey, secretKey);
        //2.调用出错,自动重试客户端
        //AutoRetryApiClient apiClient = new AutoRetryApiClient(url, appkey, secretKey);

        VerificationGetTokenRequest req = new VerificationGetTokenRequest();


        //业务场景
        //FULL: 完整流程 首次验证或重新验证 验证成功保存或更新信息
        //SECOND: 二次验证 需要之前已经进行过验证
        //FAST: 快速验证 1 验证成功不保存信息 2 不出现人工审核
        req.setAuthScene("FAST");
        //运行环境
        //SDK_ANDROID: 以SDK运行 支持Android
        //SDK_IOS: 以SDK运行  IOS
        //H5: H5运行 支持大多数手机浏览器
        req.setRunEnv("H5");
        //姓名(选填)
        //req.setRealname("XXX");
        //证件号(选填)
        //req.setIdcard("XXX");

        //服务器通知地址(选填)
        //req.setNotifyUrl("XXX.XXX.XXX");

        try {
            VerificationGetTokenResponse response = apiClient.execute(req);
            //后续业务处理
            if(response.isSuccess()){
                // 接口调用正常
            }else{
                // 接口调用失败
                int errorCode = response.getErrorCode(); //获取失败状态码
                String msg = response.getMsg(); //获取错误消息
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }

# 获取验证状态

        //提供的url
        String url = "http://eapi.spiderid.cn/openapi/verification";
        //您的appKey
        String appkey = "XXX";
        //您的appSecret
        String secretKey = "XXX";

        //1.原客户端
        ApiClient apiClient = new DefaultApiClient(url, appkey, secretKey);
        //2.调用出错,自动重试客户端
        //AutoRetryApiClient apiClient = new AutoRetryApiClient(url, appkey, secretKey);

        VerificationGetStatusRequest req = new VerificationGetStatusRequest();

        req.setAuthToken("XXX");

        try {
            VerificationGetStatusResponse response = apiClient.execute(req);
            //后续业务处理
            if(response.isSuccess()){
                // 接口调用正常
            }else{
                // 接口调用失败
                int errorCode = response.getErrorCode();//获取失败状态码
                String msg = response.getMsg();//获取错误消息
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }

# 获取验证结果

        //提供的url
        String url = "http://eapi.spiderid.cn/openapi/verification";
        //您的appKey
        String appkey = "XXX";
        //您的appSecret
        String secretKey = "XXX";


        //1.原客户端
        ApiClient apiClient = new DefaultApiClient(url, appkey, secretKey);
        //2.调用出错,自动重试客户端
        //AutoRetryApiClient apiClient = new AutoRetryApiClient(url, appkey, secretKey);
        VerificationGetResultRequest req = new VerificationGetResultRequest();

        req.setAuthToken("XXX");

        try {
            VerificationGetResultResponse response = apiClient.execute(req);
            //后续业务处理
            if(response.isSuccess()){
                // 接口调用正常
            }else{
                // 接口调用失败
                int errorCode = response.getErrorCode();//获取失败状态码
                String msg = response.getMsg();//获取错误消息
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }

# 回调通知接口示例

当慧眼实名认证流程结束后,平台服务器会向用户提供的notifyUrl参数地址向用户发送 HTTP 通知。平台服务器得到正确的确认信息后,会停止通知,避免重复向notifyUrl参数地址发送通知。

用户在接收到参数时,需要对参数进行验签,在确认无误的情况下,向实名认证系统返回"success"字符串。

回调通知接口示例

    /**
     * 回调通知示例
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "/notify", method = {RequestMethod.POST})
    public String notify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Map<String, String> paranMap = Maps.newHashMap();
        //公共参数
        paranMap.put("appKey", request.getParameter("appKey"));
        paranMap.put("t", request.getParameter("t"));
        paranMap.put("nonce", request.getParameter("nonce"));
        paranMap.put("v", request.getParameter("v"));
        paranMap.put("event", request.getParameter("event"));
        paranMap.put("signMethod", request.getParameter("signMethod"));
        paranMap.put("sign", request.getParameter("sign"));

        //业务参数
        paranMap.put("authToken", request.getParameter("authToken"));
        paranMap.put("verifyStatus", request.getParameter("verifyStatus"));

        String appSecret = "应用密钥";

        //验签
        boolean res = SignUtil.signCheck(paranMap, appSecret, SignUtil.CHARSET, request.getParameter("signMethod"));
        if (res) {
            //验签成功
            // 认证结果
            String verifyStatus = request.getParameter("verifyStatus");
            if("CREATE".equals(verifyStatus)){
                //未认证
            }else if("ACTION".equals(verifyStatus)){
                //认证中
            }else if("OVER".equals(verifyStatus)){
                //完成认证
                //提供的url
                String url = "http://eapi.spiderid.cn/openapi/verification";
                //您的appKey
                String appkey = "************";
                //您的appSecret
                String secretKey = "***********";
                
                //1.原客户端
                ApiClient apiClient = new DefaultApiClient(url, appkey, secretKey);
                try {
                    //获取认证结果
                    VerificationGetResultResponse response = apiClient.execute(request.getParameter("authToken"));
                    //后续业务处理
                    System.out.println(JSON.toJSONString(response));

                } catch (ApiException e) {
                    e.printStackTrace();
                }               
            }else if("INVALID".equals(verifyStatus)){
                //已失效
            }
            //返回通知成功
            return "success";
        }
        // 验签失败 可以给一个异常
        return "fail";
    }

# 验签工具类

import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class SignUtil {

    public final static String SIGN_TYPE_HMAC_SHA_1 = "HmacSHA1";

    public final static String SIGN_TYPE_HMAC_SHA_256 = "HmacSHA256";

    public final static String REQUEST_PUBLIC_PARAMS_SIGN = "sign";

    public final static String CHARSET = "UTF-8";

    private static final Object LOCK = new Object();

    /**
     * Prototype of the Mac instance.
     */
    private static Mac macInstance;

    /**
     * 验签
     *
     * @param paranMap
     * @param appSecret
     * @param charset
     * @param signType
     * @return
     */
    public static boolean signCheck(Map<String, String> paranMap, String appSecret, String charset, String signType) {
        // 字典排序
        String sign = paranMap.get(REQUEST_PUBLIC_PARAMS_SIGN);
        String content = getSignCheckContentV1(paranMap);

        if (SIGN_TYPE_HMAC_SHA_1.equals(signType)) {
            return sign.equals(computeSignature(appSecret, content, charset, SIGN_TYPE_HMAC_SHA_1));
        } else {
            return sign.equals(computeSignature(appSecret, content, charset, SIGN_TYPE_HMAC_SHA_256));
        }
    }


    public static String getSignCheckContentV1(Map<String, String> params) {
        if (params == null) {
            return null;
        }
        params.remove(REQUEST_PUBLIC_PARAMS_SIGN);
        return getSignatureContent(params);
    }


    public static String getSignatureContent(Map<String, String> paranMap) {
        return getSignContent(getSortedMap(paranMap));
    }

    public static Map<String, String> getSortedMap(Map<String, String> paranMap) {
        Map<String, String> sortedParams = Maps.newTreeMap();

        paranMap.keySet().stream()
                .sorted()
                .forEach(sortKey -> sortedParams.put(sortKey, paranMap.get(sortKey)));

        return sortedParams;
    }

    /**
     * @param sortedParams
     * @return
     */
    public static String getSignContent(Map<String, String> sortedParams) {
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<String>(sortedParams.keySet());
        Collections.sort(keys);

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = sortedParams.get(key);
            if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value)) {
                content.append(key).append(value);
            }
        }
        return content.toString();
    }


    public static String computeSignature(String key, String data, String charset, String algorithm) {
        try {
            byte[] signData = sign(key.getBytes(charset), data.getBytes(charset), algorithm);
            return byte2hex(signData);
        } catch (UnsupportedEncodingException ex) {
            throw new RuntimeException("Unsupported algorithm: " + charset, ex);
        }
    }


    private static byte[] sign(byte[] key, byte[] data, String algorithm) {
        try {
            /* Because Mac.getInstance(String) calls a synchronized method, it could block on
               invoked concurrently, so use prototype pattern to improve perf. */
            if (macInstance == null) {
                synchronized (LOCK) {
                    if (macInstance == null) {
                        macInstance = Mac.getInstance(algorithm);
                    }
                }
            }

            Mac mac = null;
            try {
                mac = (Mac) macInstance.clone();
            } catch (CloneNotSupportedException e) {
                // If it is not clonable, create a new one.
                mac = Mac.getInstance(algorithm);
            }
            mac.init(new SecretKeySpec(key, algorithm));
            return mac.doFinal(data);
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException("Unsupported algorithm: " + algorithm, ex);
        } catch (InvalidKeyException ex) {
            throw new RuntimeException("Invalid key: " + key, ex);
        }
    }


    /**
     * 把字节流转换为十六进制表示方式。
     */
    protected static String byte2hex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        return sign.toString();
    }
}

# url跳转说明

在配置successUrl或errorUrl的情况下,流程结束时会进行页面跳转,跳转时会以query的方式在url后拼接参数。

用户在接收到参数时,需要对参数进行验签。

# 参数示例

以 https://www.spiderid.cn 为跳转示例,生成如下url

https://www.spiderid.cn?t=1634198886048&v=1&authToken=74a52b63dcad6549a9ddd05a2231a007a800bc78f9ff5c4f43fd5f9bfa59176a&format=JSON&sign=C290CC353D23ACB2B43CACE17B79BDCFB23B0324505F095A64A03422FAA0E3E1&appKey=5bf90f68ba261b38405d16e0&nonce=wHM1dotjLI&status=SUCCESS

# 参数说明

属性 说明
appKey appKey
format 格式化类型:JSON
t 通知时间的时间戳
nonce 随机字符
v 版本
authToken 核验token
status 验证状态
sign 签名结果

# url验签

   /**
     * 跳转url验签示例
     *
     * @param request
     */
    @RequestMapping(value = "/callback", method = {RequestMethod.GET})
    public void callback(HttpServletRequest request )  {
        Map<String, String> paranMap = Maps.newHashMap();
        //公共参数
        paranMap.put("appKey", request.getParameter("appKey"));
        paranMap.put("format", request.getParameter("format"));
        paranMap.put("t", request.getParameter("t"));
        paranMap.put("nonce", request.getParameter("nonce"));
        paranMap.put("v", request.getParameter("v"));
        paranMap.put("authToken", request.getParameter("authToken"));
        paranMap.put("status", request.getParameter("status"));
        paranMap.put("sign", request.getParameter("sign"));

        String appSecret = "应用密钥";

        //验签
        boolean res = SignUtil.signCheck(paranMap, appSecret, SignUtil.CHARSET, SignUtil.SIGN_TYPE_HMAC_SHA_256);
        if (res) {
            //验签成功
        }
    }

# 验签工具类

验签工具类

# H5 认证流程说明

H5 完整流程演示

H5 二次验证演示

H5 快速验证演示

# H5 完整验证

# 第一步 获取 H5 认证入口

下载我们提供的 SDK,根据示例代码,设置运行环境为 H5,获取到 H5 认证会话入口

req.setAuthScene("FULL");  //设置业务场景为完整流程
req.setRunEnv("H5");  //设置运行环境为H5

点我查看获取认证会话入口API

{
    "code": 0,
    "message": "success",
    "requestId": "f1205ffe85afeb2f7a418bdb8453",
    "data": {
        "authToken": "9e84825d9d7710c195dd6fe6f47ddb0a62c55db0f041b1ecaba7051b15ee9432",
        "expireTime": 1610519487448,
        "h5Url": "https://eh5.spiderid.cn/auth/9e84825d9d7710c195dd6fe6f47ddb0a62c55db0f041b1ecaba7051b15ee9432"
    }
}

# 第二步 进行认证操作

直接访问第一步获取到的 h5Url,访问地址进入首页后,勾选我已认真阅读并同意认证授权,点击立即认证

认证首页

根据用户在获取 H5 认证入口所填写的参数不同,我们会返回四种不同的页面:

  1. 如果用户在获取 H5 认证入口选择进行全流程或者快速验证场景,根据参数是否验证手机号码(默认不验证),如果需要验证,我们会首先进入验证手机号码页面;
  2. 如果用户在获取 H5 认证入口时没有选择需要验证手机号码,那么会根据是否进行 OCR 识别(默认不验证)和是否传入姓名、身份证号选择进入不同页面,如果需要进行 OCR 识别,进入 OCR 识别页面;
  3. 如果用户在获取 H5 认证入口时没有选择 OCR 识别,那么根据是否传入姓名身份证号选择进入不同页面,如果未传入姓名身份证号,进入填写身份证号页面;
  4. 如果用户在获取 H5 认证入口时验证场景为二次认证或选择不进行 OCR 识别,身份证和姓名已填写,那么进入视频活体验证页面;

验证手机号码页面(用户在填写完相应手机号和验证码,点击提交,会根据参数进入 OCR 识别页面)

验证手机号码页面

OCR 识别页面(点击拍摄身份证人像面,根据提示完成上传,在身份证国徽面和人像面上传完成后,会自动将数据填充至下面的信息栏中,点击下一步,进入视频活体验证页面)

ocr识别页面

填写身份证号页面(用户在获取 H5 认证入口时没有选择需要验证手机号码和不进行 OCR 识别时,填写完相应姓名和身份证号,点击提交,会根据参数进入视频活体验证页面)

填写身份证号页面

视频活体验证页面(用户点击开始录制按钮,录制2-5秒钟的视频,上传即可)

视频活体验证页面

# 人工审核

在全流程场景下,视频活体上传验证成功,进入核验,核验失败的情况下,可以申请人工审核

申请人工审核

人工审核提交成功页面

申请人工审核成功

# 第三步 结果页面跳转

# 成功页面举例

返回结果页面(验证成功后,如果没有配置成功跳转页面)

返回结果页面

# 错误页面举例

用户在操作过程中,可能会由于不当错误,到导致页面出现报错信息,我们提供几个较为常见的错误页面。

链接失效页面(会话失效)

链接失效页面

链接失效页面(活体次数达上限)

链接失效页面

视频未检测到人脸页面

视频未检测到人脸页面

验证不通过页面(完整流程)

验证不通过页面

# H5 二次验证

# 第一步 获取 H5 认证入口

下载我们提供的 SDK,根据示例代码,设置运行环境为 H5,获取到 H5 认证会话入口

二次验证必须传入姓名和身份证号

req.setRealname("XXX"); //姓名
req.setIdcard("XXX"); //身份证号
req.setRunEnv("H5");  //设置运行环境为H5
req.setAuthScene("SECOND"); //设置业务场景为二次验证

点我查看获取认证会话入口API

# 第二步 进行认证操作

直接访问第一步获取到的 h5Url,访问地址进入首页后,勾选我已认真阅读并同意认证授权,点击立即认证

认证首页

视频活体验证页面(用户点击开始录制按钮,录制2-5秒钟的视频,上传即可)

视频活体验证页面

# 人工审核

在全流程和二次认证的场景下,视频活体上传验证成功,进入核验,核验失败的情况下,可以申请人工审核

申请人工审核

人工审核提交成功页面

申请人工审核成功

# 第三步 结果页面跳转

# 成功页面举例

返回结果页面(验证成功后,如果没有配置成功跳转页面)

返回结果页面

# 错误页面举例

用户在操作过程中,可能会由于不当错误,到导致页面出现报错信息,我们提供几个较为常见的错误页面。

验证失败页面(验证失败)

验证失败页面

# H5 快速验证

下载我们提供的 SDK,根据示例代码,设置运行环境为 H5,获取到 H5 认证会话入口

req.setAuthScene("FAST"); //设置业务场景为快速验证
req.setRunEnv("H5");  //设置运行环境为H5

验证不通过页面(快速验证,其余步骤参考H5 完整流程演示,快速验证无人工审核)

验证不通过页面

# Android/IOS 认证流程说明

Android/IOS 完整流程演示

Android/IOS 二次验证演示

Android/IOS 快速验证演示

# Android/IOS 慧眼身份核验SDK链接如下:

Android 慧眼身份核验SDK

IOS 慧眼身份核验SDK

# Android/IOS 完整流程

# 第一步 获取 Android/IOS 认证入口

下载我们提供的 SDK,根据示例代码,设置运行环境为 Android/IOS,获取到 Android/IOS 认证会话入口

req.setAuthScene("FULL");  //设置业务场景为完整流程
req.setRunEnv("SDK_ANDROID"); //设置运行环境为Android
req.setRunEnv("SDK_IOS");  //设置运行环境为IOS

点我查看获取认证会话入口API

{
    "code": 0,
    "message": "success",
    "requestId": "f1205ffe85afeb2f7a418bdb8453",
    "data": {
        "authToken": "db7f455399e0dee366610e0b5a61ca85ab01c7ee9d6f5960954201809ad5c211",
        "expireTime": 1610596858544,
    }
}

# 第二步 进行认证操作

将第一步获取到的authToken复制粘贴到身份核验页面的测试 Token 后面,点击进入SDK/开始检测进入首页

Android 身份核验页面:

Android身份核验页面

进入首页后,勾选我已认真阅读并同意认证授权,然后点击快速认证

认证首页

根据用户在获取 Android/IOS 认证入口所填写的参数不同,我们会返回四种不同的页面:

  1. 如果用户在获取 Android/IOS 认证入口选择进行全流程或者快速验证场景,根据参数是否验证手机号码(默认不验证),如果需要验证,我们会首先进入验证手机号码页面;
  2. 如果用户在获取 Android/IOS 认证入口时没有选择需要验证手机号码,那么会根据是否进行 OCR 识别(默认不验证)和是否传入姓名、身份证号选择进入不同页面,如果需要进行 OCR 识别,进入 OCR 识别页面;
  3. 如果用户在获取 Android/IOS 认证入口时没有选择 OCR 识别,那么根据是否传入姓名身份证号选择进入不同页面,如果未传入姓名身份证号,进入填写身份证号页面;
  4. 如果用户在获取 Android/IOS 认证入口时验证场景为二次认证或选择不进行 OCR 识别,身份证和姓名已填写,那么进入视频活体验证页面;

验证手机号码页面(用户在填写完相应手机号和验证码,点击提交验证,会根据参数进入ocr识别页面)

验证手机号码页面

OCR 识别页面(点击拍摄身份证人像面,根据提示完成上传,在身份证国徽面和人像面上传完成后,会自动将数据填充至下面的信息栏中,点击下一步,进入视频活体验证页面)

ocr识别页面

填写身份证号页面(用户在获取 Android/IOS 认证入口时没有选择需要验证手机号码和不进行 OCR 识别时,填写完相应姓名和身份证号,点击下一步,会根据参数进入视频活体验证页面)

填写身份证号页面

视频活体验证页面(用户点击活体采集按钮,根据提示完成采集)

视频活体验证页面

# 人工审核

在全流程和二次认证的场景下,视频活体上传验证成功,进入核验,核验失败的情况下,可以申请人工审核

Android 认证失败页面:

Android认证失败页面

IOS 认证失败页面:

IOS认证失败页面

Android 人工审核提交成功页面

Android人工审核提交成功页面

IOS 人工审核提交成功页面

IOS人工审核提交成功页面

# 第三步 结果页面跳转

# 成功页面举例

返回结果页面(验证成功后,如果没有配置成功跳转页面)

返回结果页面

# 错误页面举例

用户在操作过程中,可能会由于不当错误,到导致页面出现报错信息,我们提供几个较为常见的错误页面。

Android 未检测到人脸页面:

Android未检测到人脸页面

Android 活体采集超时页面:

Android活体采集超时页面

Android 验证不通过页面

Android验证不通过页面

IOS 活体采集超时页面:

IOS活体采集超时页面

IOS 验证不通过页面

IOS验证不通过页面

# Android/IOS 二次验证

# 第一步 获取 Android/IOS 认证入口

下载我们提供的 SDK,根据示例代码,设置运行环境为 Android/IOS,获取到 Android/IOS 认证会话入口

req.setAuthScene("SECOND"); //设置业务场景为二次验证
req.setRunEnv("SDK_ANDROID");  //设置运行环境为 Android
req.setRunEnv("SDK_IOS");  //设置运行环境为 IOS

点我查看获取认证会话入口API

# 第二步 进行认证操作

直接访问第一步获取到的 h5Url,访问地址进入首页后,勾选我已认真阅读并同意认证授权,点击立即认证

认证首页

视频活体验证页面(用户根据页面提示完成视频活体验证)

视频活体验证页面

# 第三步 结果页面跳转

# 成功页面举例

返回结果页面(验证成功后,如果没有配置成功跳转页面)

返回结果页面

# 错误页面举例

用户在操作过程中,可能会由于不当错误,到导致页面出现报错信息,我们提供几个较为常见的错误页面。

验证失败页面(验证失败)

验证失败页面

# Android/IOS 快速验证

下载我们提供的 SDK,根据示例代码,设置运行环境为 Android/IOS,获取到 Android/IOS 认证会话入口

req.setAuthScene("FAST"); //设置业务场景为快速验证
req.setRunEnv("SDK_ANDROID"); //设置运行环境为Android
req.setRunEnv("SDK_IOS");  //设置运行环境为IOS

验证不通过页面(快速验证,其余步骤参考Android/IOS 完整流程演示,快速验证无人工审核)

验证不通过页面

最后更新于: 10/15/2021, 4:21:50 PM