go-zero之App微信支付服务

APP微信支付

参考文档:gopay代码库 官网文档

由于go-zero 会生成很多代码,这里我就简单写一下主要的代码,想看完整的话参考web支付服务

实例化客户端


func NewWxAppPayClient(mchId, serialNo, apiV3Key, cPath string) *wechat.ClientV3 {
    // NewClientV3 初始化微信客户端 v3
    //    mchid:商户ID 或者服务商模式的 sp_mchid
    //     serialNo:商户证书的证书序列号
    //    apiV3Key:apiV3Key,商户平台获取
    //    privateKey:私钥 apiclient_key.pem 读取后的内容
    privateKeyPath := GetFilePath(cPath)
    privateKey, _ := ioutil.ReadFile(privateKeyPath)
    client, err := wechat.NewClientV3(mchId, serialNo, apiV3Key, string(privateKey))
    if err != nil {
        logx.Error("微信初始化失败", err)
        return nil
    }
    // 启用自动同步返回验签,并定时更新微信平台API证书
    err = client.AutoVerifySign()
    if err != nil {
        logx.Error("自动同步返回验签失败", err)
        return nil
    }
    return client
}

生成预支付

//  APP 微信生成预付单
func (l *WxPrePayLogic) WxPrePay(in *order.WxPrePayRequest) (*order.Response, error) {
    data := make(map[string]string, 0)
    appId := l.svcCtx.Config.WxAppPay.AppId
    mchId := l.svcCtx.Config.WxAppPay.MchId
    serialNo := l.svcCtx.Config.WxAppPay.MCSNum
    apiV3Key := l.svcCtx.Config.WxAppPay.ApiV3Secret
    cPath := l.svcCtx.Config.WxAppPay.CPath
    notifyUrl := l.svcCtx.Config.WxAppPay.NotifyUrl
    bm := make(gopay.BodyMap)
    bm.Set("appid", appId).
        Set("mchid", mchId).
        Set("description", in.Desc).
        Set("out_trade_no", in.OrderId).
        Set("notify_url", notifyUrl).
        SetBodyMap("amount", func(bm gopay.BodyMap) {
            bm.Set("total", in.Total).
                Set("currency", "CNY")
        })

    // 调用微信客户端
    wxResp, err := tool.NewWxAppPayClient(mchId, serialNo, apiV3Key, cPath).V3TransactionApp(context.TODO(), bm)
    if err != nil {
        logx.Error("微信APP下单失败", err)
        return &order.Response{
            Code: 201,
            Msg:  "下单失败",
            Data: data,
        }, nil
    }
    data["prepay_id"] = wxResp.Response.PrepayId
    return &order.Response{
        Code: 200,
        Msg:  "success",
        Data: data,
    }, nil
}

微信支付

//  APP 微信支付,
func (l *WxPayLogic) WxPay(in *order.WxPayRequest) (*order.Response, error) {
    data := make(map[string]string, 0)
    appId := l.svcCtx.Config.WxAppPay.AppId
    mchId := l.svcCtx.Config.WxAppPay.MchId
    serialNo := l.svcCtx.Config.WxAppPay.MCSNum
    apiV3Key := l.svcCtx.Config.WxAppPay.ApiV3Secret
    cPath := l.svcCtx.Config.WxAppPay.CPath
    // 调起支付,获取参数和签名,下发给前端APP
    app, err := tool.NewWxAppPayClient(mchId, serialNo, apiV3Key, cPath).PaySignOfApp(appId, in.PrePayId)
    if err != nil {
        logx.Error("支付失败")
        return &order.Response{
            Code: 201,
            Msg:  "支付失败",
            Data: data,
        }, nil
    }
    data["appid"] = app.Appid
    data["partnerid"] = app.Partnerid
    data["prepayid"] = in.PrePayId
    data["package"] = app.Package
    data["noncestr"] = app.Noncestr
    data["timestamp"] = app.Timestamp
    data["sign"] = app.Sign
    return &order.Response{
        Code: 200,
        Msg:  "success",
        Data: data,
    }, nil
}

接口

这里把微信和支付宝合并了,根据前端传递的类型来判断是哪种支付方式。

// APP 支付
func (l *AppPayLogic) AppPay(req types.GenerateOrderReq) (*types.OrderResponse, error) {
    data := make(map[string]interface{}, 0)
    userId, _ := l.ctx.Value("userId").(json.Number).Int64()

    // 商品详情
    goodsInfo, err := l.svcCtx.Lookclient.GoodsDetail(l.ctx, &lookclient.FindGoodsByIdRequest{Id: req.GoodsId})
    if err != nil || goodsInfo.Code != 200 {
        return &types.OrderResponse{
            Code: 201,
            Msg:  goodsInfo.Msg,
            Data: data,
        }, nil
    }
    // 商品表价格字符串转int64
    price, _ := strconv.ParseFloat(goodsInfo.Data.Price, 10)
    goodsPrice := int64(price * 100)
    // 生成订单详情
    goodsInfoData, _ := json.Marshal(goodsInfo.Data)
    // rpc 生成订单
    orderInfo, err := l.svcCtx.OrderClient.GenerateOrder(l.ctx, &orderclient.GenerateOrderRequest{
        UserId:  userId,
        GoodsId: goodsInfo.Data.Id,
        PayType: req.PayType,
        Amount:  goodsPrice,
        Desc:    goodsInfo.Data.Desc,
        Data:    string(goodsInfoData),
    })
    if err != nil || orderInfo.Code != 200 {
        return &types.OrderResponse{
            Code: 201,
            Msg:  orderInfo.Msg,
            Data: data,
        }, nil
    }
    // 判断支付方式
    if req.PayType == config.WxPay {
        // 生成预支付
        wxPrePayResp, err := l.svcCtx.OrderClient.WxPrePay(l.ctx, &orderclient.WxPrePayRequest{
            OrderId: orderInfo.Data["order_id"],
            Desc:    goodsInfo.Data.Desc,
            Total:   goodsPrice,
        })

        if err != nil || wxPrePayResp.Code != 200 {
            return &types.OrderResponse{
                Code: 201,
                Msg:  wxPrePayResp.Msg,
                Data: data,
            }, nil
        }

        // 生成支付信息
        wxPayResp, err := l.svcCtx.OrderClient.WxPay(l.ctx, &orderclient.WxPayRequest{
            PrePayId: wxPrePayResp.Data["prepay_id"],
        })
        if err != nil || wxPayResp.Code != 200 {
            return &types.OrderResponse{
                Code: 201,
                Msg:  wxPayResp.Msg,
                Data: data,
            }, nil
        }
        data["info"] = wxPayResp.Data
    } else if req.PayType == config.AliPay {
        // 支付宝支付
        aliPayResp, err := l.svcCtx.OrderClient.AliAppPay(l.ctx, &orderclient.AliPrePayRequest{
            OrderId: orderInfo.Data["order_id"],
            Desc:    goodsInfo.Data.Desc,
            Total:   goodsPrice,
        })
        if err != nil || aliPayResp.Code != 200 {
            return &types.OrderResponse{
                Code: 201,
                Msg:  aliPayResp.Msg,
                Data: data,
            }, nil
        }
        data["info"] = aliPayResp.Data
    }
    return &types.OrderResponse{
        Code: 200,
        Msg:  "success",
        Data: data,
    }, nil
}

测试下

goods_id 表示商品id,pay_type表示支付方式,1:微信,2:支付宝

curl --location --request POST 'https://localhost/order/app_pay' \
--header 'User-Agent: Apipost client Runtime/+https://www.apipost.cn/' \
--form 'goods_id=2' \
--form 'pay_type=1'


{
    "code": 200,
    "msg": "success",
    "data": {
        "info": {
            "appid": "wxfafadfadfafd1",
            "noncestr": "auwyL7PvDhdfadfadfaf",
            "package": "Sign=WXPay",
            "partnerid": "12312313131231",
            "prepayid": "fadfaefeafae124123ef23234234243",
            "sign": "f7q9A7VIP/D62/AG5QKxr2hQ==",
            "timestamp": "2342342342424"
        }
    }
}

这里只写了微信的,下次有时间再写下支付宝APP支付

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
39
粉丝
9
喜欢
71
收藏
102
排名:461
访问:1.9 万
私信
所有博文
社区赞助商