package wxpaycli import ( "context" "net/http" "os" "time" "github.com/go-pay/gopay" wxpay "github.com/go-pay/gopay/wechat/v3" "service/bizcommon/util" "service/library/configcenter" "service/library/logger" ) const ( DefaultOrderTimeoutSeconds = 900 // 默认订单超时时间,单位: s ) var defaultWxpayClient *WxpayClient type WxpayClient struct { *wxpay.ClientV3 AppId string `json:"app_id"` NotifyUrl string `json:"notify_url"` } func GetDefaultWxpayClient() *WxpayClient { return defaultWxpayClient } func Init(cfg *configcenter.WxpayClientConfig) (err error) { // 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) if err != nil { logger.Error("NewClientV3 fail, cfg: %v, err: %v", util.ToJson(cfg), err) return } defaultWxpayClient = &WxpayClient{ ClientV3: wxpayCli, AppId: cfg.AppId, NotifyUrl: cfg.NotifyUrl, } return } // 验签 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 } // 微信支付 native支付 type NativePayParam struct { Description string OutTradeNo string // 商家订单id,我们自己的订单id TotalAmount int64 // 金额,单位:分 TimeOutSeconds int // 订单有效时间,单位:秒 } func (c *WxpayClient) NativePay(ctx context.Context, param *NativePayParam) (wxpayNativeParamStr string, err error) { 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", }, } resp, err := c.V3TransactionNative(ctx, bm) if err != nil { return } if resp.Code != wxpay.Success { logger.Info("wxpay NativePay fail, code: %v, error: %v, response: %v", resp.Code, resp.Error, util.ToJson(resp.Response)) return } wxpayNativeParamStr = resp.Response.CodeUrl logger.Info("wxpay NativePay success, code: %v, error: %v, response: %v", resp.Code, resp.Error, util.ToJson(resp.Response)) return }