feat(payment): 支持强制移动端统一使用二维码支付

This commit is contained in:
wucm667
2026-05-19 18:22:12 +08:00
parent 8927ab091e
commit e4c7927eff
13 changed files with 144 additions and 3 deletions
@@ -278,6 +278,7 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
PaymentCancelRateLimitWindow: paymentCfg.CancelRateLimitWindow,
PaymentCancelRateLimitUnit: paymentCfg.CancelRateLimitUnit,
PaymentCancelRateLimitMode: paymentCfg.CancelRateLimitMode,
PaymentAlipayForceQRCode: paymentCfg.AlipayForceQRCode,
ChannelMonitorEnabled: settings.ChannelMonitorEnabled,
ChannelMonitorDefaultIntervalSeconds: settings.ChannelMonitorDefaultIntervalSeconds,
@@ -603,6 +604,9 @@ type UpdateSettingsRequest struct {
PaymentCancelRateLimitUnit *string `json:"payment_cancel_rate_limit_unit"`
PaymentCancelRateLimitMode *string `json:"payment_cancel_rate_limit_window_mode"`
// Force Alipay mobile clients to use QR code payment instead of mobile redirect
PaymentAlipayForceQRCode *bool `json:"payment_alipay_force_qrcode"`
// Channel Monitor feature switch
ChannelMonitorEnabled *bool `json:"channel_monitor_enabled"`
ChannelMonitorDefaultIntervalSeconds *int `json:"channel_monitor_default_interval_seconds"`
@@ -1774,6 +1778,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
CancelRateLimitWindow: req.PaymentCancelRateLimitWindow,
CancelRateLimitUnit: req.PaymentCancelRateLimitUnit,
CancelRateLimitMode: req.PaymentCancelRateLimitMode,
AlipayForceQRCode: req.PaymentAlipayForceQRCode,
}
if err := h.paymentConfigService.UpdatePaymentConfig(c.Request.Context(), paymentReq); err != nil {
response.ErrorFrom(c, err)
@@ -1981,6 +1986,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
PaymentCancelRateLimitWindow: updatedPaymentCfg.CancelRateLimitWindow,
PaymentCancelRateLimitUnit: updatedPaymentCfg.CancelRateLimitUnit,
PaymentCancelRateLimitMode: updatedPaymentCfg.CancelRateLimitMode,
PaymentAlipayForceQRCode: updatedPaymentCfg.AlipayForceQRCode,
ChannelMonitorEnabled: updatedSettings.ChannelMonitorEnabled,
ChannelMonitorDefaultIntervalSeconds: updatedSettings.ChannelMonitorDefaultIntervalSeconds,
@@ -2022,7 +2028,8 @@ func hasPaymentFields(req UpdateSettingsRequest) bool {
req.PaymentProductNameSuffix != nil || req.PaymentHelpImageURL != nil ||
req.PaymentHelpText != nil || req.PaymentCancelRateLimitEnabled != nil ||
req.PaymentCancelRateLimitMax != nil || req.PaymentCancelRateLimitWindow != nil ||
req.PaymentCancelRateLimitUnit != nil || req.PaymentCancelRateLimitMode != nil
req.PaymentCancelRateLimitUnit != nil || req.PaymentCancelRateLimitMode != nil ||
req.PaymentAlipayForceQRCode != nil
}
func (h *SettingHandler) auditSettingsUpdate(c *gin.Context, before *service.SystemSettings, after *service.SystemSettings, beforeAuthSourceDefaults *service.AuthSourceDefaultSettings, afterAuthSourceDefaults *service.AuthSourceDefaultSettings, req UpdateSettingsRequest) {
+3
View File
@@ -218,6 +218,9 @@ type SystemSettings struct {
PaymentCancelRateLimitUnit string `json:"payment_cancel_rate_limit_unit"`
PaymentCancelRateLimitMode string `json:"payment_cancel_rate_limit_window_mode"`
// Force Alipay mobile clients to use QR code payment instead of mobile redirect
PaymentAlipayForceQRCode bool `json:"payment_alipay_force_qrcode"`
// Balance low notification
BalanceLowNotifyEnabled bool `json:"balance_low_notify_enabled"`
BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
@@ -141,6 +141,7 @@ func (h *PaymentHandler) GetCheckoutInfo(c *gin.Context) {
HelpText: cfg.HelpText,
HelpImageURL: cfg.HelpImageURL,
StripePublishableKey: cfg.StripePublishableKey,
AlipayForceQRCode: cfg.AlipayForceQRCode,
})
}
@@ -155,6 +156,7 @@ type checkoutInfoResponse struct {
HelpText string `json:"help_text"`
HelpImageURL string `json:"help_image_url"`
StripePublishableKey string `json:"stripe_publishable_key"`
AlipayForceQRCode bool `json:"alipay_force_qrcode"`
}
type checkoutPlan struct {
@@ -858,6 +858,7 @@ func TestAPIContracts(t *testing.T) {
"payment_cancel_rate_limit_window": 0,
"payment_cancel_rate_limit_unit": "",
"payment_cancel_rate_limit_window_mode": "",
"payment_alipay_force_qrcode": false,
"balance_low_notify_enabled": false,
"account_quota_notify_enabled": false,
"balance_low_notify_threshold": 0,
@@ -1080,6 +1081,7 @@ func TestAPIContracts(t *testing.T) {
"payment_cancel_rate_limit_window": 0,
"payment_cancel_rate_limit_unit": "",
"payment_cancel_rate_limit_window_mode": "",
"payment_alipay_force_qrcode": false,
"balance_low_notify_enabled": false,
"account_quota_notify_enabled": false,
"balance_low_notify_threshold": 0,
@@ -34,6 +34,7 @@ const (
SettingCancelWindowSize = "CANCEL_RATE_LIMIT_WINDOW"
SettingCancelWindowUnit = "CANCEL_RATE_LIMIT_UNIT"
SettingCancelWindowMode = "CANCEL_RATE_LIMIT_WINDOW_MODE"
SettingAlipayForceQRCode = "ALIPAY_FORCE_QRCODE"
)
// Default values for payment configuration settings.
@@ -67,6 +68,9 @@ type PaymentConfig struct {
CancelRateLimitWindow int `json:"cancel_rate_limit_window"`
CancelRateLimitUnit string `json:"cancel_rate_limit_unit"`
CancelRateLimitMode string `json:"cancel_rate_limit_window_mode"`
// Force Alipay mobile users to use QR code instead of mobile redirect
AlipayForceQRCode bool `json:"alipay_force_qrcode"`
}
// UpdatePaymentConfigRequest contains fields to update payment configuration.
@@ -94,6 +98,9 @@ type UpdatePaymentConfigRequest struct {
CancelRateLimitUnit *string `json:"cancel_rate_limit_unit"`
CancelRateLimitMode *string `json:"cancel_rate_limit_window_mode"`
// Force Alipay mobile users to use QR code instead of mobile redirect
AlipayForceQRCode *bool `json:"alipay_force_qrcode"`
VisibleMethodAlipaySource *string `json:"payment_visible_method_alipay_source"`
VisibleMethodWxpaySource *string `json:"payment_visible_method_wxpay_source"`
VisibleMethodAlipayEnabled *bool `json:"payment_visible_method_alipay_enabled"`
@@ -202,6 +209,7 @@ func (s *PaymentConfigService) GetPaymentConfig(ctx context.Context) (*PaymentCo
SettingHelpImageURL, SettingHelpText,
SettingCancelRateLimitOn, SettingCancelRateLimitMax,
SettingCancelWindowSize, SettingCancelWindowUnit, SettingCancelWindowMode,
SettingAlipayForceQRCode,
SettingPaymentVisibleMethodAlipayEnabled, SettingPaymentVisibleMethodAlipaySource,
SettingPaymentVisibleMethodWxpayEnabled, SettingPaymentVisibleMethodWxpaySource,
}
@@ -237,6 +245,8 @@ func (s *PaymentConfigService) parsePaymentConfig(vals map[string]string) *Payme
CancelRateLimitWindow: pcParseInt(vals[SettingCancelWindowSize], 1),
CancelRateLimitUnit: vals[SettingCancelWindowUnit],
CancelRateLimitMode: vals[SettingCancelWindowMode],
AlipayForceQRCode: vals[SettingAlipayForceQRCode] == "true",
}
if cfg.LoadBalanceStrategy == "" {
cfg.LoadBalanceStrategy = payment.DefaultLoadBalanceStrategy
@@ -314,6 +324,7 @@ func (s *PaymentConfigService) UpdatePaymentConfig(ctx context.Context, req Upda
SettingCancelWindowSize: formatPositiveInt(req.CancelRateLimitWindow),
SettingCancelWindowUnit: derefStr(req.CancelRateLimitUnit),
SettingCancelWindowMode: derefStr(req.CancelRateLimitMode),
SettingAlipayForceQRCode: formatBoolOrEmpty(req.AlipayForceQRCode),
SettingPaymentVisibleMethodAlipaySource: derefStr(req.VisibleMethodAlipaySource),
SettingPaymentVisibleMethodWxpaySource: derefStr(req.VisibleMethodWxpaySource),
SettingPaymentVisibleMethodAlipayEnabled: formatBoolOrEmpty(req.VisibleMethodAlipayEnabled),