diff --git a/internal/provider/fake/fake.go b/internal/provider/fake/fake.go index da03694..e50caeb 100644 --- a/internal/provider/fake/fake.go +++ b/internal/provider/fake/fake.go @@ -76,7 +76,7 @@ func (p *Provider) Create(_ context.Context, req provider.CreateRequest) (*provi ProviderRef: ref, RenderType: provider.RenderRedirect, Payload: map[string]any{ - "url": "http://localhost:8090/result?out_trade_no=" + req.OutTradeNo, + "url": "http://localhost:8090/mock-cashier?out_trade_no=" + req.OutTradeNo, }, ExpiresAt: &exp, }, nil diff --git a/main.go b/main.go index 87a7a9d..117a078 100644 --- a/main.go +++ b/main.go @@ -94,7 +94,13 @@ func main() { // 入队,免去手工查库拼回调体。刻意不挂 stateChangeRateLimit(本机联调用,不设限)。 devH := handler.NewDevMockHandler(db, gw) r.POST("/api/v2/dev/orders/:order_no/mark-paid", devH.MarkPaid) - log.Println("[dev] MOCK_CHANNEL_ENABLED=true:已挂载 POST /api/v2/dev/orders/:order_no/mark-paid") + // dev-only:fake 渠道 redirect 形态的落地页(自包含,返回可用)。真实流程这里是 + // 支付宝/微信收银台;本地 mock 无需真付款,提示用户回购买页点「模拟付款成功」。 + r.GET("/mock-cashier", func(c *gin.Context) { + c.Header("Content-Type", "text/html; charset=utf-8") + c.String(200, mockCashierHTML) + }) + log.Println("[dev] MOCK_CHANNEL_ENABLED=true:已挂载 POST /api/v2/dev/orders/:order_no/mark-paid + GET /mock-cashier") } // P6 后台守护 / 对账:订单过期清理 + 用量刷新 + 查单对账收敛 + 已付抽查 + @@ -382,3 +388,35 @@ func seedPangolin(db *gorm.DB) { } log.Printf("[seed-pangolin] pangolin 业务套餐就绪:%d 个(pro_month/pro_quarter/pro_year,CNY+USDT)", len(plans)) } + +// mockCashierHTML — dev-only:fake 渠道 redirect 形态的自包含落地页(返回可用,无外链)。 +const mockCashierHTML = ` + +模拟收银台 + +
+
🧪
+

模拟支付收银台

+

这是本地联调的占位收银台,不是真实支付。

+
真实流程这里会是支付宝 / 微信 / Stripe 的收银台,你在此完成付款后渠道异步通知到账。 + 本地 mock 无需真付款——请关闭本页,回到购买页点击「🧪 模拟付款成功」即可看到订阅开通。
+
+ 关闭本页 + ← 返回上一页 +
+
`