Commit cfe0f8bdc0d7f074113e3cf11cb61bc0c0b838fa
1 parent
9346961f
Exists in
dev
解决重复支付问题
Showing
6 changed files
with
306 additions
and
102 deletions
Show diff stats
backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java
... | ... | @@ -160,7 +160,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { |
160 | 160 | .antMatchers("/fileUpload").permitAll() |
161 | 161 | .antMatchers("/deleteFile").permitAll() |
162 | 162 | .antMatchers("/ueditor/**", "/apiManager/getToken").permitAll() |
163 | - .antMatchers("/user/wxPay/**").permitAll() | |
163 | + .antMatchers("/user/wxPay/handlePaySuccessCallback").permitAll() | |
164 | + .antMatchers("/user/wxPay/handleRefundSuccessCallback").permitAll() | |
164 | 165 | .anyRequest().authenticated() |
165 | 166 | .accessDecisionManager(accessDecisionManager()); |
166 | 167 | ... | ... |
backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/DdConroller.java
... | ... | @@ -2,7 +2,11 @@ package com.hotent.lpg.user.controller; |
2 | 2 | |
3 | 3 | import cn.hutool.core.bean.BeanUtil; |
4 | 4 | import com.baomidou.mybatisplus.core.metadata.IPage; |
5 | +import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |
5 | 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
7 | +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; | |
8 | +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; | |
9 | +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; | |
6 | 10 | import com.hotent.base.model.CommonResult; |
7 | 11 | import com.hotent.lpg.common.enums.DdlyEnum; |
8 | 12 | import com.hotent.lpg.common.enums.DdztEnum; |
... | ... | @@ -90,51 +94,6 @@ public class DdConroller { |
90 | 94 | return CommonResult.<String>ok(); |
91 | 95 | } |
92 | 96 | |
93 | -// /** | |
94 | -// * 创建订单 | |
95 | -// * | |
96 | -// * @param request | |
97 | -// * @return | |
98 | -// * @throws Exception | |
99 | -// * @throws | |
100 | -// */ | |
101 | -// @PostMapping(value = "/save") | |
102 | -// @ApiOperation(value = "创建订单", httpMethod = "POST", notes = "创建订单") | |
103 | -// public CommonResult createOrder(@ApiParam(name = "CreateOrderRequest", value = "创建订单请求对象", required = true) @RequestBody DdDto request) throws Exception { | |
104 | -// WHydz hydz = hydzDao.selectOneByHyIdAndDzId(ContextUtil.getCurrentUserId(), request.getHydzId()); | |
105 | -// if (BeanUtil.isEmpty(hydz)){ | |
106 | -// throw new RuntimeException("未查询到地址信息。"); | |
107 | -// } | |
108 | -// WHyxx hyxx = wHyxxManager.getUseridByInfo(ContextUtil.getCurrentUserId()); | |
109 | -// if (BeanUtil.isEmpty(hyxx)){ | |
110 | -// throw new RuntimeException("未查询会员信息。"); | |
111 | -// } | |
112 | -// request.setShlxr(hydz.getFLxr()); | |
113 | -// request.setShlxrdh(hydz.getFLxrdh()); | |
114 | -// request.setShsf(hydz.getFLxrsf()); | |
115 | -// request.setShs(hydz.getFLxrs()); | |
116 | -// request.setShq(hydz.getFLxrq()); | |
117 | -// request.setShjd(hydz.getFLxrjd()); | |
118 | -// request.setShxxdz(hydz.getFLxrxxdz()); | |
119 | -// request.setJd(hydz.getFJd()); | |
120 | -// request.setWd(hydz.getFWd()); | |
121 | -// | |
122 | -// request.setSfhy("是"); | |
123 | -// request.setHydh(hyxx.getFSjh()); //账号就是电话 | |
124 | -// request.setHyid(hyxx.getFUserid()); | |
125 | -// request.setHymc(hyxx.getFXm()); | |
126 | -// request.setHylx(hyxx.getFHylx()); | |
127 | -// request.setSfzh(hyxx.getFSfzh()); | |
128 | -// request.setShtysbm(hyxx.getFShtysbm()); | |
129 | -// | |
130 | -// request.setXdrlx(UserlxEnum.hy.getInfo()); | |
131 | -// request.setXdrid(ContextUtil.getCurrentUserId()); | |
132 | -// request.setXdrmc(ContextUtil.getCurrentUser().getFullname()); | |
133 | -// request.setDdly(DdlyEnum.xsxd.getInfo()); | |
134 | -// WDd order = wDdManager.createOrder(request); | |
135 | -// return CommonResult.ok().value(order); | |
136 | -// } | |
137 | - | |
138 | 97 | @PostMapping(value = "/add") |
139 | 98 | @ApiOperation(value = "创建订单", httpMethod = "POST", notes = "创建订单") |
140 | 99 | public CommonResult createOrder(@ApiParam(name = "CreateOrderRequest", value = "创建订单请求对象", required = true) @RequestBody DdDto ddDto) { |
... | ... | @@ -172,9 +131,8 @@ public class DdConroller { |
172 | 131 | ddDto.setDdzt(DdztEnum.CREATED.getCode()); |
173 | 132 | WDd order = wDdManager.addOrder(ddDto); |
174 | 133 | log.warn("创建订单2:{}", order); |
175 | - HashMap<String, Object> resultData = wxPayManager.generatePrepayOrder(order, ddDto.getOpenId()); | |
176 | - log.warn("创建订单3:{}", resultData); | |
177 | - return CommonResult.ok().value(resultData); | |
134 | +// WxPayMpOrderResult prepayOrder = wxPayManager.generatePrepayOrder(order.getId(), ddDto.getOpenId(),order.getFZflx()); | |
135 | + return CommonResult.ok().value(order); | |
178 | 136 | } |
179 | 137 | |
180 | 138 | ... | ... |
backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/WxPayController.java
1 | 1 | package com.hotent.lpg.user.controller; |
2 | 2 | |
3 | 3 | |
4 | +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; | |
5 | +import com.github.binarywang.wxpay.exception.WxPayException; | |
6 | +import com.hotent.base.model.CommonResult; | |
7 | +import com.hotent.lpg.common.model.WDd; | |
8 | +import com.hotent.lpg.user.manager.DdManager; | |
4 | 9 | import com.hotent.lpg.user.manager.WxPayManager; |
10 | +import io.swagger.annotations.ApiOperation; | |
5 | 11 | import lombok.AllArgsConstructor; |
6 | 12 | import lombok.extern.slf4j.Slf4j; |
7 | 13 | import org.springframework.validation.annotation.Validated; |
8 | -import org.springframework.web.bind.annotation.PostMapping; | |
9 | -import org.springframework.web.bind.annotation.RequestBody; | |
10 | -import org.springframework.web.bind.annotation.RequestMapping; | |
11 | -import org.springframework.web.bind.annotation.RestController; | |
14 | +import org.springframework.web.bind.annotation.*; | |
15 | + | |
16 | +import java.util.HashMap; | |
12 | 17 | |
13 | 18 | @RestController |
14 | 19 | @RequestMapping("/user/wxPay/") |
... | ... | @@ -17,6 +22,31 @@ import org.springframework.web.bind.annotation.RestController; |
17 | 22 | @Slf4j |
18 | 23 | public class WxPayController { |
19 | 24 | private WxPayManager wxPayManager; |
25 | + private DdManager ddManager; | |
26 | + | |
27 | + /** | |
28 | + * 调用统一下单接口 | |
29 | + * | |
30 | + * @return | |
31 | + */ | |
32 | + @PostMapping("/unifiedOrder") | |
33 | + public CommonResult unifiedOrder(@RequestBody HashMap<String, String> params) throws WxPayException { | |
34 | + String ddid = String.valueOf(params.get("ddid")); | |
35 | + String openId = params.get("openId"); | |
36 | + String zflx = params.get("zflx"); | |
37 | + return CommonResult.ok().value(wxPayManager.initiateJsApiPay(ddid, openId, zflx)); | |
38 | + } | |
39 | + | |
40 | + | |
41 | + @GetMapping(value = "/getPrepayOrder") | |
42 | + @ApiOperation(value = "查询微信支付系统的预支付订单信息", httpMethod = "GET", notes = "查询微信支付系统的预支付订单信息") | |
43 | + public CommonResult getPrepayOrder(@RequestParam(required = true) String id) throws Exception { | |
44 | + WxPayOrderQueryResult weChatOrder = wxPayManager.getWxPayOrderQuery(id); | |
45 | + return CommonResult.ok().value(weChatOrder); | |
46 | + } | |
47 | + | |
48 | + | |
49 | + | |
20 | 50 | |
21 | 51 | /** |
22 | 52 | * 处理支付成功回调 | ... | ... |
backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/WxPayManager.java
1 | 1 | package com.hotent.lpg.user.manager; |
2 | 2 | |
3 | +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; | |
4 | +import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; | |
5 | +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; | |
6 | +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; | |
7 | +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; | |
8 | +import com.github.binarywang.wxpay.exception.WxPayException; | |
3 | 9 | import com.hotent.lpg.common.model.WDd; |
4 | 10 | |
5 | 11 | import java.util.HashMap; |
12 | +import java.util.Map; | |
6 | 13 | |
7 | 14 | public interface WxPayManager { |
8 | 15 | /** |
9 | 16 | * 退款 |
17 | + * | |
10 | 18 | * @param ddid |
11 | 19 | * @return |
12 | 20 | */ |
13 | - String initiateRefundOrder(String ddid); | |
21 | + WxPayRefundResult initiateRefundOrder(String ddid); | |
14 | 22 | |
15 | 23 | /** |
16 | 24 | * 处理退款成功回调 |
25 | + * | |
17 | 26 | * @param xmlData |
18 | 27 | * @return |
19 | 28 | */ |
... | ... | @@ -22,6 +31,7 @@ public interface WxPayManager { |
22 | 31 | |
23 | 32 | /** |
24 | 33 | * 处理支付成功回调 |
34 | + * | |
25 | 35 | * @param xmlData |
26 | 36 | * @return |
27 | 37 | */ |
... | ... | @@ -30,9 +40,33 @@ public interface WxPayManager { |
30 | 40 | |
31 | 41 | /** |
32 | 42 | * 生成预支付订单 |
33 | - * @param order | |
43 | + * | |
44 | + * @param ddid | |
34 | 45 | * @param openId |
35 | 46 | * @return |
36 | 47 | */ |
37 | - HashMap<String, Object> generatePrepayOrder(WDd order, String openId); | |
48 | + WxPayMpOrderResult generatePrepayOrder(String ddid, String openId, String zflx); | |
49 | + | |
50 | + /** | |
51 | + * 如果订单状态为“待支付”,则获取原有的预支付订单信息 | |
52 | + * SUCCESS: 交易支付成功 | |
53 | + * REFUND: 交易已退款 | |
54 | + * NOTPAY : 交易创建,但未支付 | |
55 | + * CLOSED: 交易关闭 | |
56 | + * REVOKED:交易已撤销(仅有服务商接口) | |
57 | + * USERPAYING: 用户支付中 | |
58 | + * PAYERROR: 支付失败 | |
59 | + * @return | |
60 | + */ | |
61 | + WxPayOrderQueryResult getWxPayOrderQuery(String id); | |
62 | + | |
63 | + | |
64 | + WxPayMpOrderResult initiateJsApiPay(String ddid, String openId, String zflx) throws WxPayException; | |
65 | + | |
66 | + | |
67 | + /** | |
68 | + * 取消订单 | |
69 | + * @param id | |
70 | + */ | |
71 | + WxPayOrderCloseResult cancelOrder(String id); | |
38 | 72 | } | ... | ... |
backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java
... | ... | @@ -9,6 +9,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
9 | 9 | import com.baomidou.mybatisplus.core.metadata.IPage; |
10 | 10 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
11 | 11 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
12 | +import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; | |
13 | +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; | |
12 | 14 | import com.hotent.base.id.IdGenerator; |
13 | 15 | import com.hotent.base.manager.impl.BaseManagerImpl; |
14 | 16 | import com.hotent.base.util.BeanUtils; |
... | ... | @@ -86,19 +88,26 @@ public class DdManagerImpl extends BaseManagerImpl<DdDao, WDd> implements DdMana |
86 | 88 | || DdztEnum.SHIPPED.getCode().equals(dd.getFDdzt()))) { |
87 | 89 | throw new RuntimeException("订单状态不正确"); |
88 | 90 | } |
89 | - | |
90 | - | |
91 | 91 | if (dd.getFDdly().equals(DdlyEnum.xsxd.getCode()) && dd.getFZffs().equals(DdZffsEnum.WX_PAY.getCode()) && dd.getFSfzf().equals(SysEnum.Y.getCode())) { |
92 | 92 | //线上下单+微信支付+已支付 才退款 |
93 | - String shtkdh = wxPayManager.initiateRefundOrder(ddid); | |
94 | - dd.setFDdzt(DdztEnum.REFUNDING.getCode()); | |
95 | - dd.setFShtkdh(shtkdh); | |
96 | - dd.setFSftk(SysEnum.N.getCode()); | |
97 | - baseMapper.updateById(dd); | |
98 | - }else { | |
93 | + WxPayRefundResult wxPayRefundResult = wxPayManager.initiateRefundOrder(ddid); | |
94 | + if ("SUCCESS".equals(wxPayRefundResult.getReturnCode()) && "SUCCESS".equals(wxPayRefundResult.getResultCode())) { | |
95 | + dd.setFDdzt(DdztEnum.REFUNDING.getCode()); | |
96 | + dd.setFShtkdh(wxPayRefundResult.getOutRefundNo()); | |
97 | + dd.setFSftk(SysEnum.N.getCode()); | |
98 | + baseMapper.updateById(dd); | |
99 | + } | |
100 | + } else { | |
101 | +// WxPayOrderCloseResult wxPayOrderCloseResult = wxPayManager.cancelOrder(dd.getId()); | |
102 | +// if ("SUCCESS".equals(wxPayOrderCloseResult.getReturnCode()) && "SUCCESS".equals(wxPayOrderCloseResult.getResultCode())) { | |
99 | 103 | dd.setFDdzt(DdztEnum.REFUNDED.getCode()); |
100 | 104 | dd.setFSftk(SysEnum.N.getCode()); |
101 | 105 | baseMapper.updateById(dd); |
106 | +// } else { | |
107 | +// String errCode = wxPayOrderCloseResult.getErrCode(); | |
108 | +// String errCodeDes = wxPayOrderCloseResult.getErrCodeDes(); | |
109 | +// throw new RuntimeException("取消订单失败,错误代码: " + errCode + ", 错误描述: " + errCodeDes); | |
110 | +// } | |
102 | 111 | } |
103 | 112 | //添加服务日志 |
104 | 113 | // wDdfwrzManager.insertDdfwrz(DdfwlxEnum.qxdd.getCode(), dd.getId()); | ... | ... |
backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WxPayManagerImpl.java
... | ... | @@ -7,13 +7,22 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
7 | 7 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
8 | 8 | import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; |
9 | 9 | import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; |
10 | +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; | |
11 | +import com.github.binarywang.wxpay.bean.request.WxPayOrderCloseRequest; | |
12 | +import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest; | |
10 | 13 | import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; |
11 | 14 | import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; |
15 | +import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; | |
16 | +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; | |
12 | 17 | import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; |
18 | +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; | |
19 | +import com.github.binarywang.wxpay.config.WxPayConfig; | |
13 | 20 | import com.github.binarywang.wxpay.exception.WxPayException; |
14 | 21 | import com.github.binarywang.wxpay.service.WxPayService; |
22 | +import com.github.binarywang.wxpay.util.SignUtils; | |
15 | 23 | import com.hotent.base.exception.BaseException; |
16 | 24 | import com.hotent.base.util.BeanUtils; |
25 | +import com.hotent.base.util.StringUtil; | |
17 | 26 | import com.hotent.lpg.common.enums.DdZffsEnum; |
18 | 27 | import com.hotent.lpg.common.enums.DdlyEnum; |
19 | 28 | import com.hotent.lpg.common.enums.DdztEnum; |
... | ... | @@ -50,7 +59,10 @@ import java.io.StringWriter; |
50 | 59 | import java.math.BigDecimal; |
51 | 60 | import java.rmi.ServerError; |
52 | 61 | import java.time.LocalDateTime; |
62 | +import java.util.Collections; | |
53 | 63 | import java.util.HashMap; |
64 | +import java.util.Map; | |
65 | +import java.util.UUID; | |
54 | 66 | |
55 | 67 | @Service |
56 | 68 | @Slf4j |
... | ... | @@ -66,6 +78,7 @@ public class WxPayManagerImpl implements WxPayManager { |
66 | 78 | @Resource |
67 | 79 | private CzzfpzDao czzfpzDao; |
68 | 80 | |
81 | + | |
69 | 82 | /** |
70 | 83 | * 发起退款请求 |
71 | 84 | * |
... | ... | @@ -73,7 +86,7 @@ public class WxPayManagerImpl implements WxPayManager { |
73 | 86 | * @return |
74 | 87 | */ |
75 | 88 | @Override |
76 | - public String initiateRefundOrder(String ddid) { | |
89 | + public WxPayRefundResult initiateRefundOrder(String ddid) { | |
77 | 90 | // 1. 查询订单信息 |
78 | 91 | WDd wDd = ddDao.selectById(ddid); |
79 | 92 | if (!DdztEnum.PAID.getCode().equals(wDd.getFDdzt())) { |
... | ... | @@ -90,22 +103,43 @@ public class WxPayManagerImpl implements WxPayManager { |
90 | 103 | // 3. 初始化微信支付服务 |
91 | 104 | WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); |
92 | 105 | try { |
93 | - // 4. 调用微信退款接口 | |
94 | - // 这里需要构造退款请求对象,具体参数根据实际情况填写 | |
95 | - // 注意:这里需要根据实际的微信支付SDK版本和退款接口文档来调整 | |
96 | - // 示例代码可能需要根据实际情况修改 | |
97 | - String tkdh = RandomUtil.randomString(32); | |
98 | - WxPayRefundRequest refundRequest = new WxPayRefundRequest(); | |
99 | - refundRequest.setTransactionId(wDd.getFZfdh()); | |
100 | - refundRequest.setOutTradeNo(wDd.getFDddh()); // 订单号 | |
101 | - refundRequest.setOutRefundNo(RandomUtil.randomString(32)); // 退款单号 | |
102 | - refundRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 订单总金额 | |
103 | - refundRequest.setRefundFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 退款金额 | |
104 | - refundRequest.setNotifyUrl(hostUrl + "/user/wxPay/handleRefundSuccessCallback"); | |
105 | - // 发起退款请求 | |
106 | - Object payment = wxPayService.refund(refundRequest); | |
107 | - // 返回结果 | |
108 | - return tkdh; | |
106 | + // 4.查询微信支付系统的预支付订单信息 | |
107 | + WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); | |
108 | + request.setOutTradeNo(wDd.getFDddh()); | |
109 | + WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder(request); | |
110 | + if ("SUCCESS".equals(wxPayOrderQueryResult.getReturnCode()) && "SUCCESS".equals(wxPayOrderQueryResult.getResultCode())) { | |
111 | + String tradeState = wxPayOrderQueryResult.getTradeState(); | |
112 | + switch (tradeState) { | |
113 | + case "SUCCESS": | |
114 | + // 4. 调用微信退款接口 | |
115 | + WxPayRefundRequest refundRequest = new WxPayRefundRequest(); | |
116 | + refundRequest.setTransactionId(wDd.getFZfdh()); | |
117 | + refundRequest.setOutTradeNo(wDd.getFDddh()); // 订单号 | |
118 | + refundRequest.setOutRefundNo(RandomUtil.randomString(32)); // 退款单号 | |
119 | + refundRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 订单总金额 | |
120 | + refundRequest.setRefundFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 退款金额 | |
121 | + refundRequest.setNotifyUrl(hostUrl + "/user/wxPay/handleRefundSuccessCallback"); | |
122 | + // 返回结果 | |
123 | + return wxPayService.refund(refundRequest); | |
124 | + case "TRADE_CLOSED": | |
125 | + throw new RuntimeException("订单已关闭"); | |
126 | + case "NOTPAY": | |
127 | + throw new RuntimeException("订单未支付"); | |
128 | + case "REFUND": | |
129 | + throw new RuntimeException("订单已退款"); | |
130 | + case "REFUNDCLOSED": | |
131 | + throw new RuntimeException("退款关闭"); | |
132 | + case "REVERSAL": | |
133 | + throw new RuntimeException("交易撤销"); | |
134 | + case "USERPAYING": | |
135 | + throw new RuntimeException("用户支付中"); | |
136 | + case "PAYERROR": | |
137 | + throw new RuntimeException("支付失败"); | |
138 | + default: | |
139 | + throw new RuntimeException("未知状态:" + tradeState); | |
140 | + } | |
141 | + } | |
142 | + throw new RuntimeException("订单状态异常"); | |
109 | 143 | } catch (WxPayException e) { |
110 | 144 | log.error("退款失败: {}", e.getErrCodeDes(), e); |
111 | 145 | throw new RuntimeException("退款失败: " + e.getErrCodeDes()); |
... | ... | @@ -132,10 +166,7 @@ public class WxPayManagerImpl implements WxPayManager { |
132 | 166 | String appid = rs.getAppid(); |
133 | 167 | String mchId = rs.getMchId(); |
134 | 168 | // 从数据库中查询对应的应用配置信息 |
135 | - WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery() | |
136 | - .eq(WCzzfpz::getFAppid, appid) | |
137 | - .eq(WCzzfpz::getFMchid, mchId) | |
138 | - .last("LIMIT 1")); | |
169 | + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFAppid, appid).eq(WCzzfpz::getFMchid, mchId).last("LIMIT 1")); | |
139 | 170 | // 如果没有找到对应的配置信息,则抛出异常 |
140 | 171 | if (wCzzfpz == null) { |
141 | 172 | throw new BaseException("退款失败,请联系管理员。"); |
... | ... | @@ -153,15 +184,13 @@ public class WxPayManagerImpl implements WxPayManager { |
153 | 184 | String transactionId = reqInfo.getTransactionId(); |
154 | 185 | String outTradeNo = reqInfo.getOutTradeNo(); |
155 | 186 | // 从数据库中查询订单信息 |
156 | - WDd wDd = ddDao.selectOne(Wrappers.<WDd>lambdaQuery() | |
157 | - .eq(WDd::getFZfdh, transactionId) | |
158 | - .eq(WDd::getFDddh, outTradeNo)); | |
187 | + WDd wDd = ddDao.selectOne(Wrappers.<WDd>lambdaQuery().eq(WDd::getFZfdh, transactionId).eq(WDd::getFDddh, outTradeNo)); | |
159 | 188 | // 如果没有查询到订单,则生成失败响应并返回 |
160 | 189 | if (wDd == null) { |
161 | 190 | return generateXmlResponse("FAIL", "未查询到订单", outTradeNo); |
162 | 191 | } |
163 | 192 | // 如果订单已经退款,则生成失败响应并返回 |
164 | - if (wDd.getFSftk().equals(SysEnum.Y.getCode())) { | |
193 | + if (StringUtil.isEmpty(wDd.getFSftk()) || wDd.getFSftk().equals(SysEnum.Y.getCode())) { | |
165 | 194 | return generateXmlResponse("FAIL", "订单已退款", outTradeNo); |
166 | 195 | } |
167 | 196 | // 更新订单状态为已退款,并记录相关信息 |
... | ... | @@ -201,6 +230,10 @@ public class WxPayManagerImpl implements WxPayManager { |
201 | 230 | String outTradeNo = extractValueFromXML(xmlData, "out_trade_no"); |
202 | 231 | //先用订单号找到订单 |
203 | 232 | WDd wDd = ddDao.selectOne(new LambdaQueryWrapper<WDd>().eq(WDd::getFDddh, outTradeNo)); |
233 | + if (wDd == null) { | |
234 | + log.warn("订单不存在: {}", wDd); | |
235 | + return generateXmlResponse("FAIL", "订单不存在", wDd.getFDddh()); | |
236 | + } | |
204 | 237 | //在用 场站信息 拿到场站对应得支付配置 |
205 | 238 | WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); |
206 | 239 | WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); |
... | ... | @@ -247,19 +280,20 @@ public class WxPayManagerImpl implements WxPayManager { |
247 | 280 | /** |
248 | 281 | * 生成预支付订单 |
249 | 282 | * |
250 | - * @param wDd | |
251 | - * @param openId | |
252 | 283 | * @return |
253 | 284 | */ |
254 | 285 | @Override |
255 | - public HashMap<String, Object> generatePrepayOrder(WDd wDd, String openId) { | |
286 | + public WxPayMpOrderResult generatePrepayOrder(String ddid, String openId, String zflx) { | |
256 | 287 | try { |
288 | + WDd wDd = ddDao.selectById(ddid); | |
289 | + if (BeanUtils.isEmpty(wDd)) { | |
290 | + throw new RuntimeException("订单不存在"); | |
291 | + } | |
257 | 292 | WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); |
258 | - if (BeanUtils.isEmpty(wCzzfpz) || wCzzfpz == null) { | |
293 | + if (BeanUtils.isEmpty(wCzzfpz)) { | |
259 | 294 | throw new RuntimeException("支付配置不存在"); |
260 | 295 | } |
261 | - String tradeType = wDd.getFZflx(); | |
262 | - if (StrUtil.isBlank(tradeType)) { | |
296 | + if (StrUtil.isBlank(zflx)) { | |
263 | 297 | throw new RuntimeException("支付方式错误"); |
264 | 298 | } |
265 | 299 | WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest(); |
... | ... | @@ -268,7 +302,7 @@ public class WxPayManagerImpl implements WxPayManager { |
268 | 302 | wxPayUnifiedOrderRequest.setBody(wDd.getFDddh()); |
269 | 303 | wxPayUnifiedOrderRequest.setOutTradeNo(wDd.getFDddh()); |
270 | 304 | wxPayUnifiedOrderRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); |
271 | - wxPayUnifiedOrderRequest.setTradeType(tradeType); | |
305 | + wxPayUnifiedOrderRequest.setTradeType(zflx); | |
272 | 306 | JSONObject scene_info = new JSONObject(); |
273 | 307 | scene_info.put("id", "LPG"); |
274 | 308 | scene_info.put("name", "燃气"); |
... | ... | @@ -292,12 +326,7 @@ public class WxPayManagerImpl implements WxPayManager { |
292 | 326 | wxPayUnifiedOrderRequest.setSceneInfo(null); |
293 | 327 | } |
294 | 328 | WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); |
295 | - Object payment = wxPayService.createOrder(wxPayUnifiedOrderRequest); | |
296 | - HashMap<String, Object> resultData = new HashMap<String, Object>(); | |
297 | - resultData.put("payment", payment); | |
298 | - resultData.put("ddid", wDd.getId()); | |
299 | - resultData.put("dddh", wDd.getFDddh()); | |
300 | - return resultData; | |
329 | + return wxPayService.createOrder(wxPayUnifiedOrderRequest); | |
301 | 330 | } catch (WxPayException e) { |
302 | 331 | if ("INVALID_REQUEST".equals(e.getErrCode())) { |
303 | 332 | throw new RuntimeException("订单号重复,请重新下单"); |
... | ... | @@ -306,6 +335,148 @@ public class WxPayManagerImpl implements WxPayManager { |
306 | 335 | } |
307 | 336 | } |
308 | 337 | |
338 | + | |
339 | + /** | |
340 | + * 获取订单状态 | |
341 | + * | |
342 | + * @return | |
343 | + */ | |
344 | + @Override | |
345 | + public WxPayOrderQueryResult getWxPayOrderQuery(String ddid) { | |
346 | + //先找到订单 | |
347 | + WDd wDd = ddDao.selectById(ddid); | |
348 | + if (wDd == null) { | |
349 | + throw new RuntimeException("订单不存在"); | |
350 | + } | |
351 | + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); | |
352 | + if (BeanUtils.isEmpty(wCzzfpz)) { | |
353 | + throw new RuntimeException("支付配置不存在"); | |
354 | + } | |
355 | + // 查询微信支付系统的预支付订单信息 | |
356 | + WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); | |
357 | + request.setOutTradeNo(wDd.getFDddh()); | |
358 | + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); | |
359 | + try { | |
360 | + return wxPayService.queryOrder(request); | |
361 | + } catch (WxPayException e) { | |
362 | + throw new RuntimeException("查询预支付订单失败:" + e.getMessage()); | |
363 | + } | |
364 | + } | |
365 | + | |
366 | + @Override | |
367 | + public WxPayMpOrderResult initiateJsApiPay(String ddid, String openId, String zflx) throws WxPayException { | |
368 | + // 1.获取订单 | |
369 | + WDd wDd = ddDao.selectById(ddid); | |
370 | + if (BeanUtils.isEmpty(wDd)) { | |
371 | + throw new RuntimeException("订单不存在"); | |
372 | + } | |
373 | + // 2. 获取支付配置 | |
374 | + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); | |
375 | + // 3. 初始化微信支付服务 | |
376 | + WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest(); | |
377 | + wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid()); | |
378 | + wxPayUnifiedOrderRequest.setOpenid(null); | |
379 | + wxPayUnifiedOrderRequest.setBody(wDd.getFDddh()); | |
380 | + wxPayUnifiedOrderRequest.setOutTradeNo(wDd.getFDddh()); | |
381 | + wxPayUnifiedOrderRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); | |
382 | + wxPayUnifiedOrderRequest.setTradeType(zflx); | |
383 | + JSONObject scene_info = new JSONObject(); | |
384 | + scene_info.put("id", "LPG"); | |
385 | + scene_info.put("name", "燃气"); | |
386 | + wxPayUnifiedOrderRequest.setSceneInfo(scene_info.toString()); | |
387 | + wxPayUnifiedOrderRequest.setNotifyUrl(hostUrl + "/user/wxPay/handlePaySuccessCallback"); // 支付回调地址,开放不用登录 | |
388 | + wxPayUnifiedOrderRequest.setSpbillCreateIp("127.0.0.1"); | |
389 | + // trade_type=APP时 移动应用内的支付场景 | |
390 | + if ("APP".equals(wxPayUnifiedOrderRequest.getTradeType())) { | |
391 | + wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid()); | |
392 | + } | |
393 | + // trade_type=NATIVE时 线下消费场景 | |
394 | + if ("NATIVE".equals(wxPayUnifiedOrderRequest.getTradeType())) { | |
395 | + wxPayUnifiedOrderRequest.setProductId(wxPayUnifiedOrderRequest.getOutTradeNo()); | |
396 | + } | |
397 | + // 公众号内或者微信内的网页支付 | |
398 | + if ("JSAPI".equals(wxPayUnifiedOrderRequest.getTradeType())) { | |
399 | + wxPayUnifiedOrderRequest.setOpenid(openId); | |
400 | + } | |
401 | + // 手机浏览器中的支付场景 | |
402 | + if ("MWEB".equals(wxPayUnifiedOrderRequest.getTradeType())) { | |
403 | + wxPayUnifiedOrderRequest.setSceneInfo(null); | |
404 | + } | |
405 | + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); | |
406 | + //创建并获取预支付订单 | |
407 | + WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest); | |
408 | + if ("SUCCESS".equals(wxPayUnifiedOrderResult.getReturnCode()) && "SUCCESS".equals(wxPayUnifiedOrderResult.getResultCode())) { | |
409 | + //生成唤起微信支付参数 | |
410 | + WxPayConfig config = wxPayService.getConfig(); | |
411 | + String prepayId = wxPayUnifiedOrderResult.getPrepayId(); | |
412 | + String signType = "MD5"; | |
413 | + // 查询订单状态 | |
414 | + WxPayOrderQueryRequest queryRequest = new WxPayOrderQueryRequest(); | |
415 | + queryRequest.setAppid(config.getAppId()); | |
416 | + queryRequest.setMchId(config.getMchId()); | |
417 | + queryRequest.setOutTradeNo(wDd.getFDddh()); // 假设 orderId 是订单号 | |
418 | + WxPayOrderQueryResult queryResult = wxPayService.queryOrder(queryRequest); | |
419 | + if ("SUCCESS".equals(queryResult.getReturnCode()) && "SUCCESS".equals(queryResult.getResultCode())) { | |
420 | + String tradeState = queryResult.getTradeState(); | |
421 | + if ("SUCCESS".equals(tradeState)) { | |
422 | + // 订单已支付 | |
423 | + throw new RuntimeException("订单已支付。"); | |
424 | + } else if ("NOTPAY".equals(tradeState)) { | |
425 | + // 订单未支付 | |
426 | + WxPayMpOrderResult wxPayMpOrderResult = WxPayMpOrderResult.builder(). | |
427 | + appId(wxPayUnifiedOrderResult.getAppid()) | |
428 | + .timeStamp(String.valueOf(System.currentTimeMillis() / 1000L)) | |
429 | + .nonceStr(UUID.randomUUID().toString().replace("-", "")) | |
430 | + .packageValue("prepay_id=" + prepayId) | |
431 | + .signType(signType).build(); | |
432 | + wxPayMpOrderResult.setPaySign(SignUtils.createSign(wxPayMpOrderResult, signType, config.getMchKey(), (String[]) null)); | |
433 | + return wxPayMpOrderResult; | |
434 | + } else { | |
435 | + // 其他状态 | |
436 | + throw new RuntimeException("订单已取消或过期,请重新下单。"); | |
437 | + } | |
438 | + } else { | |
439 | + // 查询失败 | |
440 | + String errCode = queryResult.getErrCode(); | |
441 | + String errCodeDes = queryResult.getErrCodeDes(); | |
442 | + throw new RuntimeException("查询订单状态失败,错误代码: " + errCode + ", 错误描述: " + errCodeDes); | |
443 | + } | |
444 | + | |
445 | + } else { | |
446 | + throw new RuntimeException("预支付订单创建失败,请重新下单。"); | |
447 | + } | |
448 | + } | |
449 | + | |
450 | + | |
451 | + /** | |
452 | + * 取消订单 | |
453 | + * | |
454 | + * @param ddid | |
455 | + */ | |
456 | + public WxPayOrderCloseResult cancelOrder(String ddid) { | |
457 | + try { | |
458 | + // 1.获取订单 | |
459 | + WDd wDd = ddDao.selectById(ddid); | |
460 | + if (BeanUtils.isEmpty(wDd)) { | |
461 | + throw new RuntimeException("订单不存在"); | |
462 | + } | |
463 | + // 2. 获取支付配置 | |
464 | + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); | |
465 | + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); | |
466 | + WxPayOrderCloseRequest closeRequest = new WxPayOrderCloseRequest(); | |
467 | + WxPayConfig config = wxPayService.getConfig(); | |
468 | + closeRequest.setAppid(config.getAppId()); | |
469 | + closeRequest.setMchId(config.getMchId()); | |
470 | + closeRequest.setOutTradeNo(wDd.getFDddh()); | |
471 | + WxPayOrderCloseResult closeResult = wxPayService.closeOrder(closeRequest); | |
472 | + return closeResult; | |
473 | + } catch (Exception e) { | |
474 | + log.error("取消订单时发生错误: {}", e.getMessage(), e); | |
475 | + throw new RuntimeException("取消订单时发生错误"); | |
476 | + } | |
477 | + } | |
478 | + | |
479 | + | |
309 | 480 | /** |
310 | 481 | * 生成微信回调响应 |
311 | 482 | * |
... | ... | @@ -373,4 +544,5 @@ public class WxPayManagerImpl implements WxPayManager { |
373 | 544 | } |
374 | 545 | } |
375 | 546 | |
547 | + | |
376 | 548 | } | ... | ... |