diff --git a/internal/handler/app/client_wallet.go b/internal/handler/app/client_wallet.go index ed12acd..b2e96c6 100644 --- a/internal/handler/app/client_wallet.go +++ b/internal/handler/app/client_wallet.go @@ -288,14 +288,10 @@ func (h *ClientWalletHandler) CreateRecharge(c *fiber.Ctx) error { // 先初始化微信支付实例并创建预支付订单,确认支付通道可用 // 避免先写入充值记录后支付初始化失败,导致产生孤儿记录 - cache := wechat.NewRedisCache(h.redis) - paymentApp, err := wechat.NewPaymentAppFromConfig(config, appID, cache, h.logger) - if err != nil { - return errors.Wrap(errors.CodeWechatPayFailed, err, "初始化微信支付实例失败") - } - paymentService := wechat.NewPaymentService(paymentApp, h.logger) - payResult, err := paymentService.CreateJSAPIOrder( + payResult, err := h.createJSAPIPayOrder( resolved.SkipPermissionCtx, + config, + appID, rechargeNo, "资产钱包充值", openID, @@ -585,6 +581,33 @@ func pickAppIDByType(config *model.WechatConfig, appType string) (string, error) } } +// createJSAPIPayOrder 根据支付配置的提供者类型路由到对应支付通道,发起 JSAPI 预下单。 +// 与 client_order.Service.newPaymentProvider 保持相同的路由逻辑,支持 wechat_v2 和 wechat(v3)。 +func (h *ClientWalletHandler) createJSAPIPayOrder( + ctx context.Context, + config *model.WechatConfig, + appID, orderNo, description, openID string, + amount int, +) (*wechat.JSAPIPayResult, error) { + switch config.ProviderType { + case model.ProviderTypeWechatV2: + // 微信 v2:仅需 APIv2Key,无需证书序列号 + svc, err := wechat.NewPaymentV2ServiceFromConfig(config, appID, h.logger) + if err != nil { + return nil, errors.Wrap(errors.CodeWechatPayFailed, err, "初始化微信 v2 支付实例失败") + } + return svc.CreateJSAPIOrder(ctx, orderNo, description, openID, amount) + default: + // 微信 v3(PowerWeChat):需要证书序列号和 API v3 Key + cache := wechat.NewRedisCache(h.redis) + paymentApp, err := wechat.NewPaymentAppFromConfig(config, appID, cache, h.logger) + if err != nil { + return nil, errors.Wrap(errors.CodeWechatPayFailed, err, "初始化微信支付实例失败") + } + return wechat.NewPaymentService(paymentApp, h.logger).CreateJSAPIOrder(ctx, orderNo, description, openID, amount) + } +} + func generateClientRechargeNo() string { timestamp := time.Now().Format("20060102150405") randomNum := rand.Intn(1000000)