From e535868c8985f1fdd8f991b6bfc7c1f986f8f724 Mon Sep 17 00:00:00 2001 From: czc Date: Thu, 13 Jul 2023 15:03:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E9=AA=8C=E7=AD=BE=E5=8F=8A?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../h5/controller/PayNotifyController.java | 104 ++++++++++++++++++ .../h5/pojo/dto/MicroMallOrderSyncMsg.java | 29 +++++ .../cyl/h5/pojo/dto/PayNotifyMessageDTO.java | 3 +- .../com/cyl/h5/service/H5OrderService.java | 4 +- .../com/cyl/wechat/response/WeChatAmount.java | 23 ++++ .../cyl/wechat/response/WeChatPayNotify.java | 39 +++++++ .../com/cyl/wechat/response/WeChatPayer.java | 17 +++ 7 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 ruoyi-mall/src/main/java/com/cyl/h5/controller/PayNotifyController.java create mode 100644 ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/MicroMallOrderSyncMsg.java create mode 100644 ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatAmount.java create mode 100644 ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatPayNotify.java create mode 100644 ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatPayer.java diff --git a/ruoyi-mall/src/main/java/com/cyl/h5/controller/PayNotifyController.java b/ruoyi-mall/src/main/java/com/cyl/h5/controller/PayNotifyController.java new file mode 100644 index 0000000..20e7ea4 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/h5/controller/PayNotifyController.java @@ -0,0 +1,104 @@ +package com.cyl.h5.controller; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import com.cyl.h5.pojo.dto.PayNotifyMessageDTO; +import com.cyl.h5.service.H5OrderService; +import com.cyl.wechat.WechatPayData; +import com.cyl.wechat.response.WeChatPayNotify; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import com.wechat.pay.java.core.notification.RequestParam; +import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; +import io.swagger.annotations.Api; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.parameters.P; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Map; + +/** + * 订单表Controller + * + * @author sjm + * @date 2023-04-05 + */ +@Api(description ="微信回调接口列表") +@RestController +@RequestMapping("/wechat/pay/callback") +public class PayNotifyController { + private static final Logger log = LoggerFactory.getLogger(PayNotifyController.class); + + @Autowired + private H5OrderService h5OrderService; + + private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + + /** + * 微信支付回调 + * @param request + * @throws IOException + */ + @PostMapping("/weChatPayNotify") + public void weChatPayNotify(HttpServletRequest request) throws Exception { + log.info("收到了微信支付回调"); + // 从请求头中获取信息 + String timestamp = request.getHeader("Wechatpay-Timestamp"); + String nonce = request.getHeader("Wechatpay-Nonce"); + String signature = request.getHeader("Wechatpay-Signature"); + String singType = request.getHeader("Wechatpay-Signature-Type"); + String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial"); + // 拿到请求体body + StringBuilder requestBody = new StringBuilder(); + String line; + BufferedReader reader; + reader = request.getReader(); + while (null != (line = reader.readLine())) { + requestBody.append(line); + } + // 构造 RequestParam + RequestParam requestParam = new RequestParam.Builder() + .serialNumber(wechatPayCertificateSerialNumber) + .nonce(nonce) + .signature(signature) + .timestamp(timestamp) + .body(requestBody.toString()) + .build(); + //初始化了 RSAAutoCertificateConfig + Config config = new RSAAutoCertificateConfig.Builder() + .merchantId(WechatPayData.merchantId) + .privateKeyFromPath(WechatPayData.privateKeyPath) + .merchantSerialNumber(WechatPayData.merchantSerialNumber) + .apiV3Key(WechatPayData.apiV3key) + .build(); + // 初始化解析器 NotificationParser + NotificationParser parser = new NotificationParser((NotificationConfig) config); + // 以支付通知回调为例,验签、解密并转换成 Transaction + Transaction transaction = parser.parse(requestParam, Transaction.class); + PayNotifyMessageDTO message = new PayNotifyMessageDTO(); + message.setTradeNo(transaction.getOutTradeNo()); + message.setMemberId(Long.valueOf(transaction.getAttach())); + message.setTradeStatus(transaction.getTradeState()); + if (StrUtil.isEmpty(transaction.getSuccessTime())){ + throw new RuntimeException("微信支付回调失败"); + } + message.setPayTime(formatter.parse(transaction.getSuccessTime().substring(0, transaction.getSuccessTime().indexOf("+")))); + message.setTradeNo(transaction.getTransactionId()); + h5OrderService.payCallBack(message); + } + + +} diff --git a/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/MicroMallOrderSyncMsg.java b/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/MicroMallOrderSyncMsg.java new file mode 100644 index 0000000..3afd7e2 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/MicroMallOrderSyncMsg.java @@ -0,0 +1,29 @@ +package com.cyl.h5.pojo.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +/** + * @author: Jinxin + * @date: 2023/4/16 10:22 + * @Description: + */ +@Getter +@Setter +public class MicroMallOrderSyncMsg { + @ApiModelProperty( + name = "orderId", + value = "订单id", + required = true, + dataType = "String" + ) + private Long orderId; + @ApiModelProperty( + name = "type", + value = "type 0延时关闭 1新下单 2退款", + required = true, + dataType = "Integer" + ) + private Integer type; +} diff --git a/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/PayNotifyMessageDTO.java b/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/PayNotifyMessageDTO.java index d0a589a..061d8b9 100644 --- a/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/PayNotifyMessageDTO.java +++ b/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/PayNotifyMessageDTO.java @@ -1,5 +1,6 @@ package com.cyl.h5.pojo.dto; +import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; import lombok.Data; import java.util.Date; @@ -23,7 +24,7 @@ public class PayNotifyMessageDTO { * USERPAYING:用户支付中(仅付款码支付会返回) * PAYERROR:支付失败(仅付款码支付会返回) */ - private Integer tradeStatus; + private Transaction.TradeStateEnum tradeStatus; /**支付时间**/ private Date payTime; diff --git a/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java b/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java index 7b6bc94..5a21e78 100644 --- a/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java +++ b/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.cyl.h5.pojo.dto.MicroMallOrderSyncMsg; import com.cyl.h5.pojo.dto.OrderCreateDTO; import com.cyl.h5.pojo.dto.OrderProductListDTO; import com.cyl.h5.pojo.dto.PayNotifyMessageDTO; @@ -50,6 +51,7 @@ import com.ruoyi.common.enums.OrderStatus; import com.ruoyi.common.enums.TradeStatusEnum; import com.ruoyi.common.utils.IDGenerator; import com.ruoyi.framework.config.LocalDataUtil; +import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -533,7 +535,7 @@ public class H5OrderService { try{ redisService.lock(redisKey, redisValue, 60); //先判断回信回调的是否未success - if (!TradeStatusEnum.SUCCESS.getStatus().equals(messageDTO.getTradeStatus())){ + if (!Transaction.TradeStateEnum.SUCCESS.equals(messageDTO.getTradeStatus())){ log.error("【订单支付回调】订单状态不是支付成功状态" + messageDTO.getTradeStatus()); throw new RuntimeException(); } diff --git a/ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatAmount.java b/ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatAmount.java new file mode 100644 index 0000000..ff92763 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatAmount.java @@ -0,0 +1,23 @@ +package com.cyl.wechat.response; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +/** + * @author: Jinxin + * @date: 2023/4/18 23:04 + * @Description: + */ +@Getter +@Setter +public class WeChatAmount { + @ApiModelProperty("CNY:人民币,境内商户号仅支持人民币。") + private String currency; + @ApiModelProperty("用户支付币种") + private String payer_currency; + @ApiModelProperty("用户支付金额,单位为分。(指使用优惠券的情况下,这里等于总金额-优惠券金额)") + private Long payer_total; + @ApiModelProperty("订单总金额,单位为分") + private Long total; +} diff --git a/ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatPayNotify.java b/ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatPayNotify.java new file mode 100644 index 0000000..df01ea0 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatPayNotify.java @@ -0,0 +1,39 @@ +package com.cyl.wechat.response; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +/** + * @author: Jinxin + * @date: 2023/4/18 23:03 + * @Description: + */ +@Getter +@Setter +public class WeChatPayNotify { + + @ApiModelProperty("微信支付系统生成的订单号") + private String transaction_id; + @ApiModelProperty("商户号") + private String mchid; + @ApiModelProperty("订单金额信息") + private WeChatAmount amount; + @ApiModelProperty("商户订单号") + private String out_trade_no; + @ApiModelProperty("交易类型") + private String trade_type; + @ApiModelProperty("交易状态") + private String trade_state; + @ApiModelProperty("交易状态描述") + private String trade_state_desc; + @ApiModelProperty("付款银行") + private String bank_type; + @ApiModelProperty("附加数据") + private String attach; + @ApiModelProperty("支付完成时间") + private String success_time; + @ApiModelProperty("支付者信息") + private WeChatPayer payer; + +} diff --git a/ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatPayer.java b/ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatPayer.java new file mode 100644 index 0000000..56f1fbb --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/wechat/response/WeChatPayer.java @@ -0,0 +1,17 @@ +package com.cyl.wechat.response; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +/** + * @author: Jinxin + * @date: 2023/4/18 23:03 + * @Description: + */ +@Getter +@Setter +public class WeChatPayer { + @ApiModelProperty("用户标识") + private String openid; +}