package controller import ( "fmt" "log" "math" "net/http" "time" "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/model" "github.com/QuantumNous/new-api/setting" "github.com/gin-gonic/gin" "github.com/thanhpk/randstr" ) // SubscriptionWechatPayRequest 微信支付订阅请求参数 type SubscriptionWechatPayRequest struct { PlanId int `json:"plan_id"` } // SubscriptionRequestWechatPay 微信支付订阅购买 func SubscriptionRequestWechatPay(c *gin.Context) { var req SubscriptionWechatPayRequest if err := c.ShouldBindJSON(&req); err != nil || req.PlanId <= 0 { common.ApiErrorMsg(c, "参数错误") return } plan, err := model.GetSubscriptionPlanById(req.PlanId) if err != nil { common.ApiError(c, err) return } if !plan.Enabled { common.ApiErrorMsg(c, "套餐未启用") return } if !setting.IsWechatPayConfigured() { common.ApiErrorMsg(c, "微信支付未配置") return } userId := c.GetInt("id") user, err := model.GetUserById(userId, false) if err != nil { common.ApiError(c, err) return } if user == nil { common.ApiErrorMsg(c, "用户不存在") return } if plan.MaxPurchasePerUser > 0 { count, err := model.CountUserSubscriptionsByPlan(userId, plan.Id) if err != nil { common.ApiError(c, err) return } if count >= int64(plan.MaxPurchasePerUser) { common.ApiErrorMsg(c, "已达到该套餐购买上限") return } } client, err := getWechatPayClient() if err != nil { log.Println("获取微信支付客户端失败:", err) c.JSON(http.StatusOK, gin.H{"message": "error", "data": "微信支付配置错误"}) return } tradeNo := fmt.Sprintf("ws%d%s", time.Now().UnixMilli(), randstr.String(8)) totalFee := int(math.Round(plan.PriceAmount * 100)) // 元 -> 分 codeUrl, err := createWechatNativeOrder(client, plan.Title, tradeNo, totalFee) if err != nil { log.Println(err) c.JSON(http.StatusOK, gin.H{"message": "error", "data": "拉起支付失败"}) return } order := &model.SubscriptionOrder{ UserId: userId, PlanId: plan.Id, Money: plan.PriceAmount, TradeNo: tradeNo, PaymentMethod: PaymentMethodWechatPay, CreateTime: time.Now().Unix(), Status: common.TopUpStatusPending, } if err := order.Insert(); err != nil { c.JSON(http.StatusOK, gin.H{"message": "error", "data": "创建订单失败"}) return } c.JSON(http.StatusOK, gin.H{ "message": "success", "data": gin.H{ "trade_no": tradeNo, "qr_code_url": codeUrl, }, }) }