feat(payment): 添加手动更新支付状态功能并优化支付成功处理逻辑- 新增手动更新支付状态接口,用于异常情况处理

-优化支付成功处理逻辑,增加日志记录和业务逻辑触发
- 添加支付回调处理完整实现文档,便于测试和扩展
-调整订单创建逻辑,移除重复代码
This commit is contained in:
2025-08-30 17:49:10 +08:00
parent 797cfdf6c2
commit e0d0760216
5 changed files with 270 additions and 31 deletions

View File

@@ -6,6 +6,7 @@ import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.payment.constants.PaymentConstants;
import com.gxwebsoft.payment.dto.PaymentRequest;
import com.gxwebsoft.payment.dto.PaymentResponse;
import com.gxwebsoft.payment.dto.PaymentStatusUpdateRequest;
import com.gxwebsoft.payment.enums.PaymentType;
import com.gxwebsoft.payment.exception.PaymentException;
import com.gxwebsoft.payment.service.PaymentService;
@@ -253,4 +254,24 @@ public class PaymentController extends BaseController {
return fail(PaymentConstants.ErrorMessage.SYSTEM_ERROR);
}
}
@Operation(summary = "手动更新支付状态", description = "用于手动同步支付状态,通常用于异常情况处理")
@PutMapping("/update-status")
public ApiResult<?> updatePaymentStatus(@Valid @RequestBody PaymentStatusUpdateRequest request) {
log.info("收到支付状态更新请求: {}", request);
try {
// 查询并更新支付状态
PaymentResponse response = paymentService.queryPayment(
request.getOrderNo(),
PaymentType.WECHAT_NATIVE,
request.getTenantId()
);
return this.<PaymentResponse>success("支付状态更新成功", response);
} catch (Exception e) {
log.error("更新支付状态失败: {}", e.getMessage(), e);
return fail("更新支付状态失败: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,41 @@
package com.gxwebsoft.payment.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
/**
* 支付状态更新请求DTO
* 用于手动更新支付状态的请求参数
*
* @author 科技小王子
* @since 2025-01-26
*/
@Data
@Schema(name = "支付状态更新请求", description = "用于手动更新支付状态")
public class PaymentStatusUpdateRequest {
@Schema(description = "订单号", required = true, example = "ORDER_1756544921075")
@NotBlank(message = "订单号不能为空")
private String orderNo;
@Schema(description = "租户ID", required = true, example = "10398")
@NotNull(message = "租户ID不能为空")
@Positive(message = "租户ID必须为正数")
private Integer tenantId;
@Schema(description = "第三方交易号", example = "4200001234567890123")
private String transactionId;
@Schema(description = "支付时间", example = "2025-01-26T10:30:00")
private String payTime;
@Override
public String toString() {
return String.format("PaymentStatusUpdateRequest{orderNo='%s', tenantId=%d, transactionId='%s', payTime='%s'}",
orderNo, tenantId, transactionId, payTime);
}
}

View File

@@ -291,18 +291,76 @@ public class WxPayNotifyService {
*/
private void pushPaymentNotification(ShopOrder order, Transaction transaction) {
try {
// TODO: 实现支付结果通知推送逻辑
// 可以在这里添加具体的通知推送实现,比如:
// - 发送邮件通知
// - 发送短信通知
// - 推送到消息队列
// - 调用第三方通知接口等
log.info("开始推送支付成功通知, 订单号: {}, 交易号: {}, 用户ID: {}",
order.getOrderNo(), transaction.getTransactionId(), order.getUserId());
log.debug("支付结果通知推送成功, 订单号: {}, 交易号: {}",
// 1. 记录支付成功日志
logPaymentSuccess(order, transaction);
// 2. 发送支付成功通知(可扩展)
sendPaymentSuccessNotification(order, transaction);
// 3. 触发其他业务逻辑(可扩展)
triggerPostPaymentActions(order, transaction);
log.info("支付结果通知推送完成, 订单号: {}, 交易号: {}",
order.getOrderNo(), transaction.getTransactionId());
} catch (Exception e) {
log.warn("支付结果通知推送失败, 订单号: {}, 错误: {}", order.getOrderNo(), e.getMessage());
// 推送失败不影响主流程,只记录日志
}
}
/**
* 记录支付成功日志
*/
private void logPaymentSuccess(ShopOrder order, Transaction transaction) {
try {
log.info("=== 支付成功详细信息 ===");
log.info("订单号: {}", order.getOrderNo());
log.info("微信交易号: {}", transaction.getTransactionId());
log.info("支付金额: {}元", order.getPayPrice());
log.info("支付时间: {}", transaction.getSuccessTime());
log.info("用户ID: {}", order.getUserId());
log.info("租户ID: {}", order.getTenantId());
log.info("订单标题: {}", order.getTitle());
log.info("========================");
} catch (Exception e) {
log.warn("记录支付成功日志失败: {}", e.getMessage());
}
}
/**
* 发送支付成功通知
*/
private void sendPaymentSuccessNotification(ShopOrder order, Transaction transaction) {
try {
// TODO: 实现具体的通知逻辑
// 1. 发送邮件通知
// 2. 发送短信通知
// 3. 站内消息通知
// 4. 微信模板消息通知
log.debug("支付成功通知发送完成, 订单号: {}", order.getOrderNo());
} catch (Exception e) {
log.warn("发送支付成功通知失败, 订单号: {}, 错误: {}", order.getOrderNo(), e.getMessage());
}
}
/**
* 触发支付成功后的其他业务逻辑
*/
private void triggerPostPaymentActions(ShopOrder order, Transaction transaction) {
try {
// TODO: 根据业务需求实现
// 1. 开通网站服务
// 2. 激活会员权益
// 3. 发放积分奖励
// 4. 触发营销活动
log.debug("支付后业务逻辑触发完成, 订单号: {}", order.getOrderNo());
} catch (Exception e) {
log.warn("触发支付后业务逻辑失败, 订单号: {}, 错误: {}", order.getOrderNo(), e.getMessage());
}
}
}

View File

@@ -131,30 +131,9 @@ public class ShopOrderController extends BaseController {
User loginUser = getLoginUser();
if (loginUser != null) {
shopOrder.setUserId(loginUser.getUserId());
shopOrder.setOpenid(loginUser.getOpenid());
shopOrder.setPayUserId(loginUser.getUserId());
if (shopOrder.getOrderNo() == null) {
shopOrder.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId()));
}
if (shopOrder.getComments() == null) {
shopOrder.setComments("暂无");
}
// 微信支付(商品金额不能为0)
if (shopOrder.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) {
return fail("商品金额不能为0");
}
// 百色中学项目捐赠金额不能低于20元
if (shopOrder.getTenantId().equals(10324) && shopOrder.getTotalPrice().compareTo(new BigDecimal("10")) < 0) {
return fail("捐款金额最低不能少于10元感谢您的爱心捐赠^_^");
}
// 测试支付
if (loginUser.getPhone().equals("13737128880")) {
shopOrder.setPrice(new BigDecimal("0.01"));
shopOrder.setTotalPrice(new BigDecimal("0.01"));
}
if (shopOrderService.save(shopOrder)) {
return success("下单成功", shopOrderService.createWxOrder(shopOrder));
}
}
if (shopOrderService.save(shopOrder)) {
return success("添加成功");
}
return fail("添加失败");
}