diff --git a/app/user/cmd/api/internal/logic/agent/applyforagentlogic.go b/app/user/cmd/api/internal/logic/agent/applyforagentlogic.go index 233042d..99f39da 100644 --- a/app/user/cmd/api/internal/logic/agent/applyforagentlogic.go +++ b/app/user/cmd/api/internal/logic/agent/applyforagentlogic.go @@ -70,7 +70,7 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type // } insertResult, userInsertErr := l.svcCtx.UserModel.Insert(transCtx, session, user) if userInsertErr != nil { - return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 数据库插入新用户失败, mobile%s, err: %+v", encryptedMobile, err) + return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 数据库插入新用户失败, mobile%s, err: %+v", encryptedMobile, userInsertErr) } lastId, lastInsertIdErr := insertResult.LastInsertId() if lastInsertIdErr != nil { diff --git a/app/user/cmd/api/internal/logic/pay/alipaycallbacklogic.go b/app/user/cmd/api/internal/logic/pay/alipaycallbacklogic.go index 6c17464..eb16430 100644 --- a/app/user/cmd/api/internal/logic/pay/alipaycallbacklogic.go +++ b/app/user/cmd/api/internal/logic/pay/alipaycallbacklogic.go @@ -2,7 +2,6 @@ package pay import ( "context" - "database/sql" "fmt" "net/http" "strings" @@ -163,7 +162,7 @@ func (l *AlipayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter, } else { logx.Infof("代理会员新购或升级成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) } - agentModel.MembershipExpiryTime = RenewMembership(agentModel.MembershipExpiryTime) + agentModel.MembershipExpiryTime = lzUtils.RenewMembership(agentModel.MembershipExpiryTime) if updateErr := l.svcCtx.AgentModel.UpdateWithVersion(l.ctx, nil, agentModel); updateErr != nil { return fmt.Errorf("修改代理信息失败: %+v", updateErr) @@ -183,24 +182,6 @@ func (l *AlipayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter, alipay.ACKNotification(w) return nil } -func RenewMembership(expiry sql.NullTime) sql.NullTime { - // 确定基准时间 - var baseTime time.Time - if expiry.Valid { - baseTime = expiry.Time - } else { - baseTime = time.Now() - } - - // 增加一年(自动处理闰年) - newTime := baseTime.AddDate(1, 0, 0) - - // 返回始终有效的 NullTime - return sql.NullTime{ - Time: newTime, - Valid: true, - } -} func (l *AlipayCallbackLogic) handleRefund(order *model.AgentMembershipRechargeOrder) error { ctx := context.Background() diff --git a/app/user/cmd/api/internal/logic/pay/wechatpaycallbacklogic.go b/app/user/cmd/api/internal/logic/pay/wechatpaycallbacklogic.go index 2e0e304..6f5a11d 100644 --- a/app/user/cmd/api/internal/logic/pay/wechatpaycallbacklogic.go +++ b/app/user/cmd/api/internal/logic/pay/wechatpaycallbacklogic.go @@ -2,14 +2,19 @@ package pay import ( "context" + "fmt" "net/http" + "strings" "time" "tydata-server/app/user/cmd/api/internal/service" + "tydata-server/app/user/model" "tydata-server/pkg/lzkit/lzUtils" "tydata-server/app/user/cmd/api/internal/svc" + "github.com/wechatpay-apiv3/wechatpay-go/services/payments" "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/core/stores/sqlx" ) type WechatPayCallbackLogic struct { @@ -32,6 +37,23 @@ func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *htt logx.Errorf("微信支付回调,%v", err) return nil } + + // 根据订单号前缀判断订单类型 + orderNo := *notification.OutTradeNo + if strings.HasPrefix(orderNo, "Q_") { + // 查询订单处理 + return l.handleQueryOrderPayment(w, notification) + } else if strings.HasPrefix(orderNo, "A_") { + // 代理会员订单处理 + return l.handleAgentVipOrderPayment(w, notification) + } else { + // 兼容旧订单,假设没有前缀的是查询订单 + return l.handleQueryOrderPayment(w, notification) + } +} + +// 处理查询订单支付 +func (l *WechatPayCallbackLogic) handleQueryOrderPayment(w http.ResponseWriter, notification *payments.Transaction) error { order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, *notification.OutTradeNo) if findOrderErr != nil { logx.Errorf("微信支付回调,查找订单信息失败: %+v", findOrderErr) @@ -43,11 +65,13 @@ func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *htt logx.Errorf("微信支付回调,金额不一致") return nil } + if order.Status != "pending" { w.WriteHeader(http.StatusOK) - _, _ = w.Write([]byte("success")) // 确保只写入一次响应 + _, _ = w.Write([]byte("success")) return nil } + switch *notification.TradeState { case service.TradeStateSuccess: order.Status = "paid" @@ -60,11 +84,13 @@ func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *htt default: return nil } + order.PlatformOrderId = lzUtils.StringToNullString(*notification.TransactionId) if updateErr := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); updateErr != nil { logx.Errorf("微信支付回调,更新订单失败%+v", updateErr) return nil } + if order.Status == "paid" { if asyncErr := l.svcCtx.AsynqService.SendQueryTask(order.Id); asyncErr != nil { logx.Errorf("异步任务调度失败: %v", asyncErr) @@ -72,8 +98,118 @@ func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *htt } } - // 响应微信回调成功 w.WriteHeader(http.StatusOK) - _, _ = w.Write([]byte("success")) // 确保只写入一次响应 + _, _ = w.Write([]byte("success")) + return nil +} + +// 处理代理会员订单支付 +func (l *WechatPayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter, notification *payments.Transaction) error { + agentOrder, findAgentOrderErr := l.svcCtx.AgentMembershipRechargeOrderModel.FindOneByOrderNo(l.ctx, *notification.OutTradeNo) + if findAgentOrderErr != nil { + logx.Errorf("微信支付回调,查找代理会员订单失败: %+v", findAgentOrderErr) + return nil + } + + if agentOrder.Status != "pending" { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("success")) + return nil + } + + user, err := l.svcCtx.UserModel.FindOne(l.ctx, agentOrder.UserId) + if err != nil { + logx.Errorf("微信支付回调,查找用户失败: %+v", err) + return nil + } + + amount := lzUtils.ToWechatAmount(agentOrder.Amount) + if user.Inside != 1 { + if amount != *notification.Amount.Total { + logx.Errorf("微信支付回调,金额不一致") + return nil + } + } + + switch *notification.TradeState { + case service.TradeStateSuccess: + agentOrder.Status = "paid" + default: + return nil + } + + if agentOrder.Status == "paid" { + err = l.svcCtx.AgentModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error { + agentModel, err := l.svcCtx.AgentModel.FindOne(transCtx, agentOrder.AgentId) + if err != nil { + return fmt.Errorf("查找代理信息失败: %+v", err) + } + + agentOrder.PlatformOrderId = lzUtils.StringToNullString(*notification.TransactionId) + if updateErr := l.svcCtx.AgentMembershipRechargeOrderModel.UpdateWithVersion(l.ctx, nil, agentOrder); updateErr != nil { + return fmt.Errorf("修改代理会员订单信息失败: %+v", updateErr) + } + + // 设置会员等级 + agentModel.LevelName = agentOrder.LevelName + + // 延长会员时间 + isRenewal := agentModel.LevelName == agentOrder.LevelName && agentModel.MembershipExpiryTime.Valid + if isRenewal { + logx.Infof("代理会员续费成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) + } else { + logx.Infof("代理会员新购或升级成功,会员ID:%d,等级:%s", agentModel.Id, agentModel.LevelName) + } + agentModel.MembershipExpiryTime = lzUtils.RenewMembership(agentModel.MembershipExpiryTime) + + if updateErr := l.svcCtx.AgentModel.UpdateWithVersion(l.ctx, nil, agentModel); updateErr != nil { + return fmt.Errorf("修改代理信息失败: %+v", updateErr) + } + return nil + }) + + if err != nil { + logx.Errorf("微信支付回调,处理代理会员订单失败: %+v", err) + refundErr := l.handleRefund(agentOrder) + if refundErr != nil { + logx.Errorf("微信支付回调,退款失败: %+v", refundErr) + } + return nil + } + } + + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("success")) + return nil +} + +func (l *WechatPayCallbackLogic) handleRefund(order *model.AgentMembershipRechargeOrder) error { + ctx := context.Background() + // 退款 + if order.PaymentMethod == "wechat" { + refundErr := l.svcCtx.WechatPayService.WeChatRefund(ctx, order.OrderNo, order.Amount, order.Amount) + if refundErr != nil { + return refundErr + } + } else { + refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount) + if refundErr != nil { + return refundErr + } + if refund.IsSuccess() { + logx.Errorf("支付宝退款成功, orderID: %d", order.Id) + // 更新订单状态为退款 + order.Status = "refunded" + updateOrderErr := l.svcCtx.AgentMembershipRechargeOrderModel.UpdateWithVersion(ctx, nil, order) + if updateOrderErr != nil { + logx.Errorf("更新订单状态失败,订单ID: %d, 错误: %v", order.Id, updateOrderErr) + return fmt.Errorf("更新订单状态失败: %v", updateOrderErr) + } + return nil + } else { + logx.Errorf("支付宝退款失败:%v", refundErr) + return refundErr + } + } return nil } diff --git a/pkg/lzkit/lzUtils/time.go b/pkg/lzkit/lzUtils/time.go new file mode 100644 index 0000000..3c67d1e --- /dev/null +++ b/pkg/lzkit/lzUtils/time.go @@ -0,0 +1,26 @@ +package lzUtils + +import ( + "database/sql" + "time" +) + +// RenewMembership 延长会员有效期 +func RenewMembership(expiry sql.NullTime) sql.NullTime { + // 确定基准时间 + var baseTime time.Time + if expiry.Valid { + baseTime = expiry.Time + } else { + baseTime = time.Now() + } + + // 增加一年(自动处理闰年) + newTime := baseTime.AddDate(1, 0, 0) + + // 返回始终有效的 NullTime + return sql.NullTime{ + Time: newTime, + Valid: true, + } +}