From 16e57387dba97f41b1d7fad538c8dce3a5488aea Mon Sep 17 00:00:00 2001 From: liangzai <2440983361@qq.com> Date: Sun, 11 May 2025 23:43:01 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=AE=8C=E5=96=84=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E9=80=80=E6=AC=BE=E6=97=B6=E9=97=B4=202=E3=80=81=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98=E5=BC=80=E9=80=9A?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E4=BC=9A=E5=91=98=E5=A4=B1=E8=B4=A5=E9=80=80?= =?UTF-8?q?=E6=AC=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../logic/pay/wechatpayrefundcallbacklogic.go | 96 +++++++++++++++---- .../api/internal/queue/paySuccessNotify.go | 6 ++ 2 files changed, 83 insertions(+), 19 deletions(-) diff --git a/app/user/cmd/api/internal/logic/pay/wechatpayrefundcallbacklogic.go b/app/user/cmd/api/internal/logic/pay/wechatpayrefundcallbacklogic.go index 9dc83c6..99eb604 100644 --- a/app/user/cmd/api/internal/logic/pay/wechatpayrefundcallbacklogic.go +++ b/app/user/cmd/api/internal/logic/pay/wechatpayrefundcallbacklogic.go @@ -2,9 +2,13 @@ package pay import ( "context" + "database/sql" "net/http" "qnc-server/app/user/cmd/api/internal/svc" + "strings" + "time" + "github.com/pkg/errors" "github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic" "github.com/zeromicro/go-zero/core/logx" ) @@ -23,33 +27,87 @@ func NewWechatPayRefundCallbackLogic(ctx context.Context, svcCtx *svc.ServiceCon } } +// handleQueryOrderRefund 处理查询订单退款 +func (l *WechatPayRefundCallbackLogic) handleQueryOrderRefund(orderNo string, status refunddomestic.Status) error { + order, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, orderNo) + if err != nil { + return errors.Wrapf(err, "查找查询订单信息失败: %s", orderNo) + } + + if status == refunddomestic.STATUS_SUCCESS { + order.Status = "refunded" + order.RefundTime = sql.NullTime{ + Time: time.Now(), + Valid: true, + } + } else if status == refunddomestic.STATUS_ABNORMAL { + return nil // 异常状态直接返回 + } else { + return nil // 其他状态直接返回 + } + + if err := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); err != nil { + return errors.Wrapf(err, "更新查询订单状态失败: %s", orderNo) + } + return nil +} + +// handleAgentOrderRefund 处理代理会员订单退款 +func (l *WechatPayRefundCallbackLogic) handleAgentOrderRefund(orderNo string, status refunddomestic.Status) error { + order, err := l.svcCtx.AgentMembershipRechargeOrderModel.FindOneByOrderNo(l.ctx, orderNo) + if err != nil { + return errors.Wrapf(err, "查找代理会员订单信息失败: %s", orderNo) + } + + if status == refunddomestic.STATUS_SUCCESS { + order.Status = "refunded" + } else if status == refunddomestic.STATUS_ABNORMAL { + return nil // 异常状态直接返回 + } else { + return nil // 其他状态直接返回 + } + + if err := l.svcCtx.AgentMembershipRechargeOrderModel.UpdateWithVersion(l.ctx, nil, order); err != nil { + return errors.Wrapf(err, "更新代理会员订单状态失败: %s", orderNo) + } + return nil +} + +// sendSuccessResponse 发送成功响应 +func (l *WechatPayRefundCallbackLogic) sendSuccessResponse(w http.ResponseWriter) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("success")) +} + func (l *WechatPayRefundCallbackLogic) WechatPayRefundCallback(w http.ResponseWriter, r *http.Request) error { + // 1. 处理微信退款通知 notification, err := l.svcCtx.WechatPayService.HandleRefundNotification(l.ctx, r) if err != nil { - logx.Errorf("微信退款回调,%v", err) - return nil - } - order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, *notification.OutTradeNo) - if findOrderErr != nil { - logx.Errorf("微信退款回调,查找订单信息失败: %+v", findOrderErr) + logx.Errorf("微信退款回调处理失败: %v", err) + l.sendSuccessResponse(w) return nil } - switch *notification.Status { - case refunddomestic.STATUS_SUCCESS: - order.Status = "refunded" - case refunddomestic.STATUS_ABNORMAL: - // 异常 - return nil + orderNo := *notification.OutTradeNo + var processErr error + + // 2. 根据订单号前缀处理不同类型的订单 + switch { + case strings.HasPrefix(orderNo, "Q_"): + processErr = l.handleQueryOrderRefund(orderNo, *notification.Status) + case strings.HasPrefix(orderNo, "A_"): + processErr = l.handleAgentOrderRefund(orderNo, *notification.Status) default: - return nil + // 兼容旧订单,假设没有前缀的是查询订单 + processErr = l.handleQueryOrderRefund(orderNo, *notification.Status) } - if updateErr := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); updateErr != nil { - logx.Errorf("微信退款回调,更新订单失败%+v", updateErr) - return nil + + // 3. 处理错误并响应 + if processErr != nil { + logx.Errorf("处理退款订单失败: %v", processErr) } - // 响应微信回调成功 - w.WriteHeader(http.StatusOK) - _, _ = w.Write([]byte("success")) // 确保只写入一次响应 + + // 无论处理是否成功,都返回成功响应给微信 + l.sendSuccessResponse(w) return nil } diff --git a/app/user/cmd/api/internal/queue/paySuccessNotify.go b/app/user/cmd/api/internal/queue/paySuccessNotify.go index 1b04ed7..918e3ff 100644 --- a/app/user/cmd/api/internal/queue/paySuccessNotify.go +++ b/app/user/cmd/api/internal/queue/paySuccessNotify.go @@ -2,6 +2,7 @@ package queue import ( "context" + "database/sql" "encoding/hex" "encoding/json" "fmt" @@ -13,6 +14,7 @@ import ( "qnc-server/pkg/lzkit/lzUtils" "regexp" "strings" + "time" "github.com/hibiken/asynq" "github.com/zeromicro/go-zero/core/logx" @@ -181,6 +183,10 @@ func (l *PaySuccessNotifyUserHandler) handleError(ctx context.Context, err error logx.Errorf("支付宝退款成功, orderID: %d", order.Id) // 更新订单状态为退款 order.Status = "refunded" + order.RefundTime = sql.NullTime{ + Time: time.Now(), + Valid: true, + } updateOrderErr := l.svcCtx.OrderModel.UpdateWithVersion(ctx, nil, order) if updateOrderErr != nil { logx.Errorf("更新订单状态失败,订单ID: %d, 错误: %v", order.Id, updateOrderErr)