fix(topup): reject uncreditable orders before payment (#6845)

* fix(topup): reject uncreditable orders before payment

* fix(topup): align zero-ratio Stripe validation

* fix(topup): mirror settlement conversions in validation
This commit is contained in:
Shawn Wang
2026-08-14 17:01:32 +08:00
committed by GitHub
parent e5efc73cdb
commit 2a0ce3475c
6 changed files with 251 additions and 0 deletions
+25
View File
@@ -17,6 +17,7 @@ import (
"github.com/QuantumNous/new-api/setting/operation_setting"
"github.com/gin-gonic/gin"
"github.com/shopspring/decimal"
"github.com/stripe/stripe-go/v81"
"github.com/stripe/stripe-go/v81/checkout/session"
"github.com/stripe/stripe-go/v81/webhook"
@@ -47,12 +48,20 @@ func (*StripeAdaptor) RequestAmount(c *gin.Context, req *StripePayRequest) {
c.JSON(http.StatusOK, gin.H{"message": "error", "data": fmt.Sprintf("充值数量不能小于 %d", getStripeMinTopup())})
return
}
if req.Amount > 10000 {
c.JSON(http.StatusOK, gin.H{"message": "error", "data": "充值数量不能大于 10000"})
return
}
id := c.GetInt("id")
group, err := model.GetUserGroup(id, true)
if err != nil {
c.JSON(http.StatusOK, gin.H{"message": "error", "data": "获取用户分组失败"})
return
}
if err := validateCreditedQuota(getStripeCreditedQuota(req.Amount, group)); err != nil {
c.JSON(http.StatusOK, gin.H{"message": "error", "data": err.Error()})
return
}
payMoney := getStripePayMoney(float64(req.Amount), group)
if payMoney <= 0.01 {
c.JSON(http.StatusOK, gin.H{"message": "error", "data": "充值金额过低"})
@@ -88,6 +97,12 @@ func (*StripeAdaptor) RequestPay(c *gin.Context, req *StripePayRequest) {
id := c.GetInt("id")
user, _ := model.GetUserById(id, false)
chargedMoney := GetChargedAmount(float64(req.Amount), *user)
if err := validateCreditedQuota(
decimal.NewFromFloat(chargedMoney).Mul(decimal.NewFromFloat(common.QuotaPerUnit)),
); err != nil {
c.JSON(http.StatusOK, gin.H{"message": "error", "data": err.Error()})
return
}
reference := fmt.Sprintf("new-api-ref-%d-%d-%s", user.Id, time.Now().UnixMilli(), randstr.String(4))
referenceId := "ref_" + common.Sha1([]byte(reference))
@@ -394,6 +409,16 @@ func GetChargedAmount(count float64, user model.User) float64 {
return count * topUpGroupRatio
}
func getStripeCreditedQuota(amount int64, group string) decimal.Decimal {
topUpGroupRatio := common.GetTopupGroupRatio(group)
if topUpGroupRatio == 0 {
topUpGroupRatio = 1
}
return decimal.NewFromInt(amount).
Mul(decimal.NewFromFloat(topUpGroupRatio)).
Mul(decimal.NewFromFloat(common.QuotaPerUnit))
}
func getStripePayMoney(amount float64, group string) float64 {
originalAmount := amount
if operation_setting.GetQuotaDisplayType() == operation_setting.QuotaDisplayTypeTokens {