fix(dev): redirect 形态落地自包含 mock-cashier 页(返回可用),替代 /result 的 404 死路
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 = `<!doctype html><html lang="zh"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>模拟收银台</title>
|
||||
<style>
|
||||
:root{color-scheme:dark}
|
||||
body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;
|
||||
background:#0b0f17;color:#e8edf5;font:16px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}
|
||||
.card{max-width:460px;padding:36px 32px;background:#141a24;border:1px solid #232c3a;
|
||||
border-radius:16px;text-align:center;box-shadow:0 8px 40px rgba(0,0,0,.4)}
|
||||
h1{font-size:22px;margin:8px 0 6px}
|
||||
.sub{color:#93a1b5;font-size:14px;margin:0 0 20px}
|
||||
.tip{background:#0f1622;border:1px solid #232c3a;border-radius:10px;padding:14px 16px;
|
||||
font-size:13px;color:#aab6c6;text-align:left;margin:0 0 22px}
|
||||
.btn{display:inline-block;padding:11px 20px;border-radius:10px;border:1px solid #2f3b4d;
|
||||
background:#1b2432;color:#cdd7e4;text-decoration:none;font-size:14px;cursor:pointer}
|
||||
.btn.primary{background:#2563eb;border-color:#2563eb;color:#fff}
|
||||
.row{display:flex;gap:10px;justify-content:center}
|
||||
.emoji{font-size:40px}
|
||||
</style></head><body>
|
||||
<div class="card">
|
||||
<div class="emoji">🧪</div>
|
||||
<h1>模拟支付收银台</h1>
|
||||
<p class="sub">这是本地联调的占位收银台,不是真实支付。</p>
|
||||
<div class="tip">真实流程这里会是<b>支付宝 / 微信 / Stripe</b> 的收银台,你在此完成付款后渠道异步通知到账。
|
||||
本地 mock 无需真付款——请<b>关闭本页</b>,回到购买页点击<b>「🧪 模拟付款成功」</b>即可看到订阅开通。</div>
|
||||
<div class="row">
|
||||
<a class="btn primary" href="javascript:window.close()">关闭本页</a>
|
||||
<a class="btn" href="javascript:history.back()">← 返回上一页</a>
|
||||
</div>
|
||||
</div></body></html>`
|
||||
|
||||
Reference in New Issue
Block a user