From 49148072078220c92f94f2e7ea25cd79a6810fc7 Mon Sep 17 00:00:00 2001
From: zhibing.pu <393733352@qq.com>
Date: 星期六, 24 八月 2024 15:31:37 +0800
Subject: [PATCH] 封装支付宝支付和完善充电支付功能
---
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java | 49 +
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentReq.java | 51 ++
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/SignType.java | 39 +
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java | 4
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/config/WxConfig.java | 1
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/AliProperties.java | 54 ++
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentResp.java | 24 +
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundResp.java | 27 +
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java | 2
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/model/WeixinProperties.java | 2
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java | 25
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentResp.java | 30 +
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryResp.java | 48 ++
ruoyi-service/ruoyi-payment/pom.xml | 6
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/AppletPayUtil.java | 228 +++++++++
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundReq.java | 19
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java | 86 +++
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundResp.java | 43 +
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java | 45 +
ruoyi-api/ruoyi-api-payment/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports | 3
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundReq.java | 27 +
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliQueryOrder.java | 48 ++
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentReq.java | 52 ++
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java | 396 ++++++++--------
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java | 43 +
25 files changed, 1,123 insertions(+), 229 deletions(-)
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java
new file mode 100644
index 0000000..a552827
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java
@@ -0,0 +1,45 @@
+package com.ruoyi.payment.api.factory;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.payment.api.feignClient.AliPaymentClient;
+import com.ruoyi.payment.api.vo.AliPaymentReq;
+import com.ruoyi.payment.api.vo.AliPaymentResp;
+import com.ruoyi.payment.api.vo.AliQueryOrder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * 充电订单服务降级处理
+ *
+ * @author ruoyi
+ */
+@Component
+public class AliPaymentFallbackFactory implements FallbackFactory<AliPaymentClient>
+{
+ private static final Logger log = LoggerFactory.getLogger(AliPaymentFallbackFactory.class);
+
+ @Override
+ public AliPaymentClient create(Throwable throwable) {
+ log.error("支付宝支付调用失败:{}", throwable.getMessage());
+ return new AliPaymentClient() {
+
+ @Override
+ public R<AliPaymentResp> payment(AliPaymentReq req) {
+ throw new RuntimeException("调起支付宝小程序支付失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public R<AliQueryOrder> query(String outTradeNo) {
+ throw new RuntimeException("查询支付订单失败:" + throwable.getMessage());
+ }
+
+ @Override
+ public void close(String outTradeNo) {
+ throw new RuntimeException("关闭支付订单失败:" + throwable.getMessage());
+ }
+ };
+ }
+}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java
index 6761b58..0938408 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java
@@ -29,7 +29,7 @@
@Override
public R<NotifyV3PayDecodeRespBody> queryOrderInfo(String orderId) {
- return R.fail("查询支付订单信息失败:" + throwable.getMessage());
+ throw new RuntimeException("查询支付订单信息失败:" + throwable.getMessage());
}
@Override
@@ -49,7 +49,7 @@
@Override
public void close(String outTradeNo) {
-
+ throw new RuntimeException("关闭支付订单失败:" + throwable.getMessage());
}
};
}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java
new file mode 100644
index 0000000..91e5014
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java
@@ -0,0 +1,43 @@
+package com.ruoyi.payment.api.feignClient;
+
+import com.ruoyi.common.core.constant.ServiceNameConstants;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.payment.api.factory.WxPaymentFallbackFactory;
+import com.ruoyi.payment.api.vo.AliPaymentReq;
+import com.ruoyi.payment.api.vo.AliPaymentResp;
+import com.ruoyi.payment.api.vo.AliQueryOrder;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/24 14:39
+ */
+@FeignClient(contextId = "AliPaymentClient", value = ServiceNameConstants.PAYMENT_SERVICE, fallbackFactory = WxPaymentFallbackFactory.class)
+public interface AliPaymentClient {
+
+
+ /**
+ * 调起支付宝小程序支付
+ * @param req
+ * @return
+ */
+ @PostMapping("/ali/payment")
+ R<AliPaymentResp> payment(AliPaymentReq req);
+
+
+ /**
+ * 查询支付订单
+ * @param outTradeNo
+ * @return
+ */
+ @PostMapping("/ali/query")
+ R<AliQueryOrder> query(String outTradeNo);
+
+ /**
+ * 关闭订单
+ * @param outTradeNo
+ */
+ @PostMapping("/ali/close")
+ void close(String outTradeNo);
+}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentReq.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentReq.java
new file mode 100644
index 0000000..f2f0858
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentReq.java
@@ -0,0 +1,51 @@
+package com.ruoyi.payment.api.vo;
+
+import lombok.Data;
+
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/23 16:52
+ */
+@Data
+public class AliPaymentReq {
+ /**
+ * 业务流水号
+ */
+ private String outTradeNo;
+ /**
+ * 支付总金额
+ */
+ private String totalAmount;
+ /**
+ * 订单标题
+ */
+ private String subject;
+ /**
+ * 支付用户支付宝openid
+ */
+ private String buyerOpenId;
+ /**
+ * 订单附加信息
+ */
+ private String body;
+ /**
+ * 订单超时时间
+ * 订单相对超时时间。从交易创建时间开始计算。
+ * 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
+ * 当面付场景默认值为3h
+ */
+ private String timeoutExpress;
+ /**
+ * 回传参数
+ * 如果请求时传递了该参数,支付宝会在异步通知时将该参数原样返回。
+ */
+ private String passbackParams;
+ /**
+ * 初始化默认数据
+ */
+ public AliPaymentReq() {
+ //订单超时默认30分钟
+ this.timeoutExpress = "30m";
+ }
+}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentResp.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentResp.java
new file mode 100644
index 0000000..273a5fc
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentResp.java
@@ -0,0 +1,24 @@
+package com.ruoyi.payment.api.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/24 15:09
+ */
+@Data
+@ApiModel
+public class AliPaymentResp {
+ /**
+ * 支付单号
+ */
+ @ApiModelProperty("支付单号")
+ private String tradeNo;
+ /**
+ * 回调通知地址
+ */
+ @ApiModelProperty("回调通知地址")
+ private String notifyUrl;
+}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliQueryOrder.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliQueryOrder.java
new file mode 100644
index 0000000..67a8c23
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliQueryOrder.java
@@ -0,0 +1,48 @@
+package com.ruoyi.payment.api.vo;
+
+import com.fasterxml.jackson.annotation.JsonSetter;
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/24 12:01
+ */
+@Data
+public class AliQueryOrder {
+ /**
+ * 支付宝交易号
+ */
+ @JsonSetter("trade_no")
+ private String tradeNo;
+ /**
+ * 业务流水号
+ */
+ @JsonSetter("out_trade_no")
+ private String outTradeNo;
+ /**
+ * 交易状态
+ * WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)
+ */
+ @JsonSetter("trade_status")
+ private String tradeStatus;
+ /**
+ * 交易订单金额
+ */
+ @JsonSetter("total_amount")
+ private Double totalAmount;
+ /**
+ * 回传参数
+ */
+ @JsonSetter("passback_params")
+ private String passbackParams;
+ /**
+ * 订单标题
+ */
+ @JsonSetter("subject")
+ private String subject;
+ /**
+ * 订单描述
+ */
+ @JsonSetter("body")
+ private String body;
+}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-api/ruoyi-api-payment/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index fe686fc..ecbf4d6 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-api/ruoyi-api-payment/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1,2 @@
-com.ruoyi.payment.api.factory.WxPaymentFallbackFactory
\ No newline at end of file
+com.ruoyi.payment.api.factory.WxPaymentFallbackFactory
+com.ruoyi.payment.api.factory.AliPaymentFallbackFactory
\ No newline at end of file
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
index 2cdbed5..4cce577 100644
--- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
@@ -22,210 +22,200 @@
/**
* token验证处理
- *
+ *
* @author ruoyi
*/
@Component
-public class TokenService
-{
- @Autowired
- private RedisService redisService;
-
- protected static final long MILLIS_SECOND = 1000;
-
- protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
-
- private final static long expireTime = CacheConstants.EXPIRATION;
- private final static long expireAppletTime = CacheConstants.EXPIRATION_APPLET;
-
- private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
-
- private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
-
- /**
- * 创建令牌
- */
- public Map<String, Object> createToken(LoginUser loginUser)
- {
- String token = IdUtils.fastUUID();
- Long userId = loginUser.getSysUser().getUserId();
- String userName = loginUser.getSysUser().getUserName();
- loginUser.setToken(token);
- loginUser.setUserid(userId);
- loginUser.setUsername(userName);
- loginUser.setIpaddr(IpUtils.getIpAddr());
- refreshToken(loginUser);
-
- // Jwt存储信息
- Map<String, Object> claimsMap = new HashMap<String, Object>();
- claimsMap.put(SecurityConstants.USER_KEY, token);
- claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
- claimsMap.put(SecurityConstants.USER_TYPE, "system");
- claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
-
- // 接口返回信息
- Map<String, Object> rspMap = new HashMap<String, Object>();
- rspMap.put("access_token", JwtUtils.createToken(claimsMap));
- rspMap.put("expires_in", expireTime);
- return rspMap;
- }
- /**
- * 创建小程序令牌
- */
- public Map<String, Object> createTokenApplet(LoginUserApplet loginUser) {
- String token = IdUtils.fastUUID();
- Long userId = loginUser.getUserId();
- String name = loginUser.getName();
- loginUser.setToken(token);
- loginUser.setIpaddr(IpUtils.getIpAddr());
- refreshToken1(loginUser);
- // Jwt存储信息
- Map<String, Object> claimsMap = new HashMap<String, Object>();
- claimsMap.put(SecurityConstants.USER_APPLET_KEY, token);
- claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
- claimsMap.put(SecurityConstants.USER_TYPE, "applet");
- claimsMap.put(SecurityConstants.DETAILS_USERNAME, name);
- // 接口返回信息
- Map<String, Object> rspMap = new HashMap<String, Object>();
- rspMap.put("access_token", JwtUtils.createToken(claimsMap));
- rspMap.put("expires_in", expireAppletTime);
- return rspMap;
- }
- public LoginUserApplet getLoginUserApplet() {
- LoginUserApplet loginUserAppletToken = getLoginUserAppletToken(ServletUtils.getRequest());
- if (loginUserAppletToken == null){
- throw new UserAppletException("登录失效,请重新登录!", 401);
- }
- return loginUserAppletToken;
- }
- public LoginUserApplet getLoginUserAppletToken(HttpServletRequest request) {
- // 获取请求携带的令牌
- String token = SecurityUtils.getToken(request);
- return getLoginUserApplet(token);
- }
- /**
- * 小程序 获取用户身份信息
- *
- * @return 用户信息
- */
- public LoginUserApplet getLoginUserApplet(String token) {
- LoginUserApplet user = null;
- try {
- if (StringUtils.isNotEmpty(token)) {
- String userKey = JwtUtils.getUserKeyApplet(token);
- user = redisService.getCacheObject(getTokenKey(userKey));
- return user;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return user;
- }
- /**
- * 获取用户身份信息
- *
- * @return 用户信息
- */
- public LoginUser getLoginUser()
- {
- return getLoginUser(ServletUtils.getRequest());
- }
-
- /**
- * 获取用户身份信息
- *
- * @return 用户信息
- */
- public LoginUser getLoginUser(HttpServletRequest request)
- {
- // 获取请求携带的令牌
- String token = SecurityUtils.getToken(request);
- return getLoginUser(token);
- }
-
- /**
- * 获取用户身份信息
- *
- * @return 用户信息
- */
- public LoginUser getLoginUser(String token)
- {
- LoginUser user = null;
- try
- {
- if (StringUtils.isNotEmpty(token))
- {
- String userkey = JwtUtils.getUserKey(token);
- user = redisService.getCacheObject(getTokenKey(userkey));
- return user;
- }
- }
- catch (Exception e)
- {
- }
- return user;
- }
-
- /**
- * 设置用户身份信息
- */
- public void setLoginUser(LoginUser loginUser)
- {
- if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
- {
- refreshToken(loginUser);
- }
- }
-
- /**
- * 删除用户缓存信息
- */
- public void delLoginUser(String token)
- {
- if (StringUtils.isNotEmpty(token))
- {
- String userkey = JwtUtils.getUserKey(token);
- redisService.deleteObject(getTokenKey(userkey));
- }
- }
-
- /**
- * 验证令牌有效期,相差不足120分钟,自动刷新缓存
- *
- * @param loginUser
- */
- public void verifyToken(LoginUser loginUser)
- {
- long expireTime = loginUser.getExpireTime();
- long currentTime = System.currentTimeMillis();
- if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
- {
- refreshToken(loginUser);
- }
- }
-
- /**
- * 刷新令牌有效期
- *
- * @param loginUser 登录信息
- */
- public void refreshToken(LoginUser loginUser)
- {
- loginUser.setLoginTime(System.currentTimeMillis());
- loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
- // 根据uuid将loginUser缓存
- String userKey = getTokenKey(loginUser.getToken());
- redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
- }
- public void refreshToken1(LoginUserApplet dto) {
- dto.setLoginTime(System.currentTimeMillis());
- dto.setExpireTime(dto.getLoginTime() + expireTime * MILLIS_MINUTE);
- // 根据uuid将loginUser缓存
- String userKey = getTokenKey(dto.getToken());
- redisService.setCacheObject(userKey, dto, expireTime, TimeUnit.MINUTES);
- }
- private String getTokenKey(String token)
- {
- return ACCESS_TOKEN + token;
- }
+public class TokenService {
+ @Autowired
+ private RedisService redisService;
+
+ protected static final long MILLIS_SECOND = 1000;
+
+ protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
+
+ private final static long expireTime = CacheConstants.EXPIRATION;
+ private final static long expireAppletTime = CacheConstants.EXPIRATION_APPLET;
+
+ private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
+
+ private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
+
+ /**
+ * 创建令牌
+ */
+ public Map<String, Object> createToken(LoginUser loginUser) {
+ String token = IdUtils.fastUUID();
+ Long userId = loginUser.getSysUser().getUserId();
+ String userName = loginUser.getSysUser().getUserName();
+ loginUser.setToken(token);
+ loginUser.setUserid(userId);
+ loginUser.setUsername(userName);
+ loginUser.setIpaddr(IpUtils.getIpAddr());
+ refreshToken(loginUser);
+
+ // Jwt存储信息
+ Map<String, Object> claimsMap = new HashMap<String, Object>();
+ claimsMap.put(SecurityConstants.USER_KEY, token);
+ claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
+ claimsMap.put(SecurityConstants.USER_TYPE, "system");
+ claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
+
+ // 接口返回信息
+ Map<String, Object> rspMap = new HashMap<String, Object>();
+ rspMap.put("access_token", JwtUtils.createToken(claimsMap));
+ rspMap.put("expires_in", expireTime);
+ return rspMap;
+ }
+
+ /**
+ * 创建小程序令牌
+ */
+ public Map<String, Object> createTokenApplet(LoginUserApplet loginUser) {
+ String token = IdUtils.fastUUID();
+ Long userId = loginUser.getUserId();
+ String name = loginUser.getName();
+ loginUser.setToken(token);
+ loginUser.setIpaddr(IpUtils.getIpAddr());
+ refreshToken1(loginUser);
+ // Jwt存储信息
+ Map<String, Object> claimsMap = new HashMap<String, Object>();
+ claimsMap.put(SecurityConstants.USER_APPLET_KEY, token);
+ claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
+ claimsMap.put(SecurityConstants.USER_TYPE, "applet");
+ claimsMap.put(SecurityConstants.DETAILS_USERNAME, name);
+ // 接口返回信息
+ Map<String, Object> rspMap = new HashMap<String, Object>();
+ rspMap.put("access_token", JwtUtils.createToken(claimsMap));
+ rspMap.put("expires_in", expireAppletTime);
+ return rspMap;
+ }
+
+ public LoginUserApplet getLoginUserApplet() {
+ LoginUserApplet loginUserAppletToken = getLoginUserAppletToken(ServletUtils.getRequest());
+ if (loginUserAppletToken == null) {
+ throw new UserAppletException("登录失效,请重新登录!", 401);
+ }
+ return loginUserAppletToken;
+ }
+
+ public LoginUserApplet getLoginUserAppletToken(HttpServletRequest request) {
+ // 获取请求携带的令牌
+ String token = SecurityUtils.getToken(request);
+ return getLoginUserApplet(token);
+ }
+
+ /**
+ * 小程序 获取用户身份信息
+ *
+ * @return 用户信息
+ */
+ public LoginUserApplet getLoginUserApplet(String token) {
+ LoginUserApplet user = null;
+ try {
+ if (StringUtils.isNotEmpty(token)) {
+ String userKey = JwtUtils.getUserKeyApplet(token);
+ user = redisService.getCacheObject(getTokenKey(userKey));
+ return user;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return user;
+ }
+
+ /**
+ * 获取用户身份信息
+ *
+ * @return 用户信息
+ */
+ public LoginUser getLoginUser() {
+ return getLoginUser(ServletUtils.getRequest());
+ }
+
+ /**
+ * 获取用户身份信息
+ *
+ * @return 用户信息
+ */
+ public LoginUser getLoginUser(HttpServletRequest request) {
+ // 获取请求携带的令牌
+ String token = SecurityUtils.getToken(request);
+ return getLoginUser(token);
+ }
+
+ /**
+ * 获取用户身份信息
+ *
+ * @return 用户信息
+ */
+ public LoginUser getLoginUser(String token) {
+ LoginUser user = null;
+ try {
+ if (StringUtils.isNotEmpty(token)) {
+ String userkey = JwtUtils.getUserKey(token);
+ user = redisService.getCacheObject(getTokenKey(userkey));
+ return user;
+ }
+ } catch (Exception e) {
+ }
+ return user;
+ }
+
+ /**
+ * 设置用户身份信息
+ */
+ public void setLoginUser(LoginUser loginUser) {
+ if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
+ refreshToken(loginUser);
+ }
+ }
+
+ /**
+ * 删除用户缓存信息
+ */
+ public void delLoginUser(String token) {
+ if (StringUtils.isNotEmpty(token)) {
+ String userkey = JwtUtils.getUserKey(token);
+ redisService.deleteObject(getTokenKey(userkey));
+ }
+ }
+
+ /**
+ * 验证令牌有效期,相差不足120分钟,自动刷新缓存
+ *
+ * @param loginUser
+ */
+ public void verifyToken(LoginUser loginUser) {
+ long expireTime = loginUser.getExpireTime();
+ long currentTime = System.currentTimeMillis();
+ if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
+ refreshToken(loginUser);
+ }
+ }
+
+ /**
+ * 刷新令牌有效期
+ *
+ * @param loginUser 登录信息
+ */
+ public void refreshToken(LoginUser loginUser) {
+ loginUser.setLoginTime(System.currentTimeMillis());
+ loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
+ // 根据uuid将loginUser缓存
+ String userKey = getTokenKey(loginUser.getToken());
+ redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
+ }
+
+ public void refreshToken1(LoginUserApplet dto) {
+ dto.setLoginTime(System.currentTimeMillis());
+ dto.setExpireTime(dto.getLoginTime() + expireTime * MILLIS_MINUTE);
+ // 根据uuid将loginUser缓存
+ String userKey = getTokenKey(dto.getToken());
+ redisService.setCacheObject(userKey, dto, expireTime, TimeUnit.MINUTES);
+ }
+
+ private String getTokenKey(String token) {
+ return ACCESS_TOKEN + token;
+ }
}
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
index 6f39524..fd85e38 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -24,7 +24,9 @@
import com.ruoyi.order.service.TChargingOrderService;
import com.ruoyi.order.service.TOrderEvaluateService;
import com.ruoyi.order.service.TOrderEvaluateTagService;
+import com.ruoyi.payment.api.feignClient.AliPaymentClient;
import com.ruoyi.payment.api.feignClient.WxPaymentClient;
+import com.ruoyi.payment.api.vo.AliQueryOrder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -35,6 +37,7 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.List;
@@ -64,6 +67,9 @@
@Resource
private RedisService redisService;
+
+ @Resource
+ private AliPaymentClient aliPaymentClient;
@@ -203,20 +209,23 @@
/**
* 支付宝支付成功后的回调
- * @param request
*/
@ResponseBody
@PostMapping(value = "/chargingOrderALICallback")
- public void chargingOrderALICallback(HttpServletRequest request){
- Map<String, Object> data = wxPaymentClient.payNotify(request).getData();
- if(null != data){
- String out_trade_no = data.get("out_trade_no").toString();
- String transaction_id = data.get("transaction_id").toString();
- String attach = data.get("attach").toString();
+ public void chargingOrderALICallback(@RequestBody AliQueryOrder aliQueryOrder, HttpServletResponse response){
+ try {
+ String out_trade_no = aliQueryOrder.getOutTradeNo();
+ String transaction_id = aliQueryOrder.getTradeNo();
+ String attach = aliQueryOrder.getPassbackParams();
AjaxResult ajaxResult = chargingOrderService.chargingOrderCallback(2, out_trade_no, transaction_id, attach);
if(ajaxResult.isSuccess()){
-
+ PrintWriter writer = response.getWriter();
+ writer.println("success");
+ writer.flush();
+ writer.close();
}
+ }catch (Exception e){
+ e.printStackTrace();
}
}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
index 425fe9e..51ec3ab 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -1,7 +1,5 @@
package com.ruoyi.order.service.impl;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.api.feignClient.AppUserCarClient;
@@ -22,7 +20,6 @@
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.service.TokenService;
-import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy;
import com.ruoyi.order.api.query.ChargingOrderQuery;
@@ -32,13 +29,10 @@
import com.ruoyi.order.mapper.TChargingOrderMapper;
import com.ruoyi.order.service.TChargingOrderAccountingStrategyService;
import com.ruoyi.order.service.TChargingOrderService;
-import com.ruoyi.other.api.domain.TCoupon;
-import com.ruoyi.other.api.domain.TVip;
+import com.ruoyi.payment.api.feignClient.AliPaymentClient;
import com.ruoyi.payment.api.feignClient.WxPaymentClient;
-import com.ruoyi.payment.api.vo.NotifyV3PayDecodeRespBody;
-import com.ruoyi.payment.api.vo.PaymentOrder;
+import com.ruoyi.payment.api.vo.*;
import io.seata.spring.annotation.GlobalTransactional;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@@ -48,7 +42,6 @@
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
-import java.util.stream.Collectors;
/**
* <p>
@@ -80,6 +73,9 @@
@Resource
private WxPaymentClient wxPaymentClient;
+
+ @Resource
+ private AliPaymentClient aliPaymentClient;
@Resource
private ChargingPileClient chargingPileClient;
@@ -231,7 +227,14 @@
}
}
if(2 == rechargePaymentType){
-
+ AliQueryOrder data = aliPaymentClient.query(tChargingOrder.getCode()).getData();
+ if(null != data){
+ //支付失败,删除无效的订单
+ String tradeStatus = data.getTradeStatus();
+ if(tradeStatus.equals("TRADE_CLOSED")){
+ this.removeById(tChargingOrder.getId());
+ }
+ }
}
}
@@ -261,7 +264,19 @@
}
}
if(2 == one.getRechargePaymentType()){
-
+ AliQueryOrder data = aliPaymentClient.query(one.getCode()).getData();
+ if(null != data){
+ String trade_state = data.getTradeStatus();
+ //支付失败,删除无效的订单
+ if(trade_state.equals("TRADE_CLOSED")){
+ this.removeById(one.getId());
+ }
+ if(trade_state.equals("WAIT_BUYER_PAY")){
+ //结束第三方支付,删除订单
+ aliPaymentClient.close(one.getCode());
+ this.removeById(one.getId());
+ }
+ }
}
}
@@ -313,7 +328,17 @@
return AjaxResult.success(data);
}
if(2 == addChargingOrder.getPaymentType()){
-
+ AliPaymentReq req = new AliPaymentReq();
+ req.setOutTradeNo(chargingOrder.getCode());
+ req.setTotalAmount(chargingOrder.getPaymentAmount().toString());
+ req.setSubject("充电充值");
+ req.setBuyerOpenId(appUser.getAliOpenid());
+ req.setBody("充电充值");
+ AliPaymentResp data = aliPaymentClient.payment(req).getData();
+ if(null != data){
+ data.setNotifyUrl(data.getNotifyUrl() + "/t-charging-order/chargingOrderALICallback");
+ return AjaxResult.success(data);
+ }
}
throw new RuntimeException("无效的支付方式");
}
diff --git a/ruoyi-service/ruoyi-payment/pom.xml b/ruoyi-service/ruoyi-payment/pom.xml
index eedddef..f5b4d41 100644
--- a/ruoyi-service/ruoyi-payment/pom.xml
+++ b/ruoyi-service/ruoyi-payment/pom.xml
@@ -128,6 +128,12 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api-payment</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>com.alipay.sdk</groupId>
+ <artifactId>alipay-sdk-java</artifactId>
+ <version>4.39.186.ALL</version>
+ </dependency>
</dependencies>
<build>
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/AliProperties.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/AliProperties.java
new file mode 100644
index 0000000..631dea4
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/AliProperties.java
@@ -0,0 +1,54 @@
+package com.ruoyi.payment.ali.config;
+
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/23 16:08
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "payment.ali")
+public class AliProperties {
+ /**
+ * appid
+ */
+ private String appId;
+ /**
+ * 加签方式
+ */
+ private String signType;
+ /**
+ * 开发者私钥,由开发者自己生成
+ */
+ private String privateKey;
+ /**
+ * 支付宝公钥
+ */
+ private String alipayPublicKey;
+ /**
+ * 应用公钥证书文件本地路径
+ */
+ private String appCertPath;
+ /**
+ * 支付宝公钥证书文件本地路径
+ */
+ private String alipayPublicCertPath;
+ /**
+ * 支付宝根证书文件本地路径
+ */
+ private String rootCertPath;
+ /**
+ * 回调地址
+ */
+ private String notifyUrl;
+ /**
+ * V2接口地址
+ */
+ private String v2Path = "https://openapi.alipay.com/gateway.do";
+
+
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/SignType.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/SignType.java
new file mode 100644
index 0000000..d044247
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/SignType.java
@@ -0,0 +1,39 @@
+package com.ruoyi.payment.ali.config;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/23 16:22
+ */
+public enum SignType {
+ /**
+ * V2版本
+ */
+ RSA2("RSA2"),
+ /**
+ * V3版本
+ */
+ RSA3("RSA2"),
+ /**
+ * 秘钥
+ */
+ SECRET_KEY("secret"),
+ /**
+ * 证书
+ */
+ CERT("cert");
+
+
+ private String type;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ SignType(String type) {
+ this.type = type;
+ }
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/AppletPayUtil.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/AppletPayUtil.java
new file mode 100644
index 0000000..c116fdc
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/AppletPayUtil.java
@@ -0,0 +1,228 @@
+package com.ruoyi.payment.ali.v2;
+
+import com.alibaba.fastjson.JSON;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.AlipayConfig;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.domain.*;
+import com.alipay.api.request.*;
+import com.alipay.api.response.*;
+import com.ruoyi.payment.ali.config.AliProperties;
+import com.ruoyi.payment.ali.config.SignType;
+import com.ruoyi.payment.ali.v2.model.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+
+/**
+ * 支付宝小程序支付
+ * @author zhibing.pu
+ * @Date 2024/8/23 16:05
+ */
+@Component
+public class AppletPayUtil {
+ private static Logger log = LoggerFactory.getLogger(AppletPayUtil.class);
+
+ @Resource
+ private AliProperties aliProperties;
+
+
+ /**
+ * 创建统一收单交易
+ * @param pojo
+ */
+ public PaymentResp payment(PaymentReq pojo){
+ try {
+ // 初始化SDK
+ AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
+ // 构造请求参数以调用接口
+ AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
+ AlipayTradeCreateModel model = new AlipayTradeCreateModel();
+ // 设置商户订单号
+ model.setOutTradeNo(pojo.getOutTradeNo());
+ // 设置产品码
+ model.setProductCode("JSAPI_PAY");
+ // 设置小程序支付中
+ model.setOpAppId(aliProperties.getAppId());
+ // 设置订单总金额
+ model.setTotalAmount(pojo.getTotalAmount());
+ // 设置订单标题
+ model.setSubject(pojo.getSubject());
+ // 设置订单附加信息
+ model.setBody(pojo.getBody());
+ // 设置买家支付宝用户唯一标识
+ model.setBuyerOpenId(pojo.getBuyerOpenId());
+ //超时相对时间
+ model.setTimeoutExpress(pojo.getTimeoutExpress());
+ //异步返回参数
+ model.setPassbackParams(pojo.getPassbackParams());
+ request.setBizModel(model);
+
+ AlipayTradeCreateResponse response = alipayClient.execute(request);
+ log.info("-----调起支付宝支付-----");
+ log.info("请求参数:{}", pojo);
+ log.info("返回结果:{}", response.getBody());
+ if (response.isSuccess()) {
+ return PaymentResp.build(response.getOutTradeNo(), response.getTradeNo());
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+
+ /**
+ * 查询支付订单
+ * @param outTradeNo 业务流水号
+ * @return
+ */
+ public QueryResp query(String outTradeNo){
+ try {
+ // 初始化SDK
+ AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
+ // 构造请求参数以调用接口
+ AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
+ AlipayTradeQueryModel model = new AlipayTradeQueryModel();
+ // 设置订单支付时传入的商户订单号
+ model.setOutTradeNo(outTradeNo);
+ request.setBizModel(model);
+ AlipayTradeQueryResponse response = alipayClient.execute(request);
+ log.info("-----查询支付宝支付-----");
+ log.info("请求参数:{}", outTradeNo);
+ log.info("返回结果:{}", response.getBody());
+ if (response.isSuccess()) {
+ return JSON.parseObject(response.getBody(), QueryResp.class);
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+
+ /**
+ * 交易退款
+ * @param req
+ * @return
+ */
+ public RefundResp refund(RefundReq req){
+ try {
+ // 初始化SDK
+ AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
+ // 构造请求参数以调用接口
+ AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
+ AlipayTradeRefundModel model = new AlipayTradeRefundModel();
+ // 设置商户订单号
+ model.setOutTradeNo(req.getOutTradeNo());
+ // 设置退款商户订单号
+ model.setOutRequestNo(req.getOutRequestNo());
+ // 设置退款金额
+ model.setRefundAmount(req.getRefundAmount());
+ // 设置退款原因说明
+ model.setRefundReason(req.getRefundReason());
+ request.setBizModel(model);
+ AlipayTradeRefundResponse response = alipayClient.execute(request);
+ log.info("-----支付宝退款-----");
+ log.info("请求参数:{}", req);
+ log.info("返回结果:{}", response.getBody());
+ if (response.isSuccess()) {
+ return JSON.parseObject(response.getBody(), RefundResp.class);
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 退款查询
+ * @param req
+ * @return
+ */
+ public QueryRefundResp queryRefund(QueryRefundReq req){
+ try {
+ // 初始化SDK
+ AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
+ // 构造请求参数以调用接口
+ AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
+ AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
+ // 设置商户订单号
+ model.setOutTradeNo(req.getOutTradeNo());
+ model.setOutRequestNo(req.getOutRequestNo());
+ request.setBizModel(model);
+ AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
+ log.info("-----查询支付宝退款-----");
+ log.info("请求参数:{}", req);
+ log.info("返回结果:{}", response.getBody());
+ if (response.isSuccess()) {
+ return JSON.parseObject(response.getBody(), QueryRefundResp.class);
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 支付宝关闭订单
+ * @param outTradeNo 业务流水号
+ * @return
+ */
+ public boolean close(String outTradeNo){
+ try {
+ AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
+ AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
+ AlipayTradeCloseModel model = new AlipayTradeCloseModel();
+ model.setOutTradeNo(outTradeNo);
+ request.setBizModel(model);
+ AlipayTradeCloseResponse response = alipayClient.execute(request);
+ log.info("-----关闭支付宝支付订单-----");
+ log.info("请求参数:{}", outTradeNo);
+ log.info("返回结果:{}", response.getBody());
+ if(response.isSuccess()){
+ return true;
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+
+
+ /**
+ * 构建配置数据
+ * @return
+ */
+ private AlipayConfig getAlipayConfig() throws Exception {
+ AlipayConfig alipayConfig = new AlipayConfig();
+ alipayConfig.setServerUrl(aliProperties.getV2Path());
+ alipayConfig.setAppId(aliProperties.getAppId());
+ alipayConfig.setFormat("json");
+ alipayConfig.setCharset("UTF-8");
+ alipayConfig.setSignType(SignType.RSA2.getType());
+ //判断加签方式
+ String signType = aliProperties.getSignType();
+ if(SignType.CERT.getType().equals(signType)){
+ alipayConfig.setPrivateKey(aliProperties.getPrivateKey());
+ alipayConfig.setAlipayPublicKey(aliProperties.getAlipayPublicKey());
+ return alipayConfig;
+ }
+ if(SignType.SECRET_KEY.getType().equals(signType)){
+ alipayConfig.setAppCertPath(aliProperties.getAppCertPath());
+ alipayConfig.setAlipayPublicCertPath(aliProperties.getAlipayPublicCertPath());
+ alipayConfig.setRootCertPath(aliProperties.getRootCertPath());
+ return alipayConfig;
+ }
+ throw new RuntimeException("构建配置失败");
+ }
+
+
+
+
+
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentReq.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentReq.java
new file mode 100644
index 0000000..422f4b1
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentReq.java
@@ -0,0 +1,52 @@
+package com.ruoyi.payment.ali.v2.model;
+
+import lombok.Data;
+
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/23 16:52
+ */
+@Data
+public class PaymentReq {
+ /**
+ * 业务流水号
+ */
+ private String outTradeNo;
+ /**
+ * 支付总金额
+ */
+ private String totalAmount;
+ /**
+ * 订单标题
+ */
+ private String subject;
+ /**
+ * 支付用户支付宝openid
+ */
+ private String buyerOpenId;
+ /**
+ * 订单附加信息
+ */
+ private String body;
+ /**
+ * 订单超时时间
+ * 订单相对超时时间。从交易创建时间开始计算。
+ * 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
+ * 当面付场景默认值为3h
+ */
+ private String timeoutExpress;
+ /**
+ * 回传参数
+ * 如果请求时传递了该参数,支付宝会在异步通知时将该参数原样返回。
+ */
+ private String passbackParams;
+
+ /**
+ * 初始化默认数据
+ */
+ public PaymentReq() {
+ //订单超时默认30分钟
+ this.timeoutExpress = "30m";
+ }
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentResp.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentResp.java
new file mode 100644
index 0000000..de77d29
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentResp.java
@@ -0,0 +1,30 @@
+package com.ruoyi.payment.ali.v2.model;
+
+import lombok.Data;
+
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/23 16:52
+ */
+@Data
+public class PaymentResp {
+ /**
+ * 业务流水号
+ */
+ private String outTradeNo;
+ /**
+ * 支付宝交易号
+ */
+ private String tradeNo;
+
+ private PaymentResp(String outTradeNo, String tradeNo) {
+ this.outTradeNo = outTradeNo;
+ this.tradeNo = tradeNo;
+ }
+
+ public static PaymentResp build(String outTradeNo, String tradeNo){
+ PaymentResp info = new PaymentResp(outTradeNo, tradeNo);
+ return info;
+ }
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundReq.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundReq.java
new file mode 100644
index 0000000..bb74d63
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundReq.java
@@ -0,0 +1,19 @@
+package com.ruoyi.payment.ali.v2.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/24 14:00
+ */
+@Data
+public class QueryRefundReq {
+ /**
+ * 支付业务流水号
+ */
+ private String outTradeNo;
+ /**
+ * 退款业务流水号
+ */
+ private String outRequestNo;
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundResp.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundResp.java
new file mode 100644
index 0000000..ad4263f
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundResp.java
@@ -0,0 +1,43 @@
+package com.ruoyi.payment.ali.v2.model;
+
+import com.fasterxml.jackson.annotation.JsonSetter;
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/24 13:58
+ */
+@Data
+public class QueryRefundResp {
+ /**
+ * 支付宝交易号
+ */
+ @JsonSetter("trade_no")
+ private String tradeNo;
+ /**
+ * 支付业务流水号
+ */
+ @JsonSetter("out_trade_no")
+ private String outTradeNo;
+ /**
+ * 退款业务流水号
+ */
+ @JsonSetter("out_request_no")
+ private String outRequestNo;
+ /**
+ * 交易金额
+ */
+ @JsonSetter("total_amount")
+ private Double totalAmount;
+ /**
+ * 本次退款金额
+ */
+ @JsonSetter("refund_amount")
+ private Double refundAmount;
+ /**
+ * 退款状态
+ * REFUND_SUCCESS 退款处理成功; 未返回该字段表示退款请求未收到或者退款失败; 注:如果退款查询发起时间早于退款时间,或者间隔退款发起时间太短,可能出现退款查询时还没处理成功,后面又处理成功的情况,建议商户在退款发起后间隔10秒以上再发起退款查询请求。
+ */
+ @JsonSetter("refund_status")
+ private String refundStatus;
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryResp.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryResp.java
new file mode 100644
index 0000000..c09e509
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryResp.java
@@ -0,0 +1,48 @@
+package com.ruoyi.payment.ali.v2.model;
+
+import com.fasterxml.jackson.annotation.JsonSetter;
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/24 12:01
+ */
+@Data
+public class QueryResp {
+ /**
+ * 支付宝交易号
+ */
+ @JsonSetter("trade_no")
+ private String tradeNo;
+ /**
+ * 业务流水号
+ */
+ @JsonSetter("out_trade_no")
+ private String outTradeNo;
+ /**
+ * 交易状态
+ * WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)
+ */
+ @JsonSetter("trade_status")
+ private String tradeStatus;
+ /**
+ * 交易订单金额
+ */
+ @JsonSetter("total_amount")
+ private Double totalAmount;
+ /**
+ * 回传参数
+ */
+ @JsonSetter("passback_params")
+ private String passbackParams;
+ /**
+ * 订单标题
+ */
+ @JsonSetter("subject")
+ private String subject;
+ /**
+ * 订单描述
+ */
+ @JsonSetter("body")
+ private String body;
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundReq.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundReq.java
new file mode 100644
index 0000000..a887e52
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundReq.java
@@ -0,0 +1,27 @@
+package com.ruoyi.payment.ali.v2.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/24 13:47
+ */
+@Data
+public class RefundReq {
+ /**
+ * 支付业务流水号
+ */
+ private String outTradeNo;
+ /**
+ * 退款业务流水号
+ */
+ private String outRequestNo;
+ /**
+ * 退款金额
+ */
+ private String refundAmount;
+ /**
+ * 退款原因
+ */
+ private String refundReason;
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundResp.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundResp.java
new file mode 100644
index 0000000..ed4697c
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundResp.java
@@ -0,0 +1,27 @@
+package com.ruoyi.payment.ali.v2.model;
+
+import com.fasterxml.jackson.annotation.JsonSetter;
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/24 13:50
+ */
+@Data
+public class RefundResp {
+ /**
+ * 支付宝交易号
+ */
+ @JsonSetter("trade_no")
+ private String tradeNo;
+ /**
+ * 业务流水号
+ */
+ @JsonSetter("out_trade_no")
+ private String outTradeNo;
+ /**
+ * 退款金额
+ */
+ @JsonSetter("refund_fee")
+ private Double refundFee;
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java
new file mode 100644
index 0000000..4bd7ea5
--- /dev/null
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java
@@ -0,0 +1,86 @@
+package com.ruoyi.payment.controller;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.payment.ali.config.AliProperties;
+import com.ruoyi.payment.ali.v2.AppletPayUtil;
+import com.ruoyi.payment.ali.v2.model.PaymentReq;
+import com.ruoyi.payment.ali.v2.model.PaymentResp;
+import com.ruoyi.payment.ali.v2.model.QueryResp;
+import com.ruoyi.payment.api.vo.AliPaymentReq;
+import com.ruoyi.payment.api.vo.AliPaymentResp;
+import com.ruoyi.payment.api.vo.AliQueryOrder;
+import org.springframework.beans.BeanUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/8/24 14:29
+ */
+@RestController
+@RequestMapping("/ali")
+public class AliPayController {
+
+ @Resource
+ private AppletPayUtil appletPayUtil;
+
+ @Resource
+ private AliProperties aliProperties;
+
+
+ /**
+ * 调起支付宝小程序支付
+ * @param req
+ * @return
+ */
+ @ResponseBody
+ @PostMapping("/payment")
+ public R<AliPaymentResp> payment(@RequestBody AliPaymentReq req){
+ PaymentReq pojo = new PaymentReq();
+ BeanUtils.copyProperties(req, pojo);
+ PaymentResp payment = appletPayUtil.payment(pojo);
+ if(null != payment){
+ AliPaymentResp aliPaymentResp = new AliPaymentResp();
+ aliPaymentResp.setTradeNo(payment.getTradeNo());
+ aliPaymentResp.setNotifyUrl(aliProperties.getNotifyUrl());
+ return R.ok(aliPaymentResp);
+ }
+ return R.ok();
+ }
+
+ /**
+ * 查询订单
+ * @param outTradeNo
+ * @return
+ */
+ @ResponseBody
+ @PostMapping("/query")
+ public R<AliQueryOrder> query(@RequestParam("outTradeNo") String outTradeNo){
+ QueryResp query = appletPayUtil.query(outTradeNo);
+ if(null != query){
+ AliQueryOrder aliQueryOrder = new AliQueryOrder();
+ BeanUtils.copyProperties(query, aliQueryOrder);
+ return R.ok(aliQueryOrder);
+ }
+ return R.ok();
+ }
+
+ /**
+ * 关闭订单
+ * @param outTradeNo
+ */
+ @ResponseBody
+ @PostMapping("/close")
+ public void close(@RequestParam("outTradeNo") String outTradeNo){
+ boolean close = appletPayUtil.close(outTradeNo);
+ if(!close){
+ throw new RuntimeException("关闭支付宝订单失败");
+ }
+ }
+
+
+
+
+
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/controller/WxPayController.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java
similarity index 99%
rename from ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/controller/WxPayController.java
rename to ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java
index f3e7274..51b2238 100644
--- a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/controller/WxPayController.java
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java
@@ -1,4 +1,4 @@
-package com.ruoyi.payment.wx.controller;
+package com.ruoyi.payment.controller;
import com.fasterxml.jackson.core.type.TypeReference;
import com.ruoyi.common.core.domain.R;
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/config/WxConfig.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/config/WxConfig.java
index 3aafb85..c5f4e17 100644
--- a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/config/WxConfig.java
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/config/WxConfig.java
@@ -13,7 +13,6 @@
*
* @author lihen
*/
-@ConditionalOnProperty(name = "wx.conf.enabled")
@Configuration
public class WxConfig {
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/model/WeixinProperties.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/model/WeixinProperties.java
index 5c1960b..a29040f 100644
--- a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/model/WeixinProperties.java
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/model/WeixinProperties.java
@@ -12,7 +12,7 @@
*/
@ToString
@Component
-@ConfigurationProperties(prefix = "wx.conf")
+@ConfigurationProperties(prefix = "payment.wx")
public class WeixinProperties {
/**
* 默认开启
--
Gitblit v1.7.1