支付宝刷脸支付对接流程

因为现在的支付基本都使用支付宝微信了,刷脸也应用的越来越多,所以需要写一个对接支付宝刷脸支付的接口

支付宝刷脸主要提供了两种不同的接口,一个是生活类的刷脸接口,一个是支付类的刷脸接口

生活类的刷脸接口主要是配合一个查询的接口使用的,用户刷脸查询用户的基本信息,姓名、身份证号、手机号之类的;

支付类的刷脸接口则是用户刷脸直接授权支付进行扣费的接口;两个接口虽然后面的目的不太相同,但是开始的准备和所需的参数基本类似

一、刷脸支付的基本流程
1、首先要获取商户信息
商户必须是开通了刷脸支付权限的商户,在这一步的时候商户是需要进行第三方应用授权的,拿着服务商的appid,拼接一个URL,唤起授权页,商户的账号登录点击授权获取一个app_auth_code,之后使用app_auth_code换取app_auth_token,code的有效期是有时间限制的,token是一直不变的,后续的业务要进行,商户必须有token,拼接URL的代码如下:

 public void oauthToHis() {
 
        String alipayRedirectOauthUri ="restapi/smilePay/getAuthCode";
        String alipayOauthurl = AlipayConfig.ALIPAY_OAUTHURL;//第三应用授权地址
        String oauthToHis = "";
        try {
            oauthToHis = alipayOauthurl + "?" +
                    "app_id=" + URLEncoder.encode("APPID", "utf-8") +
                    "&redirect_uri=" + URLEncoder.encode(alipayRedirectOauthUri, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            System.out.println("编码错误");
        }
        System.out.println(oauthToHis);
 
    }
商户授权后支付宝会带着code返回URL里面的回调地址,这时候用code换取token,代码如下:

AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
request.setBizContent("{" +
"    \"grant_type\":\"authorization_code\"," +
"    \"code\":\"1cc19911172e4f8aaa509c8fb5d12F56\"" +
"  }");
AlipayOpenAuthTokenAppResponse response = alipayClient.execute(request);
获取到token后,商户信息的准备就结束了,开始调用

2、商户app会拿着商户信息去预热
一般只会预热一次,预热后获取设备信息,拿到这些信息后组装参数传给服务端,服务端用这些参数去支付宝初始化,代码如下;

public static ZolozAuthenticationCustomerSmileliveInitializeResponse smileInitialize(PayAccountInfoDO payAccountInfoDO,
            SmileInitializePara smileInitializePara) throws AlipayApiException ,UnsupportedEncodingException {
        //创建API对应的request类
        ZolozAuthenticationCustomerSmileliveInitializeRequest request
                = new ZolozAuthenticationCustomerSmileliveInitializeRequest();
 
        // zolozGetMetaInfo接口返回的metainfo对象中加入业务参数
        String strZimmetainfo = smileInitializePara.getMetaInfo();
        strZimmetainfo = URLDecoder.decode(strZimmetainfo, "utf-8");
 
        JSONObject zimmetainfo = JSON.parseObject(strZimmetainfo); //客户端zolozGetMetaInfo接口返回的metainfo对象
        JSONObject extInfo = new JSONObject();
 
        /* start: 如果是1:1刷脸认证(姓名+身份证号),*/
        if (SmileInitializeBizTypeEnums.CERTNO_CERTNAME.getCode() == smileInitializePara.getBizType()) {
            extInfo.put("certNo", smileInitializePara.getCertNo()); //必填,当前被认证用户的身份证号
            extInfo.put("certName", smileInitializePara.getCertName());//必填,当前被认证用户的姓名(保持和身份证一致)
            extInfo.put("certType", "IDCARD"); //写为IDCARD,表明身份证
            extInfo.put("bizType", "1"); //固定写为1,表明1:1身份核验场景
        }
        /* end: -------------------------------------------- */
 
        /* start: 如果是1:1刷脸认证(手机号),什么都不传 */
        extInfo.put("bizType", "4"); //固定写为4,表明1:1刷脸核身(手机号)场景
        /* end: -------------------------------------- */
        zimmetainfo.put("extInfo", extInfo);
        //设置业务参数
        JSONObject biz = new JSONObject();
        try {
//            biz.put("zimmetainfo", URLEncoder.encode(zimmetainfo.toJSONString(), "utf-8"));
            biz.put("zimmetainfo",  zimmetainfo );
        } catch (Exception e) {
            e.printStackTrace();
        }
        request.setBizContent(biz.toJSONString());
 
        //通过alipayClient调用API,获得对应的response类
        AlipayClient alipayClient = AlipayAPIClientFactory.getAlipayClientOnOpenAPIGateWay(payAccountInfoDO);
        ZolozAuthenticationCustomerSmileliveInitializeResponse response = null;
        try {
            response = alipayClient.execute(request,null,payAccountInfoDO.getAppAuthToken());
        } catch (AlipayApiException e) {
            log.error("logId:{}, 刷脸支付初始化接口 异常,excepiton:", e);
            throw e;
        }
        return response;
    }
3、获取ftoken进行支付
初始化成功后会获取到一个刷脸标识的id和刷脸标识的协议,即zimId和zimInitClientData,把这两个参数返回给客户端,拿到两个参数后的商户app会自动唤起人脸识别,返回一个ftoken传给服务端,服务端拿到ftoken直接调用支付宝的条码支付接口,把ftoken的值传给auth_code再写死一个scene为security_code就可以了

/**
     * 支付宝刷脸支付收单接口,和条码支付类似  刷脸支付默认为security_code
     *
     * @param logId
     * @param payAccountInfoDO
     * @param out_trade_no
     * @param auth_code
     * @param total_amount
     * @param subject
     * @return
     * @throws AlipayApiException
     */
    public static AlipayTradePayResponse smilePay(String logId, PayAccountInfoDO payAccountInfoDO, String out_trade_no,
                                                  String ftoken, String total_amount, String subject) throws AlipayApiException {
 
        StringBuilder sb = new StringBuilder();
        sb.append("{\"out_trade_no\":\"" + out_trade_no + "\",");
        sb.append("\"scene\":\"security_code\",");
        sb.append("\"auth_code\":\"" + ftoken + "\",");
        sb.append("\"total_amount\":\"" + total_amount + "\",");
        sb.append("\"subject\":\"" + subject + "\",");
        sb.append("\"timeout_express\":\"10m\"}");
 
        AlipayClient alipayClient = AlipayAPIClientFactory.getAlipayClientOnOpenAPIGateWay(payAccountInfoDO);
 
        // 使用SDK,构建请求模型
        AlipayTradePayRequest request = new AlipayTradePayRequest();
        request.setBizContent(sb.toString());
        AlipayTradePayResponse response = null;
 
        try {
            // 使用SDK,调用交易下单接口
            response = alipayClient.execute(request,null,payAccountInfoDO.getAppAuthToken());
 
        } catch (AlipayApiException e) {
            log.error("logId:{}, 刷脸支付收单接口 异常,excepiton:", e);
            throw e;
        }
        return response;
    }
刷脸支付到这里基本就结束了。

二、生活类刷脸接口
因为必须要商户授权码,还需要用户授权,因为要查询用户的基本信息,需要先组装授权的URL给商户和用户,获取授权码后初始化之类的,回调地址要配置在商户的平台,支付宝会返回授权访问令牌,获取后再查询商户信息。

生活类刷脸获取用户信息的第一步和第二步与支付类相似,都是获取商户的token然后进行初始化唤起人脸识别,但是支付的唤起人脸识别后直接调用支付接口,查询信息的则需要先进行用户授权

3、唤起授权页用户进行授权
 empowerURL = alipayAuthurl + "?" +
                    "auth_type=" + URLEncoder.encode("FACE_REC_OAUTH", "utf-8") +
                    "&ftoken=" + URLEncoder.encode(smileInitializePara.getFtoken(), "utf-8") +
                    "&scope=" + URLEncoder.encode("auth_user", "utf-8") +
                    "&app_id=" + URLEncoder.encode(accountByMchId.getAppId(), "utf-8") +
                    "&state=" + URLEncoder.encode(state, "utf-8")  +
                    "&redirect_uri=" + URLEncoder.encode(redirectUri, "utf-8")
            ;
 4、获取授权访问令牌
 拼接授权连接获取到用户授权,支付宝会返回一个auth_code,然后调用支付宝alipay.system.oauth.token接口,返回access_token  授权访问令牌,代码如下 :

 public static AlipaySystemOauthTokenResponse oauthToken(String logId, PayAccountDO payAccountDO, String code) throws AlipayApiException {
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        AlipayClient alipayClient = AlipayAPIClientFactory.getAlipayClientOnOpenAPISmile(payAccountDO);
 
        request.setGrantType("authorization_code"); //值为authorization_code时,代表用code换取;值为refresh_token时,代表用refresh_token换取
        request.setCode(code);
        AlipaySystemOauthTokenResponse response = null;
        try {
            //这里第三方应用时,也不能传入 appAuthToken
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
             log.error("logId:{},换取授权访问令牌 异常,excepiton:", logId, e);
            throw e;
        }
 
        return response;
    }
获取到用户的授权访问令牌

5、查询用户信息
获取到授权访问令牌查询用户的基本信息,代码如下:

public static AlipayUserInfoShareResponse infoShare(String logId, PayAccountDO payAccountDO, String accessToken) {
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayClient alipayClient = AlipayAPIClientFactory.getAlipayClientOnOpenAPISmile(payAccountDO);
        AlipayUserInfoShareResponse response = null;
        try {
            response = alipayClient.execute(request, accessToken);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            log.error("logId:{},根据accessType获取用户信息 异常,excepiton:",logId, e);
        }
        log.info("logId:{},根据accessType获取用户信息结果:{}",logId, JSONObject.toJSONString(response));
        return response;
    }
到此生活类刷脸就结束了
————————————————
版权声明:本文为CSDN博主「鬼槎」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/guiqiaoai/article/details/84283406

你可能感兴趣的:(其他)