146 lines
3.7 KiB
Go
146 lines
3.7 KiB
Go
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
|
||
}
|