fix(wallet): sanitize mifapay return url

This commit is contained in:
zhx 2026-06-17 16:09:44 +08:00
parent f465c12d39
commit 87b3ebf167
2 changed files with 12 additions and 9 deletions

View File

@ -230,7 +230,7 @@ func (s *Service) createMifaPayRechargeOrder(ctx context.Context, command ledger
PayWay: order.PayWay,
PayType: order.PayType,
NotifyURL: notifyURL,
ReturnURL: mifaPayReturnURLWithOrderID(returnURL, order.OrderID),
ReturnURL: mifaPayProviderReturnURL(returnURL),
ClientIP: command.ClientIP,
Language: command.Language,
ProviderAmountMinor: providerAmountMinor,
@ -552,20 +552,19 @@ func mifaPayQueryMatchesOrder(data MifaPayNotifyData, order ledger.ExternalRecha
return err == nil && amount == order.ProviderAmountMinor
}
func mifaPayReturnURLWithOrderID(returnURL string, orderID string) string {
func mifaPayProviderReturnURL(returnURL string) string {
returnURL = strings.TrimSpace(returnURL)
orderID = strings.TrimSpace(orderID)
if returnURL == "" || orderID == "" {
if returnURL == "" {
return returnURL
}
parsed, err := url.Parse(returnURL)
if err != nil {
if err != nil || parsed.Scheme == "" || parsed.Host == "" {
return returnURL
}
query := parsed.Query()
// hyapp_order_id 是 H5 从三方收银台返回后的恢复锚点;真实归属仍由 gateway/wallet 按 target_user_id 校验
query.Set("hyapp_order_id", orderID)
parsed.RawQuery = query.Encode()
// MiFaPay 生产网关会对 payment.resultRedirect 做严格格式校验,动态 query 会在下单阶段被拒。
// 订单 ID 已经通过创建订单响应返回给 H5 并落在钱包库,回跳页只能作为稳定入口,不能依赖三方回传本地查询参数
parsed.RawQuery = ""
parsed.Fragment = ""
return parsed.String()
}

View File

@ -2251,6 +2251,7 @@ func TestH5MifaPayOrderRejectsUpstreamFailureAsUnavailable(t *testing.T) {
ProductID: product.ProductID,
ProviderCode: ledger.PaymentProviderMifaPay,
PaymentMethodID: saCardMethodID,
ReturnURL: "https://h5.global-interaction.com/recharge/index.html?app_code=lalu#checkout",
Language: "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
PayerName: "normal55",
PayerAccount: "163055",
@ -2265,6 +2266,9 @@ func TestH5MifaPayOrderRejectsUpstreamFailureAsUnavailable(t *testing.T) {
if mifaPay.createReq.Language != "zh-CN" {
t.Fatalf("mifapay language should be normalized before upstream call: %+v", mifaPay.createReq)
}
if mifaPay.createReq.ReturnURL != "https://h5.global-interaction.com/recharge/index.html" {
t.Fatalf("mifapay return url should be sent as stable provider redirect URL: %+v", mifaPay.createReq)
}
if len(mifaPay.createReq.OrderID) != 32 {
t.Fatalf("mifapay order_id must be 32 chars for upstream compatibility, got %q", mifaPay.createReq.OrderID)
}