🔧 fix: make epay webhook and return flow subscription-aware

Ensure Epay webhook acknowledges success only after order completion, returning fail on processing errors to allow retries. Redirect subscription payment returns to the subscription page instead of top-up for correct user flow.
This commit is contained in:
t0ng7u
2026-02-03 00:01:24 +08:00
parent 34e5720773
commit ef44a341a8

View File

@@ -123,24 +123,22 @@ func SubscriptionEpayNotify(c *gin.Context) {
return
}
verifyInfo, err := client.Verify(params)
if err == nil && verifyInfo.VerifyStatus {
_, _ = c.Writer.Write([]byte("success"))
} else {
if err != nil || !verifyInfo.VerifyStatus {
_, _ = c.Writer.Write([]byte("fail"))
return
}
if verifyInfo.TradeStatus != epay.StatusTradeSuccess {
return
if verifyInfo.TradeStatus == epay.StatusTradeSuccess {
LockOrder(verifyInfo.ServiceTradeNo)
defer UnlockOrder(verifyInfo.ServiceTradeNo)
if err := model.CompleteSubscriptionOrder(verifyInfo.ServiceTradeNo, common.GetJsonString(verifyInfo)); err != nil {
_, _ = c.Writer.Write([]byte("fail"))
return
}
}
LockOrder(verifyInfo.ServiceTradeNo)
defer UnlockOrder(verifyInfo.ServiceTradeNo)
if err := model.CompleteSubscriptionOrder(verifyInfo.ServiceTradeNo, common.GetJsonString(verifyInfo)); err != nil {
// do not fail webhook response after signature verified
return
}
_, _ = c.Writer.Write([]byte("success"))
}
// SubscriptionEpayReturn handles browser return after payment.
@@ -153,20 +151,20 @@ func SubscriptionEpayReturn(c *gin.Context) {
client := GetEpayClient()
if client == nil {
c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/topup?pay=fail")
c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/subscription?pay=fail")
return
}
verifyInfo, err := client.Verify(params)
if err != nil || !verifyInfo.VerifyStatus {
c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/topup?pay=fail")
c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/subscription?pay=fail")
return
}
if verifyInfo.TradeStatus == epay.StatusTradeSuccess {
LockOrder(verifyInfo.ServiceTradeNo)
defer UnlockOrder(verifyInfo.ServiceTradeNo)
_ = model.CompleteSubscriptionOrder(verifyInfo.ServiceTradeNo, common.GetJsonString(verifyInfo))
c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/topup?pay=success")
c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/subscription?pay=success")
return
}
c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/topup?pay=pending")
c.Redirect(http.StatusFound, system_setting.ServerAddress+"/console/subscription?pay=pending")
}