package qyweixin import ( "bytes" "context" "crypto/tls" butil "enterprise/base/util" "enterprise/common/config" "errors" "fmt" log "github.com/sirupsen/logrus" "github.com/smbrave/goutil" "github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/core/option" "github.com/wechatpay-apiv3/wechatpay-go/utils" "io/ioutil" "net/http" "time" ) type QyPay struct { cli *core.Client tlsClient *http.Client stdClient *http.Client } func NewQyPay() *QyPay { cfg := config.GetConfig() payCertPem, _ := ioutil.ReadFile(cfg.WxPay.PayCertPem) payKeyPem, _ := ioutil.ReadFile(cfg.WxPay.PayKeyPem) pay := &QyPay{} client, err := pay.withCert(payCertPem, payKeyPem) if err != nil { log.Errorf("with cert error :%s", err.Error()) return nil } pay.tlsClient = client return pay } // 附着商户证书 func (c *QyPay) withCert(cert, key []byte) (*http.Client, error) { tlsCert, err := tls.X509KeyPair(cert, key) if err != nil { return nil, err } conf := &tls.Config{ Certificates: []tls.Certificate{tlsCert}, } trans := &http.Transport{ TLSClientConfig: conf, } return &http.Client{ Transport: trans, }, nil } // 发送请求 func (c *QyPay) post(url string, params params, tls bool) ([]byte, error) { var httpc *http.Client if tls { if c.tlsClient == nil { return nil, errors.New("tls wepay is not initialized") } httpc = c.tlsClient } else { httpc = c.stdClient } buf := bytes.NewBuffer(params.Encode()) resp, err := httpc.Post(url, "application/xml; charset=utf-8", buf) if err != nil { return nil, err } body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } return body, nil } func (w *QyPay) initPay() error { cfg := config.GetConfig() // 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名 mchPrivateKey, err := utils.LoadPrivateKeyWithPath(cfg.WxPay.PayKeyPem) if err != nil { log.Errorf("utils.LoadPrivateKeyWithPath error %s", err.Error()) return err } ctx := context.Background() // 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力 opts := []core.ClientOption{ option.WithWechatPayAutoAuthCipher(cfg.WxPay.PayMchId, cfg.WxPay.PaySerialNumber, mchPrivateKey, cfg.WxPay.PayApiKeyV3), } client, err := core.NewClient(ctx, opts...) if err != nil { log.Errorf("core.NewClient error :%s", err.Error()) return err } fmt.Println(goutil.EncodeJSON(cfg.WxPay)) w.cli = client return nil } func (p *QyPay) PayRedMoney() error { if p.cli == nil { if err := p.initPay(); err != nil { return err } } cfg := config.GetConfig() param := newParams() param.Set("nonce_str", butil.RandomStr(32)) param.Set("mch_billno", fmt.Sprintf("QY%s%s", time.Now().Format("20060102150405"), butil.RandomStr(6))) param.Set("mch_id", cfg.WxPay.PayMchId) param.Set("wxappid", cfg.QyWeixin.Corpid) param.Set("agentid", "1") param.Set("re_openid", "oZZmL6Lx7Rj3vbNRXgA3ZpwU_tzM") param.Set("total_amount", "100") param.Set("wishing", "感谢您参加猜灯谜活动,祝您元宵节快乐!") param.Set("act_name", "猜灯谜抢红包活动") param.Set("remark", "猜越多得越多,快来抢!") param.Set("workwx_sign", param.QySignMd5(cfg.QyWeixin.PaySecret)) param.Set("sign", param.SignMd5(cfg.WxPay.PayApiKeyV2)) reqUrl := "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendworkwxredpack" rspBody, err := p.post(reqUrl, param, true) if err != nil { log.Errorf("Post [%s] [%s] error :%s", reqUrl, string(param.Encode()), err.Error()) return err } respParam := newParams() respParam.Decode(rspBody) fmt.Println("req:", string(param.Encode())) fmt.Println("resp: ", string(respParam.Encode())) return nil }