This commit is contained in:
2025-12-09 18:55:28 +08:00
parent 8d00d67540
commit c23ab8338b
209 changed files with 5445 additions and 3963 deletions

View File

@@ -182,7 +182,7 @@ func (l *AlipayCallbackLogic) handleAgentUpgradeOrderPayment(w http.ResponseWrit
if order.Status == "paid" {
err := l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 8.1 执行升级操作
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, orderNo, 0); err != nil {
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, orderNo, ""); err != nil {
return errors.Wrapf(err, "执行升级操作失败")
}

View File

@@ -2,11 +2,12 @@ package pay
import (
"context"
"fmt"
"time"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/lzUtils"
"time"
"github.com/pkg/errors"
@@ -29,7 +30,7 @@ func NewIapCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *IapCa
func (l *IapCallbackLogic) IapCallback(req *types.IapCallbackReq) error {
// Step 1: 查找订单
order, findOrderErr := l.svcCtx.OrderModel.FindOne(l.ctx, req.OrderID)
order, findOrderErr := l.svcCtx.OrderModel.FindOne(l.ctx, fmt.Sprintf("%d", req.OrderID))
if findOrderErr != nil {
logx.Errorf("苹果内购支付回调,查找订单失败: %+v", findOrderErr)
return nil

View File

@@ -16,6 +16,7 @@ import (
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/lzUtils"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/redis/go-redis/v9"
"github.com/zeromicro/go-zero/core/logx"
@@ -31,7 +32,7 @@ type PaymentTypeResp struct {
amount float64
outTradeNo string
description string
orderID int64 // 订单ID用于开发环境测试支付模式
orderID string // 订单ID用于开发环境测试支付模式
}
func NewPaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PaymentLogic {
@@ -45,7 +46,7 @@ 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{}
var orderID int64
var orderID string
// 检查是否为开发环境的测试支付模式
env := os.Getenv("ENV")
@@ -77,14 +78,14 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
// 注意:订单状态更新在事务外进行,避免在事务中查询不到订单的问题
if isDevTestPayment {
// 获取订单ID从 QueryOrderPayment 返回的 orderID
if paymentTypeResp.orderID <= 0 {
if paymentTypeResp.orderID == "" {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "开发测试模式订单ID无效")
}
orderID = paymentTypeResp.orderID
// 在事务中只记录订单ID不更新订单状态
// 订单状态的更新和后续流程在事务提交后处理
logx.Infof("开发环境测试支付模式:订单 %s (ID: %d) 将在事务提交后更新状态", paymentTypeResp.outTradeNo, orderID)
logx.Infof("开发环境测试支付模式:订单 %s (ID: %s) 将在事务提交后更新状态", paymentTypeResp.outTradeNo, orderID)
// 返回测试支付标识
prepayData = "test_payment_success"
@@ -110,7 +111,7 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
}
// 开发环境测试支付模式:事务提交后处理订单状态更新和后续流程
if isDevTestPayment && paymentTypeResp != nil && paymentTypeResp.orderID > 0 {
if isDevTestPayment && paymentTypeResp != nil && paymentTypeResp.orderID != "" {
// 使用 goroutine 异步处理,确保事务已完全提交
go func() {
// 短暂延迟,确保事务已完全提交到数据库
@@ -121,7 +122,7 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
// 查找订单并更新状态为已支付
order, findOrderErr := l.svcCtx.OrderModel.FindOne(context.Background(), finalOrderID)
if findOrderErr != nil {
logx.Errorf("开发测试模式查找订单失败订单ID: %d, 错误: %v", finalOrderID, findOrderErr)
logx.Errorf("开发测试模式查找订单失败订单ID: %s, 错误: %v", finalOrderID, findOrderErr)
return
}
@@ -133,17 +134,17 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
// 空报告模式:在 PaymentPlatform 字段中标记,用于后续生成空报告
if isEmptyReportMode {
order.PaymentPlatform = "test_empty"
logx.Infof("开发环境空报告模式:订单 %s (ID: %d) 已标记为空报告模式", paymentTypeResp.outTradeNo, finalOrderID)
logx.Infof("开发环境空报告模式:订单 %s (ID: %s) 已标记为空报告模式", paymentTypeResp.outTradeNo, finalOrderID)
}
// 更新订单状态(在事务外执行)
updateErr := l.svcCtx.OrderModel.UpdateWithVersion(context.Background(), nil, order)
if updateErr != nil {
logx.Errorf("开发测试模式更新订单状态失败订单ID: %d, 错误: %+v", finalOrderID, updateErr)
logx.Errorf("开发测试模式更新订单状态失败订单ID: %s, 错误: %+v", finalOrderID, updateErr)
return
}
logx.Infof("开发环境测试支付模式:订单 %s (ID: %d) 已自动标记为已支付", paymentTypeResp.outTradeNo, finalOrderID)
logx.Infof("开发环境测试支付模式:订单 %s (ID: %s) 已自动标记为已支付", paymentTypeResp.outTradeNo, finalOrderID)
// 再次短暂延迟,确保订单状态更新已提交
time.Sleep(100 * time.Millisecond)
@@ -162,7 +163,7 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
// 执行升级操作
err := l.svcCtx.AgentWalletModel.Trans(context.Background(), func(transCtx context.Context, session sqlx.Session) error {
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, paymentTypeResp.outTradeNo, 0); err != nil {
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, paymentTypeResp.outTradeNo, ""); err != nil {
return errors.Wrapf(err, "执行升级操作失败")
}
@@ -179,14 +180,14 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
if err != nil {
logx.Errorf("开发测试模式,处理升级订单失败,订单号: %s, 错误: %+v", paymentTypeResp.outTradeNo, err)
} else {
logx.Infof("开发测试模式,代理升级成功,订单号: %s, 代理ID: %d", paymentTypeResp.outTradeNo, upgradeRecord.AgentId)
logx.Infof("开发测试模式,代理升级成功,订单号: %s, 代理ID: %s", paymentTypeResp.outTradeNo, upgradeRecord.AgentId)
}
} else {
// 查询订单:发送支付成功通知任务,触发后续流程(生成报告和代理处理)
if sendErr := l.svcCtx.AsynqService.SendQueryTask(finalOrderID); sendErr != nil {
logx.Errorf("开发测试模式发送支付成功通知任务失败订单ID: %d, 错误: %+v", finalOrderID, sendErr)
logx.Errorf("开发测试模式发送支付成功通知任务失败订单ID: %s, 错误: %+v", finalOrderID, sendErr)
} else {
logx.Infof("开发测试模式已发送支付成功通知任务订单ID: %d", finalOrderID)
logx.Infof("开发测试模式已发送支付成功通知任务订单ID: %s", finalOrderID)
}
}
}()
@@ -247,8 +248,8 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
if user.Inside == 1 {
amount = 0.01
}
var orderID int64
order := model.Order{
Id: uuid.NewString(),
OrderNo: outTradeNo,
UserId: userID,
ProductId: product.Id,
@@ -257,15 +258,11 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
Amount: amount,
Status: "pending",
}
orderInsertResult, insertOrderErr := l.svcCtx.OrderModel.Insert(l.ctx, session, &order)
_, 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
orderID := order.Id
// 如果是代理推广订单,创建完整的代理订单记录
if data.AgentIdentifier != "" && agentLinkModel != nil {
@@ -279,7 +276,7 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
productConfig, err := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, product.Id)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单失败,产品配置不存在, productId: %d,请先在后台配置产品价格参数", product.Id)
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单失败,产品配置不存在, productId: %s,请先在后台配置产品价格参数", product.Id)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 查询产品配置失败: %+v", err)
}
@@ -314,6 +311,7 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
// 创建代理订单记录
agentOrder := model.AgentOrder{
Id: uuid.NewString(),
AgentId: agentLinkModel.AgentId,
OrderId: orderID,
ProductId: product.Id,
@@ -346,10 +344,7 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
}
// 1. 解析升级记录ID
upgradeId, err := strconv.ParseInt(req.Id, 10, 64)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "无效的升级记录ID: %s", req.Id)
}
upgradeId := req.Id
// 2. 查找升级记录
upgradeRecord, err := l.svcCtx.AgentUpgradeModel.FindOne(l.ctx, upgradeId)
@@ -374,8 +369,12 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
return nil, errors.Wrapf(xerr.NewErrMsg("无权支付此升级订单"), "")
}
// 5. 生成订单号(使用 U_ 前缀表示升级订单)
outTradeNo := fmt.Sprintf("U_%d_%d", upgradeId, time.Now().Unix())
// 5. 生成订单号(升级订单前缀 U_限制长度不超过32
base := l.svcCtx.AlipayService.GenerateOutTradeNo()
outTradeNo := "U_" + base
if len(outTradeNo) > 32 {
outTradeNo = outTradeNo[:32]
}
// 6. 获取用户信息(用于内部用户判断)
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
@@ -391,9 +390,10 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
// 8. 创建订单记录
order := model.Order{
Id: uuid.NewString(),
OrderNo: outTradeNo,
UserId: userID,
ProductId: 0, // 升级订单没有产品ID
ProductId: "", // 升级订单没有产品ID
PaymentPlatform: req.PayMethod,
PaymentScene: "app",
Amount: amount,
@@ -403,10 +403,8 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
if insertOrderErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建订单失败: %+v", insertOrderErr)
}
orderID, lastInsertIdErr := orderInsertResult.LastInsertId()
if lastInsertIdErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取订单ID失败: %+v", lastInsertIdErr)
}
_ = orderInsertResult
orderID := order.Id
// 9. 更新升级记录的订单号
upgradeRecord.OrderNo = lzUtils.StringToNullString(outTradeNo)
@@ -425,10 +423,10 @@ func (l *PaymentLogic) AgentUpgradeOrderPayment(req *types.PaymentReq, session s
description := fmt.Sprintf("代理升级:%s → %s", fromLevelName, toLevelName)
return &PaymentTypeResp{
amount: amount,
outTradeNo: outTradeNo,
amount: amount,
outTradeNo: outTradeNo,
description: description,
orderID: orderID,
orderID: orderID,
}, nil
}

View File

@@ -177,7 +177,7 @@ func (l *WechatPayCallbackLogic) handleAgentUpgradeOrderPayment(w http.ResponseW
if order.Status == "paid" {
err := l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
// 8.1 执行升级操作
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, orderNo, 0); err != nil {
if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, upgradeRecord.AgentId, upgradeRecord.ToLevel, upgradeRecord.UpgradeType, upgradeRecord.UpgradeFee, upgradeRecord.RebateAmount, orderNo, ""); err != nil {
return errors.Wrapf(err, "执行升级操作失败")
}

View File

@@ -174,7 +174,7 @@ func (l *WechatPayRefundCallbackLogic) WechatPayRefundCallback(w http.ResponseWr
var statusDetermined bool = false
if notification.Status != nil {
status = *notification.Status
status = *notification.Status
statusDetermined = true
} else if notification.SuccessTime != nil && !notification.SuccessTime.IsZero() {
// 如果Status为空但SuccessTime有值说明退款成功
@@ -219,7 +219,7 @@ func (l *WechatPayRefundCallbackLogic) WechatPayRefundCallback(w http.ResponseWr
}
// findLatestPendingRefund 查找订单最新的pending状态退款记录
func (l *WechatPayRefundCallbackLogic) findLatestPendingRefund(ctx context.Context, orderId int64) (*model.OrderRefund, error) {
func (l *WechatPayRefundCallbackLogic) findLatestPendingRefund(ctx context.Context, orderId string) (*model.OrderRefund, error) {
// 使用SelectBuilder查询最新的pending状态退款记录
builder := l.svcCtx.OrderRefundModel.SelectBuilder().
Where("order_id = ? AND status = ? AND del_state = ?", orderId, model.OrderRefundStatusPending, globalkey.DelStateNo).