這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
年前公司接入了國際版的支付,當時WeChat Wallet本身的介面還沒開發完(上幾周WeChat Wallet
終於結束灰階全面開放了), 接入時踩了一大堆坑。 除了當時因為給的文檔並不全或錯誤造成的一些困擾外,
另外有個介面問題折磨了好一陣。
當時有這樣一個問題,當支付完成時,需要去WeChat支付後台查看支付狀態。
但我依文檔的JSON格式,加密和序列化後,提交給WeChat查單介面,老提示簽名不對。
查詢的規則很簡單,前面支付的規則也是類似寫法也沒問題,按理查詢不應當出現這種問題的。
後來在前端經驗豐富的同事和那邊開發的支援下才查出,原來問題出在JSON序列化上.
Go語言序列化會自動對一些特殊字元會作編碼處理,而WeChat後台查詢那邊介面不會識別,
但WeChat支付那邊的介面卻能識別(估計是兩組不同人馬寫的介面....).
先看個例子:
package main/*Author:xclDate:2016-2-10*/import ("bytes""encoding/json""fmt""time")type Query struct {AppID string `json:"AppID"`Timestamp int64 `json:"Timestamp"`Package string `json:"Package"`}func main() {MarshalDemo()}func MarshalDemo() {v := &Query{}v.AppID = "testid"v.Timestamp = time.Now().Unix()v.Package = "xxcents=100&bank=666"data, _ := json.Marshal(v)fmt.Println("Marshal:", string(data))data = bytes.Replace(data, []byte("\\u0026"), []byte("&"), -1)data = bytes.Replace(data, []byte("\\u003c"), []byte("<"), -1)data = bytes.Replace(data, []byte("\\u003e"), []byte(">"), -1)data = bytes.Replace(data, []byte("\\u003d"), []byte("="), -1)fmt.Println("處理後:", string(data))}/*運行結果:➜ wxjson : go run wxjson.goMarshal: {"AppID":"testid","Timestamp":1455111299,"Package":"xxcents=100\u0026bank=666"}處理後: {"AppID":"testid","Timestamp":1455111299,"Package":"xxcents=100&bank=666"}*/
https://golang.org/pkg/encoding/json/
String values encode as JSON strings coerced to valid UTF-8, replacing invalid bytes with the Unicode replacement rune. The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" to keep some browsers from misinterpreting JSON output as HTML. Ampersand "&" is also escaped to "\u0026" for the same reason.
https://studygolang.com/static/pkgdoc/pkg/encoding_json.htm
字串編碼為json字串。角括弧"<"和">"會轉義為"\u003c"和"\u003e"以避免某些瀏覽器吧json輸出錯誤理解為HTML。基於同樣的原因,"&"轉義為"\u0026"。
這就是造成簽名錯誤的原因. 用Go開發這類介面時要注意這點.
BLOG:http://blog.csdn.net/xcl168