From cfe0f8bdc0d7f074113e3cf11cb61bc0c0b838fa Mon Sep 17 00:00:00 2001 From: chenwei Date: Fri, 20 Sep 2024 13:33:51 +0800 Subject: [PATCH] 解决重复支付问题 --- backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java | 3 ++- backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/DdConroller.java | 54 ++++++------------------------------------------------ backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/WxPayController.java | 38 ++++++++++++++++++++++++++++++++++---- backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/WxPayManager.java | 40 +++++++++++++++++++++++++++++++++++++--- backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java | 25 +++++++++++++++++-------- backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WxPayManagerImpl.java | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------- 6 files changed, 306 insertions(+), 102 deletions(-) diff --git a/backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java b/backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java index 6625e40..8b1b921 100644 --- a/backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java +++ b/backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java @@ -160,7 +160,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/fileUpload").permitAll() .antMatchers("/deleteFile").permitAll() .antMatchers("/ueditor/**", "/apiManager/getToken").permitAll() - .antMatchers("/user/wxPay/**").permitAll() + .antMatchers("/user/wxPay/handlePaySuccessCallback").permitAll() + .antMatchers("/user/wxPay/handleRefundSuccessCallback").permitAll() .anyRequest().authenticated() .accessDecisionManager(accessDecisionManager()); diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/DdConroller.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/DdConroller.java index 6c00b25..6a6a75b 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/DdConroller.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/DdConroller.java @@ -2,7 +2,11 @@ package com.hotent.lpg.user.controller; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; import com.hotent.base.model.CommonResult; import com.hotent.lpg.common.enums.DdlyEnum; import com.hotent.lpg.common.enums.DdztEnum; @@ -90,51 +94,6 @@ public class DdConroller { return CommonResult.ok(); } -// /** -// * 创建订单 -// * -// * @param request -// * @return -// * @throws Exception -// * @throws -// */ -// @PostMapping(value = "/save") -// @ApiOperation(value = "创建订单", httpMethod = "POST", notes = "创建订单") -// public CommonResult createOrder(@ApiParam(name = "CreateOrderRequest", value = "创建订单请求对象", required = true) @RequestBody DdDto request) throws Exception { -// WHydz hydz = hydzDao.selectOneByHyIdAndDzId(ContextUtil.getCurrentUserId(), request.getHydzId()); -// if (BeanUtil.isEmpty(hydz)){ -// throw new RuntimeException("未查询到地址信息。"); -// } -// WHyxx hyxx = wHyxxManager.getUseridByInfo(ContextUtil.getCurrentUserId()); -// if (BeanUtil.isEmpty(hyxx)){ -// throw new RuntimeException("未查询会员信息。"); -// } -// request.setShlxr(hydz.getFLxr()); -// request.setShlxrdh(hydz.getFLxrdh()); -// request.setShsf(hydz.getFLxrsf()); -// request.setShs(hydz.getFLxrs()); -// request.setShq(hydz.getFLxrq()); -// request.setShjd(hydz.getFLxrjd()); -// request.setShxxdz(hydz.getFLxrxxdz()); -// request.setJd(hydz.getFJd()); -// request.setWd(hydz.getFWd()); -// -// request.setSfhy("是"); -// request.setHydh(hyxx.getFSjh()); //账号就是电话 -// request.setHyid(hyxx.getFUserid()); -// request.setHymc(hyxx.getFXm()); -// request.setHylx(hyxx.getFHylx()); -// request.setSfzh(hyxx.getFSfzh()); -// request.setShtysbm(hyxx.getFShtysbm()); -// -// request.setXdrlx(UserlxEnum.hy.getInfo()); -// request.setXdrid(ContextUtil.getCurrentUserId()); -// request.setXdrmc(ContextUtil.getCurrentUser().getFullname()); -// request.setDdly(DdlyEnum.xsxd.getInfo()); -// WDd order = wDdManager.createOrder(request); -// return CommonResult.ok().value(order); -// } - @PostMapping(value = "/add") @ApiOperation(value = "创建订单", httpMethod = "POST", notes = "创建订单") public CommonResult createOrder(@ApiParam(name = "CreateOrderRequest", value = "创建订单请求对象", required = true) @RequestBody DdDto ddDto) { @@ -172,9 +131,8 @@ public class DdConroller { ddDto.setDdzt(DdztEnum.CREATED.getCode()); WDd order = wDdManager.addOrder(ddDto); log.warn("创建订单2:{}", order); - HashMap resultData = wxPayManager.generatePrepayOrder(order, ddDto.getOpenId()); - log.warn("创建订单3:{}", resultData); - return CommonResult.ok().value(resultData); +// WxPayMpOrderResult prepayOrder = wxPayManager.generatePrepayOrder(order.getId(), ddDto.getOpenId(),order.getFZflx()); + return CommonResult.ok().value(order); } diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/WxPayController.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/WxPayController.java index 245c2a7..c5aab0a 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/WxPayController.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/WxPayController.java @@ -1,14 +1,19 @@ package com.hotent.lpg.user.controller; +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.hotent.base.model.CommonResult; +import com.hotent.lpg.common.model.WDd; +import com.hotent.lpg.user.manager.DdManager; import com.hotent.lpg.user.manager.WxPayManager; +import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; @RestController @RequestMapping("/user/wxPay/") @@ -17,6 +22,31 @@ import org.springframework.web.bind.annotation.RestController; @Slf4j public class WxPayController { private WxPayManager wxPayManager; + private DdManager ddManager; + + /** + * 调用统一下单接口 + * + * @return + */ + @PostMapping("/unifiedOrder") + public CommonResult unifiedOrder(@RequestBody HashMap params) throws WxPayException { + String ddid = String.valueOf(params.get("ddid")); + String openId = params.get("openId"); + String zflx = params.get("zflx"); + return CommonResult.ok().value(wxPayManager.initiateJsApiPay(ddid, openId, zflx)); + } + + + @GetMapping(value = "/getPrepayOrder") + @ApiOperation(value = "查询微信支付系统的预支付订单信息", httpMethod = "GET", notes = "查询微信支付系统的预支付订单信息") + public CommonResult getPrepayOrder(@RequestParam(required = true) String id) throws Exception { + WxPayOrderQueryResult weChatOrder = wxPayManager.getWxPayOrderQuery(id); + return CommonResult.ok().value(weChatOrder); + } + + + /** * 处理支付成功回调 diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/WxPayManager.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/WxPayManager.java index d8283ac..0056b38 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/WxPayManager.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/WxPayManager.java @@ -1,19 +1,28 @@ package com.hotent.lpg.user.manager; +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; +import com.github.binarywang.wxpay.exception.WxPayException; import com.hotent.lpg.common.model.WDd; import java.util.HashMap; +import java.util.Map; public interface WxPayManager { /** * 退款 + * * @param ddid * @return */ - String initiateRefundOrder(String ddid); + WxPayRefundResult initiateRefundOrder(String ddid); /** * 处理退款成功回调 + * * @param xmlData * @return */ @@ -22,6 +31,7 @@ public interface WxPayManager { /** * 处理支付成功回调 + * * @param xmlData * @return */ @@ -30,9 +40,33 @@ public interface WxPayManager { /** * 生成预支付订单 - * @param order + * + * @param ddid * @param openId * @return */ - HashMap generatePrepayOrder(WDd order, String openId); + WxPayMpOrderResult generatePrepayOrder(String ddid, String openId, String zflx); + + /** + * 如果订单状态为“待支付”,则获取原有的预支付订单信息 + * SUCCESS: 交易支付成功 + * REFUND: 交易已退款 + * NOTPAY : 交易创建,但未支付 + * CLOSED: 交易关闭 + * REVOKED:交易已撤销(仅有服务商接口) + * USERPAYING: 用户支付中 + * PAYERROR: 支付失败 + * @return + */ + WxPayOrderQueryResult getWxPayOrderQuery(String id); + + + WxPayMpOrderResult initiateJsApiPay(String ddid, String openId, String zflx) throws WxPayException; + + + /** + * 取消订单 + * @param id + */ + WxPayOrderCloseResult cancelOrder(String id); } diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java index c04d61c..60604fd 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java +++ b/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; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; import com.hotent.base.id.IdGenerator; import com.hotent.base.manager.impl.BaseManagerImpl; import com.hotent.base.util.BeanUtils; @@ -86,19 +88,26 @@ public class DdManagerImpl extends BaseManagerImpl implements DdMana || DdztEnum.SHIPPED.getCode().equals(dd.getFDdzt()))) { throw new RuntimeException("订单状态不正确"); } - - if (dd.getFDdly().equals(DdlyEnum.xsxd.getCode()) && dd.getFZffs().equals(DdZffsEnum.WX_PAY.getCode()) && dd.getFSfzf().equals(SysEnum.Y.getCode())) { //线上下单+微信支付+已支付 才退款 - String shtkdh = wxPayManager.initiateRefundOrder(ddid); - dd.setFDdzt(DdztEnum.REFUNDING.getCode()); - dd.setFShtkdh(shtkdh); - dd.setFSftk(SysEnum.N.getCode()); - baseMapper.updateById(dd); - }else { + WxPayRefundResult wxPayRefundResult = wxPayManager.initiateRefundOrder(ddid); + if ("SUCCESS".equals(wxPayRefundResult.getReturnCode()) && "SUCCESS".equals(wxPayRefundResult.getResultCode())) { + dd.setFDdzt(DdztEnum.REFUNDING.getCode()); + dd.setFShtkdh(wxPayRefundResult.getOutRefundNo()); + dd.setFSftk(SysEnum.N.getCode()); + baseMapper.updateById(dd); + } + } else { +// WxPayOrderCloseResult wxPayOrderCloseResult = wxPayManager.cancelOrder(dd.getId()); +// if ("SUCCESS".equals(wxPayOrderCloseResult.getReturnCode()) && "SUCCESS".equals(wxPayOrderCloseResult.getResultCode())) { dd.setFDdzt(DdztEnum.REFUNDED.getCode()); dd.setFSftk(SysEnum.N.getCode()); baseMapper.updateById(dd); +// } else { +// String errCode = wxPayOrderCloseResult.getErrCode(); +// String errCodeDes = wxPayOrderCloseResult.getErrCodeDes(); +// throw new RuntimeException("取消订单失败,错误代码: " + errCode + ", 错误描述: " + errCodeDes); +// } } //添加服务日志 // wDdfwrzManager.insertDdfwrz(DdfwlxEnum.qxdd.getCode(), dd.getId()); diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WxPayManagerImpl.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WxPayManagerImpl.java index 79aaae7..f9b5bd3 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WxPayManagerImpl.java +++ b/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; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; +import com.github.binarywang.wxpay.bean.request.WxPayOrderCloseRequest; +import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest; import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; +import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.util.SignUtils; import com.hotent.base.exception.BaseException; import com.hotent.base.util.BeanUtils; +import com.hotent.base.util.StringUtil; import com.hotent.lpg.common.enums.DdZffsEnum; import com.hotent.lpg.common.enums.DdlyEnum; import com.hotent.lpg.common.enums.DdztEnum; @@ -50,7 +59,10 @@ import java.io.StringWriter; import java.math.BigDecimal; import java.rmi.ServerError; import java.time.LocalDateTime; +import java.util.Collections; import java.util.HashMap; +import java.util.Map; +import java.util.UUID; @Service @Slf4j @@ -66,6 +78,7 @@ public class WxPayManagerImpl implements WxPayManager { @Resource private CzzfpzDao czzfpzDao; + /** * 发起退款请求 * @@ -73,7 +86,7 @@ public class WxPayManagerImpl implements WxPayManager { * @return */ @Override - public String initiateRefundOrder(String ddid) { + public WxPayRefundResult initiateRefundOrder(String ddid) { // 1. 查询订单信息 WDd wDd = ddDao.selectById(ddid); if (!DdztEnum.PAID.getCode().equals(wDd.getFDdzt())) { @@ -90,22 +103,43 @@ public class WxPayManagerImpl implements WxPayManager { // 3. 初始化微信支付服务 WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); try { - // 4. 调用微信退款接口 - // 这里需要构造退款请求对象,具体参数根据实际情况填写 - // 注意:这里需要根据实际的微信支付SDK版本和退款接口文档来调整 - // 示例代码可能需要根据实际情况修改 - String tkdh = RandomUtil.randomString(32); - WxPayRefundRequest refundRequest = new WxPayRefundRequest(); - refundRequest.setTransactionId(wDd.getFZfdh()); - refundRequest.setOutTradeNo(wDd.getFDddh()); // 订单号 - refundRequest.setOutRefundNo(RandomUtil.randomString(32)); // 退款单号 - refundRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 订单总金额 - refundRequest.setRefundFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 退款金额 - refundRequest.setNotifyUrl(hostUrl + "/user/wxPay/handleRefundSuccessCallback"); - // 发起退款请求 - Object payment = wxPayService.refund(refundRequest); - // 返回结果 - return tkdh; + // 4.查询微信支付系统的预支付订单信息 + WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); + request.setOutTradeNo(wDd.getFDddh()); + WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder(request); + if ("SUCCESS".equals(wxPayOrderQueryResult.getReturnCode()) && "SUCCESS".equals(wxPayOrderQueryResult.getResultCode())) { + String tradeState = wxPayOrderQueryResult.getTradeState(); + switch (tradeState) { + case "SUCCESS": + // 4. 调用微信退款接口 + WxPayRefundRequest refundRequest = new WxPayRefundRequest(); + refundRequest.setTransactionId(wDd.getFZfdh()); + refundRequest.setOutTradeNo(wDd.getFDddh()); // 订单号 + refundRequest.setOutRefundNo(RandomUtil.randomString(32)); // 退款单号 + refundRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 订单总金额 + refundRequest.setRefundFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); // 退款金额 + refundRequest.setNotifyUrl(hostUrl + "/user/wxPay/handleRefundSuccessCallback"); + // 返回结果 + return wxPayService.refund(refundRequest); + case "TRADE_CLOSED": + throw new RuntimeException("订单已关闭"); + case "NOTPAY": + throw new RuntimeException("订单未支付"); + case "REFUND": + throw new RuntimeException("订单已退款"); + case "REFUNDCLOSED": + throw new RuntimeException("退款关闭"); + case "REVERSAL": + throw new RuntimeException("交易撤销"); + case "USERPAYING": + throw new RuntimeException("用户支付中"); + case "PAYERROR": + throw new RuntimeException("支付失败"); + default: + throw new RuntimeException("未知状态:" + tradeState); + } + } + throw new RuntimeException("订单状态异常"); } catch (WxPayException e) { log.error("退款失败: {}", e.getErrCodeDes(), e); throw new RuntimeException("退款失败: " + e.getErrCodeDes()); @@ -132,10 +166,7 @@ public class WxPayManagerImpl implements WxPayManager { String appid = rs.getAppid(); String mchId = rs.getMchId(); // 从数据库中查询对应的应用配置信息 - WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.lambdaQuery() - .eq(WCzzfpz::getFAppid, appid) - .eq(WCzzfpz::getFMchid, mchId) - .last("LIMIT 1")); + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.lambdaQuery().eq(WCzzfpz::getFAppid, appid).eq(WCzzfpz::getFMchid, mchId).last("LIMIT 1")); // 如果没有找到对应的配置信息,则抛出异常 if (wCzzfpz == null) { throw new BaseException("退款失败,请联系管理员。"); @@ -153,15 +184,13 @@ public class WxPayManagerImpl implements WxPayManager { String transactionId = reqInfo.getTransactionId(); String outTradeNo = reqInfo.getOutTradeNo(); // 从数据库中查询订单信息 - WDd wDd = ddDao.selectOne(Wrappers.lambdaQuery() - .eq(WDd::getFZfdh, transactionId) - .eq(WDd::getFDddh, outTradeNo)); + WDd wDd = ddDao.selectOne(Wrappers.lambdaQuery().eq(WDd::getFZfdh, transactionId).eq(WDd::getFDddh, outTradeNo)); // 如果没有查询到订单,则生成失败响应并返回 if (wDd == null) { return generateXmlResponse("FAIL", "未查询到订单", outTradeNo); } // 如果订单已经退款,则生成失败响应并返回 - if (wDd.getFSftk().equals(SysEnum.Y.getCode())) { + if (StringUtil.isEmpty(wDd.getFSftk()) || wDd.getFSftk().equals(SysEnum.Y.getCode())) { return generateXmlResponse("FAIL", "订单已退款", outTradeNo); } // 更新订单状态为已退款,并记录相关信息 @@ -201,6 +230,10 @@ public class WxPayManagerImpl implements WxPayManager { String outTradeNo = extractValueFromXML(xmlData, "out_trade_no"); //先用订单号找到订单 WDd wDd = ddDao.selectOne(new LambdaQueryWrapper().eq(WDd::getFDddh, outTradeNo)); + if (wDd == null) { + log.warn("订单不存在: {}", wDd); + return generateXmlResponse("FAIL", "订单不存在", wDd.getFDddh()); + } //在用 场站信息 拿到场站对应得支付配置 WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); @@ -247,19 +280,20 @@ public class WxPayManagerImpl implements WxPayManager { /** * 生成预支付订单 * - * @param wDd - * @param openId * @return */ @Override - public HashMap generatePrepayOrder(WDd wDd, String openId) { + public WxPayMpOrderResult generatePrepayOrder(String ddid, String openId, String zflx) { try { + WDd wDd = ddDao.selectById(ddid); + if (BeanUtils.isEmpty(wDd)) { + throw new RuntimeException("订单不存在"); + } WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); - if (BeanUtils.isEmpty(wCzzfpz) || wCzzfpz == null) { + if (BeanUtils.isEmpty(wCzzfpz)) { throw new RuntimeException("支付配置不存在"); } - String tradeType = wDd.getFZflx(); - if (StrUtil.isBlank(tradeType)) { + if (StrUtil.isBlank(zflx)) { throw new RuntimeException("支付方式错误"); } WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest(); @@ -268,7 +302,7 @@ public class WxPayManagerImpl implements WxPayManager { wxPayUnifiedOrderRequest.setBody(wDd.getFDddh()); wxPayUnifiedOrderRequest.setOutTradeNo(wDd.getFDddh()); wxPayUnifiedOrderRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); - wxPayUnifiedOrderRequest.setTradeType(tradeType); + wxPayUnifiedOrderRequest.setTradeType(zflx); JSONObject scene_info = new JSONObject(); scene_info.put("id", "LPG"); scene_info.put("name", "燃气"); @@ -292,12 +326,7 @@ public class WxPayManagerImpl implements WxPayManager { wxPayUnifiedOrderRequest.setSceneInfo(null); } WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); - Object payment = wxPayService.createOrder(wxPayUnifiedOrderRequest); - HashMap resultData = new HashMap(); - resultData.put("payment", payment); - resultData.put("ddid", wDd.getId()); - resultData.put("dddh", wDd.getFDddh()); - return resultData; + return wxPayService.createOrder(wxPayUnifiedOrderRequest); } catch (WxPayException e) { if ("INVALID_REQUEST".equals(e.getErrCode())) { throw new RuntimeException("订单号重复,请重新下单"); @@ -306,6 +335,148 @@ public class WxPayManagerImpl implements WxPayManager { } } + + /** + * 获取订单状态 + * + * @return + */ + @Override + public WxPayOrderQueryResult getWxPayOrderQuery(String ddid) { + //先找到订单 + WDd wDd = ddDao.selectById(ddid); + if (wDd == null) { + throw new RuntimeException("订单不存在"); + } + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); + if (BeanUtils.isEmpty(wCzzfpz)) { + throw new RuntimeException("支付配置不存在"); + } + // 查询微信支付系统的预支付订单信息 + WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); + request.setOutTradeNo(wDd.getFDddh()); + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); + try { + return wxPayService.queryOrder(request); + } catch (WxPayException e) { + throw new RuntimeException("查询预支付订单失败:" + e.getMessage()); + } + } + + @Override + public WxPayMpOrderResult initiateJsApiPay(String ddid, String openId, String zflx) throws WxPayException { + // 1.获取订单 + WDd wDd = ddDao.selectById(ddid); + if (BeanUtils.isEmpty(wDd)) { + throw new RuntimeException("订单不存在"); + } + // 2. 获取支付配置 + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); + // 3. 初始化微信支付服务 + WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest(); + wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid()); + wxPayUnifiedOrderRequest.setOpenid(null); + wxPayUnifiedOrderRequest.setBody(wDd.getFDddh()); + wxPayUnifiedOrderRequest.setOutTradeNo(wDd.getFDddh()); + wxPayUnifiedOrderRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); + wxPayUnifiedOrderRequest.setTradeType(zflx); + JSONObject scene_info = new JSONObject(); + scene_info.put("id", "LPG"); + scene_info.put("name", "燃气"); + wxPayUnifiedOrderRequest.setSceneInfo(scene_info.toString()); + wxPayUnifiedOrderRequest.setNotifyUrl(hostUrl + "/user/wxPay/handlePaySuccessCallback"); // 支付回调地址,开放不用登录 + wxPayUnifiedOrderRequest.setSpbillCreateIp("127.0.0.1"); + // trade_type=APP时 移动应用内的支付场景 + if ("APP".equals(wxPayUnifiedOrderRequest.getTradeType())) { + wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid()); + } + // trade_type=NATIVE时 线下消费场景 + if ("NATIVE".equals(wxPayUnifiedOrderRequest.getTradeType())) { + wxPayUnifiedOrderRequest.setProductId(wxPayUnifiedOrderRequest.getOutTradeNo()); + } + // 公众号内或者微信内的网页支付 + if ("JSAPI".equals(wxPayUnifiedOrderRequest.getTradeType())) { + wxPayUnifiedOrderRequest.setOpenid(openId); + } + // 手机浏览器中的支付场景 + if ("MWEB".equals(wxPayUnifiedOrderRequest.getTradeType())) { + wxPayUnifiedOrderRequest.setSceneInfo(null); + } + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); + //创建并获取预支付订单 + WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest); + if ("SUCCESS".equals(wxPayUnifiedOrderResult.getReturnCode()) && "SUCCESS".equals(wxPayUnifiedOrderResult.getResultCode())) { + //生成唤起微信支付参数 + WxPayConfig config = wxPayService.getConfig(); + String prepayId = wxPayUnifiedOrderResult.getPrepayId(); + String signType = "MD5"; + // 查询订单状态 + WxPayOrderQueryRequest queryRequest = new WxPayOrderQueryRequest(); + queryRequest.setAppid(config.getAppId()); + queryRequest.setMchId(config.getMchId()); + queryRequest.setOutTradeNo(wDd.getFDddh()); // 假设 orderId 是订单号 + WxPayOrderQueryResult queryResult = wxPayService.queryOrder(queryRequest); + if ("SUCCESS".equals(queryResult.getReturnCode()) && "SUCCESS".equals(queryResult.getResultCode())) { + String tradeState = queryResult.getTradeState(); + if ("SUCCESS".equals(tradeState)) { + // 订单已支付 + throw new RuntimeException("订单已支付。"); + } else if ("NOTPAY".equals(tradeState)) { + // 订单未支付 + WxPayMpOrderResult wxPayMpOrderResult = WxPayMpOrderResult.builder(). + appId(wxPayUnifiedOrderResult.getAppid()) + .timeStamp(String.valueOf(System.currentTimeMillis() / 1000L)) + .nonceStr(UUID.randomUUID().toString().replace("-", "")) + .packageValue("prepay_id=" + prepayId) + .signType(signType).build(); + wxPayMpOrderResult.setPaySign(SignUtils.createSign(wxPayMpOrderResult, signType, config.getMchKey(), (String[]) null)); + return wxPayMpOrderResult; + } else { + // 其他状态 + throw new RuntimeException("订单已取消或过期,请重新下单。"); + } + } else { + // 查询失败 + String errCode = queryResult.getErrCode(); + String errCodeDes = queryResult.getErrCodeDes(); + throw new RuntimeException("查询订单状态失败,错误代码: " + errCode + ", 错误描述: " + errCodeDes); + } + + } else { + throw new RuntimeException("预支付订单创建失败,请重新下单。"); + } + } + + + /** + * 取消订单 + * + * @param ddid + */ + public WxPayOrderCloseResult cancelOrder(String ddid) { + try { + // 1.获取订单 + WDd wDd = ddDao.selectById(ddid); + if (BeanUtils.isEmpty(wDd)) { + throw new RuntimeException("订单不存在"); + } + // 2. 获取支付配置 + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); + WxPayOrderCloseRequest closeRequest = new WxPayOrderCloseRequest(); + WxPayConfig config = wxPayService.getConfig(); + closeRequest.setAppid(config.getAppId()); + closeRequest.setMchId(config.getMchId()); + closeRequest.setOutTradeNo(wDd.getFDddh()); + WxPayOrderCloseResult closeResult = wxPayService.closeOrder(closeRequest); + return closeResult; + } catch (Exception e) { + log.error("取消订单时发生错误: {}", e.getMessage(), e); + throw new RuntimeException("取消订单时发生错误"); + } + } + + /** * 生成微信回调响应 * @@ -373,4 +544,5 @@ public class WxPayManagerImpl implements WxPayManager { } } + } -- libgit2 0.21.2