feat: 更新钱包充值逻辑,自动处理充值订单支付,模拟支付成功返回

This commit is contained in:
2025-12-31 12:00:38 +08:00
parent a6b870bc8f
commit 95bc5bdb5d
2 changed files with 53 additions and 36 deletions

View File

@@ -234,8 +234,17 @@ func (s *order) payWithBalance(ctx context.Context, o *models.Order) (*transacti
func (s *order) settleOrder(ctx context.Context, o *models.Order, method, externalID string) error { func (s *order) settleOrder(ctx context.Context, o *models.Order, method, externalID string) error {
var tenantOwnerID int64 var tenantOwnerID int64
err := models.Q.Transaction(func(tx *models.Query) error { err := models.Q.Transaction(func(tx *models.Query) error {
// 1. Deduct User Balance (Only for balance method) // 1. Handle Balance Updates
if method == "balance" { if o.Type == consts.OrderTypeRecharge {
// Income: Recharge (Credit User Balance)
_, err := tx.User.WithContext(ctx).
Where(tx.User.ID.Eq(o.UserID)).
Update(tx.User.Balance, gorm.Expr("balance + ?", o.AmountPaid))
if err != nil {
return err
}
} else if method == "balance" {
// Expense: Purchase with Balance (Deduct User Balance)
info, err := tx.User.WithContext(ctx). info, err := tx.User.WithContext(ctx).
Where(tx.User.ID.Eq(o.UserID), tx.User.Balance.Gte(o.AmountPaid)). Where(tx.User.ID.Eq(o.UserID), tx.User.Balance.Gte(o.AmountPaid)).
Update(tx.User.Balance, gorm.Expr("balance - ?", o.AmountPaid)) Update(tx.User.Balance, gorm.Expr("balance - ?", o.AmountPaid))
@@ -283,42 +292,44 @@ func (s *order) settleOrder(ctx context.Context, o *models.Order, method, extern
} }
} }
// 4. Create Tenant Ledger (Revenue) // 4. Create Tenant Ledger (Revenue) - Only for Content Purchase
t, err := tx.Tenant.WithContext(ctx).Where(tx.Tenant.ID.Eq(o.TenantID)).First() if o.Type == consts.OrderTypeContentPurchase {
if err != nil { t, err := tx.Tenant.WithContext(ctx).Where(tx.Tenant.ID.Eq(o.TenantID)).First()
return err if err != nil {
} return err
tenantOwnerID = t.UserID }
tenantOwnerID = t.UserID
// Calculate Commission // Calculate Commission
amount := o.AmountPaid amount := o.AmountPaid
fee := int64(float64(amount) * 0.10) fee := int64(float64(amount) * 0.10)
creatorIncome := amount - fee creatorIncome := amount - fee
// Credit Tenant Owner Balance (Net Income) // Credit Tenant Owner Balance (Net Income)
_, err = tx.User.WithContext(ctx). _, err = tx.User.WithContext(ctx).
Where(tx.User.ID.Eq(tenantOwnerID)). Where(tx.User.ID.Eq(tenantOwnerID)).
Update(tx.User.Balance, gorm.Expr("balance + ?", creatorIncome)) Update(tx.User.Balance, gorm.Expr("balance + ?", creatorIncome))
if err != nil { if err != nil {
return err return err
} }
ledger := &models.TenantLedger{ ledger := &models.TenantLedger{
TenantID: o.TenantID, TenantID: o.TenantID,
UserID: t.UserID, // Owner UserID: t.UserID, // Owner
OrderID: o.ID, OrderID: o.ID,
Type: consts.TenantLedgerTypeDebitPurchase, // Income from purchase Type: consts.TenantLedgerTypeDebitPurchase, // Income from purchase
Amount: creatorIncome, Amount: creatorIncome,
BalanceBefore: 0, // TODO BalanceBefore: 0, // TODO
BalanceAfter: 0, // TODO BalanceAfter: 0, // TODO
FrozenBefore: 0, FrozenBefore: 0,
FrozenAfter: 0, FrozenAfter: 0,
IdempotencyKey: uuid.NewString(), IdempotencyKey: uuid.NewString(),
Remark: "内容销售收入 (扣除平台费)", Remark: "内容销售收入 (扣除平台费)",
OperatorUserID: o.UserID, OperatorUserID: o.UserID,
} }
if err := tx.TenantLedger.WithContext(ctx).Create(ledger); err != nil { if err := tx.TenantLedger.WithContext(ctx).Create(ledger); err != nil {
return err return err
}
} }
return nil return nil

View File

@@ -96,9 +96,15 @@ func (s *wallet) Recharge(
return nil, errorx.ErrDatabaseError.WithCause(err) return nil, errorx.ErrDatabaseError.WithCause(err)
} }
// MOCK: Automatically pay for recharge order to close the loop
// In production, this would be a callback from payment gateway
if err := Order.ProcessExternalPayment(ctx, cast.ToString(order.ID), "mock_auto_pay"); err != nil {
return nil, err
}
// Mock Pay Params // Mock Pay Params
return &user_dto.RechargeResponse{ return &user_dto.RechargeResponse{
PayParams: "mock_recharge_url", PayParams: "mock_paid_success",
OrderID: cast.ToString(order.ID), OrderID: cast.ToString(order.ID),
}, nil }, nil
} }