diff --git a/cmd/api/main.go b/cmd/api/main.go index 64c8906..224ce4e 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -359,60 +359,16 @@ func initGateway(cfg *config.Config, appLogger *zap.Logger) *gateway.Client { func validateWechatConfig(cfg *config.Config, appLogger *zap.Logger) { wechatCfg := cfg.Wechat - if wechatCfg.OfficialAccount.AppID == "" && wechatCfg.Payment.AppID == "" { - appLogger.Warn("微信配置未设置,微信相关功能将不可用") + if wechatCfg.OfficialAccount.AppID == "" { + appLogger.Warn("微信公众号配置未设置,OAuth 相关功能将不可用") return } - if wechatCfg.OfficialAccount.AppID != "" { - if wechatCfg.OfficialAccount.AppSecret == "" { - appLogger.Fatal("微信公众号配置不完整", - zap.String("missing", "app_secret"), - zap.String("env", "JUNHONG_WECHAT_OFFICIAL_ACCOUNT_APP_SECRET")) - } - appLogger.Info("微信公众号配置已验证", - zap.String("app_id", wechatCfg.OfficialAccount.AppID)) - } - - if wechatCfg.Payment.AppID != "" { - missingFields := []string{} - - if wechatCfg.Payment.MchID == "" { - missingFields = append(missingFields, "mch_id (JUNHONG_WECHAT_PAYMENT_MCH_ID)") - } - if wechatCfg.Payment.APIV3Key == "" { - missingFields = append(missingFields, "api_v3_key (JUNHONG_WECHAT_PAYMENT_API_V3_KEY)") - } - if wechatCfg.Payment.CertPath == "" { - missingFields = append(missingFields, "cert_path (JUNHONG_WECHAT_PAYMENT_CERT_PATH)") - } - if wechatCfg.Payment.KeyPath == "" { - missingFields = append(missingFields, "key_path (JUNHONG_WECHAT_PAYMENT_KEY_PATH)") - } - if wechatCfg.Payment.SerialNo == "" { - missingFields = append(missingFields, "serial_no (JUNHONG_WECHAT_PAYMENT_SERIAL_NO)") - } - if wechatCfg.Payment.NotifyURL == "" { - missingFields = append(missingFields, "notify_url (JUNHONG_WECHAT_PAYMENT_NOTIFY_URL)") - } - - if len(missingFields) > 0 { - appLogger.Fatal("微信支付配置不完整", - zap.Strings("missing_fields", missingFields)) - } - - if _, err := os.Stat(wechatCfg.Payment.CertPath); os.IsNotExist(err) { - appLogger.Fatal("微信支付证书文件不存在", - zap.String("cert_path", wechatCfg.Payment.CertPath)) - } - - if _, err := os.Stat(wechatCfg.Payment.KeyPath); os.IsNotExist(err) { - appLogger.Fatal("微信支付私钥文件不存在", - zap.String("key_path", wechatCfg.Payment.KeyPath)) - } - - appLogger.Info("微信支付配置已验证", - zap.String("app_id", wechatCfg.Payment.AppID), - zap.String("mch_id", wechatCfg.Payment.MchID)) + if wechatCfg.OfficialAccount.AppSecret == "" { + appLogger.Fatal("微信公众号配置不完整", + zap.String("missing", "app_secret"), + zap.String("env", "JUNHONG_WECHAT_OFFICIAL_ACCOUNT_APP_SECRET")) } + appLogger.Info("微信公众号配置已验证", + zap.String("app_id", wechatCfg.OfficialAccount.AppID)) } diff --git a/go.mod b/go.mod index 65e09b3..070e6ed 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/break/junhong_cmp_fiber -go 1.25 +go 1.25.0 require ( github.com/ArtisanCloud/PowerWeChat/v3 v3.4.38 @@ -20,6 +20,7 @@ require ( github.com/xuri/excelize/v2 v2.8.1 go.uber.org/zap v1.27.1 golang.org/x/crypto v0.47.0 + golang.org/x/text v0.35.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/yaml.v3 v3.0.1 gorm.io/datatypes v1.2.7 @@ -88,9 +89,8 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/net v0.48.0 // indirect - golang.org/x/sync v0.19.0 // indirect + golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.14.0 // indirect google.golang.org/protobuf v1.36.10 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 633c8c0..5a0a6d2 100644 --- a/go.sum +++ b/go.sum @@ -298,15 +298,15 @@ golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= diff --git a/pkg/config/config.go b/pkg/config/config.go index e05b02f..b45f34d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -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 diff --git a/pkg/config/defaults/config.yaml b/pkg/config/defaults/config.yaml index ce84c02..f7d7473 100644 --- a/pkg/config/defaults/config.yaml +++ b/pkg/config/defaults/config.yaml @@ -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" + diff --git a/pkg/constants/redis.go b/pkg/constants/redis.go index 8789af4..01b3391 100644 --- a/pkg/constants/redis.go +++ b/pkg/constants/redis.go @@ -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" +} diff --git a/pkg/constants/wallet.go b/pkg/constants/wallet.go index 5f007ac..b6f931e 100644 --- a/pkg/constants/wallet.go +++ b/pkg/constants/wallet.go @@ -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 diff --git a/pkg/errors/codes.go b/pkg/errors/codes.go index 486157d..d5b8cae 100644 --- a/pkg/errors/codes.go +++ b/pkg/errors/codes.go @@ -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: "密码已过期", diff --git a/pkg/wechat/config.go b/pkg/wechat/config.go index 72b373d..b5d98ad 100644 --- a/pkg/wechat/config.go +++ b/pkg/wechat/config.go @@ -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 -}