Преглед изворни кода

feat(epay): enhance parameter parsing for notify and return handlers

- Update EpayNotify and SubscriptionEpayNotify functions to handle both POST and GET requests for parameter parsing.
- Improve error handling by logging failures and returning appropriate responses when parameters are missing or parsing fails.
- Ensure consistent behavior across both notify and return routes for better reliability in payment processing.
CaIon пре 1 недеља
родитељ
комит
85b5d0100a
3 измењених фајлова са 61 додато и 28 уклоњено
  1. 38 18
      controller/subscription_payment_epay.go
  2. 21 10
      controller/topup.go
  3. 2 0
      router/api-router.go

+ 38 - 18
controller/subscription_payment_epay.go

@@ -112,21 +112,31 @@ func SubscriptionRequestEpay(c *gin.Context) {
 }
 
 func SubscriptionEpayNotify(c *gin.Context) {
-	if err := c.Request.ParseForm(); err != nil {
-		_, _ = c.Writer.Write([]byte("fail"))
-		return
-	}
-	params := lo.Reduce(lo.Keys(c.Request.PostForm), func(r map[string]string, t string, i int) map[string]string {
-		r[t] = c.Request.PostForm.Get(t)
-		return r
-	}, map[string]string{})
-	if len(params) == 0 {
+	var params map[string]string
+
+	if c.Request.Method == "POST" {
+		// POST 请求:从 POST body 解析参数
+		if err := c.Request.ParseForm(); err != nil {
+			_, _ = c.Writer.Write([]byte("fail"))
+			return
+		}
+		params = lo.Reduce(lo.Keys(c.Request.PostForm), func(r map[string]string, t string, i int) map[string]string {
+			r[t] = c.Request.PostForm.Get(t)
+			return r
+		}, map[string]string{})
+	} else {
+		// GET 请求:从 URL Query 解析参数
 		params = lo.Reduce(lo.Keys(c.Request.URL.Query()), func(r map[string]string, t string, i int) map[string]string {
 			r[t] = c.Request.URL.Query().Get(t)
 			return r
 		}, map[string]string{})
 	}
 
+	if len(params) == 0 {
+		_, _ = c.Writer.Write([]byte("fail"))
+		return
+	}
+
 	client := GetEpayClient()
 	if client == nil {
 		_, _ = c.Writer.Write([]byte("fail"))
@@ -157,21 +167,31 @@ func SubscriptionEpayNotify(c *gin.Context) {
 // SubscriptionEpayReturn handles browser return after payment.
 // It verifies the payload and completes the order, then redirects to console.
 func SubscriptionEpayReturn(c *gin.Context) {
-	if err := c.Request.ParseForm(); err != nil {
-		c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/subscription?pay=fail")
-		return
-	}
-	params := lo.Reduce(lo.Keys(c.Request.PostForm), func(r map[string]string, t string, i int) map[string]string {
-		r[t] = c.Request.PostForm.Get(t)
-		return r
-	}, map[string]string{})
-	if len(params) == 0 {
+	var params map[string]string
+
+	if c.Request.Method == "POST" {
+		// POST 请求:从 POST body 解析参数
+		if err := c.Request.ParseForm(); err != nil {
+			c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/subscription?pay=fail")
+			return
+		}
+		params = lo.Reduce(lo.Keys(c.Request.PostForm), func(r map[string]string, t string, i int) map[string]string {
+			r[t] = c.Request.PostForm.Get(t)
+			return r
+		}, map[string]string{})
+	} else {
+		// GET 请求:从 URL Query 解析参数
 		params = lo.Reduce(lo.Keys(c.Request.URL.Query()), func(r map[string]string, t string, i int) map[string]string {
 			r[t] = c.Request.URL.Query().Get(t)
 			return r
 		}, map[string]string{})
 	}
 
+	if len(params) == 0 {
+		c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/subscription?pay=fail")
+		return
+	}
+
 	client := GetEpayClient()
 	if client == nil {
 		c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/subscription?pay=fail")

+ 21 - 10
controller/topup.go

@@ -228,21 +228,32 @@ func UnlockOrder(tradeNo string) {
 }
 
 func EpayNotify(c *gin.Context) {
-	if err := c.Request.ParseForm(); err != nil {
-		log.Println("易支付回调解析失败:", err)
-		_, _ = c.Writer.Write([]byte("fail"))
-		return
-	}
-	params := lo.Reduce(lo.Keys(c.Request.PostForm), func(r map[string]string, t string, i int) map[string]string {
-		r[t] = c.Request.PostForm.Get(t)
-		return r
-	}, map[string]string{})
-	if len(params) == 0 {
+	var params map[string]string
+
+	if c.Request.Method == "POST" {
+		// POST 请求:从 POST body 解析参数
+		if err := c.Request.ParseForm(); err != nil {
+			log.Println("易支付回调POST解析失败:", err)
+			_, _ = c.Writer.Write([]byte("fail"))
+			return
+		}
+		params = lo.Reduce(lo.Keys(c.Request.PostForm), func(r map[string]string, t string, i int) map[string]string {
+			r[t] = c.Request.PostForm.Get(t)
+			return r
+		}, map[string]string{})
+	} else {
+		// GET 请求:从 URL Query 解析参数
 		params = lo.Reduce(lo.Keys(c.Request.URL.Query()), func(r map[string]string, t string, i int) map[string]string {
 			r[t] = c.Request.URL.Query().Get(t)
 			return r
 		}, map[string]string{})
 	}
+
+	if len(params) == 0 {
+		log.Println("易支付回调参数为空")
+		_, _ = c.Writer.Write([]byte("fail"))
+		return
+	}
 	client := GetEpayClient()
 	if client == nil {
 		log.Println("易支付回调失败 未找到配置信息")

+ 2 - 0
router/api-router.go

@@ -59,6 +59,7 @@ func SetApiRouter(router *gin.Engine) {
 			//userRoute.POST("/tokenlog", middleware.CriticalRateLimit(), controller.TokenLog)
 			userRoute.GET("/logout", controller.Logout)
 			userRoute.POST("/epay/notify", controller.EpayNotify)
+			userRoute.GET("/epay/notify", controller.EpayNotify)
 			userRoute.GET("/groups", controller.GetUserGroups)
 
 			selfRoute := userRoute.Group("/")
@@ -149,6 +150,7 @@ func SetApiRouter(router *gin.Engine) {
 
 		// Subscription payment callbacks (no auth)
 		apiRouter.POST("/subscription/epay/notify", controller.SubscriptionEpayNotify)
+		apiRouter.GET("/subscription/epay/notify", controller.SubscriptionEpayNotify)
 		apiRouter.GET("/subscription/epay/return", controller.SubscriptionEpayReturn)
 		apiRouter.POST("/subscription/epay/return", controller.SubscriptionEpayReturn)
 		optionRoute := apiRouter.Group("/option")