Bladeren bron

添加微信支付回签名认证

huangrf 6 jaren geleden
bovenliggende
commit
73604a893b
2 gewijzigde bestanden met toevoegingen van 115 en 0 verwijderingen
  1. 104 0
      third/wx/verify.go
  2. 11 0
      third/wx/wx.go

+ 104 - 0
third/wx/verify.go

@@ -0,0 +1,104 @@
+package wx
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"encoding/xml"
+	"errors"
+	"io"
+	"net/url"
+	"sort"
+	"strings"
+)
+
+type XMLMap url.Values
+
+type xmlMapEntry struct {
+	XMLName xml.Name
+	Value   string `xml:",chardata"`
+}
+
+func (m XMLMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+	for {
+		var e xmlMapEntry
+		err := d.Decode(&e)
+		if err == io.EOF {
+			break
+		} else if err != nil {
+			return err
+		}
+		(m)[e.XMLName.Local] = []string{e.Value}
+	}
+	return nil
+}
+
+func (v XMLMap) Get(key string) string {
+	if v == nil {
+		return ""
+	}
+	vs := v[key]
+	if len(vs) == 0 {
+		return ""
+	}
+	return vs[0]
+}
+
+func (v XMLMap) Set(key, value string) {
+	v[key] = []string{value}
+}
+
+func (v XMLMap) Add(key, value string) {
+	v[key] = append(v[key], value)
+}
+
+func (v XMLMap) Del(key string) {
+	delete(v, key)
+}
+
+func VerifyResponseData(data []byte, key string) (ok bool, err error) {
+	var param = make(XMLMap)
+	err = xml.Unmarshal(data, &param)
+	if err != nil {
+		return false, err
+	}
+
+	return VerifyResponseValues(url.Values(param), key)
+}
+
+func VerifyResponseValues(param url.Values, key string) (bool, error) {
+	// 验证签名
+	var sign = param.Get("sign")
+	delete(param, "sign")
+	if sign == "" {
+		return false, errors.New("签名验证失败")
+	}
+
+	var sign2 = SignMD5(param, key)
+	if sign == sign2 {
+		return true, nil
+	}
+	return false, errors.New("签名验证失败")
+}
+
+func SignMD5(param url.Values, key string) (sign string) {
+	var pList = make([]string, 0, 0)
+	for key := range param {
+		var value = param.Get(key)
+		if len(value) > 0 {
+			pList = append(pList, key+"="+value)
+		}
+	}
+	sort.Strings(pList)
+	if key != "" {
+		pList = append(pList, "key="+key)
+	}
+
+	var src = strings.Join(pList, "&")
+	md5Ctx := md5.New()
+	md5Ctx.Write([]byte(src))
+	cipherStr := md5Ctx.Sum(nil)
+
+	sign = strings.ToUpper(hex.EncodeToString(cipherStr))
+	return sign
+}
+

+ 11 - 0
third/wx/wx.go

@@ -10,6 +10,7 @@ import (
 	"github.com/silenceper/wechat/oauth"
 	"github.com/silenceper/wechat/pay"
 	"github.com/silenceper/wechat/util"
+	"io/ioutil"
 	"net/url"
 	"strconv"
 	"strings"
@@ -33,6 +34,16 @@ func CallWxPayCallbackHandler(c *entitys.CtrlContext)models.SysReturn{
 		return models.SysReturn{500, err.Error(), nil}
 	}
 	if notifyRet.ResultCode == "SUCCESS" && notifyRet.ReturnCode == "SUCCESS"{
+		var data, _ = ioutil.ReadAll(c.Ctx.Request.Body)
+		ok, err := VerifyResponseData(data, wxConfig.PayKey)
+		if err != nil{
+			fmt.Println("*****************---->微信支付回调验证错误")
+			return models.SysReturn{500, err.Error(), nil}
+		}
+		if !ok{
+			fmt.Println("*****************---->微信支付回调验证错误, ok is false")
+			return models.SysReturn{500, "", nil}
+		}
 		return wxPayCallbackHandler(&notifyRet)
 	}else{
 		fmt.Println("------------------>微信支付失败", notifyRet)