Bläddra i källkod

修复统一下单接口签名问题:如果参数值为空值,则不参与签名;

song kang 7 år sedan
förälder
incheckning
d5302dbfdc
1 ändrade filer med 77 tillägg och 3 borttagningar
  1. 77 3
      pay/pay.go

+ 77 - 3
pay/pay.go

@@ -1,9 +1,11 @@
 package pay
 
 import (
+	"bytes"
 	"encoding/xml"
 	"errors"
-	"fmt"
+	"sort"
+	"strconv"
 
 	"github.com/silenceper/wechat/context"
 	"github.com/silenceper/wechat/util"
@@ -87,8 +89,20 @@ func NewPay(ctx *context.Context) *Pay {
 // PrePayOrder return data for invoke wechat payment
 func (pcf *Pay) PrePayOrder(p *Params) (payOrder PreOrder, err error) {
 	nonceStr := util.RandomStr(32)
-	template := "appid=%s&body=%s&mch_id=%s&nonce_str=%s&notify_url=%s&openid=%s&out_trade_no=%s&spbill_create_ip=%s&total_fee=%s&trade_type=%s&key=%s"
-	str := fmt.Sprintf(template, pcf.AppID, p.Body, pcf.PayMchID, nonceStr, pcf.PayNotifyURL, p.OpenID, p.OutTradeNo, p.CreateIP, p.TotalFee, p.TradeType, pcf.PayKey)
+	param := make(map[string]interface{})
+	param["appid"] = pcf.AppID
+	param["body"] = p.Body
+	param["mch_id"] = pcf.PayMchID
+	param["nonce_str"] =nonceStr
+	param["notify_url"] =pcf.PayNotifyURL
+	param["out_trade_no"] =p.OutTradeNo
+	param["spbill_create_ip"] =p.CreateIP
+	param["total_fee"] =p.TotalFee
+	param["trade_type"] =p.TradeType
+	param["openid"] = p.OpenID
+
+	bizKey := "&key="+pcf.PayKey
+	str := orderParam(param,bizKey)
 	sign := util.MD5Sum(str)
 	request := payRequest{
 		AppID:          pcf.AppID,
@@ -136,3 +150,63 @@ func (pcf *Pay) PrePayID(p *Params) (prePayID string, err error) {
 	prePayID = order.PrePayID
 	return
 }
+
+// order params
+func orderParam(source interface{}, bizKey string) (returnStr string) {
+	switch v := source.(type) {
+	case map[string]string:
+		keys := make([]string, 0, len(v))
+		for k := range v {
+			if k == "sign" {
+				continue
+			}
+			keys = append(keys, k)
+		}
+		sort.Strings(keys)
+		var buf bytes.Buffer
+		for _, k := range keys {
+			if v[k] == "" {
+				continue
+			}
+			if buf.Len() > 0 {
+				buf.WriteByte('&')
+			}
+			buf.WriteString(k)
+			buf.WriteByte('=')
+			buf.WriteString(v[k])
+		}
+		buf.WriteString(bizKey)
+		returnStr = buf.String()
+	case map[string]interface{}:
+		keys := make([]string, 0, len(v))
+		for k := range v {
+			if k == "sign" {
+				continue
+			}
+			keys = append(keys, k)
+		}
+		sort.Strings(keys)
+		var buf bytes.Buffer
+		for _, k := range keys {
+			if v[k] == "" {
+				continue
+			}
+			if buf.Len() > 0 {
+				buf.WriteByte('&')
+			}
+			buf.WriteString(k)
+			buf.WriteByte('=')
+			switch vv := v[k].(type) {
+			case string:
+				buf.WriteString(vv)
+			case int:
+				buf.WriteString(strconv.FormatInt(int64(vv), 10))
+			default:
+				panic("params type not supported")
+			}
+		}
+		buf.WriteString(bizKey)
+		returnStr = buf.String()
+	}
+	return
+}