mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-03-30 10:14:41 +00:00
✨ fix(subscription): finalize payments, log billing, and clean up dead code
Complete subscription orders by creating a matching top-up record and writing billing logs Add Epay return handler to verify and finalize browser callbacks Require Stripe/Creem webhook configuration before starting subscription payments Show subscription purchases in topup history with clearer labels/methods Remove unused subscription helper, legacy Creem webhook struct, and unused topup fields Simplify subscription self API payload to active/all lists only
This commit is contained in:
@@ -255,7 +255,11 @@ func CompleteSubscriptionOrder(tradeNo string, providerPayload string) error {
|
||||
if common.UsingPostgreSQL {
|
||||
refCol = `"trade_no"`
|
||||
}
|
||||
return DB.Transaction(func(tx *gorm.DB) error {
|
||||
var logUserId int
|
||||
var logPlanTitle string
|
||||
var logMoney float64
|
||||
var logPaymentMethod string
|
||||
err := DB.Transaction(func(tx *gorm.DB) error {
|
||||
var order SubscriptionOrder
|
||||
if err := tx.Set("gorm:query_option", "FOR UPDATE").Where(refCol+" = ?", tradeNo).First(&order).Error; err != nil {
|
||||
return errors.New("subscription order not found")
|
||||
@@ -277,13 +281,65 @@ func CompleteSubscriptionOrder(tradeNo string, providerPayload string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := upsertSubscriptionTopUpTx(tx, &order); err != nil {
|
||||
return err
|
||||
}
|
||||
order.Status = common.TopUpStatusSuccess
|
||||
order.CompleteTime = common.GetTimestamp()
|
||||
if providerPayload != "" {
|
||||
order.ProviderPayload = providerPayload
|
||||
}
|
||||
return tx.Save(&order).Error
|
||||
if err := tx.Save(&order).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
logUserId = order.UserId
|
||||
logPlanTitle = plan.Title
|
||||
logMoney = order.Money
|
||||
logPaymentMethod = order.PaymentMethod
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if logUserId > 0 {
|
||||
msg := fmt.Sprintf("订阅购买成功,套餐: %s,支付金额: %.2f,支付方式: %s", logPlanTitle, logMoney, logPaymentMethod)
|
||||
RecordLog(logUserId, LogTypeTopup, msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func upsertSubscriptionTopUpTx(tx *gorm.DB, order *SubscriptionOrder) error {
|
||||
if tx == nil || order == nil {
|
||||
return errors.New("invalid subscription order")
|
||||
}
|
||||
now := common.GetTimestamp()
|
||||
var topup TopUp
|
||||
if err := tx.Where("trade_no = ?", order.TradeNo).First(&topup).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
topup = TopUp{
|
||||
UserId: order.UserId,
|
||||
Amount: 0,
|
||||
Money: order.Money,
|
||||
TradeNo: order.TradeNo,
|
||||
PaymentMethod: order.PaymentMethod,
|
||||
CreateTime: order.CreateTime,
|
||||
CompleteTime: now,
|
||||
Status: common.TopUpStatusSuccess,
|
||||
}
|
||||
return tx.Create(&topup).Error
|
||||
}
|
||||
return err
|
||||
}
|
||||
topup.Money = order.Money
|
||||
if topup.PaymentMethod == "" {
|
||||
topup.PaymentMethod = order.PaymentMethod
|
||||
}
|
||||
if topup.CreateTime == 0 {
|
||||
topup.CreateTime = order.CreateTime
|
||||
}
|
||||
topup.CompleteTime = now
|
||||
topup.Status = common.TopUpStatusSuccess
|
||||
return tx.Save(&topup).Error
|
||||
}
|
||||
|
||||
func ExpireSubscriptionOrder(tradeNo string) error {
|
||||
@@ -323,26 +379,6 @@ func AdminBindSubscription(userId int, planId int, sourceNote string) error {
|
||||
})
|
||||
}
|
||||
|
||||
// Get current active subscription (best-effort: latest end_time)
|
||||
func GetActiveUserSubscription(userId int) (*SubscriptionSummary, error) {
|
||||
if userId <= 0 {
|
||||
return nil, errors.New("invalid userId")
|
||||
}
|
||||
now := common.GetTimestamp()
|
||||
var sub UserSubscription
|
||||
err := DB.Where("user_id = ? AND status = ? AND end_time > ?", userId, "active", now).
|
||||
Order("end_time desc, id desc").
|
||||
First(&sub).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var items []UserSubscriptionItem
|
||||
if err := DB.Where("user_subscription_id = ?", sub.Id).Find(&items).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SubscriptionSummary{Subscription: &sub, Items: items}, nil
|
||||
}
|
||||
|
||||
// GetAllActiveUserSubscriptions returns all active subscriptions for a user.
|
||||
func GetAllActiveUserSubscriptions(userId int) ([]SubscriptionSummary, error) {
|
||||
if userId <= 0 {
|
||||
|
||||
Reference in New Issue
Block a user