Browse Source

feat(payment): 添加订单支付状态更新功能并优化日志记录

- 在 ShopOrderController 中添加更新订单支付状态的 API 接口- 在 ShopOrderService 中实现 getByOrderNo 和 syncPaymentStatus 方法- 在 WechatNativeStrategy 中添加创建订单和查询支付状态的日志记录
- 优化订单号生成逻辑,支持使用请求中的订单号
pan
科技小王子 1 month ago
parent
commit
a7c51c7f80
  1. 6
      src/main/java/com/gxwebsoft/payment/strategy/WechatNativeStrategy.java
  2. 59
      src/main/java/com/gxwebsoft/shop/controller/ShopOrderController.java
  3. 32
      src/main/java/com/gxwebsoft/shop/dto/UpdatePaymentStatusRequest.java
  4. 13
      src/main/java/com/gxwebsoft/shop/service/OrderBusinessService.java
  5. 21
      src/main/java/com/gxwebsoft/shop/service/ShopOrderService.java
  6. 54
      src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java

6
src/main/java/com/gxwebsoft/payment/strategy/WechatNativeStrategy.java

@ -264,6 +264,9 @@ public class WechatNativeStrategy implements PaymentStrategy {
prepayRequest.setOutTradeNo(orderNo); prepayRequest.setOutTradeNo(orderNo);
prepayRequest.setDescription(request.getEffectiveDescription()); prepayRequest.setDescription(request.getEffectiveDescription());
log.info("创建微信支付订单 - 订单号: {}, 商户号: {}, 金额: {}分",
orderNo, paymentConfig.getMchId(), request.getAmountInCents());
// 设置回调URL(必填字段) // 设置回调URL(必填字段)
String notifyUrl = null; String notifyUrl = null;
if (StringUtils.hasText(request.getNotifyUrl())) { if (StringUtils.hasText(request.getNotifyUrl())) {
@ -289,6 +292,9 @@ public class WechatNativeStrategy implements PaymentStrategy {
*/ */
private PaymentResponse queryWechatPaymentStatus(String orderNo, Integer tenantId, Payment paymentConfig, Config wxPayConfig) throws PaymentException { private PaymentResponse queryWechatPaymentStatus(String orderNo, Integer tenantId, Payment paymentConfig, Config wxPayConfig) throws PaymentException {
try { try {
log.info("开始查询微信支付状态 - 订单号: {}, 商户号: {}, 租户ID: {}",
orderNo, paymentConfig.getMchId(), tenantId);
// 构建查询请求 // 构建查询请求
QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest(); QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
queryRequest.setOutTradeNo(orderNo); queryRequest.setOutTradeNo(orderNo);

59
src/main/java/com/gxwebsoft/shop/controller/ShopOrderController.java

@ -22,6 +22,7 @@ import com.gxwebsoft.shop.task.OrderAutoCancelTask;
import com.gxwebsoft.shop.entity.ShopOrder; import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.param.ShopOrderParam; import com.gxwebsoft.shop.param.ShopOrderParam;
import com.gxwebsoft.shop.dto.OrderCreateRequest; import com.gxwebsoft.shop.dto.OrderCreateRequest;
import com.gxwebsoft.shop.dto.UpdatePaymentStatusRequest;
import com.gxwebsoft.common.core.web.ApiResult; import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
@ -460,6 +461,64 @@ public class ShopOrderController extends BaseController {
return "fail"; return "fail";
} }
@Operation(summary = "更新订单支付状态", description = "用户支付成功后主动同步订单状态")
@PutMapping("/payment-status")
public ApiResult<?> updateOrderPaymentStatus(@RequestBody UpdatePaymentStatusRequest request) {
logger.info("收到更新订单支付状态请求: orderNo={}, paymentStatus={}, transactionId={}",
request.getOrderNo(), request.getPaymentStatus(), request.getTransactionId());
final User loginUser = getLoginUser();
if (loginUser == null) {
return fail("请先登录");
}
try {
// 参数验证
if (StrUtil.isBlank(request.getOrderNo())) {
return fail("订单号不能为空");
}
// 查询订单
ShopOrder order = shopOrderService.getByOrderNo(request.getOrderNo(), loginUser.getTenantId());
if (order == null) {
return fail("订单不存在");
}
// 权限验证:只能更新自己的订单
if (!order.getUserId().equals(loginUser.getUserId())) {
return fail("无权限操作此订单");
}
// 如果订单已经是支付成功状态,直接返回成功
if (order.getPayStatus()) {
logger.info("订单已经是支付成功状态,无需更新: orderNo={}", request.getOrderNo());
return success("订单状态已是最新");
}
// 调用支付状态同步服务
boolean updated = shopOrderService.syncPaymentStatus(
request.getOrderNo(),
request.getPaymentStatus(),
request.getTransactionId(),
request.getPayTime(),
loginUser.getTenantId()
);
if (updated) {
logger.info("订单支付状态更新成功: orderNo={}, paymentStatus={}",
request.getOrderNo(), request.getPaymentStatus());
return success("订单状态更新成功");
} else {
logger.warn("订单支付状态更新失败: orderNo={}", request.getOrderNo());
return fail("订单状态更新失败");
}
} catch (Exception e) {
logger.error("更新订单支付状态异常: orderNo={}, error={}", request.getOrderNo(), e.getMessage(), e);
return fail("更新订单状态失败: " + e.getMessage());
}
}
/** /**
* 检查是否有订单取消权限 * 检查是否有订单取消权限
*/ */

32
src/main/java/com/gxwebsoft/shop/dto/UpdatePaymentStatusRequest.java

@ -0,0 +1,32 @@
package com.gxwebsoft.shop.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 更新订单支付状态请求DTO
*
* @author 科技小王子
* @since 2025-08-30
*/
@Data
@Schema(name = "UpdatePaymentStatusRequest", description = "更新订单支付状态请求")
public class UpdatePaymentStatusRequest {
@Schema(description = "订单号", required = true)
@NotBlank(message = "订单号不能为空")
private String orderNo;
@Schema(description = "支付状态:1=支付成功,0=支付失败", required = true)
@NotNull(message = "支付状态不能为空")
private Integer paymentStatus;
@Schema(description = "微信交易号")
private String transactionId;
@Schema(description = "支付时间,格式:yyyy-MM-dd HH:mm:ss")
private String payTime;
}

13
src/main/java/com/gxwebsoft/shop/service/OrderBusinessService.java

@ -242,11 +242,14 @@ public class OrderBusinessService {
log.debug("构建订单对象 - 租户ID:{},用户ID:{}", shopOrder.getTenantId(), shopOrder.getUserId()); log.debug("构建订单对象 - 租户ID:{},用户ID:{}", shopOrder.getTenantId(), shopOrder.getUserId());
// 生成订单号
shopOrder.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId()));
// if (shopOrder.getOrderNo() == null) {
// shopOrder.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId()));
// }
// 生成订单号(如果请求中没有提供)
if (shopOrder.getOrderNo() == null || shopOrder.getOrderNo().trim().isEmpty()) {
String generatedOrderNo = Long.toString(IdUtil.getSnowflakeNextId());
shopOrder.setOrderNo(generatedOrderNo);
log.info("生成新订单号: {}", generatedOrderNo);
} else {
log.info("使用请求中的订单号: {}", shopOrder.getOrderNo());
}
// 设置默认备注 // 设置默认备注
if (shopOrder.getComments() == null) { if (shopOrder.getComments() == null) {

21
src/main/java/com/gxwebsoft/shop/service/ShopOrderService.java

@ -55,4 +55,25 @@ public interface ShopOrderService extends IService<ShopOrder> {
* @return 订单总金额 * @return 订单总金额
*/ */
BigDecimal total(); BigDecimal total();
/**
* 根据订单号查询订单
*
* @param orderNo 订单号
* @param tenantId 租户ID
* @return ShopOrder
*/
ShopOrder getByOrderNo(String orderNo, Integer tenantId);
/**
* 同步支付状态
*
* @param orderNo 订单号
* @param paymentStatus 支付状态1=支付成功0=支付失败
* @param transactionId 微信交易号
* @param payTime 支付时间
* @param tenantId 租户ID
* @return 是否更新成功
*/
boolean syncPaymentStatus(String orderNo, Integer paymentStatus, String transactionId, String payTime, Integer tenantId);
} }

54
src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java

@ -245,6 +245,11 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
request.setOutTradeNo(order.getOrderNo()); request.setOutTradeNo(order.getOrderNo());
request.setAttach(order.getTenantId().toString()); request.setAttach(order.getTenantId().toString());
System.out.println("=== 关键信息确认 ===");
System.out.println("发送给微信的订单号(OutTradeNo): " + order.getOrderNo());
System.out.println("商户号(MchId): " + payment.getMchId());
System.out.println("应用ID(AppId): " + payment.getAppId());
// 设置回调地址 // 设置回调地址
String notifyUrl = config.getServerUrl() + "/system/wx-pay/notify/" + order.getTenantId(); String notifyUrl = config.getServerUrl() + "/system/wx-pay/notify/" + order.getTenantId();
if (active.equals("dev")) { if (active.equals("dev")) {
@ -1011,5 +1016,54 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
} }
} }
@Override
public ShopOrder getByOrderNo(String orderNo, Integer tenantId) {
return this.lambdaQuery()
.eq(ShopOrder::getOrderNo, orderNo)
.eq(ShopOrder::getTenantId, tenantId)
.one();
}
@Override
public boolean syncPaymentStatus(String orderNo, Integer paymentStatus, String transactionId, String payTime, Integer tenantId) {
try {
// 查询订单
ShopOrder order = getByOrderNo(orderNo, tenantId);
if (order == null) {
log.warn("同步支付状态失败:订单不存在, orderNo={}, tenantId={}", orderNo, tenantId);
return false;
}
// 如果订单已经是支付成功状态,不需要更新
if (order.getPayStatus() && paymentStatus == 1) {
log.info("订单已经是支付成功状态,无需更新: orderNo={}", orderNo);
return true;
}
// 更新订单状态
boolean updated = this.lambdaUpdate()
.eq(ShopOrder::getOrderNo, orderNo)
.eq(ShopOrder::getTenantId, tenantId)
.set(ShopOrder::getPayStatus, paymentStatus == 1)
.set(transactionId != null, ShopOrder::getTransactionId, transactionId)
.set(payTime != null, ShopOrder::getPayTime, payTime)
.set(ShopOrder::getUpdateTime, LocalDateTime.now())
.update();
if (updated) {
log.info("订单支付状态同步成功: orderNo={}, paymentStatus={}, transactionId={}",
orderNo, paymentStatus, transactionId);
} else {
log.warn("订单支付状态同步失败: orderNo={}, paymentStatus={}", orderNo, paymentStatus);
}
return updated;
} catch (Exception e) {
log.error("同步订单支付状态异常: orderNo={}, error={}", orderNo, e.getMessage(), e);
return false;
}
}
} }

Loading…
Cancel
Save