1、微信支付回调兼容查询订单和代理会员订单处理

2、微信登录、申请代理错误处理提示微调
This commit is contained in:
liangzai 2025-05-11 03:11:16 +08:00
parent 1ecac19098
commit b91ea31727
4 changed files with 167 additions and 24 deletions

View File

@ -70,7 +70,7 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
// } // }
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(transCtx, session, user) insertResult, userInsertErr := l.svcCtx.UserModel.Insert(transCtx, session, user)
if userInsertErr != nil { 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() lastId, lastInsertIdErr := insertResult.LastInsertId()
if lastInsertIdErr != nil { if lastInsertIdErr != nil {

View File

@ -2,7 +2,6 @@ package pay
import ( import (
"context" "context"
"database/sql"
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
@ -163,7 +162,7 @@ func (l *AlipayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter,
} else { } else {
logx.Infof("代理会员新购或升级成功会员ID%d等级%s", agentModel.Id, agentModel.LevelName) 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 { if updateErr := l.svcCtx.AgentModel.UpdateWithVersion(l.ctx, nil, agentModel); updateErr != nil {
return fmt.Errorf("修改代理信息失败: %+v", updateErr) return fmt.Errorf("修改代理信息失败: %+v", updateErr)
@ -183,24 +182,6 @@ func (l *AlipayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter,
alipay.ACKNotification(w) alipay.ACKNotification(w)
return nil 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 { func (l *AlipayCallbackLogic) handleRefund(order *model.AgentMembershipRechargeOrder) error {
ctx := context.Background() ctx := context.Background()

View File

@ -2,14 +2,19 @@ package pay
import ( import (
"context" "context"
"fmt"
"net/http" "net/http"
"strings"
"time" "time"
"tydata-server/app/user/cmd/api/internal/service" "tydata-server/app/user/cmd/api/internal/service"
"tydata-server/app/user/model"
"tydata-server/pkg/lzkit/lzUtils" "tydata-server/pkg/lzkit/lzUtils"
"tydata-server/app/user/cmd/api/internal/svc" "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/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
) )
type WechatPayCallbackLogic struct { type WechatPayCallbackLogic struct {
@ -32,6 +37,23 @@ func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *htt
logx.Errorf("微信支付回调,%v", err) logx.Errorf("微信支付回调,%v", err)
return nil 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) order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, *notification.OutTradeNo)
if findOrderErr != nil { if findOrderErr != nil {
logx.Errorf("微信支付回调,查找订单信息失败: %+v", findOrderErr) logx.Errorf("微信支付回调,查找订单信息失败: %+v", findOrderErr)
@ -43,11 +65,13 @@ func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *htt
logx.Errorf("微信支付回调,金额不一致") logx.Errorf("微信支付回调,金额不一致")
return nil return nil
} }
if order.Status != "pending" { if order.Status != "pending" {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("success")) // 确保只写入一次响应 _, _ = w.Write([]byte("success"))
return nil return nil
} }
switch *notification.TradeState { switch *notification.TradeState {
case service.TradeStateSuccess: case service.TradeStateSuccess:
order.Status = "paid" order.Status = "paid"
@ -60,11 +84,13 @@ func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *htt
default: default:
return nil return nil
} }
order.PlatformOrderId = lzUtils.StringToNullString(*notification.TransactionId) order.PlatformOrderId = lzUtils.StringToNullString(*notification.TransactionId)
if updateErr := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); updateErr != nil { if updateErr := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); updateErr != nil {
logx.Errorf("微信支付回调,更新订单失败%+v", updateErr) logx.Errorf("微信支付回调,更新订单失败%+v", updateErr)
return nil return nil
} }
if order.Status == "paid" { if order.Status == "paid" {
if asyncErr := l.svcCtx.AsynqService.SendQueryTask(order.Id); asyncErr != nil { if asyncErr := l.svcCtx.AsynqService.SendQueryTask(order.Id); asyncErr != nil {
logx.Errorf("异步任务调度失败: %v", asyncErr) logx.Errorf("异步任务调度失败: %v", asyncErr)
@ -72,8 +98,118 @@ func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *htt
} }
} }
// 响应微信回调成功
w.WriteHeader(http.StatusOK) 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 return nil
} }

26
pkg/lzkit/lzUtils/time.go Normal file
View File

@ -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,
}
}