From ea546fa205b36e191a2a29a406510b40c2247b85 Mon Sep 17 00:00:00 2001 From: ross Date: Thu, 21 Sep 2023 19:06:51 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=8F=91?= =?UTF-8?q?=E6=94=BE=E7=BA=A2=E5=8C=85=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pay/pay.go | 6 ++ pay/redpacket/redpacket.go | 129 +++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 pay/redpacket/redpacket.go diff --git a/pay/pay.go b/pay/pay.go index c1f42f6..e873af2 100644 --- a/pay/pay.go +++ b/pay/pay.go @@ -4,6 +4,7 @@ import ( "github.com/silenceper/wechat/v2/pay/config" "github.com/silenceper/wechat/v2/pay/notify" "github.com/silenceper/wechat/v2/pay/order" + "github.com/silenceper/wechat/v2/pay/redpacket" "github.com/silenceper/wechat/v2/pay/refund" "github.com/silenceper/wechat/v2/pay/transfer" ) @@ -37,3 +38,8 @@ func (pay *Pay) GetRefund() *refund.Refund { func (pay *Pay) GetTransfer() *transfer.Transfer { return transfer.NewTransfer(pay.cfg) } + +// NewRedpacket 红包 +func (pay *Pay) GetRedpacket() *redpacket.Redpacket { + return redpacket.NewRedpacket(pay.cfg) +} diff --git a/pay/redpacket/redpacket.go b/pay/redpacket/redpacket.go new file mode 100644 index 0000000..f7330ff --- /dev/null +++ b/pay/redpacket/redpacket.go @@ -0,0 +1,129 @@ +package redpacket + +import ( + "encoding/xml" + "fmt" + "strconv" + + "github.com/silenceper/wechat/v2/pay/config" + "github.com/silenceper/wechat/v2/util" +) + +// redpacketGateway 发放红包接口 +// https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3 +var redpacketGateway = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack" + +// Redpacket struct extends context +type Redpacket struct { + *config.Config +} + +// NewRedpacket return an instance of Redpacket package +func NewRedpacket(cfg *config.Config) *Redpacket { + return &Redpacket{cfg} +} + +// Params 调用参数 +type Params struct { + MchBillno string // 商户订单号 + SendName string // 商户名称 + ReOpenID string + TotalAmount int + TotalNum int + Wishing string + ClientIp string + ActName string + Remark string + + RootCa string // ca证书 +} + +// request 接口请求参数 +type request struct { + NonceStr string `xml:"nonce_str"` + Sign string `xml:"sign"` + MchID string `xml:"mchid"` + Wxappid string `xml:"wxappid"` + SendName string `xml:"send_name"` + ReOpenID string `xml:"re_openid"` + TotalAmount int `xml:"total_amount"` + TotalNum int `xml:"total_num"` + Wishing string `xml:"wishing"` + ClientIp string `xml:"client_ip"` + ActName string `xml:"act_name"` + Remark string `xml:"remark"` +} + +// Response 接口返回 +type Response struct { + ReturnCode string `xml:"return_code"` + ReturnMsg string `xml:"return_msg"` + ResultCode string `xml:"result_code,omitempty"` + ErrCode string `xml:"err_code,omitempty"` + ErrCodeDes string `xml:"err_code_des,omitempty"` + MchBillno string `xml:"mch_billno,omitempty"` + MchId string `xml:"mch_id,omitempty"` + Wxappid string `xml:"wxappid"` + ReOpenID string `xml:"re_openid"` + TotalAmount int `xml:"total_amount"` + SendListid string `xml:"send_listid"` +} + +// SendRedpacket 发放红包 +func (redpacket *Redpacket) SendRedpacket(p *Params) (rsp *Response, err error) { + nonceStr := util.RandomStr(32) + param := make(map[string]string) + + param["nonce_str"] = nonceStr + param["mch_billno"] = p.MchBillno + param["mchid"] = redpacket.MchID + param["wxappid"] = redpacket.AppID + param["send_name"] = p.SendName + param["re_openid"] = p.ReOpenID + param["total_amount"] = strconv.Itoa(p.TotalAmount) + param["total_num"] = strconv.Itoa(p.TotalNum) + param["wishing"] = p.Wishing + param["client_ip"] = p.ClientIp + param["act_name"] = p.ActName + param["remark"] = p.Remark + //param["scene_id"] = "PRODUCT_2" + + sign, err := util.ParamSign(param, redpacket.Key) + if err != nil { + return + } + + req := request{ + NonceStr: nonceStr, + Sign: sign, + MchID: redpacket.MchID, + Wxappid: redpacket.AppID, + SendName: p.SendName, + ReOpenID: p.ReOpenID, + TotalAmount: p.TotalAmount, + TotalNum: p.TotalNum, + Wishing: p.Wishing, + ClientIp: p.ClientIp, + ActName: p.ActName, + Remark: p.Remark, + } + + rawRet, err := util.PostXMLWithTLS(redpacketGateway, req, p.RootCa, redpacket.MchID) + if err != nil { + return + } + err = xml.Unmarshal(rawRet, &rsp) + if err != nil { + return + } + if rsp.ReturnCode == "SUCCESS" { + if rsp.ResultCode == "SUCCESS" { + err = nil + return + } + err = fmt.Errorf("send redpacket error, errcode=%s,errmsg=%s", rsp.ErrCode, rsp.ErrCodeDes) + return + } + err = fmt.Errorf("[msg : xmlUnmarshalError] [rawReturn : %s] [sign : %s]", string(rawRet), sign) + return +} From f79259e9884a6a455f47d01f9e396d0081351124 Mon Sep 17 00:00:00 2001 From: ross Date: Thu, 21 Sep 2023 19:45:35 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=8F=91?= =?UTF-8?q?=E6=94=BE=E7=BA=A2=E5=8C=85=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pay/redpacket/redpacket.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pay/redpacket/redpacket.go b/pay/redpacket/redpacket.go index f7330ff..21448e8 100644 --- a/pay/redpacket/redpacket.go +++ b/pay/redpacket/redpacket.go @@ -42,7 +42,8 @@ type Params struct { type request struct { NonceStr string `xml:"nonce_str"` Sign string `xml:"sign"` - MchID string `xml:"mchid"` + MchID string `xml:"mch_id"` + MchBillno string `xml:"mch_billno"` Wxappid string `xml:"wxappid"` SendName string `xml:"send_name"` ReOpenID string `xml:"re_openid"` @@ -75,9 +76,9 @@ func (redpacket *Redpacket) SendRedpacket(p *Params) (rsp *Response, err error) param := make(map[string]string) param["nonce_str"] = nonceStr - param["mch_billno"] = p.MchBillno - param["mchid"] = redpacket.MchID + param["mch_id"] = redpacket.MchID param["wxappid"] = redpacket.AppID + param["mch_billno"] = p.MchBillno param["send_name"] = p.SendName param["re_openid"] = p.ReOpenID param["total_amount"] = strconv.Itoa(p.TotalAmount) @@ -98,6 +99,7 @@ func (redpacket *Redpacket) SendRedpacket(p *Params) (rsp *Response, err error) Sign: sign, MchID: redpacket.MchID, Wxappid: redpacket.AppID, + MchBillno: p.MchBillno, SendName: p.SendName, ReOpenID: p.ReOpenID, TotalAmount: p.TotalAmount, From bd5191b20622e1d0e0bd3745e194da81f99c1815 Mon Sep 17 00:00:00 2001 From: ross Date: Fri, 22 Sep 2023 09:42:35 +0800 Subject: [PATCH 3/3] chore: golang ci lint --- pay/pay.go | 2 +- pay/redpacket/redpacket.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pay/pay.go b/pay/pay.go index e873af2..95416c2 100644 --- a/pay/pay.go +++ b/pay/pay.go @@ -39,7 +39,7 @@ func (pay *Pay) GetTransfer() *transfer.Transfer { return transfer.NewTransfer(pay.cfg) } -// NewRedpacket 红包 +// GetRedpacket 红包 func (pay *Pay) GetRedpacket() *redpacket.Redpacket { return redpacket.NewRedpacket(pay.cfg) } diff --git a/pay/redpacket/redpacket.go b/pay/redpacket/redpacket.go index 21448e8..ff1a397 100644 --- a/pay/redpacket/redpacket.go +++ b/pay/redpacket/redpacket.go @@ -31,7 +31,7 @@ type Params struct { TotalAmount int TotalNum int Wishing string - ClientIp string + ClientIP string ActName string Remark string @@ -50,7 +50,7 @@ type request struct { TotalAmount int `xml:"total_amount"` TotalNum int `xml:"total_num"` Wishing string `xml:"wishing"` - ClientIp string `xml:"client_ip"` + ClientIP string `xml:"client_ip"` ActName string `xml:"act_name"` Remark string `xml:"remark"` } @@ -63,7 +63,7 @@ type Response struct { ErrCode string `xml:"err_code,omitempty"` ErrCodeDes string `xml:"err_code_des,omitempty"` MchBillno string `xml:"mch_billno,omitempty"` - MchId string `xml:"mch_id,omitempty"` + MchID string `xml:"mch_id,omitempty"` Wxappid string `xml:"wxappid"` ReOpenID string `xml:"re_openid"` TotalAmount int `xml:"total_amount"` @@ -84,7 +84,7 @@ func (redpacket *Redpacket) SendRedpacket(p *Params) (rsp *Response, err error) param["total_amount"] = strconv.Itoa(p.TotalAmount) param["total_num"] = strconv.Itoa(p.TotalNum) param["wishing"] = p.Wishing - param["client_ip"] = p.ClientIp + param["client_ip"] = p.ClientIP param["act_name"] = p.ActName param["remark"] = p.Remark //param["scene_id"] = "PRODUCT_2" @@ -105,7 +105,7 @@ func (redpacket *Redpacket) SendRedpacket(p *Params) (rsp *Response, err error) TotalAmount: p.TotalAmount, TotalNum: p.TotalNum, Wishing: p.Wishing, - ClientIp: p.ClientIp, + ClientIP: p.ClientIP, ActName: p.ActName, Remark: p.Remark, }