Record coin seller transfers without recharge policy
This commit is contained in:
parent
d79c877ec0
commit
90ea9d706d
@ -5590,12 +5590,12 @@ func TestCoinSellerTransferChecksIdentityAndPropagatesWalletCommand(t *testing.T
|
||||
SellerBalanceAfter: 80000,
|
||||
TargetBalanceAfter: 80000,
|
||||
Amount: 80000,
|
||||
RechargeUsdMinor: 100,
|
||||
RechargeCurrencyCode: "USD",
|
||||
RechargePolicyId: 7,
|
||||
RechargePolicyVersion: "recharge-v1",
|
||||
RechargePolicyCoinAmount: 80000,
|
||||
RechargePolicyUsdMinorAmount: 100,
|
||||
RechargeUsdMinor: 0,
|
||||
RechargeCurrencyCode: "",
|
||||
RechargePolicyId: 0,
|
||||
RechargePolicyVersion: "",
|
||||
RechargePolicyCoinAmount: 0,
|
||||
RechargePolicyUsdMinorAmount: 0,
|
||||
}}
|
||||
hostClient := &fakeUserHostClient{profile: &userv1.CoinSellerProfile{
|
||||
UserId: 42,
|
||||
@ -5642,7 +5642,7 @@ func TestCoinSellerTransferChecksIdentityAndPropagatesWalletCommand(t *testing.T
|
||||
t.Fatalf("decode response failed: %v", err)
|
||||
}
|
||||
data, ok := response.Data.(map[string]any)
|
||||
if response.Code != httpkit.CodeOK || !ok || data["transaction_id"] != "wtx-coin-seller" || data["seller_balance_after"] != float64(80000) || data["recharge_usd_minor"] != float64(100) {
|
||||
if response.Code != httpkit.CodeOK || !ok || data["transaction_id"] != "wtx-coin-seller" || data["seller_balance_after"] != float64(80000) || data["recharge_usd_minor"] != float64(0) || data["recharge_policy_id"] != float64(0) {
|
||||
t.Fatalf("coin seller transfer response mismatch: %+v", response)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1568,7 +1568,6 @@ func TestCreditLuckyGiftRewardIsIdempotent(t *testing.T) {
|
||||
func TestTransferCoinFromSellerMovesDedicatedAssetToPlayerCoin(t *testing.T) {
|
||||
repository := mysqltest.NewRepository(t)
|
||||
svc := walletservice.New(repository)
|
||||
repository.SetRechargePolicy(1001, "recharge-v1", 80000, 100)
|
||||
_, _, err := svc.AdminCreditAsset(context.Background(), ledger.AdminCreditAssetCommand{
|
||||
CommandID: "cmd-credit-seller",
|
||||
TargetUserID: 30001,
|
||||
@ -1599,7 +1598,7 @@ func TestTransferCoinFromSellerMovesDedicatedAssetToPlayerCoin(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("TransferCoinFromSeller retry failed: %v", err)
|
||||
}
|
||||
if first.TransactionID == "" || first.TransactionID != second.TransactionID || first.SellerBalanceAfter != 80000 || first.TargetBalanceAfter != 80000 || first.RechargeUSDMinor != 100 {
|
||||
if first.TransactionID == "" || first.TransactionID != second.TransactionID || first.SellerBalanceAfter != 80000 || first.TargetBalanceAfter != 80000 || first.RechargeUSDMinor != 0 {
|
||||
t.Fatalf("transfer receipt mismatch: first=%+v second=%+v", first, second)
|
||||
}
|
||||
|
||||
@ -1635,7 +1634,6 @@ func TestTransferCoinFromSellerMovesDedicatedAssetToPlayerCoin(t *testing.T) {
|
||||
func TestTransferCoinFromSellerAllowsSelfTransfer(t *testing.T) {
|
||||
repository := mysqltest.NewRepository(t)
|
||||
svc := walletservice.New(repository)
|
||||
repository.SetRechargePolicy(1001, "recharge-v1", 30000, 100)
|
||||
_, _, err := svc.AdminCreditAsset(context.Background(), ledger.AdminCreditAssetCommand{
|
||||
CommandID: "cmd-credit-self-seller",
|
||||
TargetUserID: 30003,
|
||||
@ -1666,7 +1664,7 @@ func TestTransferCoinFromSellerAllowsSelfTransfer(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("TransferCoinFromSeller self transfer retry failed: %v", err)
|
||||
}
|
||||
if first.TransactionID == "" || first.TransactionID != second.TransactionID || first.SellerBalanceAfter != 70000 || first.TargetBalanceAfter != 30000 || first.RechargeUSDMinor != 100 {
|
||||
if first.TransactionID == "" || first.TransactionID != second.TransactionID || first.SellerBalanceAfter != 70000 || first.TargetBalanceAfter != 30000 || first.RechargeUSDMinor != 0 {
|
||||
t.Fatalf("self transfer receipt mismatch: first=%+v second=%+v", first, second)
|
||||
}
|
||||
|
||||
@ -1691,11 +1689,10 @@ func TestTransferCoinFromSellerAllowsSelfTransfer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestTransferCoinFromSellerAllowsSubCentRechargeAmount 验证小额金币也必须到账,美元统计按最小货币单位向下取整。
|
||||
func TestTransferCoinFromSellerAllowsSubCentRechargeAmount(t *testing.T) {
|
||||
// TestTransferCoinFromSellerRecordsCoinsWithoutUSDConversion 验证币商转账只按金币记录充值事实,不再走 USD 换算。
|
||||
func TestTransferCoinFromSellerRecordsCoinsWithoutUSDConversion(t *testing.T) {
|
||||
repository := mysqltest.NewRepository(t)
|
||||
svc := walletservice.New(repository)
|
||||
repository.SetRechargePolicy(1001, "recharge-v1", 1000, 100)
|
||||
_, _, err := svc.AdminCreditAsset(context.Background(), ledger.AdminCreditAssetCommand{
|
||||
CommandID: "cmd-credit-small-seller",
|
||||
TargetUserID: 30004,
|
||||
@ -1731,7 +1728,7 @@ func TestTransferCoinFromSellerAllowsSubCentRechargeAmount(t *testing.T) {
|
||||
if balanceAmount(balances, ledger.AssetCoinSellerCoin) != 10 || balanceAmount(balances, ledger.AssetCoin) != 1 {
|
||||
t.Fatalf("small transfer balances mismatch: %+v", balances)
|
||||
}
|
||||
if got := repository.CountRows("wallet_recharge_records", "transaction_id = ? AND coin_amount = ? AND usd_minor_amount = ?", receipt.TransactionID, int64(1), int64(0)); got != 1 {
|
||||
if got := repository.CountRows("wallet_recharge_records", "transaction_id = ? AND coin_amount = ? AND usd_minor_amount = ? AND policy_id = ? AND policy_version = ? AND exchange_coin_amount = ? AND exchange_usd_minor_amount = ?", receipt.TransactionID, int64(1), int64(0), int64(0), "", int64(1), int64(0)); got != 1 {
|
||||
t.Fatalf("small transfer should write recharge record with zero USD minor, got %d", got)
|
||||
}
|
||||
}
|
||||
@ -1758,8 +1755,8 @@ func TestTransferCoinFromSellerInsufficientBalance(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestTransferCoinFromSellerRequiresRechargePolicy 验证缺少区域充值政策时不会产生半成品充值事实。
|
||||
func TestTransferCoinFromSellerRequiresRechargePolicy(t *testing.T) {
|
||||
// TestTransferCoinFromSellerDoesNotRequireRechargePolicy 验证币商转账不依赖外部充值定价策略。
|
||||
func TestTransferCoinFromSellerDoesNotRequireRechargePolicy(t *testing.T) {
|
||||
repository := mysqltest.NewRepository(t)
|
||||
svc := walletservice.New(repository)
|
||||
_, _, err := svc.AdminCreditAsset(context.Background(), ledger.AdminCreditAssetCommand{
|
||||
@ -1775,7 +1772,7 @@ func TestTransferCoinFromSellerRequiresRechargePolicy(t *testing.T) {
|
||||
t.Fatalf("seed seller asset failed: %v", err)
|
||||
}
|
||||
|
||||
_, err = svc.TransferCoinFromSeller(context.Background(), ledger.CoinSellerTransferCommand{
|
||||
receipt, err := svc.TransferCoinFromSeller(context.Background(), ledger.CoinSellerTransferCommand{
|
||||
CommandID: "cmd-seller-no-policy",
|
||||
SellerUserID: 32001,
|
||||
TargetUserID: 32002,
|
||||
@ -1784,14 +1781,17 @@ func TestTransferCoinFromSellerRequiresRechargePolicy(t *testing.T) {
|
||||
Amount: 80000,
|
||||
Reason: "player recharge",
|
||||
})
|
||||
if !xerr.IsCode(err, xerr.NotFound) {
|
||||
t.Fatalf("expected NOT_FOUND when recharge policy is missing, got %v", err)
|
||||
if err != nil {
|
||||
t.Fatalf("TransferCoinFromSeller without recharge policy failed: %v", err)
|
||||
}
|
||||
if got := repository.CountRows("wallet_transactions", "command_id = ?", "cmd-seller-no-policy"); got != 0 {
|
||||
t.Fatalf("missing recharge policy must not write transaction, got %d", got)
|
||||
if receipt.RechargeUSDMinor != 0 || receipt.RechargePolicyID != 0 || receipt.RechargePolicyVersion != "" {
|
||||
t.Fatalf("policy-free transfer receipt mismatch: %+v", receipt)
|
||||
}
|
||||
if got := repository.CountRows("wallet_recharge_records", "transaction_id LIKE ?", "wtx_%"); got != 0 {
|
||||
t.Fatalf("missing recharge policy must not write recharge record, got %d", got)
|
||||
if got := repository.CountRows("wallet_transactions", "command_id = ?", "cmd-seller-no-policy"); got != 1 {
|
||||
t.Fatalf("policy-free seller transfer should write transaction, got %d", got)
|
||||
}
|
||||
if got := repository.CountRows("wallet_recharge_records", "transaction_id = ? AND coin_amount = ? AND usd_minor_amount = ? AND policy_id = ?", receipt.TransactionID, int64(80000), int64(0), int64(0)); got != 1 {
|
||||
t.Fatalf("policy-free seller transfer should write coin-only recharge record, got %d", got)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1214,14 +1214,8 @@ func (r *Repository) TransferCoinFromSeller(ctx context.Context, command ledger.
|
||||
}
|
||||
|
||||
transactionID := transactionID(command.AppCode, command.CommandID)
|
||||
policy, err := r.resolveRechargePolicy(ctx, tx, command.TargetRegionID, nowMs)
|
||||
if err != nil {
|
||||
return ledger.CoinSellerTransferReceipt{}, err
|
||||
}
|
||||
rechargeUSDMinor, err := calculateRechargeUSDMinor(command.Amount, policy)
|
||||
if err != nil {
|
||||
return ledger.CoinSellerTransferReceipt{}, err
|
||||
}
|
||||
// 币商转账的事实口径只记录金币数量;USD 价格策略属于外部充值定价,不参与币商库存转普通金币。
|
||||
rechargeUSDMinor := int64(0)
|
||||
rechargeSequence, err := r.reserveUserRechargeSequence(ctx, tx, command.AppCode, command.TargetUserID, transactionID, command.Amount, rechargeUSDMinor, nowMs)
|
||||
if err != nil {
|
||||
return ledger.CoinSellerTransferReceipt{}, err
|
||||
@ -1242,11 +1236,11 @@ func (r *Repository) TransferCoinFromSeller(ctx context.Context, command ledger.
|
||||
TargetBalanceAfter: targetAfter,
|
||||
RechargeSequence: rechargeSequence,
|
||||
RechargeUSDMinor: rechargeUSDMinor,
|
||||
RechargeCurrencyCode: policy.CurrencyCode,
|
||||
RechargePolicyID: policy.PolicyID,
|
||||
RechargePolicyVersion: policy.PolicyVersion,
|
||||
RechargePolicyCoinAmount: policy.CoinAmount,
|
||||
RechargePolicyUSDMinorAmount: policy.USDMinorAmount,
|
||||
RechargeCurrencyCode: "",
|
||||
RechargePolicyID: 0,
|
||||
RechargePolicyVersion: "",
|
||||
RechargePolicyCoinAmount: 0,
|
||||
RechargePolicyUSDMinorAmount: 0,
|
||||
}
|
||||
if err := r.insertTransaction(ctx, tx, transactionID, command.CommandID, bizTypeCoinSellerTransfer, requestHash, fmt.Sprintf("coin_seller:%d:%d", command.SellerUserID, command.TargetUserID), metadata, nowMs); err != nil {
|
||||
return ledger.CoinSellerTransferReceipt{}, err
|
||||
@ -1917,7 +1911,7 @@ func (r *Repository) insertRechargeRecord(ctx context.Context, tx *sql.Tx, trans
|
||||
metadata.RechargeCurrencyCode,
|
||||
metadata.Amount,
|
||||
metadata.RechargeUSDMinor,
|
||||
metadata.RechargePolicyCoinAmount,
|
||||
metadata.Amount,
|
||||
metadata.RechargePolicyUSDMinorAmount,
|
||||
nowMs,
|
||||
)
|
||||
|
||||
@ -449,7 +449,7 @@ func (r *Repository) SetGiftDiamondRatio(regionID int64, giftTypeCode string, ra
|
||||
}
|
||||
}
|
||||
|
||||
// SetRechargePolicy 配置区域充值汇率,用于币商转账充值口径测试。
|
||||
// SetRechargePolicy 配置区域充值定价,用于外部充值类事实测试。
|
||||
func (r *Repository) SetRechargePolicy(regionID int64, policyVersion string, coinAmount int64, usdMinorAmount int64) {
|
||||
r.t.Helper()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user