This commit is contained in:
2026-04-22 17:49:20 +08:00
parent a2fad4a095
commit f545aee45e
15 changed files with 268 additions and 140 deletions

View File

@@ -1,14 +1,15 @@
package pay
import (
"context"
"database/sql"
"net/http"
"strings"
"time"
"bdrp-server/app/main/api/internal/svc"
"bdrp-server/app/main/model"
"bdrp-server/common/globalkey"
"context"
"database/sql"
"math"
"net/http"
"strings"
"time"
"github.com/Masterminds/squirrel"
"github.com/pkg/errors"
@@ -17,10 +18,15 @@ import (
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
func roundMoney(v float64) float64 {
return math.Round(v*100) / 100
}
// HandleCommissionAndWalletDeduction 处理退款后的佣金状态更新和钱包金额扣除
// refundAmount 为本次实际退款金额(单位:元),从代理侧总共需要承担的金额
// 该函数会优先冲减当前订单相关的佣金(基于 RefundedAmount不足部分再从钱包余额/冻结余额中扣除
func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.ServiceContext, session sqlx.Session, order *model.Order, refundAmount float64) error {
refundAmount = roundMoney(refundAmount)
if refundAmount <= 0 {
return nil
}
@@ -52,7 +58,7 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
// 1. 先在佣金记录上做冲减:增加 RefundedAmount必要时将状态置为已退款
for _, commission := range commissions {
available := commission.Amount - commission.RefundedAmount
available := roundMoney(commission.Amount - commission.RefundedAmount)
if available <= 0 {
continue
}
@@ -66,11 +72,12 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
if currentRefund > remainRefundAmount {
currentRefund = remainRefundAmount
}
currentRefund = roundMoney(currentRefund)
// 更新佣金的已退款金额
commission.RefundedAmount += currentRefund
commission.RefundedAmount = roundMoney(commission.RefundedAmount + currentRefund)
// 如果这条佣金已经被完全冲减,则标记为已退款
if commission.RefundedAmount >= commission.Amount {
if commission.RefundedAmount >= roundMoney(commission.Amount) {
commission.Status = 2
}
@@ -92,9 +99,9 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
wa = &walletAdjust{agentId: commission.AgentId}
walletAdjustMap[commission.AgentId] = wa
}
wa.amount += currentRefund
wa.amount = roundMoney(wa.amount + currentRefund)
remainRefundAmount -= currentRefund
remainRefundAmount = roundMoney(remainRefundAmount - currentRefund)
}
// 2. 再按代理维度,从钱包(冻结余额/可用余额)中扣除对应金额
@@ -115,19 +122,19 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
frozenBalanceBefore := wallet.FrozenBalance
// 优先从冻结余额中扣除(与原先“冻结佣金优先使用冻结余额”的设计一致)
deduct := wa.amount
deduct := roundMoney(wa.amount)
if wallet.FrozenBalance >= deduct {
wallet.FrozenBalance -= deduct
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - deduct)
} else {
remaining := deduct - wallet.FrozenBalance
remaining := roundMoney(deduct - wallet.FrozenBalance)
wallet.FrozenBalance = 0
// 可用余额可以为负数,由业务承担风险
wallet.Balance -= remaining
wallet.Balance = roundMoney(wallet.Balance - remaining)
}
// 变动后余额和冻结余额
balanceAfter := wallet.Balance
frozenBalanceAfter := wallet.FrozenBalance
balanceAfter := roundMoney(wallet.Balance)
frozenBalanceAfter := roundMoney(wallet.FrozenBalance)
// 更新钱包
var updateWalletErr error
if session != nil {
@@ -145,7 +152,7 @@ func HandleCommissionAndWalletDeduction(ctx context.Context, svcCtx *svc.Service
session,
wa.agentId,
model.WalletTransactionTypeRefund,
-wa.amount*-1, // 钱包流水金额为负数
roundMoney(-wa.amount*-1), // 钱包流水金额为负数
balanceBefore,
balanceAfter,
frozenBalanceBefore,
@@ -348,7 +355,7 @@ func (l *WechatPayRefundCallbackLogic) WechatPayRefundCallback(w http.ResponseWr
var refundAmountYuan float64
if notification.Amount != nil && notification.Amount.Refund != nil {
// 微信退款金额单位为分,这里转换为元
refundAmountYuan = float64(*notification.Amount.Refund) / 100.0
refundAmountYuan = roundMoney(float64(*notification.Amount.Refund) / 100.0)
}
// 4. 根据订单号前缀处理不同类型的订单