refactor: 清理 YAML 支付配置遗留代码,重命名 Card* 常量为 Asset*,新增支付配置相关错误码

- 删除 PaymentConfig 结构体和 WechatConfig.Payment 字段(YAML 方案已废弃)
- 删除 wechat.payment 配置节和 NewPaymentApp() 函数
- 删除 validateWechatConfig 中所有 wechatCfg.Payment.* 校验代码
- pkg/constants/wallet.go: Card* 前缀统一重命名为 Asset*,旧名保留废弃别名
- pkg/constants/redis.go: 新增 RedisWechatConfigActiveKey()
- pkg/errors/codes.go: 新增错误码 1170-1175
- go.mod: 新增 golang.org/x/text 依赖(富友支付 GBK 编解码)

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-03-16 23:28:29 +08:00
parent 7f18765911
commit b0da71bd25
9 changed files with 115 additions and 152 deletions

View File

@@ -160,7 +160,6 @@ type PresignConfig struct {
// WechatConfig 微信配置
type WechatConfig struct {
OfficialAccount OfficialAccountConfig `mapstructure:"official_account"`
Payment PaymentConfig `mapstructure:"payment"`
}
// OfficialAccountConfig 微信公众号配置
@@ -172,20 +171,6 @@ type OfficialAccountConfig struct {
OAuthRedirectURL string `mapstructure:"oauth_redirect_url"`
}
// PaymentConfig 微信支付配置
type PaymentConfig struct {
AppID string `mapstructure:"app_id"`
MchID string `mapstructure:"mch_id"`
APIV3Key string `mapstructure:"api_v3_key"`
APIV2Key string `mapstructure:"api_v2_key"`
CertPath string `mapstructure:"cert_path"`
KeyPath string `mapstructure:"key_path"`
SerialNo string `mapstructure:"serial_no"`
NotifyURL string `mapstructure:"notify_url"`
HttpDebug bool `mapstructure:"http_debug"`
Timeout time.Duration `mapstructure:"timeout"`
}
type requiredField struct {
value string
name string

View File

@@ -120,14 +120,4 @@ wechat:
token: "" # 可选JUNHONG_WECHAT_OFFICIAL_ACCOUNT_TOKEN
aes_key: "" # 可选JUNHONG_WECHAT_OFFICIAL_ACCOUNT_AES_KEY敏感
oauth_redirect_url: "" # 可选JUNHONG_WECHAT_OFFICIAL_ACCOUNT_OAUTH_REDIRECT_URL
payment:
app_id: "" # 必填JUNHONG_WECHAT_PAYMENT_APP_ID
mch_id: "" # 必填JUNHONG_WECHAT_PAYMENT_MCH_ID
api_v3_key: "" # 必填JUNHONG_WECHAT_PAYMENT_API_V3_KEY敏感
api_v2_key: "" # 可选JUNHONG_WECHAT_PAYMENT_API_V2_KEY敏感
cert_path: "" # 必填JUNHONG_WECHAT_PAYMENT_CERT_PATH证书文件路径
key_path: "" # 必填JUNHONG_WECHAT_PAYMENT_KEY_PATH私钥文件路径
serial_no: "" # 必填JUNHONG_WECHAT_PAYMENT_SERIAL_NO
notify_url: "" # 必填JUNHONG_WECHAT_PAYMENT_NOTIFY_URL
http_debug: false
timeout: "30s"

View File

@@ -313,3 +313,14 @@ func RedisDeviceRefreshCooldownKey(deviceID uint) string {
func RedisPollingQueueProtectKey() string {
return "polling:queue:protect"
}
// ========================================
// 微信配置相关 Redis Key
// ========================================
// RedisWechatConfigActiveKey 生效支付配置缓存键
// 用途缓存当前激活的微信参数配置JSON 或 "none" 空标记)
// 过期时间5 分钟(有配置)/ 1 分钟(空标记)
func RedisWechatConfigActiveKey() string {
return "wechat:config:active"
}

View File

@@ -47,37 +47,37 @@ const (
AgentRechargeMaxAmount = 100000000 // 最大充值金额1000000元
)
// ========== 钱包常量 ==========
// ========== 资产钱包常量 ==========
// 钱包资源类型
// 资产钱包资源类型
const (
CardWalletResourceTypeIotCard = "iot_card" // 物联网卡钱包
CardWalletResourceTypeDevice = "device" // 设备钱包(多卡共享)
AssetWalletResourceTypeIotCard = "iot_card" // 物联网卡钱包
AssetWalletResourceTypeDevice = "device" // 设备钱包(多卡共享)
)
// 钱包状态
// 资产钱包状态
const (
CardWalletStatusNormal = 1 // 正常
CardWalletStatusFrozen = 2 // 冻结
CardWalletStatusClosed = 3 // 关闭
AssetWalletStatusNormal = 1 // 正常
AssetWalletStatusFrozen = 2 // 冻结
AssetWalletStatusClosed = 3 // 关闭
)
// 钱包交易类型
// 资产钱包交易类型
const (
CardTransactionTypeRecharge = "recharge" // 充值
CardTransactionTypeDeduct = "deduct" // 扣款
CardTransactionTypeRefund = "refund" // 退款
AssetTransactionTypeRecharge = "recharge" // 充值
AssetTransactionTypeDeduct = "deduct" // 扣款
AssetTransactionTypeRefund = "refund" // 退款
)
// 充值订单号前缀
// 资产充值订单号前缀
const (
CardRechargeOrderPrefix = "CRCH" // 充值订单号前缀
AssetRechargeOrderPrefix = "CRCH" // 资产充值订单号前缀
)
// 充值金额限制(单位:分)
// 资产充值金额限制(单位:分)
const (
CardRechargeMinAmount = 100 // 最小充值金额1元
CardRechargeMaxAmount = 10000000 // 最大充值金额100000元
AssetRechargeMinAmount = 100 // 最小充值金额1元
AssetRechargeMaxAmount = 10000000 // 最大充值金额100000元
)
// ========== 通用常量 ==========
@@ -154,31 +154,31 @@ const WalletTypeMain = AgentWalletTypeMain
// WalletTypeCommission 分佣钱包(已废弃,使用 AgentWalletTypeCommission
const WalletTypeCommission = AgentWalletTypeCommission
// WalletResourceTypeIotCard 物联网卡钱包(已废弃,使用 CardWalletResourceTypeIotCard
const WalletResourceTypeIotCard = CardWalletResourceTypeIotCard
// WalletResourceTypeIotCard 物联网卡钱包(已废弃,使用 AssetWalletResourceTypeIotCard
const WalletResourceTypeIotCard = AssetWalletResourceTypeIotCard
// WalletResourceTypeDevice 设备钱包(已废弃,使用 CardWalletResourceTypeDevice
const WalletResourceTypeDevice = CardWalletResourceTypeDevice
// WalletResourceTypeDevice 设备钱包(已废弃,使用 AssetWalletResourceTypeDevice
const WalletResourceTypeDevice = AssetWalletResourceTypeDevice
// WalletResourceTypeShop 店铺钱包(已废弃,代理钱包不再使用 resource_type
const WalletResourceTypeShop = "shop"
// WalletStatusNormal 钱包状态-正常(已废弃,使用 AgentWalletStatusNormal 或 CardWalletStatusNormal
// WalletStatusNormal 钱包状态-正常(已废弃,使用 AgentWalletStatusNormal 或 AssetWalletStatusNormal
const WalletStatusNormal = AgentWalletStatusNormal
// WalletStatusFrozen 钱包状态-冻结(已废弃,使用 AgentWalletStatusFrozen 或 CardWalletStatusFrozen
// WalletStatusFrozen 钱包状态-冻结(已废弃,使用 AgentWalletStatusFrozen 或 AssetWalletStatusFrozen
const WalletStatusFrozen = AgentWalletStatusFrozen
// WalletStatusClosed 钱包状态-关闭(已废弃,使用 AgentWalletStatusClosed 或 CardWalletStatusClosed
// WalletStatusClosed 钱包状态-关闭(已废弃,使用 AgentWalletStatusClosed 或 AssetWalletStatusClosed
const WalletStatusClosed = AgentWalletStatusClosed
// TransactionTypeRecharge 交易类型-充值(已废弃,使用 AgentTransactionTypeRecharge 或 CardTransactionTypeRecharge
// TransactionTypeRecharge 交易类型-充值(已废弃,使用 AgentTransactionTypeRecharge 或 AssetTransactionTypeRecharge
const TransactionTypeRecharge = AgentTransactionTypeRecharge
// TransactionTypeDeduct 交易类型-扣款(已废弃,使用 AgentTransactionTypeDeduct 或 CardTransactionTypeDeduct
// TransactionTypeDeduct 交易类型-扣款(已废弃,使用 AgentTransactionTypeDeduct 或 AssetTransactionTypeDeduct
const TransactionTypeDeduct = AgentTransactionTypeDeduct
// TransactionTypeRefund 交易类型-退款(已废弃,使用 AgentTransactionTypeRefund 或 CardTransactionTypeRefund
// TransactionTypeRefund 交易类型-退款(已废弃,使用 AgentTransactionTypeRefund 或 AssetTransactionTypeRefund
const TransactionTypeRefund = AgentTransactionTypeRefund
// TransactionTypeCommission 交易类型-分佣(已废弃,使用 AgentTransactionTypeCommission
@@ -187,11 +187,46 @@ const TransactionTypeCommission = AgentTransactionTypeCommission
// TransactionTypeWithdrawal 交易类型-提现(已废弃,使用 AgentTransactionTypeWithdrawal
const TransactionTypeWithdrawal = AgentTransactionTypeWithdrawal
// RechargeOrderPrefix 充值订单号前缀(已废弃,使用 AgentRechargeOrderPrefix 或 CardRechargeOrderPrefix
// RechargeOrderPrefix 充值订单号前缀(已废弃,使用 AgentRechargeOrderPrefix 或 AssetRechargeOrderPrefix
const RechargeOrderPrefix = "RCH"
// RechargeMinAmount 最小充值金额(已废弃,使用 AgentRechargeMinAmount 或 CardRechargeMinAmount
const RechargeMinAmount = CardRechargeMinAmount
// RechargeMinAmount 最小充值金额(已废弃,使用 AgentRechargeMinAmount 或 AssetRechargeMinAmount
const RechargeMinAmount = AssetRechargeMinAmount
// RechargeMaxAmount 最大充值金额(已废弃,使用 AgentRechargeMaxAmount 或 CardRechargeMaxAmount
const RechargeMaxAmount = CardRechargeMaxAmount
// RechargeMaxAmount 最大充值金额(已废弃,使用 AgentRechargeMaxAmount 或 AssetRechargeMaxAmount
const RechargeMaxAmount = AssetRechargeMaxAmount
// ========== Card* 废弃别名(向后兼容)==========
// Deprecated: 使用 AssetWalletResourceTypeIotCard
const CardWalletResourceTypeIotCard = AssetWalletResourceTypeIotCard
// Deprecated: 使用 AssetWalletResourceTypeDevice
const CardWalletResourceTypeDevice = AssetWalletResourceTypeDevice
// Deprecated: 使用 AssetWalletStatusNormal
const CardWalletStatusNormal = AssetWalletStatusNormal
// Deprecated: 使用 AssetWalletStatusFrozen
const CardWalletStatusFrozen = AssetWalletStatusFrozen
// Deprecated: 使用 AssetWalletStatusClosed
const CardWalletStatusClosed = AssetWalletStatusClosed
// Deprecated: 使用 AssetTransactionTypeRecharge
const CardTransactionTypeRecharge = AssetTransactionTypeRecharge
// Deprecated: 使用 AssetTransactionTypeDeduct
const CardTransactionTypeDeduct = AssetTransactionTypeDeduct
// Deprecated: 使用 AssetTransactionTypeRefund
const CardTransactionTypeRefund = AssetTransactionTypeRefund
// Deprecated: 使用 AssetRechargeOrderPrefix
const CardRechargeOrderPrefix = AssetRechargeOrderPrefix
// Deprecated: 使用 AssetRechargeMinAmount
const CardRechargeMinAmount = AssetRechargeMinAmount
// Deprecated: 使用 AssetRechargeMaxAmount
const CardRechargeMaxAmount = AssetRechargeMaxAmount

View File

@@ -126,13 +126,21 @@ const (
CodePollingCleanupConfigNotFound = 1155 // 数据清理配置不存在
CodePollingManualTriggerLimit = 1156 // 手动触发次数已达上限
// 套餐相关错误 (1160-1179)
// 套餐相关错误 (1160-1169)
CodeNoAvailablePackage = 1160 // 没有可用套餐
CodePackageActivationConflict = 1161 // 套餐正在激活中
CodeNoMainPackage = 1162 // 必须有主套餐才能购买加油包
CodeRealnameRequired = 1163 // 设备/卡必须先完成实名认证才能购买套餐
CodeMixedOrderForbidden = 1164 // 同订单不能同时购买正式套餐和加油包
// 微信配置相关错误 (1170-1179)
CodeWechatConfigNotFound = 1170 // 微信支付配置不存在
CodeWechatConfigActive = 1171 // 不能删除/操作当前生效的支付配置
CodeWechatConfigHasPendingOrders = 1172 // 该配置存在未完成的支付订单
CodeFuiouPayFailed = 1173 // 富友支付发起失败
CodeFuiouCallbackInvalid = 1174 // 富友回调签名验证失败
CodeNoPaymentConfig = 1175 // 当前无可用的支付配置
// 服务端错误 (2000-2999) -> 5xx HTTP 状态码
CodeInternalError = 2001 // 内部服务器错误
CodeDatabaseError = 2002 // 数据库错误
@@ -244,6 +252,12 @@ var allErrorCodes = []int{
CodeNoMainPackage,
CodeRealnameRequired,
CodeMixedOrderForbidden,
CodeWechatConfigNotFound,
CodeWechatConfigActive,
CodeWechatConfigHasPendingOrders,
CodeFuiouPayFailed,
CodeFuiouCallbackInvalid,
CodeNoPaymentConfig,
CodeInternalError,
CodeDatabaseError,
CodeRedisError,
@@ -353,6 +367,12 @@ var errorMessages = map[int]string{
CodeNoMainPackage: "必须有主套餐才能购买加油包",
CodeRealnameRequired: "设备/卡必须先完成实名认证才能购买套餐",
CodeMixedOrderForbidden: "同订单不能同时购买正式套餐和加油包",
CodeWechatConfigNotFound: "微信支付配置不存在",
CodeWechatConfigActive: "不能删除当前生效的支付配置,请先停用",
CodeWechatConfigHasPendingOrders: "该配置存在未完成的支付订单,暂时无法删除",
CodeFuiouPayFailed: "支付发起失败,请重试",
CodeFuiouCallbackInvalid: "支付回调签名验证失败",
CodeNoPaymentConfig: "当前无可用的支付配置,请联系管理员",
CodeInvalidCredentials: "用户名或密码错误",
CodeAccountLocked: "账号已锁定",
CodePasswordExpired: "密码已过期",

View File

@@ -5,7 +5,6 @@ import (
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel"
"github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount"
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment"
"github.com/break/junhong_cmp_fiber/pkg/config"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
@@ -50,36 +49,3 @@ func NewOfficialAccountApp(cfg *config.Config, cache kernel.CacheInterface, logg
logger.Info("微信公众号应用初始化成功", zap.String("app_id", oaCfg.AppID))
return app, nil
}
// NewPaymentApp 创建微信支付应用实例
func NewPaymentApp(cfg *config.Config, cache kernel.CacheInterface, logger *zap.Logger) (*payment.Payment, error) {
payCfg := cfg.Wechat.Payment
if payCfg.AppID == "" || payCfg.MchID == "" {
return nil, fmt.Errorf("微信支付配置不完整:缺少 AppID 或 MchID")
}
userConfig := &payment.UserConfig{
AppID: payCfg.AppID,
MchID: payCfg.MchID,
MchApiV3Key: payCfg.APIV3Key,
Key: payCfg.APIV2Key,
CertPath: payCfg.CertPath,
KeyPath: payCfg.KeyPath,
SerialNo: payCfg.SerialNo,
NotifyURL: payCfg.NotifyURL,
HttpDebug: payCfg.HttpDebug,
Cache: cache,
}
app, err := payment.NewPayment(userConfig)
if err != nil {
logger.Error("创建微信支付应用失败", zap.Error(err))
return nil, fmt.Errorf("创建微信支付应用失败: %w", err)
}
logger.Info("微信支付应用初始化成功",
zap.String("app_id", payCfg.AppID),
zap.String("mch_id", payCfg.MchID),
)
return app, nil
}