GithubHelp home page GithubHelp logo

wxpay's Introduction

wxpay

Powered by zch Language License

wxpay 提供了以下的方法:

方法名 说明
MicroPay 刷卡支付
UnifiedOrder 统一下单
OrderQuery 查询订单
Reverse 撤销订单
CloseOrder 关闭订单
Refund 申请退款
RefundQuery 查询退款
DownloadBill 下载对账单
Report 交易保障
ShortUrl 转换短链接
AuthCodeToOpenid 授权码查询openid
  • 参数为Params类型,返回类型也是ParamsParams 是一个 map[string]string 类型。
  • 方法内部会将参数会转换成含有appidmch_idnonce_strsign_typesign的XML;
  • 默认使用MD5进行签名;
  • 通过HTTPS请求得到返回数据后会对其做必要的处理(例如验证签名,签名错误则抛出异常)。
  • 对于DownloadBill,无论是否成功都返回Map,且都含有return_codereturn_msg。若成功,其中return_codeSUCCESS,另外data对应对账单数据。

安装

$ go get github.com/objcoding/wxpay

go modules

// go.mod
require github.com/objcoding/wxpay v1.0.5

示例

// 创建支付账户
account1 := wxpay.NewAccount("appid", "mchid", "apiKey", false)
account2 := wxpay.NewAccount("appid", "mchid", "apiKey", false)

// 新建微信支付客户端
client := wxpay.NewClient(account1)

// 设置证书
account.SetCertData("证书地址")

// 设置支付账户
client.setAccount(account2)

// 设置http请求超时时间
client.SetHttpConnectTimeoutMs(2000)

// 设置http读取信息流超时时间
client.SetHttpReadTimeoutMs(1000)

// 更改签名类型
client.SetSignType(HMACSHA256)

// 统一下单
params := make(wxpay.Params)
params.SetString("body", "test").
		SetString("out_trade_no", "436577857").
		SetInt64("total_fee", 1).
		SetString("spbill_create_ip", "127.0.0.1").
		SetString("notify_url", "http://notify.objcoding.com/notify").
		SetString("trade_type", "APP")
p, _ := client.UnifiedOrder(params)

// 订单查询
params := make(wxpay.Params)
params.SetString("out_trade_no", "3568785")
p, _ := client.OrderQuery(params)

// 退款
params := make(wxpay.Params)
params.SetString("out_trade_no", "3568785").
		SetString("out_refund_no", "19374568").
		SetInt64("total_fee", 1).
		SetInt64("refund_fee", 1)
p, _ := client.Refund(params)

// 退款查询
params := make(wxpay.Params)
params.SetString("out_refund_no", "3568785")
p, _ := client.RefundQuery(params)

// 签名
signStr := client.Sign(params)

// 校验签名
b := client.ValidSign(params)

// xml解析
params := wxpay.XmlToMap(xmlStr)

// map封装xml请求参数
b := wxpay.MapToXml(params)

// 支付或退款返回成功信息
return wxpay.Notifies{}.OK()

// 支付或退款返回失败信息
return wxpay.Notifies{}.NotOK("支付失败或退款失败了")

objcoding

License

MIT license

wxpay's People

Contributors

juwanxu avatar objcoding avatar wzxjohn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wxpay's Issues

http.Post 未传入timeout

return &Client{
...
httpConnectTimeoutMs: 2000,
httpReadTimeoutMs: 1000,
}

为什么项目里面不使用这两个参数呢? 按照godoc: "A Timeout of zero means no timeout."

XmlToMap 这个方法有bug,当xml 前面有空格的时候,返回的map为空

str := `<xml>
   <trade_type><![CDATA[APP]]></trade_type>
   <prepay_id><![CDATA[wx20190506151427404120]]></prepay_id>
   <nonce_str><![CDATA[1557126867008139000]]></nonce_str>
   <return_code><![CDATA[SUCCESS]]></return_code>
   <err_code_des><![CDATA[ok]]></err_code_des>
   <sign><![CDATA[3C323ECE220CC631240E874F80C3737D]]></sign>
   <mch_id><![CDATA[1225268501]]></mch_id>
   <return_msg><![CDATA[OK]]></return_msg>
   <appid><![CDATA[wxe353414396c4b931]]></appid>
   <device_info><![CDATA[sandbox]]></device_info>
   <result_code><![CDATA[SUCCESS]]></result_code>
   <err_code><![CDATA[SUCCESS]]></err_code>
 </xml>`
	mp := wxpay.XmlToMap(str)

wxpay 下的util.go的nonceStr() 方法报错

package wxpay
// 生成随机字符串
func nonceStr() string {
	uid := uuid.NewV4()
	//if err != nil {
	//	return errors.New("生成随机字符串").Error()
	//}
	return strings.Replace(uid.String(), "-", "", -1)
}```

XmlToMap方法有Bug,我是这样修改的

type xmlMapEntry struct {
XMLName xml.Name
Value string xml:",chardata"
}

func (m Params) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
if len(m) == 0 {
return nil
}
start.Name.Local = "xml" // 更改xml开始标签
err := e.EncodeToken(start)
if err != nil {
return err
}

for k, v := range m {
	e.Encode(xmlMapEntry{XMLName: xml.Name{Local: k}, Value: v})
}

return e.EncodeToken(start.End())

}

func (m *Params) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
*m = Params{}
for {
var e xmlMapEntry

	err := d.Decode(&e)
	if err == io.EOF {
		break
	} else if err != nil {
		return err
	}

	(*m)[e.XMLName.Local] = e.Value
}
return nil

}

func XmlToMap(xmlStr string) Params {

params := make(Params)
err := xml.Unmarshal([]byte(xmlStr), &params)
if err != nil {
	panic(err)
}
return params
// params := make(Params)
// decoder := xml.NewDecoder(strings.NewReader(xmlStr))

// var (
// 	key   string
// 	value string
// )

// for t, err := decoder.Token(); err == nil; t, err = decoder.Token() {
// 	switch token := t.(type) {
// 	case xml.StartElement: // 开始标签
// 		key = token.Name.Local
// 	case xml.CharData: // 标签内容
// 		content := string([]byte(token))
// 		value = content
// 	}
// 	if key != "xml" {
// 		if value != "\n" && value != "\n  " {
// 			params.SetString(key, value)
// 		}
// 	}
// }

return params

}

func MapToXml(params Params) string {
buf, err := xml.Marshal(params)
if err != nil {
panic(err)
}
return string(buf)
// var buf bytes.Buffer
// buf.WriteString(<xml>)
// for k, v := range params {
// buf.WriteString(<)
// buf.WriteString(k)
// buf.WriteString(><![CDATA[)
// buf.WriteString(v)
// buf.WriteString(]]></)
// buf.WriteString(k)
// buf.WriteString(>)
// }
// buf.WriteString(</xml>)

// return buf.String()

}

给你提个建议,把调起app支付的方法加上,今天调了一天才找的是这个原因掉不起来微信支付

client := m.getWxPayClient()
// 统一下单
params := make(wxpay.Params)
params.SetString("body", goodsInfo.GoodsName).
SetString("out_trade_no", convert.Int64ToStr(orderInfo.OrderID)).
SetInt64("total_fee", int64(orderInfo.Price)).
SetString("spbill_create_ip", ip).
SetString("notify_url", m.getWxPayCallBackUrl()).
SetString("trade_type", "APP")
//获取统一下单的prepayid
params, err := client.UnifiedOrder(params)
if err != nil {
return nil, err
}
//下面代码建议加上一个方法 直接获取 GetPayParams(params)
//获取调起微信支付的sign
PayParams := make(wxpay.Params)
PayParams.SetString("appid", params.GetString("appid"))
PayParams.SetString("partnerid", params.GetString("mch_id"))
PayParams.SetString("noncestr", params.GetString("nonce_str"))
PayParams.SetString("prepayid", params.GetString("prepay_id"))
PayParams.SetString("timestamp", convert.Int64ToStr(time.Now().Unix()))
PayParams.SetString("package", "Sign=WXPay")
PayParams.SetString("sign", client.Sign(PayParams))
return PayParams, nil

沙箱验证失败的问题

在调用client类函数Refund()退款时会报错

return_code value is invalid in XML

查看微信的回复内容为

<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[沙箱验证签名失败,请确认沙箱签名key是否正确(通过getsignkey调用生成)]]></return_msg> </xml>

麻烦问一下为什么会出现沙箱验证失败

我多加了一个单元,回调解码用,供参考

从另外一个项目抄过来的。

package wxpay

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"io"
)

// ToJSON 转化成JSON字符
func (p Params) ToJSON() string {
	mjson, _ := json.Marshal(p)
	return string(mjson)
}

// Decode XML解码
func Decode(r io.Reader) Params {
	var (
		d      *xml.Decoder
		start  *xml.StartElement
		params Params
	)
	d = xml.NewDecoder(r)
	params = make(Params)
	for {
		tok, err := d.Token()
		if err != nil {
			break
		}
		switch t := tok.(type) {
		case xml.StartElement:
			start = &t
		case xml.CharData:
			if t = bytes.TrimSpace(t); len(t) > 0 {
				params.SetString(start.Name.Local, string(t))
			}
		}
	}
	return params
}

// Encode XML编码
func Encode(params Params) io.Reader {
	var buf bytes.Buffer
	buf.WriteString(``)
	for k, v := range params {
		buf.WriteString(`<`)
		buf.WriteString(k)
		buf.WriteString(`>`)
	}
	buf.WriteString(``)
	return &buf
}

调用微信api的http请求存在资源泄露 responsebody没有关闭

// https no cert post
func (c *Client) postWithoutCert(url string, params Params) (string, error) {
h := &http.Client{}
p := c.fillRequestData(params)
response, err := h.Post(url, bodyType, strings.NewReader(MapToXml(p)))
if err != nil {
return "", err
}
//应该加上 defer response.Body.Close()
res, err := ioutil.ReadAll(response.Body)
if err != nil {
return "", err
}
return string(res), nil
}

为什么支付回调的方法没有?

你只有校验签名的,在签名前需要组装你param 还要解析xml 你的方法都没暴露外面,这样我需要自己写xml解析,能加上校验回调的方法吗?或者暴露解析xml方法

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.