feat(order): add validation for quantity and amount limits in order requests

This commit is contained in:
Chang lue Tsen
2026-02-08 06:41:23 -05:00
parent 1995987f00
commit 701d47ed21
8 changed files with 106 additions and 23 deletions
+5
View File
@@ -6,4 +6,9 @@ const (
StripeAlipay = "stripe_alipay"
StripeWeChatPay = "stripe_wechat_pay"
Balance = "balance"
// MaxOrderAmount Order amount limits
MaxOrderAmount = 2147483647 // int32 max value (2.1 billion)
MaxRechargeAmount = 2000000000 // 2 billion, slightly lower for safety
MaxQuantity = 1000 // Maximum quantity per order
)
@@ -58,6 +58,12 @@ func (l *PurchaseLogic) Purchase(req *types.PurchaseOrderRequest) (resp *types.P
req.Quantity = 1
}
// Validate quantity limit
if req.Quantity > MaxQuantity {
l.Errorw("[Purchase] Quantity exceeds maximum limit", logger.Field("quantity", req.Quantity), logger.Field("max", MaxQuantity))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "quantity exceeds maximum limit of %d", MaxQuantity)
}
// find user subscription
userSub, err := l.svcCtx.UserModel.QueryUserSubscribe(l.ctx, u.Id)
if err != nil {
@@ -110,6 +116,17 @@ func (l *PurchaseLogic) Purchase(req *types.PurchaseOrderRequest) (resp *types.P
// discount amount
amount := int64(float64(price) * discount)
discountAmount := price - amount
// Validate amount to prevent overflow
if amount > MaxOrderAmount {
l.Errorw("[Purchase] Order amount exceeds maximum limit",
logger.Field("amount", amount),
logger.Field("max", MaxOrderAmount),
logger.Field("user_id", u.Id),
logger.Field("subscribe_id", req.SubscribeId))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "order amount exceeds maximum limit")
}
var coupon int64 = 0
// Calculate the coupon deduction
if req.Coupon != "" {
@@ -167,6 +184,15 @@ func (l *PurchaseLogic) Purchase(req *types.PurchaseOrderRequest) (resp *types.P
if amount > 0 {
feeAmount = calculateFee(amount, payment)
amount += feeAmount
// Final validation after adding fee
if amount > MaxOrderAmount {
l.Errorw("[Purchase] Final order amount exceeds maximum limit after fee",
logger.Field("amount", amount),
logger.Field("max", MaxOrderAmount),
logger.Field("user_id", u.Id))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "order amount exceeds maximum limit")
}
}
// query user is new purchase or renewal
isNew, err := l.svcCtx.OrderModel.IsUserEligibleForNewOrder(l.ctx, u.Id)
+27 -1
View File
@@ -40,6 +40,21 @@ func (l *RechargeLogic) Recharge(req *types.RechargeOrderRequest) (resp *types.R
logger.Error("current user is not found in context")
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
}
// Validate recharge amount
if req.Amount <= 0 {
l.Errorw("[Recharge] Invalid recharge amount", logger.Field("amount", req.Amount), logger.Field("user_id", u.Id))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "recharge amount must be greater than 0")
}
if req.Amount > MaxRechargeAmount {
l.Errorw("[Recharge] Recharge amount exceeds maximum limit",
logger.Field("amount", req.Amount),
logger.Field("max", MaxRechargeAmount),
logger.Field("user_id", u.Id))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "recharge amount exceeds maximum limit")
}
// find payment method
payment, err := l.svcCtx.PaymentModel.FindOne(l.ctx, req.Payment)
if err != nil {
@@ -48,6 +63,17 @@ func (l *RechargeLogic) Recharge(req *types.RechargeOrderRequest) (resp *types.R
}
// Calculate the handling fee
feeAmount := calculateFee(req.Amount, payment)
totalAmount := req.Amount + feeAmount
// Validate total amount after adding fee
if totalAmount > MaxOrderAmount {
l.Errorw("[Recharge] Total amount exceeds maximum limit after fee",
logger.Field("amount", totalAmount),
logger.Field("max", MaxOrderAmount),
logger.Field("user_id", u.Id))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "total amount exceeds maximum limit")
}
// query user is new purchase or renewal
isNew, err := l.svcCtx.OrderModel.IsUserEligibleForNewOrder(l.ctx, u.Id)
if err != nil {
@@ -59,7 +85,7 @@ func (l *RechargeLogic) Recharge(req *types.RechargeOrderRequest) (resp *types.R
OrderNo: tool.GenerateTradeNo(),
Type: 4,
Price: req.Amount,
Amount: req.Amount + feeAmount,
Amount: totalAmount,
FeeAmount: feeAmount,
PaymentId: payment.Id,
Method: payment.Platform,
@@ -50,6 +50,12 @@ func (l *RenewalLogic) Renewal(req *types.RenewalOrderRequest) (resp *types.Rene
req.Quantity = 1
}
// Validate quantity limit
if req.Quantity > MaxQuantity {
l.Errorw("[Renewal] Quantity exceeds maximum limit", logger.Field("quantity", req.Quantity), logger.Field("max", MaxQuantity))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "quantity exceeds maximum limit of %d", MaxQuantity)
}
orderNo := tool.GenerateTradeNo()
// find user subscribe
userSubscribe, err := l.svcCtx.UserModel.FindOneUserSubscribe(l.ctx, req.UserSubscribeID)
@@ -75,6 +81,17 @@ func (l *RenewalLogic) Renewal(req *types.RenewalOrderRequest) (resp *types.Rene
price := sub.UnitPrice * req.Quantity
amount := int64(float64(price) * discount)
discountAmount := price - amount
// Validate amount to prevent overflow
if amount > MaxOrderAmount {
l.Errorw("[Renewal] Order amount exceeds maximum limit",
logger.Field("amount", amount),
logger.Field("max", MaxOrderAmount),
logger.Field("user_id", u.Id),
logger.Field("subscribe_id", sub.Id))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "order amount exceeds maximum limit")
}
var coupon int64 = 0
if req.Coupon != "" {
couponInfo, err := l.svcCtx.CouponModel.FindOneByCode(l.ctx, req.Coupon)
@@ -134,6 +151,15 @@ func (l *RenewalLogic) Renewal(req *types.RenewalOrderRequest) (resp *types.Rene
amount += feeAmount
// Final validation after adding fee
if amount > MaxOrderAmount {
l.Errorw("[Renewal] Final order amount exceeds maximum limit after fee",
logger.Field("amount", amount),
logger.Field("max", MaxOrderAmount),
logger.Field("user_id", u.Id))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "order amount exceeds maximum limit")
}
// create order
orderInfo := order.Order{
UserId: u.Id,