分享
用Go开发WeChat接口的一个小坑
xcltapestry · · 6496 次点击 · · 开始浏览这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
年前公司接入了微信国际版的支付,当时WeChat Wallet本身的接口还没开发完(上几周WeChat Wallet
终于结束灰度全面开放了), 接入时踩了一大堆坑。 除了当时因为给的文档并不全或错误造成的一些困扰外,
另外有个接口问题折磨了好一阵。当时有这样一个问题,当支付完成时,需要去WeChat支付后台查看支付状态。
但我依文档的JSON格式,加密和序列化后,提交给WeChat查单接口,老提示签名不对。
查询的规则很简单,前面支付的规则也是类似写法也没问题,按理查询不应当出现这种问题的。
后来在前端经验丰富的同事和微信那边开发的支持下才查出,原来问题出在JSON序列化上.
Go语言序列化会自动对一些特殊字符会作编码处理,而WeChat后台查询那边接口不会识别,
但WeChat支付那边的接口却能识别(估计是两组不同人马写的接口....).
先看个例子:
package main
/*
Author:xcl
Date: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.go
Marshal: {"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
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信6496 次点击
上一篇:golang之web编程执行流程
下一篇:Go语言并发与并行学习笔记(一)
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
年前公司接入了微信国际版的支付,当时WeChat Wallet本身的接口还没开发完(上几周WeChat Wallet
终于结束灰度全面开放了), 接入时踩了一大堆坑。 除了当时因为给的文档并不全或错误造成的一些困扰外,
另外有个接口问题折磨了好一阵。当时有这样一个问题,当支付完成时,需要去WeChat支付后台查看支付状态。
但我依文档的JSON格式,加密和序列化后,提交给WeChat查单接口,老提示签名不对。
查询的规则很简单,前面支付的规则也是类似写法也没问题,按理查询不应当出现这种问题的。
后来在前端经验丰富的同事和微信那边开发的支持下才查出,原来问题出在JSON序列化上.
Go语言序列化会自动对一些特殊字符会作编码处理,而WeChat后台查询那边接口不会识别,
但WeChat支付那边的接口却能识别(估计是两组不同人马写的接口....).
先看个例子:
package main
/*
Author:xcl
Date: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.go
Marshal: {"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