fix: Waffo webhook 支持 GET 探测,避免浏览器打开 404

仪表盘/浏览器用 GET 校验 URL 时返回 ready;支付事件仍走 POST。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Logan.LiandCursor committed 2026-08-12 15:57:37 +08:00
1 parent ac31cc059a
commit f00ea7e873
5 files changed
+16 -5

No files matched your search

+1 -1
View File
@@ -49,7 +49,7 @@ WAFFO_STORE_SLUG=opsxshell-pwsi6m4n
WAFFO_PRODUCT_ID=PROD_0pcnzzT4nalEkkcdyIUoD5
WAFFO_PRODUCT_ID_YEARLY=PROD_2WmkUVoYWt0NN8OVEyC6n3
WAFFO_PRODUCT_ID_PERPETUAL=PROD_0pcnzzT4nalEkkcdyIUoD5
WAFFO_CURRENCY=CNY
WAFFO_CURRENCY=USD
# test | live(test 时自动附加 test=true)
WAFFO_ENVIRONMENT=test
# 支付成功回跳(桌面端 deep link;CreateOrder/Checkout 的 return_url 可覆盖)
@@ -113,6 +113,16 @@ func (ctrl *OrderController) PaymentWebhook(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "Webhook processed"})
}
// WaffoWebhookReady GET/HEAD probe for dashboard URL checks (browser opens as GET). // Logan.Li
func (ctrl *OrderController) WaffoWebhookReady(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "waffo webhook ready",
"methods": []string{"POST"},
"hint": "Payment events must POST JSON with order_no / orderNo",
})
}
// WaffoWebhook accepts loosely-shaped Waffo payment events and maps to PaymentWebhook. // Logan.Li
func (ctrl *OrderController) WaffoWebhook(c *gin.Context) {
body, err := io.ReadAll(c.Request.Body)
+1 -1
View File
@@ -31,7 +31,7 @@ func LoadWaffoConfig() WaffoConfig {
}
currency := strings.TrimSpace(os.Getenv("WAFFO_CURRENCY"))
if currency == "" {
currency = "CNY"
currency = "USD"
}
defaultProduct := strings.TrimSpace(os.Getenv("WAFFO_PRODUCT_ID"))
yearly := strings.TrimSpace(os.Getenv("WAFFO_PRODUCT_ID_YEARLY"))
@@ -11,7 +11,7 @@ func TestBuildCheckoutURL_YearlySubscription(t *testing.T) {
StoreSlug: "opsxshell-pwsi6m4n",
ProductIDYearly: "PROD_2WmkUVoYWt0NN8OVEyC6n3",
ProductIDPerpetual: "PROD_0pcnzzT4nalEkkcdyIUoD5",
Currency: "CNY",
Currency: "USD",
Environment: "test",
SuccessURL: "opsxshell://pro/activated",
}
@@ -30,7 +30,7 @@ func TestBuildCheckoutURL_YearlySubscription(t *testing.T) {
if q.Get("type") != "subscription" {
t.Fatalf("type=%s want subscription", q.Get("type"))
}
if q.Get("currency") != "CNY" {
if q.Get("currency") != "USD" {
t.Fatalf("currency=%s", q.Get("currency"))
}
if q.Get("test") != "true" {
@@ -43,7 +43,7 @@ func TestBuildCheckoutURL_PerpetualOnetime(t *testing.T) {
StoreSlug: "opsxshell-pwsi6m4n",
ProductIDYearly: "PROD_2WmkUVoYWt0NN8OVEyC6n3",
ProductIDPerpetual: "PROD_0pcnzzT4nalEkkcdyIUoD5",
Currency: "CNY",
Currency: "USD",
Environment: "test",
SuccessURL: "opsxshell://pro/activated",
}
+1
View File
@@ -109,6 +109,7 @@ func SetupRouter(db *gorm.DB, cfg *config.Config) *gin.Engine {
register(clientAPI, "POST", "/checkout", orderController.Checkout)
register(clientAPI, "POST", "/purchase/claim", orderController.ClaimPurchase)
register(clientAPI, "POST", "/webhooks/payment", orderController.PaymentWebhook)
register(clientAPI, "GET", "/webhooks/waffo", orderController.WaffoWebhookReady)
register(clientAPI, "POST", "/webhooks/waffo", orderController.WaffoWebhook)
register(clientAPI, "POST", "/purchase/check", orderController.CheckDuplicatePurchase)
register(clientAPI, "POST", "/purchase/status", orderController.CheckPurchaseStatus)