v2.0
This commit is contained in:
		@@ -2,16 +2,20 @@ package pay
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"database/sql"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
	"tydata-server/pkg/lzkit/lzUtils"
 | 
			
		||||
 | 
			
		||||
	"github.com/smartwalle/alipay/v3"
 | 
			
		||||
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/svc"
 | 
			
		||||
	"tydata-server/app/user/model"
 | 
			
		||||
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/stores/sqlx"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type AlipayCallbackLogic struct {
 | 
			
		||||
@@ -29,31 +33,46 @@ func NewAlipayCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Al
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *AlipayCallbackLogic) AlipayCallback(w http.ResponseWriter, r *http.Request) error {
 | 
			
		||||
	env := os.Getenv("ENV")
 | 
			
		||||
	if env == "development" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	notification, err := l.svcCtx.AlipayService.HandleAliPaymentNotification(r)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		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 *AlipayCallbackLogic) handleQueryOrderPayment(w http.ResponseWriter, notification *alipay.Notification) error {
 | 
			
		||||
	order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, notification.OutTradeNo)
 | 
			
		||||
	if findOrderErr != nil {
 | 
			
		||||
		logx.Errorf("支付宝支付回调,查找订单失败: %+v", findOrderErr)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if order.Status != "pending" {
 | 
			
		||||
		alipay.ACKNotification(w)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	user, err := l.svcCtx.UserModel.FindOne(l.ctx, order.UserId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logx.Errorf("支付宝支付回调,查找用户失败: %+v", err)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	amount := lzUtils.ToAlipayAmount(order.Amount)
 | 
			
		||||
 | 
			
		||||
	amount := lzUtils.ToAlipayAmount(order.Amount)
 | 
			
		||||
	if user.Inside != 1 {
 | 
			
		||||
		// 确保订单金额和状态正确,防止重复更新
 | 
			
		||||
		if amount != notification.TotalAmount {
 | 
			
		||||
@@ -62,11 +81,6 @@ func (l *AlipayCallbackLogic) AlipayCallback(w http.ResponseWriter, r *http.Requ
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if order.Status != "pending" {
 | 
			
		||||
		w.WriteHeader(http.StatusOK)
 | 
			
		||||
		_, _ = w.Write([]byte("success")) // 确保只写入一次响应
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	switch notification.TradeStatus {
 | 
			
		||||
	case alipay.TradeStatusSuccess:
 | 
			
		||||
		order.Status = "paid"
 | 
			
		||||
@@ -74,17 +88,148 @@ func (l *AlipayCallbackLogic) AlipayCallback(w http.ResponseWriter, r *http.Requ
 | 
			
		||||
	default:
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	order.PlatformOrderId = lzUtils.StringToNullString(notification.TradeNo)
 | 
			
		||||
	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)
 | 
			
		||||
			return asyncErr
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	alipay.ACKNotification(w)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 处理代理会员订单支付
 | 
			
		||||
func (l *AlipayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter, notification *alipay.Notification) error {
 | 
			
		||||
	agentOrder, findAgentOrderErr := l.svcCtx.AgentMembershipRechargeOrderModel.FindOneByOrderNo(l.ctx, notification.OutTradeNo)
 | 
			
		||||
	if findAgentOrderErr != nil {
 | 
			
		||||
		logx.Errorf("支付宝支付回调,查找代理会员订单失败: %+v", findAgentOrderErr)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if agentOrder.Status != "pending" {
 | 
			
		||||
		alipay.ACKNotification(w)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	user, err := l.svcCtx.UserModel.FindOne(l.ctx, agentOrder.UserId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logx.Errorf("支付宝支付回调,查找用户失败: %+v", err)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	amount := lzUtils.ToAlipayAmount(agentOrder.Amount)
 | 
			
		||||
	if user.Inside != 1 {
 | 
			
		||||
		// 确保订单金额和状态正确,防止重复更新
 | 
			
		||||
		if amount != notification.TotalAmount {
 | 
			
		||||
			logx.Errorf("支付宝支付回调,金额不一致")
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch notification.TradeStatus {
 | 
			
		||||
	case alipay.TradeStatusSuccess:
 | 
			
		||||
		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.TradeNo)
 | 
			
		||||
			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 = 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
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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()
 | 
			
		||||
	// 退款
 | 
			
		||||
	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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,13 +2,14 @@ package pay
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"time"
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/svc"
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/types"
 | 
			
		||||
	"tydata-server/common/xerr"
 | 
			
		||||
	"tydata-server/pkg/lzkit/lzUtils"
 | 
			
		||||
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								app/user/cmd/api/internal/logic/pay/paymentchecklogic.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/user/cmd/api/internal/logic/pay/paymentchecklogic.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
package pay
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/svc"
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/types"
 | 
			
		||||
	"tydata-server/common/xerr"
 | 
			
		||||
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type PaymentCheckLogic struct {
 | 
			
		||||
	logx.Logger
 | 
			
		||||
	ctx    context.Context
 | 
			
		||||
	svcCtx *svc.ServiceContext
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewPaymentCheckLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PaymentCheckLogic {
 | 
			
		||||
	return &PaymentCheckLogic{
 | 
			
		||||
		Logger: logx.WithContext(ctx),
 | 
			
		||||
		ctx:    ctx,
 | 
			
		||||
		svcCtx: svcCtx,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *PaymentCheckLogic) PaymentCheck(req *types.PaymentCheckReq) (resp *types.PaymentCheckResp, err error) {
 | 
			
		||||
	if strings.HasPrefix(req.OrderNo, "A_") {
 | 
			
		||||
		order, err := l.svcCtx.AgentMembershipRechargeOrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询订单失败: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		return &types.PaymentCheckResp{
 | 
			
		||||
			Type:   "agent_vip",
 | 
			
		||||
			Status: order.Status,
 | 
			
		||||
		}, nil
 | 
			
		||||
	} else {
 | 
			
		||||
		order, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询订单失败: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		return &types.PaymentCheckResp{
 | 
			
		||||
			Type:   "query",
 | 
			
		||||
			Status: order.Status,
 | 
			
		||||
		}, nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -5,7 +5,6 @@ import (
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/svc"
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/types"
 | 
			
		||||
	"tydata-server/app/user/model"
 | 
			
		||||
@@ -14,6 +13,7 @@ import (
 | 
			
		||||
	"tydata-server/pkg/lzkit/crypto"
 | 
			
		||||
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"github.com/redis/go-redis/v9"
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/stores/sqlx"
 | 
			
		||||
)
 | 
			
		||||
@@ -23,6 +23,11 @@ type PaymentLogic struct {
 | 
			
		||||
	ctx    context.Context
 | 
			
		||||
	svcCtx *svc.ServiceContext
 | 
			
		||||
}
 | 
			
		||||
type PaymentTypeResp struct {
 | 
			
		||||
	amount      float64
 | 
			
		||||
	outTradeNo  string
 | 
			
		||||
	description string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewPaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PaymentLogic {
 | 
			
		||||
	return &PaymentLogic{
 | 
			
		||||
@@ -33,20 +38,61 @@ func NewPaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PaymentLo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp, err error) {
 | 
			
		||||
	var paymentTypeResp *PaymentTypeResp
 | 
			
		||||
	var prepayData interface{}
 | 
			
		||||
	l.svcCtx.OrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
 | 
			
		||||
		switch req.PayType {
 | 
			
		||||
		case "agent_vip":
 | 
			
		||||
			paymentTypeResp, err = l.AgentVipOrderPayment(req, session)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		case "query":
 | 
			
		||||
			paymentTypeResp, err = l.QueryOrderPayment(req, session)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var createOrderErr error
 | 
			
		||||
		if req.PayMethod == "wechat" {
 | 
			
		||||
			prepayData, createOrderErr = l.svcCtx.WechatPayService.CreateWechatOrder(l.ctx, paymentTypeResp.amount, paymentTypeResp.description, paymentTypeResp.outTradeNo)
 | 
			
		||||
		} else if req.PayMethod == "alipay" {
 | 
			
		||||
			prepayData, createOrderErr = l.svcCtx.AlipayService.CreateAlipayOrder(l.ctx, paymentTypeResp.amount, paymentTypeResp.description, paymentTypeResp.outTradeNo)
 | 
			
		||||
		} else if req.PayMethod == "appleiap" {
 | 
			
		||||
			prepayData = l.svcCtx.ApplePayService.GetIappayAppID(paymentTypeResp.outTradeNo)
 | 
			
		||||
		}
 | 
			
		||||
		if createOrderErr != nil {
 | 
			
		||||
			return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 创建支付订单失败: %+v", createOrderErr)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	switch v := prepayData.(type) {
 | 
			
		||||
	case string:
 | 
			
		||||
		// 如果 prepayData 是字符串类型,直接返回
 | 
			
		||||
		return &types.PaymentResp{PrepayId: v, OrderNo: paymentTypeResp.outTradeNo}, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return &types.PaymentResp{PrepayData: prepayData, OrderNo: paymentTypeResp.outTradeNo}, nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Session) (resp *PaymentTypeResp, err error) {
 | 
			
		||||
	userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
 | 
			
		||||
	if getUidErr != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取用户信息失败, %+v", getUidErr)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	brand, ok := l.ctx.Value("brand").(string)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取平台失败, %+v", getUidErr)
 | 
			
		||||
	}
 | 
			
		||||
	outTradeNo := req.Id
 | 
			
		||||
	redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
 | 
			
		||||
	redisKey := fmt.Sprintf(types.QueryCacheKey, userID, outTradeNo)
 | 
			
		||||
	cache, cacheErr := l.svcCtx.Redis.GetCtx(l.ctx, redisKey)
 | 
			
		||||
	if cacheErr != nil {
 | 
			
		||||
		return nil, cacheErr
 | 
			
		||||
		if cacheErr == redis.Nil {
 | 
			
		||||
			return nil, errors.Wrapf(xerr.NewErrMsg("订单已过期"), "生成订单, 缓存不存在, %+v", cacheErr)
 | 
			
		||||
		}
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取缓存失败, %+v", cacheErr)
 | 
			
		||||
	}
 | 
			
		||||
	var data types.QueryCacheLoad
 | 
			
		||||
	err = json.Unmarshal([]byte(cache), &data)
 | 
			
		||||
@@ -59,9 +105,7 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 查找产品错误: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var prepayData interface{}
 | 
			
		||||
	var amount float64
 | 
			
		||||
	var orderAmount float64
 | 
			
		||||
	user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取用户信息失败: %v", err)
 | 
			
		||||
@@ -73,79 +117,95 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
 | 
			
		||||
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取代理订单失败: %+v", findAgentLinkErr)
 | 
			
		||||
		}
 | 
			
		||||
		amount = agentLinkModel.Price
 | 
			
		||||
		orderAmount = agentLinkModel.Price
 | 
			
		||||
	} else {
 | 
			
		||||
		amount = product.SellPrice
 | 
			
		||||
		orderAmount = product.SellPrice
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if user.Inside == 1 {
 | 
			
		||||
		amount = 0.01
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var createOrderErr error
 | 
			
		||||
	if req.PayMethod == "wechat" {
 | 
			
		||||
		prepayData, createOrderErr = l.svcCtx.WechatPayService.CreateWechatOrder(l.ctx, amount, product.ProductName, outTradeNo)
 | 
			
		||||
	} else if req.PayMethod == "alipay" {
 | 
			
		||||
		prepayData, createOrderErr = l.svcCtx.AlipayService.CreateAlipayOrder(l.ctx, amount, product.ProductName, outTradeNo, brand)
 | 
			
		||||
	} else if req.PayMethod == "appleiap" {
 | 
			
		||||
		prepayData = l.svcCtx.ApplePayService.GetIappayAppID(product.ProductEn)
 | 
			
		||||
	}
 | 
			
		||||
	if createOrderErr != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 创建支付订单失败: %+v", createOrderErr)
 | 
			
		||||
	}
 | 
			
		||||
	var orderID int64
 | 
			
		||||
	transErr := l.svcCtx.OrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
 | 
			
		||||
		order := model.Order{
 | 
			
		||||
			OrderNo:         outTradeNo,
 | 
			
		||||
			UserId:          userID,
 | 
			
		||||
			ProductId:       product.Id,
 | 
			
		||||
			PaymentPlatform: req.PayMethod,
 | 
			
		||||
			PaymentScene:    "app",
 | 
			
		||||
			Amount:          orderAmount,
 | 
			
		||||
			Status:          "pending",
 | 
			
		||||
		}
 | 
			
		||||
		orderInsertResult, insertOrderErr := l.svcCtx.OrderModel.Insert(ctx, session, &order)
 | 
			
		||||
		if insertOrderErr != nil {
 | 
			
		||||
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存订单失败: %+v", insertOrderErr)
 | 
			
		||||
		}
 | 
			
		||||
		insertedOrderID, lastInsertIdErr := orderInsertResult.LastInsertId()
 | 
			
		||||
		if lastInsertIdErr != nil {
 | 
			
		||||
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取保存订单ID失败: %+v", lastInsertIdErr)
 | 
			
		||||
		}
 | 
			
		||||
		orderID = insertedOrderID
 | 
			
		||||
	order := model.Order{
 | 
			
		||||
		OrderNo:         outTradeNo,
 | 
			
		||||
		UserId:          userID,
 | 
			
		||||
		ProductId:       product.Id,
 | 
			
		||||
		PaymentPlatform: req.PayMethod,
 | 
			
		||||
		PaymentScene:    "app",
 | 
			
		||||
		Amount:          amount,
 | 
			
		||||
		Status:          "pending",
 | 
			
		||||
	}
 | 
			
		||||
	orderInsertResult, insertOrderErr := l.svcCtx.OrderModel.Insert(l.ctx, session, &order)
 | 
			
		||||
	if insertOrderErr != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存订单失败: %+v", insertOrderErr)
 | 
			
		||||
	}
 | 
			
		||||
	insertedOrderID, lastInsertIdErr := orderInsertResult.LastInsertId()
 | 
			
		||||
	if lastInsertIdErr != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取保存订单ID失败: %+v", lastInsertIdErr)
 | 
			
		||||
	}
 | 
			
		||||
	orderID = insertedOrderID
 | 
			
		||||
 | 
			
		||||
		if data.AgentIdentifier != "" {
 | 
			
		||||
			agent, parsingErr := l.agentParsing(data.AgentIdentifier)
 | 
			
		||||
			if parsingErr != nil {
 | 
			
		||||
				return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 解析代理标识符失败: %+v", parsingErr)
 | 
			
		||||
			}
 | 
			
		||||
			var agentOrder model.AgentOrder
 | 
			
		||||
			agentOrder.OrderId = orderID
 | 
			
		||||
			agentOrder.AgentId = agent.AgentID
 | 
			
		||||
			_, agentOrderInsert := l.svcCtx.AgentOrderModel.Insert(ctx, session, &agentOrder)
 | 
			
		||||
			if agentOrderInsert != nil {
 | 
			
		||||
				return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存代理订单失败: %+v", agentOrderInsert)
 | 
			
		||||
			}
 | 
			
		||||
	if data.AgentIdentifier != "" {
 | 
			
		||||
		agent, parsingErr := l.agentParsing(data.AgentIdentifier)
 | 
			
		||||
		if parsingErr != nil {
 | 
			
		||||
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 解析代理标识符失败: %+v", parsingErr)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	})
 | 
			
		||||
	if transErr != nil {
 | 
			
		||||
		return nil, transErr
 | 
			
		||||
	}
 | 
			
		||||
	env := os.Getenv("ENV")
 | 
			
		||||
	if env == "development" {
 | 
			
		||||
		if asyncErr := l.svcCtx.AsynqService.SendQueryTask(orderID); asyncErr != nil {
 | 
			
		||||
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 异步订单调用失败: %+v", asyncErr)
 | 
			
		||||
		var agentOrder model.AgentOrder
 | 
			
		||||
		agentOrder.OrderId = orderID
 | 
			
		||||
		agentOrder.AgentId = agent.AgentID
 | 
			
		||||
		_, agentOrderInsert := l.svcCtx.AgentOrderModel.Insert(l.ctx, session, &agentOrder)
 | 
			
		||||
		if agentOrderInsert != nil {
 | 
			
		||||
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存代理订单失败: %+v", agentOrderInsert)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	switch v := prepayData.(type) {
 | 
			
		||||
	case string:
 | 
			
		||||
		// 如果 prepayData 是字符串类型,直接返回
 | 
			
		||||
		return &types.PaymentResp{PrepayId: v, OrderID: orderID}, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return &types.PaymentResp{PrepayData: prepayData, OrderID: orderID}, nil
 | 
			
		||||
	return &PaymentTypeResp{amount: amount, outTradeNo: outTradeNo, description: product.ProductName}, nil
 | 
			
		||||
}
 | 
			
		||||
func (l *PaymentLogic) AgentVipOrderPayment(req *types.PaymentReq, session sqlx.Session) (resp *PaymentTypeResp, err error) {
 | 
			
		||||
	userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
 | 
			
		||||
	if getUidErr != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取用户信息失败, %+v", getUidErr)
 | 
			
		||||
	}
 | 
			
		||||
	user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取用户信息失败: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	// 查询用户代理信息
 | 
			
		||||
	agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	redisKey := fmt.Sprintf(types.AgentVipCacheKey, userID, req.Id)
 | 
			
		||||
	cache, cacheErr := l.svcCtx.Redis.GetCtx(l.ctx, redisKey)
 | 
			
		||||
	if cacheErr != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取缓存失败, %+v", cacheErr)
 | 
			
		||||
	}
 | 
			
		||||
	var agentVipCache types.AgentVipCache
 | 
			
		||||
	err = json.Unmarshal([]byte(cache), &agentVipCache)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解析缓存内容失败, %+v", err)
 | 
			
		||||
	}
 | 
			
		||||
	agentMembershipConfig, err := l.svcCtx.AgentMembershipConfigModel.FindOneByLevelName(l.ctx, agentVipCache.Type)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取代理会员配置失败, %+v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	amount := agentMembershipConfig.Price.Float64
 | 
			
		||||
	if user.Inside == 1 {
 | 
			
		||||
		amount = 0.01
 | 
			
		||||
	}
 | 
			
		||||
	agentMembershipRechargeOrder := model.AgentMembershipRechargeOrder{
 | 
			
		||||
		OrderNo:       req.Id,
 | 
			
		||||
		UserId:        userID,
 | 
			
		||||
		AgentId:       agentModel.Id,
 | 
			
		||||
		Amount:        amount,
 | 
			
		||||
		PaymentMethod: req.PayMethod,
 | 
			
		||||
		LevelName:     agentVipCache.Type,
 | 
			
		||||
		Status:        "pending",
 | 
			
		||||
	}
 | 
			
		||||
	_, err = l.svcCtx.AgentMembershipRechargeOrderModel.Insert(l.ctx, session, &agentMembershipRechargeOrder)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存代理会员充值订单失败: %+v", err)
 | 
			
		||||
	}
 | 
			
		||||
	return &PaymentTypeResp{amount: amount, outTradeNo: req.Id, description: fmt.Sprintf("%s代理会员充值", agentMembershipConfig.LevelName)}, nil
 | 
			
		||||
}
 | 
			
		||||
func (l *PaymentLogic) agentParsing(agentIdentifier string) (*types.AgentIdentifier, error) {
 | 
			
		||||
	key, decodeErr := hex.DecodeString("8e3e7a2f60edb49221e953b9c029ed10")
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,9 @@ import (
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/service"
 | 
			
		||||
	"tydata-server/pkg/lzkit/lzUtils"
 | 
			
		||||
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/svc"
 | 
			
		||||
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type WechatPayCallbackLogic struct {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,11 @@ package pay
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic"
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"tydata-server/app/user/cmd/api/internal/svc"
 | 
			
		||||
 | 
			
		||||
	"github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic"
 | 
			
		||||
	"github.com/zeromicro/go-zero/core/logx"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type WechatPayRefundCallbackLogic struct {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user