Commit 4e2d5446bb03a0c69ac1189982b7bb4f4448e16e

Authored by 陈威
1 parent 29574b70
Exists in dev

微信h5退款

backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java
@@ -160,7 +160,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @@ -160,7 +160,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
160 .antMatchers("/fileUpload").permitAll() 160 .antMatchers("/fileUpload").permitAll()
161 .antMatchers("/deleteFile").permitAll() 161 .antMatchers("/deleteFile").permitAll()
162 .antMatchers("/ueditor/**", "/apiManager/getToken").permitAll() 162 .antMatchers("/ueditor/**", "/apiManager/getToken").permitAll()
163 - .antMatchers("/user/order/payment/notifyOrder").permitAll() 163 + .antMatchers("/user/wxPay/**").permitAll()
164 .anyRequest().authenticated() 164 .anyRequest().authenticated()
165 .accessDecisionManager(accessDecisionManager()); 165 .accessDecisionManager(accessDecisionManager());
166 166
backend/lpg-common/src/main/java/com/hotent/lpg/common/enums/DdztEnum.java
@@ -17,6 +17,10 @@ public enum DdztEnum { @@ -17,6 +17,10 @@ public enum DdztEnum {
17 dzf("dzf", "待支付"), 17 dzf("dzf", "待支付"),
18 18
19 /** 19 /**
  20 + * 退款中
  21 + */
  22 + tkz("tkz", "退款中"),
  23 + /**
20 * 待配送 24 * 待配送
21 */ 25 */
22 dps("dps", "待配送"), 26 dps("dps", "待配送"),
backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WCzzfpz.java
@@ -2,6 +2,7 @@ package com.hotent.lpg.common.model; @@ -2,6 +2,7 @@ package com.hotent.lpg.common.model;
2 2
3 import com.baomidou.mybatisplus.annotation.IdType; 3 import com.baomidou.mybatisplus.annotation.IdType;
4 import com.hotent.base.entity.BaseModel; 4 import com.hotent.base.entity.BaseModel;
  5 +import com.baomidou.mybatisplus.extension.activerecord.Model;
5 import com.baomidou.mybatisplus.annotation.TableId; 6 import com.baomidou.mybatisplus.annotation.TableId;
6 import com.baomidou.mybatisplus.annotation.TableField; 7 import com.baomidou.mybatisplus.annotation.TableField;
7 import java.io.Serializable; 8 import java.io.Serializable;
@@ -11,8 +12,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; @@ -11,8 +12,9 @@ import com.fasterxml.jackson.annotation.JsonProperty;
11 /** 12 /**
12 * 厂站支付配置 13 * 厂站支付配置
13 * 14 *
14 - * @author cw  
15 - * @since 2024-09-04 15 + * @company
  16 + * @author 超级管理员
  17 + * @since 2024-09-06
16 */ 18 */
17 @ApiModel(value="WCzzfpz对象", description="厂站支付配置") 19 @ApiModel(value="WCzzfpz对象", description="厂站支付配置")
18 public class WCzzfpz extends BaseModel<WCzzfpz> { 20 public class WCzzfpz extends BaseModel<WCzzfpz> {
@@ -83,6 +85,21 @@ public class WCzzfpz extends BaseModel&lt;WCzzfpz&gt; { @@ -83,6 +85,21 @@ public class WCzzfpz extends BaseModel&lt;WCzzfpz&gt; {
83 @JsonProperty("fFormDataRev") 85 @JsonProperty("fFormDataRev")
84 private Long fFormDataRev; 86 private Long fFormDataRev;
85 87
  88 + @ApiModelProperty(value = " .p12 格式的密钥文件路径,私钥和证书")
  89 + @TableField("F_keyPath")
  90 + @JsonProperty("fKeypath")
  91 + private String fKeypath;
  92 +
  93 + @ApiModelProperty(value = "私钥文件路径")
  94 + @TableField("F_privateKeyPath")
  95 + @JsonProperty("fPrivatekeypath")
  96 + private String fPrivatekeypath;
  97 +
  98 + @ApiModelProperty(value = "私有证书文件路径")
  99 + @TableField("F_privateCertPath")
  100 + @JsonProperty("fPrivatecertpath")
  101 + private String fPrivatecertpath;
  102 +
86 103
87 public String getId() { 104 public String getId() {
88 return id; 105 return id;
@@ -175,6 +192,27 @@ public class WCzzfpz extends BaseModel&lt;WCzzfpz&gt; { @@ -175,6 +192,27 @@ public class WCzzfpz extends BaseModel&lt;WCzzfpz&gt; {
175 public void setFFormDataRev(Long fFormDataRev) { 192 public void setFFormDataRev(Long fFormDataRev) {
176 this.fFormDataRev = fFormDataRev; 193 this.fFormDataRev = fFormDataRev;
177 } 194 }
  195 + public String getFKeypath() {
  196 + return fKeypath;
  197 + }
  198 +
  199 + public void setFKeypath(String fKeypath) {
  200 + this.fKeypath = fKeypath;
  201 + }
  202 + public String getFPrivatekeypath() {
  203 + return fPrivatekeypath;
  204 + }
  205 +
  206 + public void setFPrivatekeypath(String fPrivatekeypath) {
  207 + this.fPrivatekeypath = fPrivatekeypath;
  208 + }
  209 + public String getFPrivatecertpath() {
  210 + return fPrivatecertpath;
  211 + }
  212 +
  213 + public void setFPrivatecertpath(String fPrivatecertpath) {
  214 + this.fPrivatecertpath = fPrivatecertpath;
  215 + }
178 216
179 217
180 @Override 218 @Override
@@ -185,19 +223,22 @@ public class WCzzfpz extends BaseModel&lt;WCzzfpz&gt; { @@ -185,19 +223,22 @@ public class WCzzfpz extends BaseModel&lt;WCzzfpz&gt; {
185 @Override 223 @Override
186 public String toString() { 224 public String toString() {
187 return "WCzzfpz{" + 225 return "WCzzfpz{" +
188 - "id=" + id +  
189 - ", refId=" + refId +  
190 - ", fQyid=" + fQyid +  
191 - ", fCzid=" + fCzid +  
192 - ", fQymc=" + fQymc +  
193 - ", fCzmc=" + fCzmc +  
194 - ", fZflx=" + fZflx +  
195 - ", fAppid=" + fAppid +  
196 - ", fMchid=" + fMchid +  
197 - ", fMchkey=" + fMchkey +  
198 - ", fCertserialno=" + fCertserialno +  
199 - ", fApiv3key=" + fApiv3key +  
200 - ", fFormDataRev=" + fFormDataRev +  
201 - "}"; 226 + "id=" + id +
  227 + ", refId=" + refId +
  228 + ", fQyid=" + fQyid +
  229 + ", fCzid=" + fCzid +
  230 + ", fQymc=" + fQymc +
  231 + ", fCzmc=" + fCzmc +
  232 + ", fZflx=" + fZflx +
  233 + ", fAppid=" + fAppid +
  234 + ", fMchid=" + fMchid +
  235 + ", fMchkey=" + fMchkey +
  236 + ", fCertserialno=" + fCertserialno +
  237 + ", fApiv3key=" + fApiv3key +
  238 + ", fFormDataRev=" + fFormDataRev +
  239 + ", fKeypath=" + fKeypath +
  240 + ", fPrivatekeypath=" + fPrivatekeypath +
  241 + ", fPrivatecertpath=" + fPrivatecertpath +
  242 + "}";
202 } 243 }
203 } 244 }
backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WDd.java
@@ -269,6 +269,31 @@ public class WDd extends BaseModel&lt;WDd&gt; { @@ -269,6 +269,31 @@ public class WDd extends BaseModel&lt;WDd&gt; {
269 private String fZfdh; 269 private String fZfdh;
270 270
271 271
  272 + @ApiModelProperty(value = "是否退款(是,否)")
  273 + @TableField("F_sftk")
  274 + @JsonProperty("fSftk")
  275 + private String fSftk;
  276 +
  277 +
  278 + @ApiModelProperty(value = "退款单号")
  279 + @TableField("F_tkdh")
  280 + @JsonProperty("fTkdh")
  281 + private String fTkdh;
  282 +
  283 + @ApiModelProperty(value = "商户退款单号")
  284 + @TableField("F_shtkdh")
  285 + @JsonProperty("fShtkdh")
  286 + private String fShtkdh;
  287 +
  288 +
  289 + @ApiModelProperty(value = "退款时间")
  290 + @TableField("F_tksj")
  291 + @JsonProperty("fTksj")
  292 + private LocalDateTime fTksj;
  293 +
  294 +
  295 +
  296 +
272 /** 297 /**
273 * 订单详情 298 * 订单详情
274 */ 299 */
backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/DdConroller.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
5 import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
6 import com.hotent.base.model.CommonResult; 6 import com.hotent.base.model.CommonResult;
7 import com.hotent.lpg.common.enums.DdlyEnum; 7 import com.hotent.lpg.common.enums.DdlyEnum;
  8 +import com.hotent.lpg.common.enums.DdztEnum;
8 import com.hotent.lpg.common.enums.UserlxEnum; 9 import com.hotent.lpg.common.enums.UserlxEnum;
9 import com.hotent.lpg.common.model.WDd; 10 import com.hotent.lpg.common.model.WDd;
10 import com.hotent.lpg.common.model.WHydz; 11 import com.hotent.lpg.common.model.WHydz;
@@ -13,16 +14,20 @@ import com.hotent.lpg.user.dao.HydzDao; @@ -13,16 +14,20 @@ import com.hotent.lpg.user.dao.HydzDao;
13 import com.hotent.lpg.user.dto.DdDto; 14 import com.hotent.lpg.user.dto.DdDto;
14 import com.hotent.lpg.user.manager.DdManager; 15 import com.hotent.lpg.user.manager.DdManager;
15 import com.hotent.lpg.user.manager.HyxxManager; 16 import com.hotent.lpg.user.manager.HyxxManager;
  17 +import com.hotent.lpg.user.manager.WxPayManager;
16 import com.hotent.uc.util.ContextUtil; 18 import com.hotent.uc.util.ContextUtil;
17 import io.swagger.annotations.ApiOperation; 19 import io.swagger.annotations.ApiOperation;
18 import io.swagger.annotations.ApiParam; 20 import io.swagger.annotations.ApiParam;
  21 +import lombok.extern.slf4j.Slf4j;
19 import org.springframework.beans.factory.annotation.Autowired; 22 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.validation.annotation.Validated; 23 import org.springframework.validation.annotation.Validated;
21 import org.springframework.web.bind.annotation.*; 24 import org.springframework.web.bind.annotation.*;
22 25
23 import javax.annotation.Resource; 26 import javax.annotation.Resource;
  27 +import java.util.HashMap;
24 import java.util.List; 28 import java.util.List;
25 29
  30 +@Slf4j
26 @RestController 31 @RestController
27 //@RequestMapping("/customer/dd/") 32 //@RequestMapping("/customer/dd/")
28 @RequestMapping("/user/order/") 33 @RequestMapping("/user/order/")
@@ -36,6 +41,8 @@ public class DdConroller { @@ -36,6 +41,8 @@ public class DdConroller {
36 private HydzDao hydzDao; 41 private HydzDao hydzDao;
37 @Resource 42 @Resource
38 private HyxxManager wHyxxManager; 43 private HyxxManager wHyxxManager;
  44 + @Resource
  45 + private WxPayManager wxPayManager;
39 46
40 47
41 /** 48 /**
@@ -82,49 +89,92 @@ public class DdConroller { @@ -82,49 +89,92 @@ public class DdConroller {
82 return CommonResult.<String>ok(); 89 return CommonResult.<String>ok();
83 } 90 }
84 91
85 - /**  
86 - * 创建订单  
87 - *  
88 - * @param request  
89 - * @return  
90 - * @throws Exception  
91 - * @throws  
92 - */  
93 - @PostMapping(value = "/save") 92 +// /**
  93 +// * 创建订单
  94 +// *
  95 +// * @param request
  96 +// * @return
  97 +// * @throws Exception
  98 +// * @throws
  99 +// */
  100 +// @PostMapping(value = "/save")
  101 +// @ApiOperation(value = "创建订单", httpMethod = "POST", notes = "创建订单")
  102 +// public CommonResult createOrder(@ApiParam(name = "CreateOrderRequest", value = "创建订单请求对象", required = true) @RequestBody DdDto request) throws Exception {
  103 +// WHydz hydz = hydzDao.selectOneByHyIdAndDzId(ContextUtil.getCurrentUserId(), request.getHydzId());
  104 +// if (BeanUtil.isEmpty(hydz)){
  105 +// throw new RuntimeException("未查询到地址信息。");
  106 +// }
  107 +// WHyxx hyxx = wHyxxManager.getUseridByInfo(ContextUtil.getCurrentUserId());
  108 +// if (BeanUtil.isEmpty(hyxx)){
  109 +// throw new RuntimeException("未查询会员信息。");
  110 +// }
  111 +// request.setShlxr(hydz.getFLxr());
  112 +// request.setShlxrdh(hydz.getFLxrdh());
  113 +// request.setShsf(hydz.getFLxrsf());
  114 +// request.setShs(hydz.getFLxrs());
  115 +// request.setShq(hydz.getFLxrq());
  116 +// request.setShjd(hydz.getFLxrjd());
  117 +// request.setShxxdz(hydz.getFLxrxxdz());
  118 +// request.setJd(hydz.getFJd());
  119 +// request.setWd(hydz.getFWd());
  120 +//
  121 +// request.setSfhy("是");
  122 +// request.setHydh(hyxx.getFSjh()); //账号就是电话
  123 +// request.setHyid(hyxx.getFUserid());
  124 +// request.setHymc(hyxx.getFXm());
  125 +// request.setHylx(hyxx.getFHylx());
  126 +// request.setSfzh(hyxx.getFSfzh());
  127 +// request.setShtysbm(hyxx.getFShtysbm());
  128 +//
  129 +// request.setXdrlx(UserlxEnum.hy.getInfo());
  130 +// request.setXdrid(ContextUtil.getCurrentUserId());
  131 +// request.setXdrmc(ContextUtil.getCurrentUser().getFullname());
  132 +// request.setDdly(DdlyEnum.xsxd.getInfo());
  133 +// WDd order = wDdManager.createOrder(request);
  134 +// return CommonResult.ok().value(order);
  135 +// }
  136 +
  137 + @PostMapping(value = "/add")
94 @ApiOperation(value = "创建订单", httpMethod = "POST", notes = "创建订单") 138 @ApiOperation(value = "创建订单", httpMethod = "POST", notes = "创建订单")
95 - public CommonResult createOrder(@ApiParam(name = "CreateOrderRequest", value = "创建订单请求对象", required = true) @RequestBody DdDto request) throws Exception {  
96 - WHydz hydz = hydzDao.selectOneByHyIdAndDzId(ContextUtil.getCurrentUserId(), request.getHydzId());  
97 - if (BeanUtil.isEmpty(hydz)){ 139 + public CommonResult createOrder(@ApiParam(name = "CreateOrderRequest", value = "创建订单请求对象", required = true) @RequestBody DdDto ddDto) {
  140 + log.warn("创建订单1:{}", ddDto);
  141 + WHydz hydz = hydzDao.selectOneByHyIdAndDzId(ContextUtil.getCurrentUserId(), ddDto.getHydzId());
  142 + if (BeanUtil.isEmpty(hydz)) {
98 throw new RuntimeException("未查询到地址信息。"); 143 throw new RuntimeException("未查询到地址信息。");
99 } 144 }
100 WHyxx hyxx = wHyxxManager.getUseridByInfo(ContextUtil.getCurrentUserId()); 145 WHyxx hyxx = wHyxxManager.getUseridByInfo(ContextUtil.getCurrentUserId());
101 - if (BeanUtil.isEmpty(hyxx)){ 146 + if (BeanUtil.isEmpty(hyxx)) {
102 throw new RuntimeException("未查询会员信息。"); 147 throw new RuntimeException("未查询会员信息。");
103 } 148 }
104 - request.setShlxr(hydz.getFLxr());  
105 - request.setShlxrdh(hydz.getFLxrdh());  
106 - request.setShsf(hydz.getFLxrsf());  
107 - request.setShs(hydz.getFLxrs());  
108 - request.setShq(hydz.getFLxrq());  
109 - request.setShjd(hydz.getFLxrjd());  
110 - request.setShxxdz(hydz.getFLxrxxdz());  
111 - request.setJd(hydz.getFJd());  
112 - request.setWd(hydz.getFWd());  
113 -  
114 - request.setSfhy("是");  
115 - request.setHydh(hyxx.getFSjh()); //账号就是电话  
116 - request.setHyid(hyxx.getFUserid());  
117 - request.setHymc(hyxx.getFXm());  
118 - request.setHylx(hyxx.getFHylx());  
119 - request.setSfzh(hyxx.getFSfzh());  
120 - request.setShtysbm(hyxx.getFShtysbm());  
121 -  
122 - request.setXdrlx(UserlxEnum.hy.getInfo());  
123 - request.setXdrid(ContextUtil.getCurrentUserId());  
124 - request.setXdrmc(ContextUtil.getCurrentUser().getFullname());  
125 - request.setDdly(DdlyEnum.xsxd.getInfo());  
126 - WDd order = wDdManager.createOrder(request);  
127 - return CommonResult.ok().value(order); 149 + ddDto.setShlxr(hydz.getFLxr());
  150 + ddDto.setShlxrdh(hydz.getFLxrdh());
  151 + ddDto.setShsf(hydz.getFLxrsf());
  152 + ddDto.setShs(hydz.getFLxrs());
  153 + ddDto.setShq(hydz.getFLxrq());
  154 + ddDto.setShjd(hydz.getFLxrjd());
  155 + ddDto.setShxxdz(hydz.getFLxrxxdz());
  156 + ddDto.setJd(hydz.getFJd());
  157 + ddDto.setWd(hydz.getFWd());
  158 +
  159 + ddDto.setSfhy("是");
  160 + ddDto.setHydh(hyxx.getFSjh()); //账号就是电话
  161 + ddDto.setHyid(hyxx.getFUserid());
  162 + ddDto.setHymc(hyxx.getFXm());
  163 + ddDto.setHylx(hyxx.getFHylx());
  164 + ddDto.setSfzh(hyxx.getFSfzh());
  165 + ddDto.setShtysbm(hyxx.getFShtysbm());
  166 +
  167 + ddDto.setXdrlx(UserlxEnum.hy.getInfo());
  168 + ddDto.setXdrid(ContextUtil.getCurrentUserId());
  169 + ddDto.setXdrmc(ContextUtil.getCurrentUser().getFullname());
  170 + ddDto.setDdly(DdlyEnum.xsxd.getInfo());
  171 + ddDto.setDdzt(DdztEnum.dzf.getInfo());
  172 + WDd order = wDdManager.addOrder(ddDto);
  173 + log.warn("创建订单2:{}", order);
  174 + HashMap<String, Object> resultData = wxPayManager.generatePrepayOrder(order, ddDto.getOpenId());
  175 + log.warn("创建订单3:{}", resultData);
  176 + return CommonResult.ok().value(resultData);
128 } 177 }
129 178
  179 +
130 } 180 }
backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/PaymentController.java
@@ -1,110 +0,0 @@ @@ -1,110 +0,0 @@
1 -package com.hotent.lpg.user.controller;  
2 -  
3 -import cn.hutool.core.bean.BeanUtil;  
4 -import com.hotent.base.model.CommonResult;  
5 -import com.hotent.lpg.common.enums.DdlyEnum;  
6 -import com.hotent.lpg.common.enums.DdztEnum;  
7 -import com.hotent.lpg.common.enums.UserlxEnum;  
8 -import com.hotent.lpg.common.model.WDd;  
9 -import com.hotent.lpg.common.model.WHydz;  
10 -import com.hotent.lpg.common.model.WHyxx;  
11 -import com.hotent.lpg.user.dao.HydzDao;  
12 -import com.hotent.lpg.user.dto.DdDto;  
13 -import com.hotent.lpg.user.enums.PayTypeEnum;  
14 -import com.hotent.lpg.user.manager.DdManager;  
15 -import com.hotent.lpg.user.manager.HyxxManager;  
16 -import com.hotent.lpg.user.manager.PaymentManage;  
17 -import com.hotent.lpg.user.vo.ResultData;  
18 -import com.hotent.uc.util.ContextUtil;  
19 -import io.swagger.annotations.ApiOperation;  
20 -import io.swagger.annotations.ApiParam;  
21 -import lombok.AllArgsConstructor;  
22 -import lombok.extern.slf4j.Slf4j;  
23 -import org.springframework.beans.factory.annotation.Autowired;  
24 -import org.springframework.validation.annotation.Validated;  
25 -import org.springframework.web.bind.annotation.*;  
26 -  
27 -import javax.annotation.Resource;  
28 -import java.util.HashMap;  
29 -  
30 -@RestController  
31 -@RequestMapping("/user/order/payment/")  
32 -@AllArgsConstructor  
33 -@Validated  
34 -@Slf4j  
35 -public class PaymentController {  
36 - private final PaymentManage paymentManage;  
37 -  
38 - private final DdManager wDdManager;  
39 - private final HydzDao hydzDao;  
40 - private final HyxxManager wHyxxManager;  
41 -// /**  
42 -// * 预支付  
43 -// * @param ddid  
44 -// * @return  
45 -// */  
46 -// @PostMapping("/{ddid}")  
47 -// public ResultData pay(@PathVariable("ddid") String ddid) {  
48 -// String payType = PayTypeEnum.WX.getName(); // 默认微信  
49 -// return paymentManage.pay(ddid, payType);  
50 -// }  
51 -  
52 -  
53 - @PostMapping(value = "/add")  
54 - @ApiOperation(value = "创建订单", httpMethod = "POST", notes = "创建订单")  
55 - public CommonResult createOrder(@ApiParam(name = "CreateOrderRequest", value = "创建订单请求对象", required = true) @RequestBody DdDto ddDto) throws Exception {  
56 - log.warn("创建订单1:{}", ddDto);  
57 - WHydz hydz = hydzDao.selectOneByHyIdAndDzId(ContextUtil.getCurrentUserId(), ddDto.getHydzId());  
58 - if (BeanUtil.isEmpty(hydz)){  
59 - throw new RuntimeException("未查询到地址信息。");  
60 - }  
61 - WHyxx hyxx = wHyxxManager.getUseridByInfo(ContextUtil.getCurrentUserId());  
62 - if (BeanUtil.isEmpty(hyxx)){  
63 - throw new RuntimeException("未查询会员信息。");  
64 - }  
65 - ddDto.setShlxr(hydz.getFLxr());  
66 - ddDto.setShlxrdh(hydz.getFLxrdh());  
67 - ddDto.setShsf(hydz.getFLxrsf());  
68 - ddDto.setShs(hydz.getFLxrs());  
69 - ddDto.setShq(hydz.getFLxrq());  
70 - ddDto.setShjd(hydz.getFLxrjd());  
71 - ddDto.setShxxdz(hydz.getFLxrxxdz());  
72 - ddDto.setJd(hydz.getFJd());  
73 - ddDto.setWd(hydz.getFWd());  
74 -  
75 - ddDto.setSfhy("是");  
76 - ddDto.setHydh(hyxx.getFSjh()); //账号就是电话  
77 - ddDto.setHyid(hyxx.getFUserid());  
78 - ddDto.setHymc(hyxx.getFXm());  
79 - ddDto.setHylx(hyxx.getFHylx());  
80 - ddDto.setSfzh(hyxx.getFSfzh());  
81 - ddDto.setShtysbm(hyxx.getFShtysbm());  
82 -  
83 - ddDto.setXdrlx(UserlxEnum.hy.getInfo());  
84 - ddDto.setXdrid(ContextUtil.getCurrentUserId());  
85 - ddDto.setXdrmc(ContextUtil.getCurrentUser().getFullname());  
86 - ddDto.setDdly(DdlyEnum.xsxd.getInfo());  
87 - ddDto.setDdzt(DdztEnum.dzf.getInfo());  
88 - WDd order = wDdManager.addOrder(ddDto);  
89 - log.warn("创建订单2:{}", order);  
90 - HashMap<String,Object> resultData = paymentManage.wxPay(order,ddDto.getOpenId());  
91 - log.warn("创建订单3:{}", resultData);  
92 - return CommonResult.ok().value(resultData);  
93 - }  
94 -  
95 -  
96 -  
97 -  
98 -  
99 - /**  
100 - * 支付回调  
101 - * @return  
102 - */  
103 - @PostMapping("/notifyOrder")  
104 - public String notifyOrder(@RequestBody String xmlData) {  
105 - log.warn("支付回调:{}", xmlData);  
106 - String res = paymentManage.notifyOrder(xmlData);  
107 - log.warn("处理状态:{}", xmlData);  
108 - return xmlData;  
109 - }  
110 -}  
backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/WxPayController.java 0 → 100644
@@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
  1 +package com.hotent.lpg.user.controller;
  2 +
  3 +
  4 +import com.hotent.lpg.user.manager.WxPayManager;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +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;
  12 +
  13 +@RestController
  14 +@RequestMapping("/user/wxPay/")
  15 +@AllArgsConstructor
  16 +@Validated
  17 +@Slf4j
  18 +public class WxPayController {
  19 + private WxPayManager wxPayManager;
  20 + /**
  21 + * 处理支付成功回调
  22 + * @param xmlData
  23 + * @return
  24 + */
  25 + @PostMapping("/handlePaySuccessCallback")
  26 + public String handlePaySuccessCallback(@RequestBody String xmlData) {
  27 + log.warn("支付回调:{}", xmlData);
  28 + String res = wxPayManager.handlePaySuccessCallback(xmlData);
  29 + log.warn("处理状态:{}", xmlData);
  30 + return xmlData;
  31 + }
  32 +
  33 +
  34 + /**
  35 + * 处理退款成功回调
  36 + * @param xmlData
  37 + * @return
  38 + */
  39 + @PostMapping("/handleRefundSuccessCallback")
  40 + public String handleRefundSuccessCallback(@RequestBody String xmlData) {
  41 + log.warn("退款回调:{}", xmlData);
  42 + String res = wxPayManager.handleRefundSuccessCallback(xmlData);
  43 + log.warn("退款状态:{}", xmlData);
  44 + return res;
  45 + }
  46 +
  47 +}
backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/PaymentManage.java
@@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
1 -package com.hotent.lpg.user.manager;  
2 -  
3 -  
4 -import com.hotent.lpg.common.model.WDd;  
5 -import com.hotent.lpg.user.vo.ResultData;  
6 -  
7 -import java.util.HashMap;  
8 -  
9 -public interface PaymentManage {  
10 -// ResultData pay(String ddid, String payType);  
11 -  
12 - String notifyOrder(String xmlData);  
13 -  
14 - HashMap<String,Object> wxPay(WDd order,String openId);  
15 -  
16 -}  
backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/WxPayManager.java 0 → 100644
@@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
  1 +package com.hotent.lpg.user.manager;
  2 +
  3 +import com.hotent.lpg.common.model.WDd;
  4 +
  5 +import java.util.HashMap;
  6 +
  7 +public interface WxPayManager {
  8 + /**
  9 + * 退款
  10 + * @param ddid
  11 + * @return
  12 + */
  13 + String initiateRefundOrder(String ddid);
  14 +
  15 + /**
  16 + * 处理退款成功回调
  17 + * @param xmlData
  18 + * @return
  19 + */
  20 + String handleRefundSuccessCallback(String xmlData);
  21 +
  22 +
  23 + /**
  24 + * 处理支付成功回调
  25 + * @param xmlData
  26 + * @return
  27 + */
  28 + String handlePaySuccessCallback(String xmlData);
  29 +
  30 +
  31 + /**
  32 + * 生成预支付订单
  33 + * @param order
  34 + * @param openId
  35 + * @return
  36 + */
  37 + HashMap<String, Object> generatePrepayOrder(WDd order, String openId);
  38 +}
backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java
@@ -19,14 +19,12 @@ import com.hotent.lpg.common.model.WDd; @@ -19,14 +19,12 @@ import com.hotent.lpg.common.model.WDd;
19 import com.hotent.lpg.common.model.WDdxq; 19 import com.hotent.lpg.common.model.WDdxq;
20 import com.hotent.lpg.common.model.WHyyqjl; 20 import com.hotent.lpg.common.model.WHyyqjl;
21 import com.hotent.lpg.common.model.WQplx; 21 import com.hotent.lpg.common.model.WQplx;
  22 +import com.hotent.lpg.user.dao.CzzfpzDao;
22 import com.hotent.lpg.user.dao.DdDao; 23 import com.hotent.lpg.user.dao.DdDao;
23 import com.hotent.lpg.user.dao.DdxqDao; 24 import com.hotent.lpg.user.dao.DdxqDao;
24 import com.hotent.lpg.user.dao.QplxDao; 25 import com.hotent.lpg.user.dao.QplxDao;
25 import com.hotent.lpg.user.dto.DdDto; 26 import com.hotent.lpg.user.dto.DdDto;
26 -import com.hotent.lpg.user.manager.DdManager;  
27 -import com.hotent.lpg.user.manager.DdfwrzManager;  
28 -import com.hotent.lpg.user.manager.HyxxManager;  
29 -import com.hotent.lpg.user.manager.HyyqjlManager; 27 +import com.hotent.lpg.user.manager.*;
30 import com.hotent.lpg.user.vo.DdxxVo; 28 import com.hotent.lpg.user.vo.DdxxVo;
31 import com.hotent.uc.util.ContextUtil; 29 import com.hotent.uc.util.ContextUtil;
32 import lombok.extern.slf4j.Slf4j; 30 import lombok.extern.slf4j.Slf4j;
@@ -63,6 +61,11 @@ public class DdManagerImpl extends BaseManagerImpl&lt;DdDao, WDd&gt; implements DdMana @@ -63,6 +61,11 @@ public class DdManagerImpl extends BaseManagerImpl&lt;DdDao, WDd&gt; implements DdMana
63 private HyxxManager wHyxxManager; 61 private HyxxManager wHyxxManager;
64 @Resource 62 @Resource
65 private HyyqjlManager wHyyqjlManager; 63 private HyyqjlManager wHyyqjlManager;
  64 + @Resource
  65 + private CzzfpzDao czzfpzDao;
  66 + @Resource
  67 + private WxPayManager wxPayManager;
  68 +
66 @Override 69 @Override
67 public WDd getDetail(String id) { 70 public WDd getDetail(String id) {
68 WDd wDd = this.get(id); 71 WDd wDd = this.get(id);
@@ -72,20 +75,29 @@ public class DdManagerImpl extends BaseManagerImpl&lt;DdDao, WDd&gt; implements DdMana @@ -72,20 +75,29 @@ public class DdManagerImpl extends BaseManagerImpl&lt;DdDao, WDd&gt; implements DdMana
72 wDd.setDdxqList(ddxqDao.selectList(new LambdaQueryWrapper<WDdxq>().eq(WDdxq::getfDdid, wDd.getId()))); 75 wDd.setDdxqList(ddxqDao.selectList(new LambdaQueryWrapper<WDdxq>().eq(WDdxq::getfDdid, wDd.getId())));
73 return wDd; 76 return wDd;
74 } 77 }
  78 +
75 @Override 79 @Override
76 public void cancel(String ddid) { 80 public void cancel(String ddid) {
77 WDd dd = baseMapper.selectById(ddid); 81 WDd dd = baseMapper.selectById(ddid);
78 if (ObjectUtil.isNull(dd)) { 82 if (ObjectUtil.isNull(dd)) {
79 throw new RuntimeException("参数错误:订单不存在"); 83 throw new RuntimeException("参数错误:订单不存在");
80 } 84 }
81 - if (DdztEnum.dps.getInfo().equals(dd.getFDdzt()) || DdztEnum.psz.getInfo().equals(dd.getFDdzt())) {  
82 - dd.setFDdzt(DdztEnum.yqx.getInfo());  
83 - baseMapper.updateById(dd);  
84 - } else { 85 + if (!(DdztEnum.dps.getInfo().equals(dd.getFDdzt()) || DdztEnum.psz.getInfo().equals(dd.getFDdzt()) || DdztEnum.dzf.getInfo().equals(dd.getFDdzt()))) {
85 throw new RuntimeException("订单状态不正确"); 86 throw new RuntimeException("订单状态不正确");
86 } 87 }
  88 +// dd.setFDdzt(DdztEnum.yqx.getInfo());
  89 +// baseMapper.updateById(dd);
  90 +
  91 + if (dd.getFDdly().equals("线上下单") && dd.getFZffs().equals("微信") && dd.getFSfzf().equals("是")) {
  92 + //线上下单+微信支付+已支付 才退款
  93 + String shtkdh = wxPayManager.initiateRefundOrder(ddid);
  94 + dd.setFDdzt(DdztEnum.tkz.getInfo());
  95 + dd.setFShtkdh(shtkdh);
  96 + dd.setFSftk("否");
  97 + baseMapper.updateById(dd);
  98 + }
87 //添加服务日志 99 //添加服务日志
88 - wDdfwrzManager.insertDdfwrz(DdfwlxEnum.qxdd.getCode(), dd.getId()); 100 +// wDdfwrzManager.insertDdfwrz(DdfwlxEnum.qxdd.getCode(), dd.getId());
89 } 101 }
90 102
91 @Override 103 @Override
@@ -216,7 +228,7 @@ public class DdManagerImpl extends BaseManagerImpl&lt;DdDao, WDd&gt; implements DdMana @@ -216,7 +228,7 @@ public class DdManagerImpl extends BaseManagerImpl&lt;DdDao, WDd&gt; implements DdMana
216 dd.setFZflx(ddDto.getZflx()); 228 dd.setFZflx(ddDto.getZflx());
217 dd.setFSfzf("否"); 229 dd.setFSfzf("否");
218 dd.setFPsfs(ddDto.getPsfs()); 230 dd.setFPsfs(ddDto.getPsfs());
219 - dd.setFDdzt(StringUtil.isEmail(ddDto.getDdzt())?DdztEnum.dps.getInfo():ddDto.getDdzt()); 231 + dd.setFDdzt(StringUtil.isEmail(ddDto.getDdzt()) ? DdztEnum.dps.getInfo() : ddDto.getDdzt());
220 dd.setFMjly(ddDto.getMjly()); 232 dd.setFMjly(ddDto.getMjly());
221 dd.setFBz(ddDto.getBz()); 233 dd.setFBz(ddDto.getBz());
222 dd.setFCzid(qplx.getfSsczid()); 234 dd.setFCzid(qplx.getfSsczid());
backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/PaymentManageImpl.java
@@ -1,213 +0,0 @@ @@ -1,213 +0,0 @@
1 -package com.hotent.lpg.user.manager.impl;  
2 -  
3 -import cn.hutool.core.util.RandomUtil;  
4 -import cn.hutool.core.util.StrUtil;  
5 -import com.alibaba.fastjson.JSONObject;  
6 -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;  
7 -import com.baomidou.mybatisplus.core.toolkit.Wrappers;  
8 -import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;  
9 -import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;  
10 -import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;  
11 -import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;  
12 -import com.github.binarywang.wxpay.exception.WxPayException;  
13 -import com.github.binarywang.wxpay.service.WxPayService;  
14 -  
15 -import com.hotent.base.util.BeanUtils;  
16 -import com.hotent.lpg.common.model.WCzzfpz;  
17 -import com.hotent.lpg.common.model.WDd;  
18 -import com.hotent.lpg.common.model.WQpxx;  
19 -import com.hotent.lpg.user.dao.CzzfpzDao;  
20 -import com.hotent.lpg.user.dao.DdDao;  
21 -import com.hotent.lpg.user.enums.PayTypeEnum;  
22 -import com.hotent.lpg.user.manager.PaymentManage;  
23 -import com.hotent.lpg.user.util.LocalDateTimeUtils;  
24 -import com.hotent.lpg.user.util.WxPayConfiguration;  
25 -import com.hotent.lpg.user.vo.ResultData;  
26 -import lombok.AllArgsConstructor;  
27 -import lombok.extern.slf4j.Slf4j;  
28 -import org.springframework.stereotype.Service;  
29 -import org.springframework.transaction.annotation.Transactional;  
30 -import org.w3c.dom.Document;  
31 -import org.w3c.dom.Element;  
32 -import org.w3c.dom.Node;  
33 -import org.xml.sax.InputSource;  
34 -  
35 -import javax.xml.parsers.DocumentBuilder;  
36 -import javax.xml.parsers.DocumentBuilderFactory;  
37 -import javax.xml.transform.Transformer;  
38 -import javax.xml.transform.TransformerFactory;  
39 -import javax.xml.transform.dom.DOMSource;  
40 -import javax.xml.transform.stream.StreamResult;  
41 -import java.io.StringReader;  
42 -import java.io.StringWriter;  
43 -import java.math.BigDecimal;  
44 -import java.sql.Wrapper;  
45 -import java.time.LocalDateTime;  
46 -import java.util.HashMap;  
47 -  
48 -@Service  
49 -@Transactional  
50 -@AllArgsConstructor  
51 -@Slf4j  
52 -public class PaymentManageImpl implements PaymentManage {  
53 - private final DdDao ddDao;  
54 - private final CzzfpzDao czzfpzDao;  
55 - @Override  
56 - public String notifyOrder(String xmlData) {  
57 - // 从 XML 数据中提取支付单号  
58 - String outTradeNo = extractValueFromXML(xmlData, "out_trade_no");  
59 - //先用订单号找到订单  
60 - WDd wDd = ddDao.selectOne(new LambdaQueryWrapper<WDd>().eq(WDd::getFDddh, outTradeNo));  
61 - //在用 场站信息 拿到场站对应得支付配置  
62 - WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs()));  
63 - WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz);  
64 - //下面依旧是走微信sdk,查询订单和验证订单,为了保证数据得安全性,还是重复验证一次  
65 - String dddh = null;  
66 - try {  
67 - WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);  
68 - // 获取订单编号  
69 - dddh = notifyResult.getOutTradeNo();  
70 - // 获取微信支付单号  
71 - String transactionId = notifyResult.getTransactionId();  
72 - wDd = ddDao.selectOne(new LambdaQueryWrapper<WDd>().eq(WDd::getFDddh, dddh));  
73 - if (wDd == null) {  
74 - log.warn("订单不存在: {}", dddh);  
75 - return generateXmlResponse("FAIL", "订单不存在", dddh);  
76 - }  
77 - // 检查订单状态是否已支付  
78 - if ("已支付".equals(wDd.getFDdzt())) {  
79 - log.warn("订单 {} 已经处理过,忽略本次通知", dddh);  
80 - return generateXmlResponse("SUCCESS", "已处理过", dddh);  
81 - }  
82 - BigDecimal payPrice = wDd.getFDdje();  
83 - if (payPrice.multiply(new BigDecimal(100)).intValue() != notifyResult.getTotalFee()) {  
84 - log.warn("付款金额与订单金额不等: {}", dddh);  
85 - return generateXmlResponse("FAIL", "付款金额与订单金额不等", dddh);  
86 - }  
87 -  
88 - String timeEnd = notifyResult.getTimeEnd();  
89 - LocalDateTime paymentTime = LocalDateTimeUtils.parse(timeEnd);  
90 - wDd.setFFksj(paymentTime);  
91 - wDd.setFSfzf("是");  
92 - wDd.setFDdzt("待配送");  
93 - wDd.setFZfdh(transactionId);  
94 - ddDao.updateById(wDd);  
95 -  
96 - log.info("订单支付成功: {}", dddh);  
97 - return generateXmlResponse("SUCCESS", "成功", dddh);  
98 - } catch (WxPayException e) {  
99 - log.error("支付回调处理失败: {}", e.getErrCodeDes(), e);  
100 - return generateXmlResponse("FAIL", e.getErrCodeDes(), dddh);  
101 - }  
102 - }  
103 -  
104 -  
105 - private String extractValueFromXML(String xmlData, String paramName) {  
106 - // 解析 XML 数据以提取指定参数的值  
107 - try {  
108 - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();  
109 - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();  
110 - InputSource is = new InputSource(new StringReader(xmlData));  
111 - Document doc = dBuilder.parse(is);  
112 -  
113 - Element element = doc.getDocumentElement();  
114 - Node paramNode = element.getElementsByTagName(paramName).item(0).getFirstChild();  
115 - return paramNode != null ? paramNode.getNodeValue() : null;  
116 - } catch (Exception e) {  
117 - log.error("解析 XML 数据失败: {}", e.getMessage(), e);  
118 - return null;  
119 - }  
120 - }  
121 -  
122 -  
123 - private String generateXmlResponse(String returnCode, String returnMsg, String outTradeNo) {  
124 - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();  
125 - DocumentBuilder dBuilder;  
126 - try {  
127 - dBuilder = dbFactory.newDocumentBuilder();  
128 - Document doc = dBuilder.newDocument();  
129 -  
130 - Element rootElement = doc.createElement("xml");  
131 - doc.appendChild(rootElement);  
132 -  
133 - Element returnCodeElement = doc.createElement("return_code");  
134 - returnCodeElement.appendChild(doc.createTextNode(returnCode));  
135 - rootElement.appendChild(returnCodeElement);  
136 -  
137 - Element returnMsgElement = doc.createElement("return_msg");  
138 - returnMsgElement.appendChild(doc.createTextNode(returnMsg));  
139 - rootElement.appendChild(returnMsgElement);  
140 -  
141 - Element outTradeNoElement = doc.createElement("out_trade_no");  
142 - outTradeNoElement.appendChild(doc.createTextNode(outTradeNo));  
143 - rootElement.appendChild(outTradeNoElement);  
144 -  
145 - TransformerFactory transformerFactory = TransformerFactory.newInstance();  
146 - Transformer transformer = transformerFactory.newTransformer();  
147 - DOMSource source = new DOMSource(doc);  
148 - StringWriter writer = new StringWriter();  
149 - StreamResult result = new StreamResult(writer);  
150 - transformer.transform(source, result);  
151 - return writer.toString();  
152 - } catch (Exception e) {  
153 - log.error("构建 XML 响应失败", e);  
154 - return "<xml><return_code>FAIL</return_code><return_msg>处理失败</return_msg></xml>";  
155 - }  
156 - }  
157 -  
158 - @Override  
159 - public HashMap<String, Object> wxPay(WDd wDd,String openId) {  
160 - try {  
161 - WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs()));  
162 - if (BeanUtils.isEmpty(wCzzfpz) || wCzzfpz == null) {  
163 - throw new RuntimeException("支付配置不存在");  
164 - }  
165 - String tradeType = wDd.getFZflx();  
166 - if (StrUtil.isBlank(tradeType)) {  
167 - throw new RuntimeException("支付方式错误");  
168 - }  
169 - WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();  
170 - wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid());  
171 - wxPayUnifiedOrderRequest.setOpenid(null);  
172 - wxPayUnifiedOrderRequest.setBody(wDd.getFDddh());  
173 - wxPayUnifiedOrderRequest.setOutTradeNo(wDd.getFDddh());  
174 - wxPayUnifiedOrderRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue());  
175 - wxPayUnifiedOrderRequest.setTradeType(tradeType);  
176 - log.warn("创建订单5:{}", wxPayUnifiedOrderRequest);  
177 - JSONObject scene_info = new JSONObject();  
178 - scene_info.put("id", "LPG");  
179 - scene_info.put("name", "燃气");  
180 - wxPayUnifiedOrderRequest.setSceneInfo(scene_info.toString());  
181 - wxPayUnifiedOrderRequest.setNotifyUrl("http://pmrsig.natappfree.cc/api/user/order/payment/notifyOrder"); // 支付回调地址,开放不用登录  
182 - wxPayUnifiedOrderRequest.setSpbillCreateIp("127.0.0.1");  
183 - // trade_type=APP时 移动应用内的支付场景  
184 - if ("APP".equals(wxPayUnifiedOrderRequest.getTradeType())) {  
185 - wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid());  
186 - }  
187 - // trade_type=NATIVE时 线下消费场景  
188 - if ("NATIVE".equals(wxPayUnifiedOrderRequest.getTradeType())) {  
189 - wxPayUnifiedOrderRequest.setProductId(wxPayUnifiedOrderRequest.getOutTradeNo());  
190 - }  
191 - // 公众号内或者微信内的网页支付  
192 - if ("JSAPI".equals(wxPayUnifiedOrderRequest.getTradeType())) {  
193 - wxPayUnifiedOrderRequest.setOpenid(openId);  
194 - }  
195 - // 手机浏览器中的支付场景  
196 - if ("MWEB".equals(wxPayUnifiedOrderRequest.getTradeType())) {  
197 - wxPayUnifiedOrderRequest.setSceneInfo(null);  
198 - }  
199 - WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz);  
200 - Object payment = wxPayService.createOrder(wxPayUnifiedOrderRequest);  
201 - HashMap<String, Object> resultData = new HashMap<String, Object>();  
202 - resultData.put("payment", payment);  
203 - resultData.put("ddid", wDd.getId());  
204 - resultData.put("dddh", wDd.getFDddh());  
205 - return resultData;  
206 - } catch (WxPayException e) {  
207 - if ("INVALID_REQUEST".equals(e.getErrCode())) {  
208 - throw new RuntimeException("订单号重复,请重新下单");  
209 - }  
210 - throw new RuntimeException(e.getMessage());  
211 - }  
212 - }  
213 -}  
backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WxPayManagerImpl.java 0 → 100644
@@ -0,0 +1,336 @@ @@ -0,0 +1,336 @@
  1 +package com.hotent.lpg.user.manager.impl;
  2 +
  3 +import cn.hutool.core.util.RandomUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import com.alibaba.fastjson.JSONObject;
  6 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  7 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  8 +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
  9 +import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
  10 +import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
  11 +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
  12 +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
  13 +import com.github.binarywang.wxpay.exception.WxPayException;
  14 +import com.github.binarywang.wxpay.service.WxPayService;
  15 +import com.hotent.base.util.BeanUtils;
  16 +import com.hotent.lpg.common.enums.DdztEnum;
  17 +import com.hotent.lpg.common.model.WCzzfpz;
  18 +import com.hotent.lpg.common.model.WDd;
  19 +import com.hotent.lpg.user.dao.CzzfpzDao;
  20 +import com.hotent.lpg.user.dao.DdDao;
  21 +import com.hotent.lpg.user.manager.WxPayManager;
  22 +import com.hotent.lpg.user.util.LocalDateTimeUtils;
  23 +import com.hotent.lpg.user.util.WxPayConfiguration;
  24 +import lombok.AllArgsConstructor;
  25 +import lombok.extern.slf4j.Slf4j;
  26 +import org.springframework.stereotype.Service;
  27 +import org.w3c.dom.Document;
  28 +import org.w3c.dom.Element;
  29 +import org.w3c.dom.Node;
  30 +import org.xml.sax.InputSource;
  31 +
  32 +import javax.xml.bind.JAXBContext;
  33 +import javax.xml.parsers.DocumentBuilder;
  34 +import javax.xml.parsers.DocumentBuilderFactory;
  35 +import javax.xml.transform.Transformer;
  36 +import javax.xml.transform.TransformerFactory;
  37 +import javax.xml.transform.dom.DOMSource;
  38 +import javax.xml.transform.stream.StreamResult;
  39 +import javax.xml.xpath.XPath;
  40 +import javax.xml.xpath.XPathConstants;
  41 +import javax.xml.xpath.XPathFactory;
  42 +import java.io.StringReader;
  43 +import java.io.StringWriter;
  44 +import java.math.BigDecimal;
  45 +import java.time.LocalDateTime;
  46 +import java.util.HashMap;
  47 +
  48 +@Service
  49 +@AllArgsConstructor
  50 +@Slf4j
  51 +public class WxPayManagerImpl implements WxPayManager {
  52 +
  53 + private final DdDao ddDao;
  54 + private final CzzfpzDao czzfpzDao;
  55 +
  56 + /**
  57 + * 发起退款请求
  58 + *
  59 + * @param ddid
  60 + * @return
  61 + */
  62 + @Override
  63 + public String initiateRefundOrder(String ddid) {
  64 + // 1. 查询订单信息
  65 + WDd wDd = ddDao.selectById(ddid);
  66 + if (!DdztEnum.dps.getInfo().equals(wDd.getFDdzt())) {
  67 + throw new RuntimeException("订单状态不正确");
  68 + }
  69 + if (!(wDd.getFDdly().equals("线上下单") && wDd.getFZffs().equals("微信") && wDd.getFSfzf().equals("是"))) {
  70 + throw new RuntimeException("订单状态不正确");
  71 + }
  72 + // 2. 获取支付配置
  73 + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs()));
  74 + if (wCzzfpz == null) {
  75 + throw new RuntimeException("支付配置不存在");
  76 + }
  77 + // 3. 初始化微信支付服务
  78 + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz);
  79 + try {
  80 + // 4. 调用微信退款接口
  81 + // 这里需要构造退款请求对象,具体参数根据实际情况填写
  82 + // 注意:这里需要根据实际的微信支付SDK版本和退款接口文档来调整
  83 + // 示例代码可能需要根据实际情况修改
  84 + String tkdh = RandomUtil.randomString(32);
  85 + WxPayRefundRequest refundRequest = new WxPayRefundRequest();
  86 + refundRequest.setTransactionId(wDd.getFZfdh());
  87 + refundRequest.setOutTradeNo(wDd.getFDddh()); // 订单号
  88 + refundRequest.setOutRefundNo(RandomUtil.randomString(32)); // 退款单号
  89 + refundRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 订单总金额
  90 + refundRequest.setRefundFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 退款金额
  91 + refundRequest.setNotifyUrl(WxPayConfiguration.hostUrl + "/user/wxPay/handleRefundSuccessCallback");
  92 + // 发起退款请求
  93 + Object payment = wxPayService.refund(refundRequest);
  94 + // 返回结果
  95 + return tkdh;
  96 + } catch (WxPayException e) {
  97 + log.error("退款失败: {}", e.getErrCodeDes(), e);
  98 + throw new RuntimeException("退款失败: " + e.getErrCodeDes());
  99 + }
  100 + }
  101 +
  102 + /**
  103 + * 处理退款成功回调
  104 + *
  105 + * @param xmlData
  106 + * @return
  107 + */
  108 + @Override
  109 + public String handleRefundSuccessCallback(String xmlData) {
  110 + WxPayOrderNotifyResult rs = WxPayOrderNotifyResult.fromXML(xmlData);
  111 + String returnCode = rs.getReturnCode();
  112 + if (!returnCode.equals("SUCCESS")) {
  113 + return generateXmlResponse("FAIL", "退款失败", returnCode);
  114 + }
  115 + String appid = rs.getAppid();
  116 + String mchId = rs.getMchId();
  117 + //在用 场站信息 拿到场站对应得支付配置
  118 + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFAppid, appid).eq(WCzzfpz::getFMchid, mchId));
  119 + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz);
  120 + //下面依旧是走微信sdk,查询订单和验证订单,为了保证数据得安全性,还是重复验证一次
  121 + String dddh = null;
  122 + try {
  123 + WxPayRefundNotifyResult notifyResult = wxPayService.parseRefundNotifyResult(xmlData);
  124 + WxPayRefundNotifyResult.ReqInfo reqInfo = notifyResult.getReqInfo();
  125 + String refundId = reqInfo.getRefundId();
  126 + String successTime = reqInfo.getSuccessTime();
  127 + String transactionId = reqInfo.getTransactionId();
  128 + String outTradeNo = reqInfo.getOutTradeNo();
  129 + WDd wDd = ddDao.selectOne(Wrappers.<WDd>lambdaQuery().eq(WDd::getFZfdh, transactionId).eq(WDd::getFDddh, outTradeNo));
  130 + if (wDd == null) {
  131 + return generateXmlResponse("FAIL", "未查询到订单", outTradeNo);
  132 + }
  133 + if (wDd.getFSftk().equals("是")){
  134 + return generateXmlResponse("FAIL", "订单已退款", outTradeNo);
  135 + }
  136 + // 5. 更新订单状态
  137 + wDd.setFDdzt(DdztEnum.yqx.getInfo());
  138 + wDd.setFSftk("是");
  139 + wDd.setFTkdh(refundId);
  140 + wDd.setFTksj(LocalDateTimeUtils.parse(successTime));
  141 + ddDao.updateById(wDd);
  142 + log.info("微信退款成功: {}", dddh);
  143 + return generateXmlResponse("SUCCESS", "成功", dddh);
  144 + } catch (WxPayException e) {
  145 + log.error("微信退款回调处理失败: {}", e.getErrCodeDes(), e);
  146 + return generateXmlResponse("FAIL", e.getErrCodeDes(), dddh);
  147 + }
  148 + }
  149 +
  150 +
  151 +
  152 +
  153 + /**
  154 + * 处理支付成功回调
  155 + *
  156 + * @param xmlData
  157 + * @return
  158 + */
  159 + @Override
  160 + public String handlePaySuccessCallback(String xmlData) {
  161 + // 从 XML 数据中提取支付单号
  162 + String outTradeNo = extractValueFromXML(xmlData, "out_trade_no");
  163 + //先用订单号找到订单
  164 + WDd wDd = ddDao.selectOne(new LambdaQueryWrapper<WDd>().eq(WDd::getFDddh, outTradeNo));
  165 + //在用 场站信息 拿到场站对应得支付配置
  166 + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs()));
  167 + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz);
  168 + //下面依旧是走微信sdk,查询订单和验证订单,为了保证数据得安全性,还是重复验证一次
  169 + String dddh = null;
  170 + try {
  171 + WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
  172 + // 获取订单编号
  173 + dddh = notifyResult.getOutTradeNo();
  174 + // 获取微信支付单号
  175 + String transactionId = notifyResult.getTransactionId();
  176 + wDd = ddDao.selectOne(new LambdaQueryWrapper<WDd>().eq(WDd::getFDddh, dddh));
  177 + if (wDd == null) {
  178 + log.warn("订单不存在: {}", dddh);
  179 + return generateXmlResponse("FAIL", "订单不存在", dddh);
  180 + }
  181 + // 检查订单状态是否已支付
  182 + if ("已支付".equals(wDd.getFDdzt())) {
  183 + log.warn("订单 {} 已经处理过,忽略本次通知", dddh);
  184 + return generateXmlResponse("SUCCESS", "已处理过", dddh);
  185 + }
  186 + BigDecimal payPrice = wDd.getFDdje();
  187 + if (payPrice.multiply(new BigDecimal(100)).intValue() != notifyResult.getTotalFee()) {
  188 + log.warn("付款金额与订单金额不等: {}", dddh);
  189 + return generateXmlResponse("FAIL", "付款金额与订单金额不等", dddh);
  190 + }
  191 +
  192 + String timeEnd = notifyResult.getTimeEnd();
  193 + LocalDateTime paymentTime = LocalDateTimeUtils.parse(timeEnd);
  194 + wDd.setFFksj(paymentTime);
  195 + wDd.setFSfzf("是");
  196 + wDd.setFDdzt("待配送");
  197 + wDd.setFZfdh(transactionId);
  198 + ddDao.updateById(wDd);
  199 +
  200 + log.info("订单支付成功: {}", dddh);
  201 + return generateXmlResponse("SUCCESS", "成功", dddh);
  202 + } catch (WxPayException e) {
  203 + log.error("支付回调处理失败: {}", e.getErrCodeDes(), e);
  204 + return generateXmlResponse("FAIL", e.getErrCodeDes(), dddh);
  205 + }
  206 + }
  207 +
  208 + /**
  209 + * 生成预支付订单
  210 + * @param wDd
  211 + * @param openId
  212 + * @return
  213 + */
  214 + @Override
  215 + public HashMap<String, Object> generatePrepayOrder(WDd wDd, String openId) {
  216 + try {
  217 + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.<WCzzfpz>lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs()));
  218 + if (BeanUtils.isEmpty(wCzzfpz) || wCzzfpz == null) {
  219 + throw new RuntimeException("支付配置不存在");
  220 + }
  221 + String tradeType = wDd.getFZflx();
  222 + if (StrUtil.isBlank(tradeType)) {
  223 + throw new RuntimeException("支付方式错误");
  224 + }
  225 + WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
  226 + wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid());
  227 + wxPayUnifiedOrderRequest.setOpenid(null);
  228 + wxPayUnifiedOrderRequest.setBody(wDd.getFDddh());
  229 + wxPayUnifiedOrderRequest.setOutTradeNo(wDd.getFDddh());
  230 + wxPayUnifiedOrderRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue());
  231 + wxPayUnifiedOrderRequest.setTradeType(tradeType);
  232 + JSONObject scene_info = new JSONObject();
  233 + scene_info.put("id", "LPG");
  234 + scene_info.put("name", "燃气");
  235 + wxPayUnifiedOrderRequest.setSceneInfo(scene_info.toString());
  236 + wxPayUnifiedOrderRequest.setNotifyUrl(WxPayConfiguration.hostUrl + "/user/wxPay/handlePaySuccessCallback"); // 支付回调地址,开放不用登录
  237 + wxPayUnifiedOrderRequest.setSpbillCreateIp("127.0.0.1");
  238 + // trade_type=APP时 移动应用内的支付场景
  239 + if ("APP".equals(wxPayUnifiedOrderRequest.getTradeType())) {
  240 + wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid());
  241 + }
  242 + // trade_type=NATIVE时 线下消费场景
  243 + if ("NATIVE".equals(wxPayUnifiedOrderRequest.getTradeType())) {
  244 + wxPayUnifiedOrderRequest.setProductId(wxPayUnifiedOrderRequest.getOutTradeNo());
  245 + }
  246 + // 公众号内或者微信内的网页支付
  247 + if ("JSAPI".equals(wxPayUnifiedOrderRequest.getTradeType())) {
  248 + wxPayUnifiedOrderRequest.setOpenid(openId);
  249 + }
  250 + // 手机浏览器中的支付场景
  251 + if ("MWEB".equals(wxPayUnifiedOrderRequest.getTradeType())) {
  252 + wxPayUnifiedOrderRequest.setSceneInfo(null);
  253 + }
  254 + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz);
  255 + Object payment = wxPayService.createOrder(wxPayUnifiedOrderRequest);
  256 + HashMap<String, Object> resultData = new HashMap<String, Object>();
  257 + resultData.put("payment", payment);
  258 + resultData.put("ddid", wDd.getId());
  259 + resultData.put("dddh", wDd.getFDddh());
  260 + return resultData;
  261 + } catch (WxPayException e) {
  262 + if ("INVALID_REQUEST".equals(e.getErrCode())) {
  263 + throw new RuntimeException("订单号重复,请重新下单");
  264 + }
  265 + throw new RuntimeException(e.getMessage());
  266 + }
  267 + }
  268 +
  269 + /**
  270 + * 生成微信回调响应
  271 + *
  272 + * @param returnCode
  273 + * @param returnMsg
  274 + * @param outTradeNo
  275 + * @return
  276 + */
  277 + private String generateXmlResponse(String returnCode, String returnMsg, String outTradeNo) {
  278 + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
  279 + DocumentBuilder dBuilder;
  280 + try {
  281 + dBuilder = dbFactory.newDocumentBuilder();
  282 + Document doc = dBuilder.newDocument();
  283 +
  284 + Element rootElement = doc.createElement("xml");
  285 + doc.appendChild(rootElement);
  286 +
  287 + Element returnCodeElement = doc.createElement("return_code");
  288 + returnCodeElement.appendChild(doc.createTextNode(returnCode));
  289 + rootElement.appendChild(returnCodeElement);
  290 +
  291 + Element returnMsgElement = doc.createElement("return_msg");
  292 + returnMsgElement.appendChild(doc.createTextNode(returnMsg));
  293 + rootElement.appendChild(returnMsgElement);
  294 +
  295 + Element outTradeNoElement = doc.createElement("out_trade_no");
  296 + outTradeNoElement.appendChild(doc.createTextNode(outTradeNo));
  297 + rootElement.appendChild(outTradeNoElement);
  298 +
  299 + TransformerFactory transformerFactory = TransformerFactory.newInstance();
  300 + Transformer transformer = transformerFactory.newTransformer();
  301 + DOMSource source = new DOMSource(doc);
  302 + StringWriter writer = new StringWriter();
  303 + StreamResult result = new StreamResult(writer);
  304 + transformer.transform(source, result);
  305 + return writer.toString();
  306 + } catch (Exception e) {
  307 + log.error("构建 XML 响应失败", e);
  308 + return "<xml><return_code>FAIL</return_code><return_msg>处理失败</return_msg></xml>";
  309 + }
  310 + }
  311 +
  312 + /**
  313 + * 从 XML 数据中提取指定参数的值
  314 + *
  315 + * @param xmlData
  316 + * @param paramName
  317 + * @return
  318 + */
  319 + private String extractValueFromXML(String xmlData, String paramName) {
  320 + // 解析 XML 数据以提取指定参数的值
  321 + try {
  322 + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
  323 + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
  324 + InputSource is = new InputSource(new StringReader(xmlData));
  325 + Document doc = dBuilder.parse(is);
  326 +
  327 + Element element = doc.getDocumentElement();
  328 + Node paramNode = element.getElementsByTagName(paramName).item(0).getFirstChild();
  329 + return paramNode != null ? paramNode.getNodeValue() : null;
  330 + } catch (Exception e) {
  331 + log.error("解析 XML 数据失败: {}", e.getMessage(), e);
  332 + return null;
  333 + }
  334 + }
  335 +
  336 +}
backend/lpg-user/src/main/java/com/hotent/lpg/user/util/WxPayConfiguration.java
@@ -6,6 +6,9 @@ import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; @@ -6,6 +6,9 @@ import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
6 import com.hotent.lpg.common.model.WCzzfpz; 6 import com.hotent.lpg.common.model.WCzzfpz;
7 7
8 public class WxPayConfiguration { 8 public class WxPayConfiguration {
  9 +
  10 +
  11 + public static final String hostUrl = "http://qyhtiz.natappfree.cc/api";
9 public static WxPayService getPayService(WCzzfpz wCzzfpz) { 12 public static WxPayService getPayService(WCzzfpz wCzzfpz) {
10 WxPayConfig wxPayConfig = new WxPayConfig(); 13 WxPayConfig wxPayConfig = new WxPayConfig();
11 wxPayConfig.setAppId(wCzzfpz.getFAppid()); // appId(应用id)(微信支付商户平台获取) 14 wxPayConfig.setAppId(wCzzfpz.getFAppid()); // appId(应用id)(微信支付商户平台获取)
@@ -18,6 +21,9 @@ public class WxPayConfiguration { @@ -18,6 +21,9 @@ public class WxPayConfiguration {
18 wxPayConfig.setUseSandboxEnv(false); 21 wxPayConfig.setUseSandboxEnv(false);
19 WxPayService wxPayService = new WxPayServiceImpl(); 22 WxPayService wxPayService = new WxPayServiceImpl();
20 wxPayService.setConfig(wxPayConfig); 23 wxPayService.setConfig(wxPayConfig);
  24 + wxPayConfig.setKeyPath(wCzzfpz.getFKeypath());
  25 + wxPayConfig.setPrivateKeyPath(wCzzfpz.getFPrivatekeypath());
  26 + wxPayConfig.setPrivateCertPath(wCzzfpz.getFPrivatecertpath());
21 return wxPayService; 27 return wxPayService;
22 } 28 }
23 } 29 }