From 07ad436fd5b778bbd486a769a65b273e12c69a4f Mon Sep 17 00:00:00 2001 From: Mrx <18278715334@163.com> Date: Mon, 9 Feb 2026 14:51:03 +0800 Subject: [PATCH] f --- app/main/api/desc/front/pay.api | 1 + .../api/internal/logic/pay/paymentlogic.go | 21 +++++++++++++++++ .../api/internal/service/wechatpayService.go | 23 +++++++++++-------- app/main/api/internal/types/types.go | 1 + 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/app/main/api/desc/front/pay.api b/app/main/api/desc/front/pay.api index a00ec38..553b80d 100644 --- a/app/main/api/desc/front/pay.api +++ b/app/main/api/desc/front/pay.api @@ -51,6 +51,7 @@ type ( Id string `json:"id"` PayMethod string `json:"pay_method"` // 支付方式: wechat, alipay, appleiap, test(仅开发环境), test_empty(仅开发环境-空报告模式) PayType string `json:"pay_type" validate:"required,oneof=query agent_vip agent_upgrade whitelist"` + Code string `json:"code,optional"` // 微信小程序登录 code,未绑定 openid 时传此参数以换取 openid 并调起支付 } PaymentResp { PrepayData interface{} `json:"prepay_data"` diff --git a/app/main/api/internal/logic/pay/paymentlogic.go b/app/main/api/internal/logic/pay/paymentlogic.go index 051beef..90a33f2 100644 --- a/app/main/api/internal/logic/pay/paymentlogic.go +++ b/app/main/api/internal/logic/pay/paymentlogic.go @@ -53,6 +53,27 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp, isDevTestPayment := env == "development" && (req.PayMethod == "test" || req.PayMethod == "test_empty") isEmptyReportMode := env == "development" && req.PayMethod == "test_empty" + // 微信小程序:若未绑定 openid 但前端传了 code,则用 code 换取 openid 并写入 user_auth,以便 CreateWechatOrder 能拿到 openid 并返回 prepay_data + if req.PayMethod == "wechat" && req.Code != "" { + platformVal := l.ctx.Value("platform") + platform, _ := platformVal.(string) + if platform == model.PlatformWxMini { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr == nil { + _, findErr := l.svcCtx.UserAuthModel.FindOneByUserIdAuthType(l.ctx, userID, model.UserAuthTypeWxMiniOpenID) + if findErr != nil { + openid, codeErr := l.svcCtx.VerificationService.GetWechatMiniOpenID(l.ctx, req.Code) + if codeErr == nil { + ua := &model.UserAuth{Id: uuid.NewString(), UserId: userID, AuthType: model.UserAuthTypeWxMiniOpenID, AuthKey: openid} + if _, insertErr := l.svcCtx.UserAuthModel.Insert(l.ctx, nil, ua); insertErr != nil { + logx.Infof("支付前绑定 openid 写入失败(可忽略): %v", insertErr) + } + } + } + } + } + } + l.svcCtx.OrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error { switch req.PayType { case "agent_vip": diff --git a/app/main/api/internal/service/wechatpayService.go b/app/main/api/internal/service/wechatpayService.go index 81d10b9..738788d 100644 --- a/app/main/api/internal/service/wechatpayService.go +++ b/app/main/api/internal/service/wechatpayService.go @@ -252,8 +252,12 @@ func (w *WechatPayService) CreateWechatH5Order(ctx context.Context, amount float // CreateWechatOrder 创建微信支付订单(集成 APP、H5、小程序) func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64, description string, outTradeNo string) (interface{}, error) { - // 根据 ctx 中的 platform 判断平台 - platform := ctx.Value("platform").(string) + // 安全读取 platform,未设置或非小程序时避免误走 APP 支付导致 prepay_data 为空 + platformVal := ctx.Value("platform") + platform, _ := platformVal.(string) + if platform == "" { + return nil, fmt.Errorf("请携带 X-Platform 请求头(wxmini/h5/app)以使用微信支付") + } var prepayData interface{} var err error @@ -262,34 +266,35 @@ func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64 case model.PlatformWxMini: userID, getUidErr := ctxdata.GetUidFromCtx(ctx) if getUidErr != nil { - return "", getUidErr + return nil, getUidErr } userAuthModel, findAuthModelErr := w.userAuthModel.FindOneByUserIdAuthType(ctx, userID, model.UserAuthTypeWxMiniOpenID) if findAuthModelErr != nil { - return "", findAuthModelErr + // 返回明确文案,便于前端用 code 重试 + return nil, fmt.Errorf("未绑定微信小程序,请重试或携带 code 参数") } prepayData, err = w.CreateWechatMiniProgramOrder(ctx, amount, description, outTradeNo, userAuthModel.AuthKey) if err != nil { - return "", err + return nil, err } case model.PlatformWxH5: userID, getUidErr := ctxdata.GetUidFromCtx(ctx) if getUidErr != nil { - return "", getUidErr + return nil, getUidErr } userAuthModel, findAuthModelErr := w.userAuthModel.FindOneByUserIdAuthType(ctx, userID, model.UserAuthTypeWxh5OpenID) if findAuthModelErr != nil { - return "", findAuthModelErr + return nil, findAuthModelErr } prepayData, err = w.CreateWechatH5Order(ctx, amount, description, outTradeNo, userAuthModel.AuthKey) if err != nil { - return "", err + return nil, err } case model.PlatformApp: // 如果是 APP 平台,调用 APP 支付订单创建 prepayData, err = w.CreateWechatAppOrder(ctx, amount, description, outTradeNo) default: - return "", fmt.Errorf("不支持的支付平台: %s", platform) + return nil, fmt.Errorf("不支持的支付平台: %s", platform) } // 如果创建支付订单失败,返回错误 diff --git a/app/main/api/internal/types/types.go b/app/main/api/internal/types/types.go index 333d975..e673065 100644 --- a/app/main/api/internal/types/types.go +++ b/app/main/api/internal/types/types.go @@ -1975,6 +1975,7 @@ type PaymentReq struct { Id string `json:"id"` PayMethod string `json:"pay_method"` // 支付方式: wechat, alipay, appleiap, test(仅开发环境), test_empty(仅开发环境-空报告模式) PayType string `json:"pay_type" validate:"required,oneof=query agent_vip agent_upgrade whitelist"` + Code string `json:"code"` // 微信小程序登录 code,用于未绑定 openid 时换取 openid 并调起支付(可选) } type PaymentResp struct {