feat: 更新钱包充值逻辑,自动处理充值订单支付,模拟支付成功返回
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user