2023-12-21 22:17:40 +08:00
|
|
|
|
package wxpaycli
|
|
|
|
|
|
|
|
|
|
import (
|
2024-02-03 16:04:56 +08:00
|
|
|
|
"context"
|
2024-02-05 21:16:49 +08:00
|
|
|
|
"net/http"
|
2024-02-05 21:55:44 +08:00
|
|
|
|
"os"
|
2024-02-03 16:04:56 +08:00
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/go-pay/gopay"
|
2023-12-21 22:17:40 +08:00
|
|
|
|
wxpay "github.com/go-pay/gopay/wechat/v3"
|
2024-02-03 16:04:56 +08:00
|
|
|
|
|
2023-12-21 22:17:40 +08:00
|
|
|
|
"service/bizcommon/util"
|
|
|
|
|
"service/library/configcenter"
|
|
|
|
|
"service/library/logger"
|
|
|
|
|
)
|
|
|
|
|
|
2024-02-03 16:04:56 +08:00
|
|
|
|
const (
|
|
|
|
|
DefaultOrderTimeoutSeconds = 900 // 默认订单超时时间,单位: s
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var defaultWxpayClient *WxpayClient
|
|
|
|
|
|
2023-12-21 22:17:40 +08:00
|
|
|
|
type WxpayClient struct {
|
|
|
|
|
*wxpay.ClientV3
|
2024-02-03 16:04:56 +08:00
|
|
|
|
AppId string `json:"app_id"`
|
|
|
|
|
NotifyUrl string `json:"notify_url"`
|
2023-12-21 22:17:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-03 16:04:56 +08:00
|
|
|
|
func GetDefaultWxpayClient() *WxpayClient {
|
|
|
|
|
return defaultWxpayClient
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Init(cfg *configcenter.WxpayClientConfig) (err error) {
|
2024-02-05 21:55:44 +08:00
|
|
|
|
// private key
|
|
|
|
|
bs, err := os.ReadFile(cfg.PrivateKeyPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("real PrivateKeyPath fail, cfg: %v, err: %v", util.ToJson(cfg), err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
privateKey := string(bs)
|
|
|
|
|
|
|
|
|
|
wxpayCli, err := wxpay.NewClientV3(cfg.MchId, cfg.SerialNo, cfg.ApiV3Key, privateKey)
|
2023-12-21 22:17:40 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("NewClientV3 fail, cfg: %v, err: %v", util.ToJson(cfg), err)
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-02-03 16:04:56 +08:00
|
|
|
|
|
|
|
|
|
defaultWxpayClient = &WxpayClient{
|
2024-02-05 01:15:29 +08:00
|
|
|
|
ClientV3: wxpayCli,
|
|
|
|
|
AppId: cfg.AppId,
|
|
|
|
|
NotifyUrl: cfg.NotifyUrl,
|
2024-02-03 16:04:56 +08:00
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验签
|
2024-02-05 21:16:49 +08:00
|
|
|
|
func (c *WxpayClient) ParseNotify(req *http.Request) (notify *wxpay.V3DecryptResult, err error) {
|
|
|
|
|
notifyReq, err := wxpay.V3ParseNotify(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("V3ParseNotify fail, notifyReq: %v, err: %v", util.ToJson(notifyReq), err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if notifyReq == nil {
|
|
|
|
|
logger.Error("V3ParseNotify nil, err: %v", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
notifyTmp, err := notifyReq.DecryptCipherText(string(c.ApiV3Key))
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("DecryptCipherText fail, notifyTmp: %v, err: %v", util.ToJson(notifyTmp), err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if notifyTmp == nil {
|
|
|
|
|
logger.Error("DecryptCipherText nil, err: %v", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
logger.Info("Wxpay ParseNotify, %v", util.ToJson(notifyTmp))
|
|
|
|
|
|
|
|
|
|
notify = notifyTmp
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-02-03 16:04:56 +08:00
|
|
|
|
|
|
|
|
|
// 微信支付 native支付
|
|
|
|
|
type NativePayParam struct {
|
|
|
|
|
Description string
|
|
|
|
|
OutTradeNo string // 商家订单id,我们自己的订单id
|
|
|
|
|
TotalAmount int64 // 金额,单位:分
|
|
|
|
|
TimeOutSeconds int // 订单有效时间,单位:秒
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 21:16:49 +08:00
|
|
|
|
func (c *WxpayClient) NativePay(ctx context.Context, param *NativePayParam) (wxpayNativeParamStr string, err error) {
|
2024-02-03 16:04:56 +08:00
|
|
|
|
if param.TimeOutSeconds <= 0 {
|
|
|
|
|
param.TimeOutSeconds = DefaultOrderTimeoutSeconds
|
|
|
|
|
}
|
|
|
|
|
bm := gopay.BodyMap{
|
|
|
|
|
"appid": c.AppId,
|
|
|
|
|
"description": param.Description,
|
|
|
|
|
"out_trade_no": param.OutTradeNo,
|
|
|
|
|
"time_expire": time.Now().Add(time.Second * time.Duration(param.TimeOutSeconds)).Format(time.RFC3339),
|
|
|
|
|
"notify_url": c.NotifyUrl,
|
|
|
|
|
"amount": gopay.BodyMap{
|
|
|
|
|
"total": param.TotalAmount,
|
|
|
|
|
"currency": "CNY",
|
|
|
|
|
},
|
|
|
|
|
}
|
2024-02-05 21:16:49 +08:00
|
|
|
|
resp, err := c.V3TransactionNative(ctx, bm)
|
2024-02-03 16:04:56 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-02-05 01:15:29 +08:00
|
|
|
|
if resp.Code != wxpay.Success {
|
2024-02-05 21:16:49 +08:00
|
|
|
|
logger.Info("wxpay NativePay fail, code: %v, error: %v, response: %v", resp.Code, resp.Error, util.ToJson(resp.Response))
|
2024-02-03 16:04:56 +08:00
|
|
|
|
return
|
2023-12-21 22:17:40 +08:00
|
|
|
|
}
|
2024-02-05 21:16:49 +08:00
|
|
|
|
wxpayNativeParamStr = resp.Response.CodeUrl
|
|
|
|
|
logger.Info("wxpay NativePay success, code: %v, error: %v, response: %v", resp.Code, resp.Error, util.ToJson(resp.Response))
|
2023-12-21 22:17:40 +08:00
|
|
|
|
return
|
|
|
|
|
}
|