fix: load direct payment options

Register Alipay and WxPay option keys and sync option updates into runtime payment settings.
This commit is contained in:
zizi 2026-05-20 15:41:36 +08:00
parent 0625c6304b
commit 9264873e2c
4 changed files with 270 additions and 0 deletions

View File

@ -92,6 +92,12 @@ func InitOptionMap() {
common.OptionMap["StripePriceId"] = setting.StripePriceId
common.OptionMap["StripeUnitPrice"] = strconv.FormatFloat(setting.StripeUnitPrice, 'f', -1, 64)
common.OptionMap["StripePromotionCodesEnabled"] = strconv.FormatBool(setting.StripePromotionCodesEnabled)
for k, v := range setting.AlipayOptionValues() {
common.OptionMap[k] = v
}
for k, v := range setting.WxpayOptionValues() {
common.OptionMap[k] = v
}
common.OptionMap["CreemApiKey"] = setting.CreemApiKey
common.OptionMap["CreemProducts"] = setting.CreemProducts
common.OptionMap["CreemTestMode"] = strconv.FormatBool(setting.CreemTestMode)
@ -240,6 +246,9 @@ func updateOptionMap(key string, value string) (err error) {
if handleConfigUpdate(key, value) {
return nil // 已由配置系统处理
}
if setting.UpdateAlipayOption(key, value) || setting.UpdateWxpayOption(key, value) {
return nil
}
// 处理传统配置项...
if strings.HasSuffix(key, "Permission") {

View File

@ -0,0 +1,141 @@
package model
import (
"testing"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/setting"
"github.com/stretchr/testify/require"
)
func TestPaymentOptionsUpdateRuntimeSettings(t *testing.T) {
originalAlipay := setting.Alipay
originalWxpay := setting.Wxpay
common.OptionMapRWMutex.RLock()
originalOptionMap := common.OptionMap
common.OptionMapRWMutex.RUnlock()
t.Cleanup(func() {
setting.Alipay = originalAlipay
setting.Wxpay = originalWxpay
common.OptionMapRWMutex.Lock()
common.OptionMap = originalOptionMap
common.OptionMapRWMutex.Unlock()
})
common.OptionMapRWMutex.Lock()
common.OptionMap = map[string]string{}
common.OptionMapRWMutex.Unlock()
require.NoError(t, updateOptionMap(setting.AlipayEnabledOption, "true"))
require.NoError(t, updateOptionMap(setting.AlipayAppIDOption, "alipay-app"))
require.NoError(t, updateOptionMap(setting.AlipayPrivateKeyOption, "alipay-private"))
require.NoError(t, updateOptionMap(setting.AlipayPublicKeyOption, "alipay-public"))
require.NoError(t, updateOptionMap(setting.AlipayGatewayUrlOption, "https://alipay-gateway.test"))
require.NoError(t, updateOptionMap(setting.AlipayNotifyURLOption, "https://example.test/alipay/notify"))
require.NoError(t, updateOptionMap(setting.AlipayReturnURLOption, "https://example.test/alipay/return"))
require.True(t, setting.Alipay.Enabled)
require.Equal(t, "alipay-app", setting.Alipay.AppID)
require.Equal(t, "alipay-private", setting.Alipay.PrivateKey)
require.Equal(t, "alipay-public", setting.Alipay.PublicKey)
require.Equal(t, "https://alipay-gateway.test", setting.Alipay.GatewayUrl)
require.Equal(t, "https://example.test/alipay/notify", setting.Alipay.NotifyURL)
require.Equal(t, "https://example.test/alipay/return", setting.Alipay.ReturnURL)
require.NoError(t, updateOptionMap(setting.WxpayEnabledOption, "true"))
require.NoError(t, updateOptionMap(setting.WxpayAppIDOption, "wxpay-app"))
require.NoError(t, updateOptionMap(setting.WxpayMchIDOption, "wxpay-mch"))
require.NoError(t, updateOptionMap(setting.WxpayPrivateKeyOption, "wxpay-private"))
require.NoError(t, updateOptionMap(setting.WxpayMerchantSerialNoOption, "merchant-serial"))
require.NoError(t, updateOptionMap(setting.WxpayAPIv3KeyOption, "12345678901234567890123456789012"))
require.NoError(t, updateOptionMap(setting.WxpayPlatformPublicKeyOption, "wxpay-platform-public"))
require.NoError(t, updateOptionMap(setting.WxpayPlatformCertificateOption, "wxpay-platform-cert"))
require.NoError(t, updateOptionMap(setting.WxpayPlatformSerialNoOption, "platform-serial"))
require.NoError(t, updateOptionMap(setting.WxpayGatewayURLOption, "https://wxpay-gateway.test"))
require.NoError(t, updateOptionMap(setting.WxpayNotifyURLOption, "https://example.test/wxpay/notify"))
require.NoError(t, updateOptionMap(setting.WxpayReturnURLOption, "https://example.test/wxpay/return"))
require.NoError(t, updateOptionMap(setting.WxpayH5AppNameOption, "new-api"))
require.NoError(t, updateOptionMap(setting.WxpayH5AppURLOption, "https://example.test"))
require.True(t, setting.Wxpay.Enabled)
require.Equal(t, "wxpay-app", setting.Wxpay.AppID)
require.Equal(t, "wxpay-mch", setting.Wxpay.MchID)
require.Equal(t, "wxpay-private", setting.Wxpay.PrivateKey)
require.Equal(t, "merchant-serial", setting.Wxpay.MerchantSerialNo)
require.Equal(t, "12345678901234567890123456789012", setting.Wxpay.APIv3Key)
require.Equal(t, "wxpay-platform-public", setting.Wxpay.PlatformPublicKey)
require.Equal(t, "wxpay-platform-cert", setting.Wxpay.PlatformCertificate)
require.Equal(t, "platform-serial", setting.Wxpay.PlatformSerialNo)
require.Equal(t, "https://wxpay-gateway.test", setting.Wxpay.GatewayURL)
require.Equal(t, "https://example.test/wxpay/notify", setting.Wxpay.NotifyURL)
require.Equal(t, "https://example.test/wxpay/return", setting.Wxpay.ReturnURL)
require.Equal(t, "new-api", setting.Wxpay.H5AppName)
require.Equal(t, "https://example.test", setting.Wxpay.H5AppURL)
}
func TestInitOptionMapIncludesDirectPaymentOptions(t *testing.T) {
originalAlipay := setting.Alipay
originalWxpay := setting.Wxpay
common.OptionMapRWMutex.RLock()
originalOptionMap := common.OptionMap
common.OptionMapRWMutex.RUnlock()
t.Cleanup(func() {
setting.Alipay = originalAlipay
setting.Wxpay = originalWxpay
common.OptionMapRWMutex.Lock()
common.OptionMap = originalOptionMap
common.OptionMapRWMutex.Unlock()
})
setting.Alipay = setting.AlipaySetting{
Enabled: true,
AppID: "init-alipay-app",
PrivateKey: "init-alipay-private",
PublicKey: "init-alipay-public",
GatewayUrl: "https://init-alipay-gateway.test",
NotifyURL: "https://example.test/init-alipay/notify",
ReturnURL: "https://example.test/init-alipay/return",
}
setting.Wxpay = setting.WxpaySetting{
Enabled: true,
AppID: "init-wxpay-app",
MchID: "init-wxpay-mch",
PrivateKey: "init-wxpay-private",
MerchantSerialNo: "init-merchant-serial",
APIv3Key: "12345678901234567890123456789012",
PlatformPublicKey: "init-platform-public",
PlatformCertificate: "init-platform-cert",
PlatformSerialNo: "init-platform-serial",
GatewayURL: "https://init-wxpay-gateway.test",
NotifyURL: "https://example.test/init-wxpay/notify",
ReturnURL: "https://example.test/init-wxpay/return",
H5AppName: "init-new-api",
H5AppURL: "https://init.example.test",
}
InitOptionMap()
common.OptionMapRWMutex.RLock()
defer common.OptionMapRWMutex.RUnlock()
require.Equal(t, "true", common.OptionMap[setting.AlipayEnabledOption])
require.Equal(t, "init-alipay-app", common.OptionMap[setting.AlipayAppIDOption])
require.Equal(t, "init-alipay-private", common.OptionMap[setting.AlipayPrivateKeyOption])
require.Equal(t, "init-alipay-public", common.OptionMap[setting.AlipayPublicKeyOption])
require.Equal(t, "https://init-alipay-gateway.test", common.OptionMap[setting.AlipayGatewayUrlOption])
require.Equal(t, "https://example.test/init-alipay/notify", common.OptionMap[setting.AlipayNotifyURLOption])
require.Equal(t, "https://example.test/init-alipay/return", common.OptionMap[setting.AlipayReturnURLOption])
require.Equal(t, "true", common.OptionMap[setting.WxpayEnabledOption])
require.Equal(t, "init-wxpay-app", common.OptionMap[setting.WxpayAppIDOption])
require.Equal(t, "init-wxpay-mch", common.OptionMap[setting.WxpayMchIDOption])
require.Equal(t, "init-wxpay-private", common.OptionMap[setting.WxpayPrivateKeyOption])
require.Equal(t, "init-merchant-serial", common.OptionMap[setting.WxpayMerchantSerialNoOption])
require.Equal(t, "12345678901234567890123456789012", common.OptionMap[setting.WxpayAPIv3KeyOption])
require.Equal(t, "init-platform-public", common.OptionMap[setting.WxpayPlatformPublicKeyOption])
require.Equal(t, "init-platform-cert", common.OptionMap[setting.WxpayPlatformCertificateOption])
require.Equal(t, "init-platform-serial", common.OptionMap[setting.WxpayPlatformSerialNoOption])
require.Equal(t, "https://init-wxpay-gateway.test", common.OptionMap[setting.WxpayGatewayURLOption])
require.Equal(t, "https://example.test/init-wxpay/notify", common.OptionMap[setting.WxpayNotifyURLOption])
require.Equal(t, "https://example.test/init-wxpay/return", common.OptionMap[setting.WxpayReturnURLOption])
require.Equal(t, "init-new-api", common.OptionMap[setting.WxpayH5AppNameOption])
require.Equal(t, "https://init.example.test", common.OptionMap[setting.WxpayH5AppURLOption])
}

View File

@ -1,5 +1,7 @@
package setting
import "strconv"
type AlipaySetting struct {
Enabled bool `json:"enabled"`
AppID string `json:"app_id"`
@ -13,3 +15,47 @@ type AlipaySetting struct {
var Alipay = AlipaySetting{
GatewayUrl: "https://openapi.alipay.com/gateway.do",
}
const (
AlipayEnabledOption = "AlipayEnabled"
AlipayAppIDOption = "AlipayAppID"
AlipayPrivateKeyOption = "AlipayPrivateKey"
AlipayPublicKeyOption = "AlipayPublicKey"
AlipayGatewayUrlOption = "AlipayGatewayUrl"
AlipayNotifyURLOption = "AlipayNotifyURL"
AlipayReturnURLOption = "AlipayReturnURL"
)
func AlipayOptionValues() map[string]string {
return map[string]string{
AlipayEnabledOption: strconv.FormatBool(Alipay.Enabled),
AlipayAppIDOption: Alipay.AppID,
AlipayPrivateKeyOption: Alipay.PrivateKey,
AlipayPublicKeyOption: Alipay.PublicKey,
AlipayGatewayUrlOption: Alipay.GatewayUrl,
AlipayNotifyURLOption: Alipay.NotifyURL,
AlipayReturnURLOption: Alipay.ReturnURL,
}
}
func UpdateAlipayOption(key string, value string) bool {
switch key {
case AlipayEnabledOption:
Alipay.Enabled = value == "true"
case AlipayAppIDOption:
Alipay.AppID = value
case AlipayPrivateKeyOption:
Alipay.PrivateKey = value
case AlipayPublicKeyOption:
Alipay.PublicKey = value
case AlipayGatewayUrlOption:
Alipay.GatewayUrl = value
case AlipayNotifyURLOption:
Alipay.NotifyURL = value
case AlipayReturnURLOption:
Alipay.ReturnURL = value
default:
return false
}
return true
}

View File

@ -1,5 +1,7 @@
package setting
import "strconv"
type WxpaySetting struct {
Enabled bool `json:"enabled"`
AppID string `json:"app_id"`
@ -20,3 +22,75 @@ type WxpaySetting struct {
var Wxpay = WxpaySetting{
GatewayURL: "https://api.mch.weixin.qq.com",
}
const (
WxpayEnabledOption = "WxpayEnabled"
WxpayAppIDOption = "WxpayAppID"
WxpayMchIDOption = "WxpayMchID"
WxpayPrivateKeyOption = "WxpayPrivateKey"
WxpayMerchantSerialNoOption = "WxpayMerchantSerialNo"
WxpayAPIv3KeyOption = "WxpayAPIv3Key"
WxpayPlatformPublicKeyOption = "WxpayPlatformPublicKey"
WxpayPlatformCertificateOption = "WxpayPlatformCertificate"
WxpayPlatformSerialNoOption = "WxpayPlatformSerialNo"
WxpayGatewayURLOption = "WxpayGatewayURL"
WxpayNotifyURLOption = "WxpayNotifyURL"
WxpayReturnURLOption = "WxpayReturnURL"
WxpayH5AppNameOption = "WxpayH5AppName"
WxpayH5AppURLOption = "WxpayH5AppURL"
)
func WxpayOptionValues() map[string]string {
return map[string]string{
WxpayEnabledOption: strconv.FormatBool(Wxpay.Enabled),
WxpayAppIDOption: Wxpay.AppID,
WxpayMchIDOption: Wxpay.MchID,
WxpayPrivateKeyOption: Wxpay.PrivateKey,
WxpayMerchantSerialNoOption: Wxpay.MerchantSerialNo,
WxpayAPIv3KeyOption: Wxpay.APIv3Key,
WxpayPlatformPublicKeyOption: Wxpay.PlatformPublicKey,
WxpayPlatformCertificateOption: Wxpay.PlatformCertificate,
WxpayPlatformSerialNoOption: Wxpay.PlatformSerialNo,
WxpayGatewayURLOption: Wxpay.GatewayURL,
WxpayNotifyURLOption: Wxpay.NotifyURL,
WxpayReturnURLOption: Wxpay.ReturnURL,
WxpayH5AppNameOption: Wxpay.H5AppName,
WxpayH5AppURLOption: Wxpay.H5AppURL,
}
}
func UpdateWxpayOption(key string, value string) bool {
switch key {
case WxpayEnabledOption:
Wxpay.Enabled = value == "true"
case WxpayAppIDOption:
Wxpay.AppID = value
case WxpayMchIDOption:
Wxpay.MchID = value
case WxpayPrivateKeyOption:
Wxpay.PrivateKey = value
case WxpayMerchantSerialNoOption:
Wxpay.MerchantSerialNo = value
case WxpayAPIv3KeyOption:
Wxpay.APIv3Key = value
case WxpayPlatformPublicKeyOption:
Wxpay.PlatformPublicKey = value
case WxpayPlatformCertificateOption:
Wxpay.PlatformCertificate = value
case WxpayPlatformSerialNoOption:
Wxpay.PlatformSerialNo = value
case WxpayGatewayURLOption:
Wxpay.GatewayURL = value
case WxpayNotifyURLOption:
Wxpay.NotifyURL = value
case WxpayReturnURLOption:
Wxpay.ReturnURL = value
case WxpayH5AppNameOption:
Wxpay.H5AppName = value
case WxpayH5AppURLOption:
Wxpay.H5AppURL = value
default:
return false
}
return true
}