支付宝刷脸模块
This commit is contained in:
parent
d46490fc6b
commit
237cf8dbe3
|
@ -1,16 +1,22 @@
|
|||
package com.dpkj.modules.scanface.ali.controller;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dpkj.common.vo.Result;
|
||||
import com.dpkj.modules.scanface.ali.config.AliFaceConfig;
|
||||
import com.dpkj.modules.scanface.ali.constants.AliFaceConstants;
|
||||
import com.dpkj.modules.scanface.ali.dll.AbcpInvoke;
|
||||
import com.dpkj.modules.scanface.ali.service.IAliScanFaceService;
|
||||
import com.dpkj.modules.scanface.ali.vo.MyCallbackRsp;
|
||||
import com.dpkj.modules.scanface.ali.vo.AliOrderVo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
@ -35,6 +41,21 @@ public class AliScanFaceController {
|
|||
@Resource
|
||||
private AliFaceConfig aliFaceConfig;
|
||||
|
||||
|
||||
/**
|
||||
* 完整的统一的支付宝刷脸支付
|
||||
* 1、调用硬件刷脸获取到ftoken
|
||||
* 2、调用后端的支付宝支付、存入hispay
|
||||
* @param aliOrderVo
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@PostMapping("/aliFacePay")
|
||||
public Result<JSONObject> aliFacePay(@RequestBody AliOrderVo aliOrderVo) throws Exception {
|
||||
return aliScanFaceService.aliFacePay(aliOrderVo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ABCP初始化,
|
||||
* 文档地址:https://opendocs.alipay.com/iot/05e9ye
|
||||
|
@ -73,6 +94,8 @@ public class AliScanFaceController {
|
|||
|
||||
/**
|
||||
* ABCP服务停用
|
||||
* 终止正在进行中的某次(service_code + traceId)或某类(service_code)服务调用
|
||||
* 如处于支付环节,此次服务调用将不接受停止。
|
||||
* @param traceId
|
||||
* @return
|
||||
*/
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
package com.dpkj.modules.scanface.ali.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dpkj.common.vo.Result;
|
||||
import com.dpkj.modules.scanface.ali.vo.AliOrderVo;
|
||||
|
||||
public interface IAliScanFaceService {
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
Result<Object> iniAbcp() ;
|
||||
* 完整的统一的支付宝刷脸支付
|
||||
* 1、调用硬件刷脸获取到ftoken
|
||||
* 2、调用后端的支付宝支付、存入hispay记录
|
||||
* @param aliOrderVo
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
Result<JSONObject> aliFacePay(AliOrderVo aliOrderVo);
|
||||
|
||||
/**
|
||||
* 初始化,调用阿里的ABCP_SDK部署出来的代码中的API文件
|
||||
|
@ -31,6 +38,7 @@ public interface IAliScanFaceService {
|
|||
/**
|
||||
* ABCP服务停用
|
||||
* 终止正在进行中的某次(service_code + traceId)或某类(service_code)服务调用,然后通过回调返回服务终止结果
|
||||
* 如处于支付环节,此次服务调用将不接受停止。
|
||||
* @param json 组装参数
|
||||
* @param service_code 组件编码
|
||||
* @return
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
package com.dpkj.modules.scanface.ali.service.impl;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.dpkj.common.vo.Result;
|
||||
import com.dpkj.modules.scanface.ali.config.AliFaceConfig;
|
||||
import com.dpkj.modules.scanface.ali.constants.AliFaceConstants;
|
||||
import com.dpkj.modules.scanface.ali.dll.AbcpInvoke;
|
||||
import com.dpkj.modules.scanface.ali.service.IAliScanFaceService;
|
||||
import com.dpkj.modules.scanface.ali.vo.MyCallbackRsp;
|
||||
import com.dpkj.modules.scanface.ali.vo.AliOrderVo;
|
||||
import jodd.util.StringUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thymeleaf.util.StringUtils;
|
||||
|
||||
|
@ -20,6 +27,7 @@ import java.util.concurrent.CountDownLatch;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
||||
/**
|
||||
* @Auther: 萧道子
|
||||
* @Date: 2025/4/16 16:47
|
||||
|
@ -27,16 +35,78 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Component
|
||||
public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
||||
|
||||
@Value("${dpkj.serverurl}")
|
||||
private String serverUrl;
|
||||
|
||||
@Resource
|
||||
private AliFaceConfig aliFaceConfig;
|
||||
|
||||
|
||||
/**
|
||||
* 使用绝对路径调用ABCP_SDK部署出来的AbcpInvoke类
|
||||
*
|
||||
* @return
|
||||
* @description: * 完整的统一的支付宝刷脸支付
|
||||
* 1、调用硬件刷脸获取到ftoken
|
||||
* 2、调用后端的支付宝支付、存入hispay
|
||||
* @author: zhangxue
|
||||
* @date: 2025/5/7 9:45
|
||||
* @Param [aliOrderVo]
|
||||
* @return: com.dpkj.common.vo.Result<com.alibaba.fastjson.JSONObject>
|
||||
*/
|
||||
@Override
|
||||
public Result<JSONObject> aliFacePay(AliOrderVo aliOrderVo) {
|
||||
try {
|
||||
/**
|
||||
* 1、获取刷脸"刷脸去初始化服务"的ftoken返回值
|
||||
*/
|
||||
this.iniAbcpAbsolute();
|
||||
//参数
|
||||
JSONObject zolozConfig = new JSONObject().fluentPut("installAngle", 90);
|
||||
JSONObject params = new JSONObject()
|
||||
.fluentPut("serviceId", aliFaceConfig.getServiceId())
|
||||
.fluentPut("zolozConfig", zolozConfig);
|
||||
String json = params.toJSONString();
|
||||
String service_code = AliFaceConstants.SMILEVERIFYNIN_V1; //调用的组件编码:初始化
|
||||
Result<Object> startServiceIniResult = this.startServiceIni(json, service_code);
|
||||
if (startServiceIniResult.isSuccess()) {
|
||||
Map<String, String> res = (Map<String, String>) startServiceIniResult.getResult();
|
||||
String ftoken = res.get("ftoken");
|
||||
|
||||
/**
|
||||
* 2、调用后端的支付宝统一收单交易支付接口、存入hisPay
|
||||
*/
|
||||
aliOrderVo.setAuthCode(ftoken);//Demo值:"fp128d26333fa66e66e7f34c493d30cdh76"
|
||||
JSONObject serverParams = (JSONObject) JSON.toJSON(aliOrderVo);
|
||||
|
||||
String url = serverUrl + "openapi/aliPayOrderApi/createOrder";
|
||||
String req = HttpRequest.post(url)
|
||||
.header(Header.CONTENT_TYPE, ContentType.JSON.toString(CharsetUtil.CHARSET_UTF_8))
|
||||
.body(serverParams.toJSONString())
|
||||
.execute()
|
||||
.body();
|
||||
JSONObject serverResult = JSONObject.parseObject(req);
|
||||
|
||||
return Result.ok(serverResult);
|
||||
} else {
|
||||
//调用ABCP 刷脸初始化服务失败
|
||||
log.error("[AliScanFaceServiceImpl][aliFacePay][299]调用ABCP 刷脸初始化服务失败 :{}", startServiceIniResult.getMessage());
|
||||
return Result.error(startServiceIniResult.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[AliScanFaceServiceImpl][aliFacePay][302][整个支付宝刷脸模块出现失败:] :{}", e.getMessage());
|
||||
return Result.error("支付宝刷脸失败:" + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description: 使用绝对路径调用ABCP_SDK部署出来的AbcpInvoke类
|
||||
* @author: zhangxue
|
||||
* @date: 2025/5/7 9:45
|
||||
* @Param []
|
||||
* @return: com.dpkj.common.vo.Result<java.lang.Object>
|
||||
*/
|
||||
@Override
|
||||
public Result<Object> iniAbcpAbsolute() {
|
||||
|
@ -87,6 +157,7 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
|||
* ABCP服务调用 刷脸初始化服务,获取ftoken
|
||||
* 接受调用者传入的参数信息,执行指定服务(service_code),然后通过回调返回服务结果。
|
||||
* https://opendocs.alipay.com/iot/05e9ye#ABCP%E6%9C%8D%E5%8A%A1%E8%B0%83%E7%94%A8
|
||||
*
|
||||
* @param json 组装参数
|
||||
* @param service_code 所要调用的组件编码
|
||||
* @return
|
||||
|
@ -114,7 +185,7 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
|||
AbcpInvoke.CallbackRsp callbackRsp = new AbcpInvoke.CallbackRsp() {
|
||||
@Override
|
||||
public void OnProcess(int code, String subCode, String subMsg, String result) {
|
||||
log.info("[AliScanFaceServiceImpl][OnProcess][123][service_code:{}][code:{}][subCode:{}][subMsg:{}][result:{}]",service_code, code, subCode, subMsg, result);
|
||||
log.info("[AliScanFaceServiceImpl][OnProcess][123][service_code:{}][code:{}][subCode:{}][subMsg:{}][result:{}]", service_code, code, subCode, subMsg, result);
|
||||
try {
|
||||
processCode.set(code);
|
||||
processResult.set(result);
|
||||
|
@ -125,7 +196,7 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
|||
|
||||
@Override
|
||||
public void OnFinish(int code, String subCode, String subMsg, String result) {
|
||||
log.info("[AliScanFaceServiceImpl][OnFinish][128][service_code:{}][code:{}][subCode:{}][subMsg:{}][result:{}]",service_code, code, subCode, subMsg, result);
|
||||
log.info("[AliScanFaceServiceImpl][OnFinish][128][service_code:{}][code:{}][subCode:{}][subMsg:{}][result:{}]", service_code, code, subCode, subMsg, result);
|
||||
|
||||
/**Demo示例记录
|
||||
* [service_code:BPaaSSmileVerifyNonInitV1][code:1000][subCode:E00000][subMsg:SUCCESS][result:{"code":1000,"subCode":"OK_SUCCESS","subMessage":"SUCCESS","barCode":"281215320962898068","ftoken":"fp1efd3d4c0230a28f5261efe7c5050eh28","alipayUid":"2088812449506047","accountList":"[\"104***@qq.com\"]","authToken":"44686f7195c77ee2e09c09bcdc657dd5h28i","result":{"accountList":["104***@qq.com"],"alipayUid":"2088812449506047","allowRetry":false,"authToken":"44686f7195c77ee2e09c09bcdc657dd5h28i","barCode":"281215320962898068","certName":"您好,*雪","ftoken":"fp1efd3d4c0230a28f5261efe7c5050eh28","type":"selectUid"},"easterEgg":false,"zolozConfig":{"installAngle":90},"serviceId":"pay","traceId":"2444-44-1745802328","callStartTimeMs":1745802328114,"localTime":"2025-04-28-09-05-41-791"}]
|
||||
|
@ -168,7 +239,7 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
|||
if (finishCode.get() == 1000) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(finishResult.get());
|
||||
if (jsonObject.containsKey("ftoken")) {
|
||||
res.put("ftoken", jsonObject.getString("ftoken"));
|
||||
res.put("ftoken", jsonObject.getString("ftoken"));//ftoken参数的有效期为2分钟
|
||||
res.put("barCode", jsonObject.getString("barCode"));
|
||||
finishResultRef.set(Result.ok("ABCP调用刷脸初始化finish服务成功", res));
|
||||
} else {
|
||||
|
@ -188,10 +259,11 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ABCP服务停用
|
||||
* 终止正在进行中的某次(service_code + traceId)或某类(service_code)服务调用,然后通过回调返回服务终止结果
|
||||
* 如处于支付环节,此次服务调用将不接受停止。
|
||||
*
|
||||
* @param json 组装参数
|
||||
* @param service_code 组件编码
|
||||
* @return
|
||||
|
@ -209,12 +281,12 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
|||
AbcpInvoke.CallbackRsp callbackRsp = new AbcpInvoke.CallbackRsp() {
|
||||
@Override
|
||||
public void OnProcess(int code, String subCode, String subMsg, String result) {
|
||||
log.info("[AliScanFaceServiceImpl][261][ABCP服务停用-OnProcess][code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result);
|
||||
log.info("[AliScanFaceServiceImpl][261][ABCP服务停用-OnProcess][code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnFinish(int code, String subCode, String subMsg, String result) {
|
||||
log.info("[AliScanFaceServiceImpl][OnFinish][266][ABCP服务停用-OnFinish] [code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result);
|
||||
log.info("[AliScanFaceServiceImpl][OnFinish][266][ABCP服务停用-OnFinish] [code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result);
|
||||
try {
|
||||
returnCode.set(code);
|
||||
returnResult.set(result);
|
||||
|
@ -234,7 +306,7 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
|||
return Result.error("等待回调超时");
|
||||
} else {
|
||||
if (returnCode.get() == 0) {
|
||||
System.out.println("停止结果:"+returnResult.get());
|
||||
System.out.println("停止结果:" + returnResult.get());
|
||||
} else {
|
||||
return Result.error("ABCP停止服务失败");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package com.dpkj.modules.scanface.ali.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @description: 支付宝支付参数,传入统一下单接口
|
||||
* @author: Zhangxue
|
||||
* @time: 2025/4/29 14:24
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class AliOrderVo implements Serializable {
|
||||
|
||||
/**
|
||||
* 付款模块
|
||||
*/
|
||||
private String eventModule;
|
||||
|
||||
/**
|
||||
* 患者Id
|
||||
*/
|
||||
private String patientId;
|
||||
|
||||
/**
|
||||
* 商户机具终端编号
|
||||
*/
|
||||
private String terminalId;
|
||||
|
||||
/**
|
||||
* 系统订单编号
|
||||
*/
|
||||
private String outTradeNo;
|
||||
|
||||
/**
|
||||
* 用户支付金额
|
||||
*/
|
||||
//@ApiModelProperty(value = "用户支付金额")
|
||||
private String totalAmount;
|
||||
|
||||
/**
|
||||
* 订单标题
|
||||
*/
|
||||
//@ApiModelProperty(value = "订单标题")
|
||||
private String subject;
|
||||
|
||||
/**
|
||||
* 支付授权码
|
||||
* 刷脸标识串(fp开头的35位字符串)
|
||||
* 从调用"BPaaSSmileVerifyNonInitV1"服务中获取
|
||||
*/
|
||||
//@ApiModelProperty(value = "支付授权码")
|
||||
private String authCode;
|
||||
|
||||
/**
|
||||
* 支付场景
|
||||
* bar_code:当面付条码支付场景;默认值
|
||||
* security_code:当面付刷脸支付场景,对应的auth_code为fp开头的刷脸标识串;
|
||||
*/
|
||||
//@ApiModelProperty(value = "支付授权码")
|
||||
private String scene;
|
||||
|
||||
/**
|
||||
* 产品码:商家和支付宝签约的产品码
|
||||
* 当面付场景下,如果签约的是当面付快捷版,则传 OFFLINE_PAYMENT;
|
||||
* 其它支付宝当面付产品传 FACE_TO_FACE_PAYMENT;
|
||||
* 不传则默认使用FACE_TO_FACE_PAYMENT。
|
||||
*/
|
||||
//@ApiModelProperty(value = "订单标题")
|
||||
private String productCode;
|
||||
|
||||
/**
|
||||
* 卖家支付宝用户ID
|
||||
*/
|
||||
//@ApiModelProperty(value = "订单标题")
|
||||
private String sellerId;
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package com.dpkj.modules.scanface.ali.vo;
|
||||
|
||||
import com.dpkj.common.vo.Result;
|
||||
import com.dpkj.modules.scanface.ali.dll.AbcpInvoke;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @description: 自定义回调实现类
|
||||
* @author: Zhangxue
|
||||
* @time: 2025/4/15 20:41
|
||||
*/
|
||||
@Slf4j
|
||||
public class MyCallbackRsp implements AbcpInvoke.CallbackRsp {
|
||||
|
||||
@Override
|
||||
public void OnProcess(int code, String subCode, String subMsg, String result) {
|
||||
// 处理初始化过程中的中间状态(如进度更新)
|
||||
log.info("[MyCallbackRsp][OnProcess][18][OnProcess] code=%d, subCode=%s, subMsg=%s, result=%s%n", code, subCode, subMsg, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnFinish(int code, String subCode, String subMsg, String result) {
|
||||
// 处理初始化完成结果
|
||||
if (code == 0) {
|
||||
log.info("[MyCallbackRsp][OnFinish][27][返回结果:] :{}", result);
|
||||
} else {
|
||||
log.info("[MyCallbackRsp][OnFinish][29] :初始化失败!错误码: %s, 错误信息: %s%n", subCode, subMsg);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ server:
|
|||
port: 5948
|
||||
|
||||
dpkj:
|
||||
#后端项目访问地址 #https://yinyitong.yzqingyan.cn/ http://172.16.11.13:15946/ ttps://yinyitong.yzqingyan.cn
|
||||
serverurl: http://localhost:5946/api/
|
||||
# 医保配置
|
||||
chs:
|
||||
# 医保机构编码
|
||||
|
|
|
@ -2,6 +2,9 @@ server:
|
|||
port: 5946
|
||||
|
||||
dpkj:
|
||||
#后端项目访问地址
|
||||
#TODO 改为正式的地址 http://www.lczyyy.com/api
|
||||
serverurl: http://127.0.0.1:15946/api
|
||||
# 医保配置
|
||||
chs:
|
||||
# 医保机构编码
|
||||
|
|
|
@ -22,4 +22,4 @@ spring:
|
|||
application:
|
||||
name: ems-express-bridge
|
||||
profiles:
|
||||
active: pro
|
||||
active: dev
|
||||
|
|
Loading…
Reference in New Issue