| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- package transfer
- import (
- "encoding/xml"
- "fmt"
- "strconv"
- "github.com/silenceper/wechat/v2/pay/config"
- "github.com/silenceper/wechat/v2/util"
- )
- // walletTransferGateway 付款到零钱
- // https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
- var walletTransferGateway = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"
- // Transfer struct extends context
- type Transfer struct {
- *config.Config
- }
- // NewTransfer return an instance of Transfer package
- func NewTransfer(cfg *config.Config) *Transfer {
- return &Transfer{cfg}
- }
- // Params 调用参数
- type Params struct {
- DeviceInfo string
- PartnerTradeNo string
- OpenID string
- CheckName bool
- ReUserName string
- Amount int
- Desc string
- SpbillCreateIP string
- RootCa string // ca证书
- }
- // request 接口请求参数
- type request struct {
- AppID string `xml:"mch_appid"`
- MchID string `xml:"mchid"`
- NonceStr string `xml:"nonce_str"`
- Sign string `xml:"sign"`
- DeviceInfo string `xml:"device_info,omitempty"`
- PartnerTradeNo string `xml:"partner_trade_no"`
- OpenID string `xml:"openid"`
- CheckName string `xml:"check_name"`
- ReUserName string `xml:"re_user_name,omitempty"`
- Amount int `xml:"amount"`
- Desc string `xml:"desc"`
- SpbillCreateIP string `xml:"spbill_create_ip,omitempty"`
- }
- // Response 接口返回
- type Response struct {
- ReturnCode string `xml:"return_code"`
- ReturnMsg string `xml:"return_msg"`
- AppID string `xml:"appid,omitempty"`
- MchID string `xml:"mch_id,omitempty"`
- DeviceInfo string `xml:"device_info,omitempty"`
- NonceStr string `xml:"nonce_str,omitempty"`
- ResultCode string `xml:"result_code,omitempty"`
- ErrCode string `xml:"err_code,omitempty"`
- ErrCodeDes string `xml:"err_code_des,omitempty"`
- PartnerTradeNo string `xml:"partner_trade_no"`
- PaymentNo string `xml:"payment_no"`
- PaymentTime string `xml:"payment_time"`
- }
- // WalletTransfer 付款到零钱
- func (transfer *Transfer) WalletTransfer(p *Params) (rsp *Response, err error) {
- nonceStr := util.RandomStr(32)
- param := make(map[string]string)
- param["mch_appid"] = transfer.AppID
- param["mchid"] = transfer.MchID
- param["nonce_str"] = nonceStr
- param["partner_trade_no"] = p.PartnerTradeNo
- param["openid"] = p.OpenID
- param["amount"] = strconv.Itoa(p.Amount)
- param["desc"] = p.Desc
- if p.DeviceInfo != "" {
- param["device_info"] = p.DeviceInfo
- }
- param["check_name"] = "NO_CHECK"
- if p.CheckName {
- param["check_name"] = "FORCE_CHECK"
- param["re_user_name"] = p.ReUserName
- }
- if p.SpbillCreateIP != "" {
- param["spbill_create_ip"] = p.SpbillCreateIP
- }
- sign, err := util.ParamSign(param, transfer.Key)
- if err != nil {
- return
- }
- req := request{
- AppID: transfer.AppID,
- MchID: transfer.MchID,
- NonceStr: nonceStr,
- Sign: sign,
- DeviceInfo: p.DeviceInfo,
- PartnerTradeNo: p.PartnerTradeNo,
- OpenID: p.OpenID,
- Amount: p.Amount,
- Desc: p.Desc,
- SpbillCreateIP: p.SpbillCreateIP,
- }
- req.CheckName = "NO_CHECK"
- if p.CheckName {
- req.CheckName = "FORCE_CHECK"
- req.ReUserName = p.ReUserName
- }
- rawRet, err := util.PostXMLWithTLS(walletTransferGateway, req, p.RootCa, transfer.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("transfer error, errcode=%s,errmsg=%s", rsp.ErrCode, rsp.ErrCodeDes)
- return
- }
- err = fmt.Errorf("[msg : xmlUnmarshalError] [rawReturn : %s] [sign : %s]", string(rawRet), sign)
- return
- }
|