mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-04 12:52:27 +08:00
feat: 添加发放红包接口 (#726)
* feat: 添加发放红包接口 * feat: 添加发放红包接口 * chore: golang ci lint --------- Co-authored-by: ross <ross@ross.ross>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/silenceper/wechat/v2/pay/config"
|
"github.com/silenceper/wechat/v2/pay/config"
|
||||||
"github.com/silenceper/wechat/v2/pay/notify"
|
"github.com/silenceper/wechat/v2/pay/notify"
|
||||||
"github.com/silenceper/wechat/v2/pay/order"
|
"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/refund"
|
||||||
"github.com/silenceper/wechat/v2/pay/transfer"
|
"github.com/silenceper/wechat/v2/pay/transfer"
|
||||||
)
|
)
|
||||||
@@ -37,3 +38,8 @@ func (pay *Pay) GetRefund() *refund.Refund {
|
|||||||
func (pay *Pay) GetTransfer() *transfer.Transfer {
|
func (pay *Pay) GetTransfer() *transfer.Transfer {
|
||||||
return transfer.NewTransfer(pay.cfg)
|
return transfer.NewTransfer(pay.cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetRedpacket 红包
|
||||||
|
func (pay *Pay) GetRedpacket() *redpacket.Redpacket {
|
||||||
|
return redpacket.NewRedpacket(pay.cfg)
|
||||||
|
}
|
||||||
|
|||||||
131
pay/redpacket/redpacket.go
Normal file
131
pay/redpacket/redpacket.go
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
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:"mch_id"`
|
||||||
|
MchBillno string `xml:"mch_billno"`
|
||||||
|
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_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)
|
||||||
|
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,
|
||||||
|
MchBillno: p.MchBillno,
|
||||||
|
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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user