mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-21 14:19:18 +08:00
fix(payment): keep subscription price as direct pay amount
This commit is contained in:
@@ -23,14 +23,6 @@ func calculateCreditedBalance(paymentAmount, multiplier float64) float64 {
|
||||
InexactFloat64()
|
||||
}
|
||||
|
||||
func calculateGatewayPaymentAmount(orderAmount, multiplier float64, currency string) float64 {
|
||||
fractionDigits := int32(payment.CurrencyMaxFractionDigits(currency))
|
||||
return decimal.NewFromFloat(orderAmount).
|
||||
Div(decimal.NewFromFloat(normalizeBalanceRechargeMultiplier(multiplier))).
|
||||
Round(fractionDigits).
|
||||
InexactFloat64()
|
||||
}
|
||||
|
||||
func calculateGatewayRefundAmount(orderAmount, payAmount, refundAmount float64, currency string) float64 {
|
||||
if orderAmount <= 0 || payAmount <= 0 || refundAmount <= 0 {
|
||||
return 0
|
||||
|
||||
@@ -67,7 +67,8 @@ func (s *PaymentService) CreateOrder(ctx context.Context, req CreateOrderRequest
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
payAmountStr, payAmount, err := calculateCreateOrderPayAmountForOrder(req.OrderType, limitAmount, feeRate, cfg.BalanceRechargeMultiplier, methodCurrency)
|
||||
// 订阅套餐 price 是直付价,余额充值倍率只影响余额充值到账,不参与订阅 pay_amount 计算。
|
||||
payAmountStr, payAmount, err := calculateCreateOrderPayAmount(limitAmount, feeRate, methodCurrency)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -83,7 +84,7 @@ func (s *PaymentService) CreateOrder(ctx context.Context, req CreateOrderRequest
|
||||
selectedCurrency = paymentProviderConfigCurrency(sel.ProviderKey, sel.Config)
|
||||
}
|
||||
if selectedCurrency != methodCurrency {
|
||||
payAmountStr, payAmount, err = calculateCreateOrderPayAmountForOrder(req.OrderType, limitAmount, feeRate, cfg.BalanceRechargeMultiplier, selectedCurrency)
|
||||
payAmountStr, payAmount, err = calculateCreateOrderPayAmount(limitAmount, feeRate, selectedCurrency)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -612,19 +613,6 @@ func calculateCreateOrderPayAmount(limitAmount, feeRate float64, currency string
|
||||
return payAmountStr, payAmount, nil
|
||||
}
|
||||
|
||||
func calculateCreateOrderPayAmountForOrder(orderType string, limitAmount, feeRate, multiplier float64, currency string) (string, float64, error) {
|
||||
paymentAmount := calculateCreateOrderPaymentAmount(orderType, limitAmount, multiplier, currency)
|
||||
return calculateCreateOrderPayAmount(paymentAmount, feeRate, currency)
|
||||
}
|
||||
|
||||
func calculateCreateOrderPaymentAmount(orderType string, limitAmount, multiplier float64, currency string) float64 {
|
||||
normalizedCurrency, err := payment.NormalizePaymentCurrency(currency)
|
||||
if err != nil || normalizedCurrency != payment.DefaultPaymentCurrency || orderType != payment.OrderTypeSubscription {
|
||||
return limitAmount
|
||||
}
|
||||
return calculateGatewayPaymentAmount(limitAmount, multiplier, normalizedCurrency)
|
||||
}
|
||||
|
||||
func validateCreateOrderAmountCurrency(amount float64, currency string) error {
|
||||
amountStr := strconv.FormatFloat(amount, 'f', -1, 64)
|
||||
if _, err := payment.AmountToMinorUnit(amountStr, currency); err != nil {
|
||||
|
||||
@@ -126,69 +126,41 @@ func TestCalculateCreateOrderPayAmountUsesCurrencyPrecision(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateCreateOrderPayAmountForSubscriptionAppliesCNYMultiplier(t *testing.T) {
|
||||
func TestCalculateCreateOrderPayAmountForSubscriptionKeepsDirectPrice(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
amountStr, amount, err := calculateCreateOrderPayAmountForOrder(payment.OrderTypeSubscription, 7.99, 0, 0.14, "CNY")
|
||||
amountStr, amount, err := calculateCreateOrderPayAmount(5, 0, "CNY")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if amountStr != "57.07" || amount != 57.07 {
|
||||
t.Fatalf("subscription CNY pay amount = (%q, %v), want (57.07, 57.07)", amountStr, amount)
|
||||
if amountStr != "5.00" || amount != 5 {
|
||||
t.Fatalf("subscription CNY pay amount = (%q, %v), want (5.00, 5)", amountStr, amount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateCreateOrderPayAmountForSubscriptionDefaultMultiplierKeepsPrice(t *testing.T) {
|
||||
func TestCalculateCreateOrderPayAmountForSubscriptionAppliesFeeToDirectPrice(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, multiplier := range []float64{0, 1} {
|
||||
amountStr, amount, err := calculateCreateOrderPayAmountForOrder(payment.OrderTypeSubscription, 7.99, 0, multiplier, "CNY")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error for multiplier %v: %v", multiplier, err)
|
||||
}
|
||||
if amountStr != "7.99" || amount != 7.99 {
|
||||
t.Fatalf("multiplier %v pay amount = (%q, %v), want (7.99, 7.99)", multiplier, amountStr, amount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateCreateOrderPayAmountForSubscriptionDoesNotConvertNonCNY(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
amountStr, amount, err := calculateCreateOrderPayAmountForOrder(payment.OrderTypeSubscription, 7.99, 0, 0.14, "USD")
|
||||
amountStr, amount, err := calculateCreateOrderPayAmount(5, 2.5, "CNY")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if amountStr != "7.99" || amount != 7.99 {
|
||||
t.Fatalf("subscription USD pay amount = (%q, %v), want (7.99, 7.99)", amountStr, amount)
|
||||
if amountStr != "5.13" || amount != 5.13 {
|
||||
t.Fatalf("subscription CNY pay amount with fee = (%q, %v), want (5.13, 5.13)", amountStr, amount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateCreateOrderPayAmountForSubscriptionMatchesBalanceRechargeRatio(t *testing.T) {
|
||||
func TestCalculateCreditedBalanceStillUsesRechargeMultiplier(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
credited := calculateCreditedBalance(10, 0.14)
|
||||
if credited != 1.4 {
|
||||
t.Fatalf("credited balance = %v, want 1.4", credited)
|
||||
got := calculateCreditedBalance(10, 0.14)
|
||||
if got != 1.4 {
|
||||
t.Fatalf("credited balance = %v, want 1.4", got)
|
||||
}
|
||||
amountStr, amount, err := calculateCreateOrderPayAmountForOrder(payment.OrderTypeSubscription, credited, 0, 0.14, "CNY")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if amountStr != "10.00" || amount != 10 {
|
||||
t.Fatalf("subscription CNY pay amount = (%q, %v), want (10.00, 10)", amountStr, amount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateCreateOrderPayAmountForSubscriptionAppliesFeeAfterMultiplier(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
amountStr, amount, err := calculateCreateOrderPayAmountForOrder(payment.OrderTypeSubscription, 7.99, 2.5, 0.14, "CNY")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if amountStr != "58.50" || amount != 58.5 {
|
||||
t.Fatalf("subscription CNY pay amount with fee = (%q, %v), want (58.50, 58.5)", amountStr, amount)
|
||||
got = calculateCreditedBalance(5, 10)
|
||||
if got != 50 {
|
||||
t.Fatalf("credited balance = %v, want 50", got)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user