zhibing.pu
2024-08-24 49148072078220c92f94f2e7ea25cd79a6810fc7
封装支付宝支付和完善充电支付功能
1 文件已重命名
8个文件已修改
16个文件已添加
1352 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentReq.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentResp.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliQueryOrder.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java 396 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/AliProperties.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/SignType.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/AppletPayUtil.java 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentReq.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentResp.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundReq.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundResp.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryResp.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundReq.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundResp.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/config/WxConfig.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/model/WeixinProperties.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java
New file
@@ -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());
            }
        };
    }
}
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());
            }
        };
    }
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java
New file
@@ -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);
}
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentReq.java
New file
@@ -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";
    }
}
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliPaymentResp.java
New file
@@ -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;
}
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/vo/AliQueryOrder.java
New file
@@ -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;
}
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
com.ruoyi.payment.api.factory.WxPaymentFallbackFactory
com.ruoyi.payment.api.factory.AliPaymentFallbackFactory
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;
    }
}
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();
        }
    }
    
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("无效的支付方式");
    }
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>
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/AliProperties.java
New file
@@ -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";
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/config/SignType.java
New file
@@ -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;
    }
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/AppletPayUtil.java
New file
@@ -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("构建配置失败");
    }
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentReq.java
New file
@@ -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";
    }
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/PaymentResp.java
New file
@@ -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;
    }
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundReq.java
New file
@@ -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;
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryRefundResp.java
New file
@@ -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;
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/QueryResp.java
New file
@@ -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;
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundReq.java
New file
@@ -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;
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/ali/v2/model/RefundResp.java
New file
@@ -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;
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java
New file
@@ -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("关闭支付宝订单失败");
        }
    }
}
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java
File was renamed from ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/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;
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 {
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 {
    /**
     * 默认开启