feat: integrate unified payment and wallet refunds

This commit is contained in:
2026-08-02 23:24:32 +08:00
parent f0b8af0bc8
commit 82a2106a97
64 changed files with 1519 additions and 254 deletions

View File

@@ -1,4 +1,4 @@
// Package config 沿用 sample/server 的 BSM 配置加载与校验方式。
// Package config 使用仓库统一的 BSM 配置加载与校验方式。
package config
import (
@@ -31,7 +31,42 @@ type WalletConfig struct {
ManualRechargeMaxAmount int64 `yaml:"-"`
}
// SrvConfig 与 sample/server 配置结构保持一致
// AlipayConfig 保存支付宝证书模式商户配置。私钥和证书只允许服务端读取
type AlipayConfig struct {
Enabled bool `yaml:"Enabled"`
Production bool `yaml:"Production"`
AppID string `yaml:"AppID"`
PrivateKeyPath string `yaml:"PrivateKeyPath"`
AppPublicCertPath string `yaml:"AppPublicCertPath"`
AlipayPublicCertPath string `yaml:"AlipayPublicCertPath"`
AlipayRootCertPath string `yaml:"AlipayRootCertPath"`
NotifyURL string `yaml:"NotifyURL"`
ReturnURL string `yaml:"ReturnURL"`
}
// WechatPayConfig 保存微信支付 API v3 平台单商户配置。
type WechatPayConfig struct {
Enabled bool `yaml:"Enabled"`
MerchantID string `yaml:"MerchantID"`
MerchantCertificateSerial string `yaml:"MerchantCertificateSerial"`
MerchantPrivateKeyPath string `yaml:"MerchantPrivateKeyPath"`
APIv3Key string `yaml:"APIv3Key"`
AppAppID string `yaml:"AppAppID"`
OfficialAccountAppID string `yaml:"OfficialAccountAppID"`
MiniProgramAppID string `yaml:"MiniProgramAppID"`
NotifyURL string `yaml:"NotifyURL"`
}
// PaymentConfig 保存统一支付、退款和 Worker 内部调用参数。
type PaymentConfig struct {
ExpireMinutes int `yaml:"ExpireMinutes"`
RefundWindowDays int `yaml:"RefundWindowDays"`
InternalServiceToken string `yaml:"InternalServiceToken"`
Alipay AlipayConfig `yaml:"Alipay"`
Wechat WechatPayConfig `yaml:"Wechat"`
}
// SrvConfig 与仓库现有进程的配置结构保持一致。
type SrvConfig struct {
conf.Base `yaml:",inline"`
Databases *conf.DBConf `yaml:"Databases"`
@@ -39,6 +74,7 @@ type SrvConfig struct {
Apm *conf.ApmConf `yaml:"APM"`
Global GlobalConfig `yaml:"Global"`
Wallet WalletConfig `yaml:"-"`
Payment PaymentConfig `yaml:"Payment"`
}
// New 初始化 BSM 配置并校验服务监听地址。
@@ -64,6 +100,9 @@ func New(srvKey string) {
panic("Global.FieldEncryptionKey must contain at least 32 characters")
}
Spec.Wallet.ManualRechargeMaxAmount = Spec.Global.ManualRechargeMaxAmount
if Spec.Payment.ExpireMinutes <= 0 || Spec.Payment.RefundWindowDays <= 0 {
panic("Payment expiration and refund window must be greater than zero")
}
registerURL, err := url.ParseRequestURI(Spec.Global.UserRegisterURL)
if err != nil || (registerURL.Scheme != "http" && registerURL.Scheme != "https") || registerURL.Host == "" {
panic("Global.UserRegisterURL must be a valid HTTP or HTTPS URL")