fix: move withdrawal commission deduction from application to approval
Build docker and publish / build (20.15.1) (push) Failing after 8m28s
Build docker and publish / build (20.15.1) (push) Failing after 8m28s
- commissionWithdrawLogic: remove upfront commission deduction; balance check now includes sum of all pending withdrawals to prevent double-spending; transaction only creates the withdrawal record (status=0) - approveWithdrawal: add FOR UPDATE lock on user row, balance check before deducting, atomic commission decrement and commission log inside one transaction; clear user cache after commit - rejectWithdrawal: remove commission refund and log — commission was never deducted on application under the new flow - add migration 02150: refund commission for existing status=0 withdrawals that were deducted under the old logic; includes rollback script Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/perfect-panel/server/internal/model/log"
|
||||
usermodel "github.com/perfect-panel/server/internal/model/user"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func WriteCommissionLog(tx *gorm.DB, objectID int64, logType uint16, amount int64, orderNo string) error {
|
||||
logInfo := log.Commission{
|
||||
Type: logType,
|
||||
Amount: amount,
|
||||
OrderNo: orderNo,
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
|
||||
content, err := logInfo.Marshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Model(log.SystemLog{}).Create(&log.SystemLog{
|
||||
Type: log.TypeCommission.Uint8(),
|
||||
Date: time.Now().Format(time.DateOnly),
|
||||
ObjectID: objectID,
|
||||
Content: string(content),
|
||||
CreatedAt: time.Now(),
|
||||
}).Error
|
||||
}
|
||||
|
||||
func LoadPendingWithdrawalForUpdate(ctx context.Context, tx *gorm.DB, withdrawalID int64) (*usermodel.Withdrawal, error) {
|
||||
var withdrawal usermodel.Withdrawal
|
||||
if err := tx.WithContext(ctx).
|
||||
Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||
Where("id = ?", withdrawalID).
|
||||
First(&withdrawal).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if withdrawal.Status != 0 {
|
||||
return nil, errors.New("withdrawal status invalid")
|
||||
}
|
||||
return &withdrawal, nil
|
||||
}
|
||||
Reference in New Issue
Block a user