25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

109 satır
2.5 KiB

  1. package controller
  2. import (
  3. "fmt"
  4. "log"
  5. "math"
  6. "net/http"
  7. "time"
  8. "github.com/QuantumNous/new-api/common"
  9. "github.com/QuantumNous/new-api/model"
  10. "github.com/QuantumNous/new-api/setting"
  11. "github.com/gin-gonic/gin"
  12. "github.com/thanhpk/randstr"
  13. )
  14. // SubscriptionWechatPayRequest 微信支付订阅请求参数
  15. type SubscriptionWechatPayRequest struct {
  16. PlanId int `json:"plan_id"`
  17. }
  18. // SubscriptionRequestWechatPay 微信支付订阅购买
  19. func SubscriptionRequestWechatPay(c *gin.Context) {
  20. var req SubscriptionWechatPayRequest
  21. if err := c.ShouldBindJSON(&req); err != nil || req.PlanId <= 0 {
  22. common.ApiErrorMsg(c, "参数错误")
  23. return
  24. }
  25. plan, err := model.GetSubscriptionPlanById(req.PlanId)
  26. if err != nil {
  27. common.ApiError(c, err)
  28. return
  29. }
  30. if !plan.Enabled {
  31. common.ApiErrorMsg(c, "套餐未启用")
  32. return
  33. }
  34. if !setting.IsWechatPayConfigured() {
  35. common.ApiErrorMsg(c, "微信支付未配置")
  36. return
  37. }
  38. userId := c.GetInt("id")
  39. user, err := model.GetUserById(userId, false)
  40. if err != nil {
  41. common.ApiError(c, err)
  42. return
  43. }
  44. if user == nil {
  45. common.ApiErrorMsg(c, "用户不存在")
  46. return
  47. }
  48. if plan.MaxPurchasePerUser > 0 {
  49. count, err := model.CountUserSubscriptionsByPlan(userId, plan.Id)
  50. if err != nil {
  51. common.ApiError(c, err)
  52. return
  53. }
  54. if count >= int64(plan.MaxPurchasePerUser) {
  55. common.ApiErrorMsg(c, "已达到该套餐购买上限")
  56. return
  57. }
  58. }
  59. client, err := getWechatPayClient()
  60. if err != nil {
  61. log.Println("获取微信支付客户端失败:", err)
  62. c.JSON(http.StatusOK, gin.H{"message": "error", "data": "微信支付配置错误"})
  63. return
  64. }
  65. tradeNo := fmt.Sprintf("ws%d%s", time.Now().UnixMilli(), randstr.String(8))
  66. totalFee := int(math.Round(plan.PriceAmount * 100)) // 元 -> 分
  67. codeUrl, err := createWechatNativeOrder(client, plan.Title, tradeNo, totalFee)
  68. if err != nil {
  69. log.Println(err)
  70. c.JSON(http.StatusOK, gin.H{"message": "error", "data": "拉起支付失败"})
  71. return
  72. }
  73. order := &model.SubscriptionOrder{
  74. UserId: userId,
  75. PlanId: plan.Id,
  76. Money: plan.PriceAmount,
  77. TradeNo: tradeNo,
  78. PaymentMethod: PaymentMethodWechatPay,
  79. CreateTime: time.Now().Unix(),
  80. Status: common.TopUpStatusPending,
  81. }
  82. if err := order.Insert(); err != nil {
  83. c.JSON(http.StatusOK, gin.H{"message": "error", "data": "创建订单失败"})
  84. return
  85. }
  86. c.JSON(http.StatusOK, gin.H{
  87. "message": "success",
  88. "data": gin.H{
  89. "trade_no": tradeNo,
  90. "qr_code_url": codeUrl,
  91. },
  92. })
  93. }