APP微信支付
由於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 協議》,轉載必須註明作者和本文連結