fix wx payment

This commit is contained in:
2025-01-21 20:00:18 +08:00
parent 8d3750618c
commit 6099e5bec7
11 changed files with 115 additions and 65 deletions

View File

@@ -50,6 +50,8 @@ type AlipayConfig struct {
type WxpayConfig struct {
AppID string
MchID string
MchPublicKeyID string
MchPublicKeyPath string
MchCertificateSerialNumber string
MchApiv3Key string
MchPrivateKeyPath string

View File

@@ -68,7 +68,7 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
if aesEncryptErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 加密参数失败: %+v", aesEncryptErr)
}
var prepayID string
var prepayData interface{}
var outTradeNo string
var amount float64
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
@@ -84,13 +84,13 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
var createOrderErr error
if req.PayMethod == "wechatpay" {
outTradeNo = l.svcCtx.WechatPayService.GenerateOutTradeNo()
prepayID, createOrderErr = l.svcCtx.WechatPayService.CreateWechatOrder(l.ctx, amount, product.ProductName, outTradeNo)
prepayData, createOrderErr = l.svcCtx.WechatPayService.CreateWechatOrder(l.ctx, amount, product.ProductName, outTradeNo)
} else if req.PayMethod == "alipay" {
outTradeNo = l.svcCtx.AlipayService.GenerateOutTradeNo()
prepayID, createOrderErr = l.svcCtx.AlipayService.CreateAlipayOrder(l.ctx, amount, product.ProductName, outTradeNo, brand)
prepayData, createOrderErr = l.svcCtx.AlipayService.CreateAlipayOrder(l.ctx, amount, product.ProductName, outTradeNo, brand)
} else if req.PayMethod == "appleiap" {
outTradeNo = l.svcCtx.ApplePayService.GenerateOutTradeNo()
prepayID = l.svcCtx.ApplePayService.GetIappayAppID(product.ProductEn)
prepayData = l.svcCtx.ApplePayService.GetIappayAppID(product.ProductEn)
}
if createOrderErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 创建支付订单失败: %+v", createOrderErr)
@@ -132,5 +132,11 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
return nil, transErr
}
return &types.PaymentResp{PrepayID: prepayID, OrderID: orderID}, nil
switch v := prepayData.(type) {
case string:
// 如果 prepayData 是字符串类型,直接返回
return &types.PaymentResp{PrepayId: v, OrderID: orderID}, nil
default:
return &types.PaymentResp{PrepayData: prepayData, OrderID: orderID}, nil
}
}

View File

@@ -114,23 +114,23 @@ func GetAccessToken(code string) (*AccessTokenResp, error) {
resp, err := http.Get(url)
if err != nil {
return nil, errors.Wrap(err, "获取access_token失败")
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "读取access_token响应失败")
return nil, err
}
var accessTokenResp AccessTokenResp
if err := json.Unmarshal(body, &accessTokenResp); err != nil {
return nil, errors.Wrap(err, "解析access_token响应失败")
if err = json.Unmarshal(body, &accessTokenResp); err != nil {
return nil, err
}
if accessTokenResp.AccessToken == "" {
return nil, errors.New("获取access_token失败")
}
//if accessTokenResp.AccessToken == "" {
// return nil, errors.New("accessTokenResp.AccessToken为空")
//}
return &accessTokenResp, nil
}

View File

@@ -18,6 +18,8 @@ import (
"strconv"
"time"
"tydata-server/app/user/cmd/api/internal/config"
"tydata-server/app/user/model"
"tydata-server/common/ctxdata"
"tydata-server/pkg/lzkit/lzUtils"
)
@@ -35,25 +37,31 @@ type WechatPayService struct {
config config.WxpayConfig
wechatClient *core.Client
notifyHandler *notify.Handler
userAuthModel model.UserAuthModel
}
// NewWechatPayService 初始化微信支付服务
func NewWechatPayService(c config.Config) *WechatPayService {
func NewWechatPayService(c config.Config, userAuthModel model.UserAuthModel) *WechatPayService {
// 从配置中加载商户信息
mchID := c.Wxpay.MchID
mchCertificateSerialNumber := c.Wxpay.MchCertificateSerialNumber
mchAPIv3Key := c.Wxpay.MchApiv3Key
mchPublicKeyID := c.Wxpay.MchPublicKeyID
// 从文件中加载商户私钥
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(c.Wxpay.MchPrivateKeyPath)
if err != nil {
logx.Errorf("加载商户私钥失败: %v", err)
panic(fmt.Sprintf("初始化失败,服务停止: %v", err)) // 记录错误并停止程序
}
// 从文件中加载公钥
mchPublicKey, err := utils.LoadPublicKeyWithPath(c.Wxpay.MchPublicKeyPath)
if err != nil {
logx.Errorf("加载商户私钥失败: %v", err)
panic(fmt.Sprintf("初始化失败,服务停止: %v", err)) // 记录错误并停止程序
}
// 使用商户私钥和其他参数初始化微信支付客户端
opts := []core.ClientOption{
option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
option.WithWechatPayPublicKeyAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchPublicKeyID, mchPublicKey),
}
client, err := core.NewClient(context.Background(), opts...)
if err != nil {
@@ -71,6 +79,7 @@ func NewWechatPayService(c config.Config) *WechatPayService {
config: c.Wxpay,
wechatClient: client,
notifyHandler: notifyHandler,
userAuthModel: userAuthModel,
}
}
@@ -104,7 +113,7 @@ func (w *WechatPayService) CreateWechatAppOrder(ctx context.Context, amount floa
}
// CreateWechatMiniProgramOrder 创建微信小程序支付订单
func (w *WechatPayService) CreateWechatMiniProgramOrder(ctx context.Context, amount float64, description string, outTradeNo string, openid string) (string, error) {
func (w *WechatPayService) CreateWechatMiniProgramOrder(ctx context.Context, amount float64, description string, outTradeNo string, openid string) (interface{}, error) {
totalAmount := lzUtils.ToWechatAmount(amount)
// 构建支付请求参数
@@ -131,24 +140,41 @@ func (w *WechatPayService) CreateWechatMiniProgramOrder(ctx context.Context, amo
}
// 返回预支付交易会话标识
return *resp.PrepayId, nil
return resp, nil
}
// CreateWechatOrder 创建微信支付订单(集成 APP、H5、小程序
func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64, description string, outTradeNo string) (string, error) {
func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64, description string, outTradeNo string) (interface{}, error) {
// 根据 ctx 中的 platform 判断平台
platform := ctx.Value("platform").(string)
var prepayId string
var prepayData interface{}
var err error
switch platform {
case "mp-weixin":
// 如果是小程序平台,调用小程序支付订单创建
prepayId, err = w.CreateWechatMiniProgramOrder(ctx, amount, description, outTradeNo, "asdasd")
userID, getUidErr := ctxdata.GetUidFromCtx(ctx)
if getUidErr != nil {
return "", getUidErr
}
userAuthModel, findAuthModelErr := w.userAuthModel.FindOneByUserIdAuthType(ctx, userID, model.UserAuthTypeWxMini)
if findAuthModelErr != nil {
return "", findAuthModelErr
}
prepayData, err = w.CreateWechatMiniProgramOrder(ctx, amount, description, outTradeNo, userAuthModel.AuthKey)
case "h5-weixin":
userID, getUidErr := ctxdata.GetUidFromCtx(ctx)
if getUidErr != nil {
return "", getUidErr
}
userAuthModel, findAuthModelErr := w.userAuthModel.FindOneByUserIdAuthType(ctx, userID, model.UserAuthTypeWxh5)
if findAuthModelErr != nil {
return "", findAuthModelErr
}
prepayData, err = w.CreateWechatMiniProgramOrder(ctx, amount, description, outTradeNo, userAuthModel.AuthKey)
case "app":
// 如果是 APP 平台,调用 APP 支付订单创建
prepayId, err = w.CreateWechatAppOrder(ctx, amount, description, outTradeNo)
prepayData, err = w.CreateWechatAppOrder(ctx, amount, description, outTradeNo)
default:
return "", fmt.Errorf("不支持的支付平台: %s", platform)
}
@@ -159,7 +185,7 @@ func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64
}
// 返回预支付ID
return prepayId, nil
return prepayData, nil
}
// HandleWechatPayNotification 处理微信支付回调

View File

@@ -56,12 +56,13 @@ func NewServiceContext(c config.Config) *ServiceContext {
yushanService := service.NewYushanService(c)
productFeatureModel := model.NewProductFeatureModel(db, c.CacheRedis)
featureModel := model.NewFeatureModel(db, c.CacheRedis)
userAuthModel := model.NewUserAuthModel(db, c.CacheRedis)
return &ServiceContext{
Config: c,
Redis: redis.MustNewRedis(redisConf),
SourceInterceptor: middleware.NewSourceInterceptorMiddleware().Handle,
AlipayService: service.NewAliPayService(c),
WechatPayService: service.NewWechatPayService(c),
WechatPayService: service.NewWechatPayService(c, userAuthModel),
ApplePayService: service.NewApplePayService(c),
WestDexService: westDexService,
YushanService: yushanService,
@@ -70,7 +71,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
ApiRequestService: service.NewApiRequestService(c, westDexService, yushanService, featureModel, productFeatureModel),
AsynqService: service.NewAsynqService(c),
UserModel: model.NewUserModel(db, c.CacheRedis),
UserAuthModel: model.NewUserAuthModel(db, c.CacheRedis),
UserAuthModel: userAuthModel,
ProductModel: model.NewProductModel(db, c.CacheRedis),
OrderModel: model.NewOrderModel(db, c.CacheRedis),
QueryModel: model.NewQueryModel(db, c.CacheRedis),

View File

@@ -63,8 +63,9 @@ type PaymentReq struct {
}
type PaymentResp struct {
PrepayID string `json:"prepay_id"`
OrderID int64 `json:"order_id"`
PrepayData interface{} `json:"prepay_data"`
PrepayId string `json:"prepay_id"`
OrderID int64 `json:"order_id"`
}
type Product struct {