refactor: 微信支付回调处理

This commit is contained in:
Ray.Hao 2024-06-07 08:25:16 +08:00
parent 184bd7c1f3
commit 21a4310e84
7 changed files with 111 additions and 48 deletions

View File

@ -34,7 +34,7 @@ import java.util.Optional;
@RestController
@RequestMapping("/api/v1/orders")
@RequiredArgsConstructor
public class AdminOrderController {
public class OrderController {
private final OmsOrderService orderService;

View File

@ -1,4 +1,4 @@
package com.youlai.mall.order.controller;
package com.youlai.mall.order.controller.app;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.youlai.common.result.PageResult;
@ -26,7 +26,7 @@ import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/app-api/v1/orders")
@RequiredArgsConstructor
public class OrderController {
public class AppOrderController {
private final OrderService orderService;

View File

@ -1,4 +1,4 @@
package com.youlai.mall.order.controller;
package com.youlai.mall.order.controller.common;
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.constant.WxPayConstants;
@ -24,7 +24,7 @@ import org.springframework.web.bind.annotation.*;
@Tag(name = "微信支付接口-APIv3")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v3/wx-pay")
@RequestMapping("/common-api/v3/wx-pay")
@Validated
@Slf4j
public class WxPayController {
@ -38,10 +38,17 @@ public class WxPayController {
@RequestHeader HttpHeaders headers
) throws WxPayException {
SignatureHeader signatureHeader = WxPayUtils.getSignatureHeader(headers);
orderService.handleWxPayOrderNotify(signatureHeader, notifyData);
return new WxPayResult()
.setCode(WxPayConstants.ResultCode.SUCCESS)
.setMessage("成功");
try {
orderService.handleWxPayOrderNotify(signatureHeader, notifyData);
return new WxPayResult()
.setCode(WxPayConstants.ResultCode.SUCCESS)
.setMessage("成功");
} catch (Exception e) {
return new WxPayResult()
.setCode(WxPayConstants.ResultCode.FAIL)
.setMessage("失败");
}
}
@Operation(summary = "微信退款结果回调")
@ -49,11 +56,18 @@ public class WxPayController {
public WxPayResult wxPayRefundNotify(
@Parameter(description = "加密数据") @RequestBody String notifyData,
@Parameter(description = "请求头") @RequestHeader HttpHeaders headers
) throws WxPayException {
) {
SignatureHeader signatureHeader = WxPayUtils.getSignatureHeader(headers);
orderService.handleWxPayRefundNotify(signatureHeader, notifyData);
return new WxPayResult()
.setCode(WxPayConstants.ResultCode.SUCCESS)
.setMessage("成功");
try {
orderService.handleWxPayRefundNotify(signatureHeader, notifyData);
return new WxPayResult()
.setCode(WxPayConstants.ResultCode.SUCCESS)
.setMessage("成功");
} catch (Exception e) {
return new WxPayResult()
.setCode(WxPayConstants.ResultCode.FAIL)
.setMessage("失败");
}
}
}

View File

@ -15,11 +15,10 @@ public enum OrderStatusEnum implements IBaseEnum<Integer> {
PENDING_PAYMENT(0, "待支付"),
PENDING_SHIPMENT(1, "待发货"),
PENDING_RECEIPT(2, "待收货"),
COMPLETED(3, "已完成"),
CANCELLED(4, "已取消"),
RETURN_IN_PROGRESS(5, "退货中"),
RETURNED(6, "已退货");
CANCELLED(3, "已取消"),
RETURN_IN_PROGRESS(4, "退货中"),
RETURNED(5, "已退货"),
REFUNDED(6, "已退款");
OrderStatusEnum(Integer value, String label) {
this.value = value;

View File

@ -4,16 +4,36 @@ import lombok.Data;
import lombok.experimental.Accessors;
/**
* 微信支付回调结果类用于封装微信支付回调处理后的响应结果
*
* <p>该类包含两个属性</p>
* <ul>
* <li>{@code code}表示处理结果的状态码通常为 "SUCCESS" "FAIL"</li>
* <li>{@code message}表示处理结果的描述信息</li>
* </ul>
*
* @author Ray Hao
* <p>示例用法</p>
* <pre>
* WxPayResult result = new WxPayResult()
* .setCode("SUCCESS")
* .setMessage("处理成功");
* </pre>
* @author Ray
* @since 2021-06-04
*/
@Data
@Accessors(chain = true)
public class WxPayResult {
/**
* 处理结果的状态码
* 通常为 "SUCCESS" "FAIL"
*/
private String code;
/**
* 处理结果的描述信息
*/
private String message;
}

View File

@ -402,51 +402,81 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
return this.removeById(orderId);
}
/**
* 处理微信支付结果通知
*
* @param signatureHeader 签名头信息
* @param notifyData 通知数据
* @throws WxPayException 微信支付异常
*/
@Override
public void handleWxPayOrderNotify(SignatureHeader signatureHeader, String notifyData) throws WxPayException {
log.info("开始处理支付结果通知");
// 解密支付通知内容
final WxPayOrderNotifyV3Result.DecryptNotifyResult result = this.wxPayService.parseOrderNotifyV3Result(
// 记录开始处理支付结果通知的日志
log.info("开始处理订单支付结果通知");
// 解密支付通知数据获取支付结果
WxPayOrderNotifyV3Result.DecryptNotifyResult result = this.wxPayService.parseOrderNotifyV3Result(
notifyData,
signatureHeader
).getResult();
// 记录支付通知解密成功的日志并打印解密结果
log.debug("支付通知解密成功:{}", JSONUtil.toJsonStr(result));
// 根据商户订单号查询订单
// 获取商户订单号
String outTradeNo = result.getOutTradeNo();
// 根据商户订单号查询订单信息
OmsOrder order = this.getOne(new LambdaQueryWrapper<OmsOrder>()
.eq(OmsOrder::getOutTradeNo, result.getOutTradeNo())
.eq(OmsOrder::getOutTradeNo, outTradeNo)
);
// 支付成功处理
if (WxPayConstants.WxpayTradeStatus.SUCCESS.equals(result.getTradeState())) {
order.setStatus(OrderStatusEnum.PENDING_SHIPMENT.getValue());
order.setTransactionId(result.getTransactionId());
order.setPaymentTime(new Date());
this.updateById(order);
}
Assert.isTrue(order != null, "订单不存在");
// 支付成功删除购物车已勾选的商品
rabbitTemplate
.convertAndSend(RabbitMqConstants.CART_EXCHANGE, RabbitMqConstants.CART_REMOVE_ROUTING_KEY, order.getOrderNo());
// 如果支付状态为成功更新订单状态和相关信息
if (WxPayConstants.WxpayTradeStatus.SUCCESS.equals(result.getTradeState())) {
// 设置订单状态为待发货
order.setStatus(OrderStatusEnum.PENDING_SHIPMENT.getValue());
// 设置交易流水号
order.setTransactionId(result.getTransactionId());
// 设置支付时间为当前时间
order.setPaymentTime(new Date());
// 更新订单信息
this.updateById(order);
// 支付成功后删除购物车中已勾选的商品
rabbitTemplate
.convertAndSend(RabbitMqConstants.CART_EXCHANGE,
RabbitMqConstants.CART_REMOVE_ROUTING_KEY,
order.getOrderNo());
}
}
/**
* 处理微信退款结果通知
*
* @param signatureHeader 签名头信息
* @param notifyData 通知数据
* @throws WxPayException 微信支付异常
*/
@Override
public void handleWxPayRefundNotify(SignatureHeader signatureHeader, String notifyData) throws WxPayException {
log.info("开始处理退款结果通知");
// 解密支付通知内容
final WxPayRefundNotifyV3Result.DecryptNotifyResult result = this.wxPayService.parseRefundNotifyV3Result(notifyData, signatureHeader).getResult();
log.debug("退款通知解密成功:[{}]", result.toString());
// 根据商户退款单号查询订单
QueryWrapper<OmsOrder> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(OmsOrder::getOutTradeNo, result.getOutTradeNo());
OmsOrder orderDO = this.getOne(wrapper);
log.debug("退款通知解密成功:{}", JSONUtil.toJsonStr(result));
// 获取商户订单号
String outTradeNo = result.getOutTradeNo();
// 根据商户订单号查询订单信息
OmsOrder order = this.getOne(new LambdaQueryWrapper<OmsOrder>()
.eq(OmsOrder::getOutTradeNo, outTradeNo)
);
Assert.isTrue(order != null, "订单不存在");
// 退款成功处理
if (WxPayConstants.RefundStatus.SUCCESS.equals(result.getRefundStatus())) {
orderDO.setStatus(OrderStatusEnum.COMPLETED.getValue());
orderDO.setRefundId(result.getRefundId());
this.updateById(orderDO);
order.setStatus(OrderStatusEnum.REFUNDED.getValue());
order.setRefundId(result.getRefundId());
this.updateById(order);
}
log.info("账单更新成功");
}

View File

@ -38,7 +38,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@SpringBootTest
@AutoConfigureMockMvc
@Slf4j
public class OrderControllerTest {
public class AppOrderControllerTest {
@Autowired
@ -189,7 +189,7 @@ public class OrderControllerTest {
private void payOrder(String orderSn, HttpHeaders headers) throws Exception {
OrderPayForm paymentForm = new OrderPayForm();
paymentForm.setOrderSn(orderSn);
paymentForm.setOrderNo(orderSn);
paymentForm.setPaymentMethod(PaymentMethodEnum.BALANCE);
mockMvc.perform(post("/app-api/v1/orders/payment")
.headers(headers)