因为现在的支付基本都使用支付宝微信了,刷脸也应用的越来越多,所以需要写一个对接支付宝刷脸支付的接口
支付宝刷脸主要提供了两种不同的接口,一个是生活类的刷脸接口,一个是支付类的刷脸接口
生活类的刷脸接口主要是配合一个查询的接口使用的,用户刷脸查询用户的基本信息,姓名、身份证号、手机号之类的;
支付类的刷脸接口则是用户刷脸直接授权支付进行扣费的接口;两个接口虽然后面的目的不太相同,但是开始的准备和所需的参数基本类似
一、刷脸支付的基本流程
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