Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

110 rader
2.6 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. reference := fmt.Sprintf("wx-sub-%d-%d-%s", user.Id, time.Now().UnixMilli(), randstr.String(4))
  66. tradeNo := "wx_sub_" + common.Sha1([]byte(reference))
  67. totalFee := int(math.Round(plan.PriceAmount * 100)) // 元 -> 分
  68. codeUrl, err := createWechatNativeOrder(client, plan.Title, tradeNo, totalFee)
  69. if err != nil {
  70. log.Println(err)
  71. c.JSON(http.StatusOK, gin.H{"message": "error", "data": "拉起支付失败"})
  72. return
  73. }
  74. order := &model.SubscriptionOrder{
  75. UserId: userId,
  76. PlanId: plan.Id,
  77. Money: plan.PriceAmount,
  78. TradeNo: tradeNo,
  79. PaymentMethod: PaymentMethodWechatPay,
  80. CreateTime: time.Now().Unix(),
  81. Status: common.TopUpStatusPending,
  82. }
  83. if err := order.Insert(); err != nil {
  84. c.JSON(http.StatusOK, gin.H{"message": "error", "data": "创建订单失败"})
  85. return
  86. }
  87. c.JSON(http.StatusOK, gin.H{
  88. "message": "success",
  89. "data": gin.H{
  90. "trade_no": tradeNo,
  91. "qr_code_url": codeUrl,
  92. },
  93. })
  94. }