From 8a2c092b5458193afe4095af272cf070ee57d7a0 Mon Sep 17 00:00:00 2001 From: orenzhang <41963680+OrenZhang@users.noreply.github.com> Date: Tue, 21 Apr 2026 17:13:41 +0800 Subject: [PATCH 1/2] feat(payment): add redirect base URL configuration for payment processing --- config.example.yaml | 9 +++++---- internal/apps/payment/epay.go | 2 +- internal/config/model.go | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/config.example.yaml b/config.example.yaml index 96b83e07..ac2c4924 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -116,7 +116,8 @@ otel: # Payment (LDC Credit EasyPay-compatible) payment: enabled: false - api_url: "https://credit.linux.do/epay" # 易支付网关地址 - notify_base_url: "https://your-domain.com" # 本项目公网基址,用于拼接回调 URL - config_encryption_key: "<32-char-secret-key!!>" # AES-256 密钥,恰好 32 字节,首次部署后不可更改 - order_expire_minutes: 10 # 订单未付款超时时间(分钟) + api_url: "https://credit.linux.do/epay" # 易支付网关地址 + notify_base_url: "http://cdk.cdk.svc.cluster.local" # CDK 的内网或公网地址,供支付网关回调使用 + redirect_base_url: "https://cdk.linux.do" # 支付完成后跳转的 URL 基址 + config_encryption_key: "<32-char-secret-key!!>" # AES-256 密钥,恰好 32 字节,首次部署后不可更改 + order_expire_minutes: 10 # 订单未付款超时时间(分钟) diff --git a/internal/apps/payment/epay.go b/internal/apps/payment/epay.go index 418c3bb7..d046d4e7 100644 --- a/internal/apps/payment/epay.go +++ b/internal/apps/payment/epay.go @@ -65,7 +65,7 @@ func callbackNotifyURL() string { // callbackReturnURL 返回同步回跳地址。 func callbackReturnURL() string { - return strings.TrimRight(config.Config.Payment.NotifyBaseURL, "/") + "/received" + return strings.TrimRight(config.Config.Payment.RedirectBaseURL, "/") + "/received" } // refundResponse 易支付退款接口响应 diff --git a/internal/config/model.go b/internal/config/model.go index bada9772..191b35f8 100644 --- a/internal/config/model.go +++ b/internal/config/model.go @@ -163,6 +163,9 @@ type PaymentConfig struct { // NotifyBaseURL 本项目对外可访问的基址(不含路径),例如 https://cdk.linux.do // 用于拼接 notify_url / return_url 并提示用户在 LDC 商户后台填写 NotifyBaseURL string `mapstructure:"notify_base_url"` + // RedirectBaseURL 本项目对外可访问的基址(不含路径),例如 https://cdk.linux.do + // 用于拼接 redirect_url 并提示用户在 LDC 商户后台填写 + RedirectBaseURL string `mapstructure:"redirect_base_url"` // ConfigEncryptionKey 用于加密用户 clientSecret 的密钥,必须是 32 字节长度 // 建议直接填 32 字符 ASCII 字符串或 base64 解码得 32 字节 ConfigEncryptionKey string `mapstructure:"config_encryption_key"` From bab70b424e412152ba52caa08bedbe94e6329339 Mon Sep 17 00:00:00 2001 From: orenzhang <41963680+OrenZhang@users.noreply.github.com> Date: Tue, 21 Apr 2026 17:26:10 +0800 Subject: [PATCH 2/2] feat(payment): update callbackReturnURL to include project ID in return path --- internal/apps/payment/epay.go | 8 ++++++-- internal/apps/payment/service.go | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/internal/apps/payment/epay.go b/internal/apps/payment/epay.go index d046d4e7..7a73c9b4 100644 --- a/internal/apps/payment/epay.go +++ b/internal/apps/payment/epay.go @@ -64,8 +64,12 @@ func callbackNotifyURL() string { } // callbackReturnURL 返回同步回跳地址。 -func callbackReturnURL() string { - return strings.TrimRight(config.Config.Payment.RedirectBaseURL, "/") + "/received" +func callbackReturnURL(projectID string) string { + baseURL := strings.TrimRight(config.Config.Payment.RedirectBaseURL, "/") + if projectID == "" { + return baseURL + "/received" + } + return baseURL + "/receive/" + projectID } // refundResponse 易支付退款接口响应 diff --git a/internal/apps/payment/service.go b/internal/apps/payment/service.go index dece1b4d..0758fc1d 100644 --- a/internal/apps/payment/service.go +++ b/internal/apps/payment/service.go @@ -227,9 +227,17 @@ func InitiatePayment(ctx context.Context, p *project.Project, payer *oauth.User, name := truncateRuneLen("CDK-"+p.Name, 60) init = PaymentInitiation{ OutTradeNo: outTradeNo, - PayURL: submitURL(cfg.ClientID, secret, name, moneyString(p.Price), outTradeNo, callbackNotifyURL(), callbackReturnURL()), - Amount: moneyString(p.Price), - ExpireAt: expireAt, + PayURL: submitURL( + cfg.ClientID, + secret, + name, + moneyString(p.Price), + outTradeNo, + callbackNotifyURL(), + callbackReturnURL(p.ID), + ), + Amount: moneyString(p.Price), + ExpireAt: expireAt, } return nil }) @@ -385,7 +393,7 @@ func fulfillPaidOrder(ctx context.Context, order *PaymentOrder) error { // CallbackURLs 返回当前平台配置的回调地址,用于前端展示给用户。 func CallbackURLs() (notifyURL, returnURL string) { - return callbackNotifyURL(), callbackReturnURL() + return callbackNotifyURL(), callbackReturnURL("") } // ErrOrderNotFoundSentinel 外部判断