Skip to content

feat(billing): allow site-relative EPay V2 endpoint - #267

Merged
Ember-Moth merged 2 commits into
perfect-panel:masterfrom
echoowall:feat/epay-v2-relative-endpoint
Oct 28, 2026
Merged

Ember-Moth merged 2 commits into
perfect-panel:masterfrom
echoowall:feat/epay-v2-relative-endpoint

Conversation

@echoowall

Copy link
Copy Markdown
Contributor

背景

#266 让 V1 页面支付的 EPay 地址可以填 /pay 这类站内路径:浏览器拿到的付款链接保持相对,跟着用户当前访问的域名走;服务端查单用支付方式的 Domain 拼出完整地址。

V2(RSA)目前做不到这一点。protocol.NewClient 要求 BaseURL 是不带路径的 HTTPS 根地址,openEPay 也只对 V1 页面支付解析相对地址。结果是:

  • V2 填 /pay 或 //pay.example/pay 会在保存或打开支付方式时直接报错;
  • 即使填绝对地址,只要 EPay 部署在子路径下(如 https://pay.example/pay),V2 也无法使用。

面板通过多个域名或多层反向代理对外服务、而 EPay 部署在面板站点子路径下时,V2 用户和 V1 用户遇到的是同一个问题。

改动

  • protocol.NewClient:BaseURL 仍然必须是 HTTPS、不带凭据、查询串和片段,但允许规范的部署路径(path.Clean 后不变,不含 ..、重复斜杠和转义字符)。所有请求按 BaseURL + /api/... 拼接。
  • openEPay:V2(页面支付和 API 下单)与 V1 页面支付一样,用 epayEndpoint 解析站内路径和协议相对地址;站内路径必须配置 Domain,且 V2 要求它是 HTTPS。
  • StartPayment:V2 页面支付的跳转链接与 V1 一样,站内路径时只返回 RequestURI,协议相对时去掉 https:。两处共用 browserURL。
  • normalizeEPay:V2 的相对地址先按占位域名做校验,保存时保留原写法,不会被改写成绝对地址。
  • V1 API 下单(checkout_mode=api)行为不变。
  • 更新 docs/guide/epay.md 和 docs/guide/epay-zh.md 中的地址规则。

测试

新增 internal/module/billing/internal/gateway/epay_v2_relative_test.go,使用现有的 billingtest.NewEPayV2(独立签名验签的 V2 测试桩):

  • 站内路径 /pay:页面支付返回 /pay/api/pay/submit?...,签名参数完整;服务端查单请求 /pay/api/pay/query。
  • 站内路径 + API 下单:下单请求 /pay/api/pay/create。
  • 绝对部署路径 https://…/pay/ 和协议相对 //…/pay:链接前缀正确,查单走 /pay/api/pay/query。
  • 站内路径缺少 Domain、或 Domain 是 HTTP 时拒绝打开。
  • 规范化保留 /pay、/pay/、//pay.example/pay、https://pay.example/pay 原样;拒绝 /pay?key=x、/pay#fragment、///host、/pay/../admin、/pay/%2e%2e、http://…。

protocol/client_test.go 新增 TestClientAcceptsDeploymentPath,覆盖带路径基址的拼接,以及 HTTP、查询串、片段、凭据、..、重复斜杠、转义字符的拒绝。

逐一撤回各处改动做过反向验证,对应测试均会失败。

gofmt -l .        # 无输出
go build ./...
go vet ./...
go test ./...
go test -race ./internal/module/billing/...
make lint

echoowall and others added 2 commits October 28, 2026 14:29
Reject canonical escapes and repeated slashes before trimming the deployment path, and preserve escaped path serialization when constructing the client URL. Cover configuration normalization, gateway opening, root deployment redirects and both checkout modes.
@Ember-Moth
Ember-Moth merged commit 9232f51 into perfect-panel:master Oct 28, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants