index.adoc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. = GoWechat使用文档
  2. :toc: left
  3. //:icons: font
  4. == 零、使用前阅读
  5. === 综述
  6. image::img/GoWechat_overview.png[]
  7. 项目目标:构建一套最简单易用的微信各大平台通用golang API
  8. 适用范围:可以与各种平台无缝整合,beego, gin, http (example目录提供完整的使用例子)
  9. 开源地址:[Github地址](https://github.com/yaotian/gowechat)
  10. GoDoc: [GoDoc地址](https://godoc.org/github.com/yaotian/gowechat)
  11. [[install,安装]]
  12. === 安装
  13. go get github.com/yaotian/gowechat
  14. [[use,使用]]
  15. === 配置
  16. ==== 参数
  17. ```go
  18. var config = wxcontext.Config{
  19. //微信公众平台,商户平台,需要填写的信息
  20. AppID: "your app id",
  21. AppSecret: "your app secret",
  22. Token: "your token",
  23. EncodingAESKey: "your encoding aes key",
  24. //以下是 mch商户平台需要的变量
  25. SslCertFilePath string //证书公钥文件的路径
  26. SslKeyFilePath string //证书私钥文件的路径
  27. SslCertContent string //公钥证书的内容
  28. SslKeyContent string //私钥证书的内容
  29. MchID string //商户ID
  30. MchAPIKey string //商户平台设置的api key
  31. }
  32. ```
  33. === 微信平台的操作接口
  34. ==== 微信公众平台
  35. ```go
  36. wc := gowechat.NewWechat(config)
  37. //微信公众平台
  38. mp, err := wc.MpMgr()
  39. if err != nil {
  40. return
  41. }
  42. ```
  43. ==== 微信商户平台
  44. ```go
  45. wc := gowechat.NewWechat(config)
  46. //微信商户平台
  47. mch , err := wc.MchMgr()
  48. if err != nil {
  49. return
  50. }
  51. ```
  52. === 在框架中使用
  53. ==== beego中使用的例子
  54. ./examples/beego
  55. ==== gin中使用的例子
  56. ./examples/gin
  57. ==== net/http中使用的例子
  58. ./examples/http
  59. [[mp,mp]]
  60. == 一、微信公众平台
  61. === 概述
  62. image::img/GoWechat_mp.png[]
  63. === 1.获取接口
  64. [source,go]
  65. ----
  66. var config = wxcontext.Config{
  67. //微信公众平台,商户平台,需要填写的信息
  68. AppID: "your app id",
  69. AppSecret: "your app secret",
  70. Token: "your token",
  71. EncodingAESKey: "your encoding aes key",
  72. }
  73. wc := gowechat.NewWechat(config)
  74. //微信公众平台
  75. mp, err := wc.MpMgr()
  76. if err != nil {
  77. return
  78. }
  79. ----
  80. === 2.开发消息服务器
  81. 将开发的消息服务器(http://your_domain/wx_server)接入到微信公众平台,有几个步骤
  82. 1. 接入你的消息服务器时,微信公众号后台,会发信息给你的服务器,来进行验证。所以你的服务器需要知道如何处理验证消息。
  83. 2. 微信公众平台与你的消息服务器之间通过消息通信来进行同步合作。所以你的消息服务器需要知道如何处理消息与如何发送消息。
  84. 本接口将复杂的过程(加密,打包,验证等等)封装了,让你只需要关心业务环节。
  85. 将以下的代码,加入到你的controller中,接口自动完成上面所说的两个功能,
  86. [IMPORTANT]
  87. 你的controller需要能接收GET与POST两种消息
  88. [source,go]
  89. ----
  90. wc := gowechat.NewWechat(config)
  91. //微信公众平台
  92. mp, err := wc.MpMgr()
  93. if err != nil {
  94. return
  95. }
  96. // 传入request和responseWriter
  97. msgHandler := mp.GetMsgHandler(c.Ctx.Request, c.Ctx.ResponseWriter)
  98. //设置接收消息的处理方法
  99. msgHandler.SetHandleMessageFunc(func(msg message.MixMessage) *message.Reply {
  100. switch msg.Event {
  101. case message.EventSubscribe:
  102. return c.handleSubscribe(&msg)
  103. case message.EventScan:
  104. return c.handleScan(&msg)
  105. case message.EventUnsubscribe:
  106. return c.handleUnsubscribe(&msg)
  107. case message.EventClick:
  108. return c.handleClick(&msg)
  109. case message.EventLocation:
  110. return c.handleLocation(&msg)
  111. }
  112. switch msg.MsgType {
  113. case message.MsgTypeText:
  114. //回复消息:演示回复用户发送的消息
  115. text := message.NewText(msg.Content)
  116. return &message.Reply{message.MsgTypeText, text}
  117. case message.MsgTypeImage:
  118. return c.handleImage(&msg)
  119. }
  120. //处理消息接收以及回复
  121. err = msgHandler.Handle()
  122. if err != nil {
  123. beego.Error(err)
  124. }
  125. })
  126. ----
  127. ==== 消息类型
  128. 消息分为以下几种:文本、图片、视频、声音、链接、坐标、图文、文章。
  129. ===== 文本消息
  130. [source,go]
  131. ----
  132. //回复消息:演示回复用户发送的消息
  133. text := message.NewText("your message want to be sent")
  134. return &message.Reply{message.MsgTypeText, text}
  135. ----
  136. ===== 图片消息
  137. [source,go]
  138. ----
  139. pic := message.NewImage("your_pic_mediaID")
  140. return &message.Reply{message.MsgTypeImage, pic}
  141. ----
  142. ===== 视频消息
  143. [source,go]
  144. ----
  145. video := message.NewVideo("your_mediaID", "your_title", "your_description")
  146. return &message.Reply{message.MsgTypeVideo, video}
  147. ----
  148. ===== 声音消息
  149. [source,go]
  150. ----
  151. voice := message.NewVoice("your_mediaID")
  152. return &message.Reply{message.MsgTypeVoice, voice}
  153. ----
  154. ===== 链接消息
  155. NOTE: 微信目前不支持回复链接消息
  156. ===== 坐标消息
  157. NOTE: 微信目前不支持坐标消息
  158. ===== 图文消息
  159. [source,go]
  160. ----
  161. news := message.NewNews([]*Article{message.NewArticle("your_title", "your_description", "your_picURL", "your_url")})
  162. return &message.Reply{message.MsgTypeNews, news}
  163. ----
  164. === 3.网页授权
  165. [source,go]
  166. ----
  167. wc := gowechat.NewWechat(config)
  168. //微信公众平台
  169. mp, err := wc.MpMgr()
  170. if err != nil {
  171. return
  172. }
  173. oauthHandler := mp.GetPageOAuthHandler(c.Ctx.Request, c.Ctx.ResponseWriter, "http://your_domain/wxoauth")
  174. oauthHandler.SetFuncCheckOpenIDExisting(func(openID string) (existing bool, stopNow bool) {
  175. //看自己的系统中是否已经存在此openID的用户
  176. //如果已经存在, 调用自己的Login 方法,设置cookie等,return true
  177. //如果还不存在,return false, handler会自动去取用户信息
  178. //your code
  179. return
  180. })
  181. oauthHandler.SetFuncAfterGetUserInfo(func(user user.Info) (stopNow bool) {
  182. //已获得用户信息,这里用信息做注册使用
  183. //调用自己的Login方法,设置cookie等
  184. //your code
  185. })
  186. oauthHandler.Handle()
  187. ----
  188. === 4.模板消息
  189. [source,go]
  190. ----
  191. wc := gowechat.NewWechat(config)
  192. //微信公众平台
  193. mp, err := wc.MpMgr()
  194. if err != nil {
  195. return
  196. }
  197. api := mp.GetTemplate()
  198. tmplMsg := new(template.Message)
  199. tmplMsg.URL = your_url
  200. tmplMsg.ToUser = your_to_user_openID
  201. tmplMsg.TemplateID = your_templateID
  202. tmplMsg.Data = makeMsgMessageData("your_first", "your_subject", "your_sender_name", "your_msg_content")
  203. _, err = api.Send(tmplMsg)
  204. func makeMsgMessageData(first, subject, sender, remark string) (data map[string]*template.DataItem) {
  205. data = make(map[string]*template.DataItem)
  206. data["first"] = &template.DataItem{Value: first, Color: "#173177"}
  207. data["keyword1"] = &template.DataItem{Value: sender, Color: "#173177"}
  208. data["keyword2"] = &template.DataItem{Value: subject, Color: "#173177"}
  209. remark = remark + "\n如果您不想收到此通知,请点击后->[消息]->右上角的设置按钮"
  210. data["remark"] = &template.DataItem{Value: remark, Color: "#2eb3ff"}
  211. return
  212. }
  213. ----
  214. === 5.二维码
  215. 支持
  216. * 临时二维码
  217. * 永久二维码
  218. 输入参数支持 string, int
  219. [source,go]
  220. ----
  221. wc := gowechat.NewWechat(config)
  222. //微信公众平台
  223. mp, err := wc.MpMgr()
  224. if err != nil {
  225. return
  226. }
  227. qrResult, err := mp.GetQrcode().CreateTemporaryQRCodeWithSceneString("your_scene_string", 60)
  228. if err != nil {
  229. return
  230. }
  231. qrImageURL := qrResult.ImageURL()
  232. ----
  233. === 6.用户
  234. [source,go]
  235. ----
  236. wc := gowechat.NewWechat(config)
  237. //微信公众平台
  238. mp, err := wc.MpMgr()
  239. if err != nil {
  240. return
  241. }
  242. var userInfo = new(user.Info)
  243. userInfo, err = mp.GetUser().GetUserInfo("your_openID")
  244. if err != nil {
  245. return
  246. }
  247. ----
  248. === 7.菜单
  249. [source,go]
  250. ----
  251. wc := gowechat.NewWechat(config)
  252. //微信公众平台
  253. mp, err := wc.MpMgr()
  254. if err != nil {
  255. return
  256. }
  257. var btnMenus []*menu.Button
  258. btn = new(menu.Button)
  259. btn.Name = m.Name
  260. btn.SetViewButton("your_name", "your_url") //url menu
  261. btnMenus = append(btnMenus,btn)
  262. mp.GetMenu().SetMenu(btnMenus)
  263. ----
  264. [[mch,mch]]
  265. == 二、商户平台(微信支付)
  266. === 概述
  267. image::img/GoWechat_mch.png[]
  268. === 1.获取接口
  269. [source,go]
  270. ----
  271. var config = wxcontext.Config{
  272. //微信公众平台,商户平台,需要填写的信息
  273. AppID: "your app id",
  274. AppSecret: "your app secret",
  275. Token: "your token",
  276. EncodingAESKey: "your encoding aes key",
  277. //------以下是 mch商户平台需要的变量
  278. //
  279. //证书公钥,路径,内容要保证只要有一项设置
  280. SslCertFilePath: "your cert file path" //证书公钥文件的路径
  281. SslCertContent: "your cert content" //公钥证书的内容
  282. //私钥,路径,内容要保证只要有一项设置
  283. SslKeyFilePath: "your key file path" //证书私钥文件的路径
  284. SslKeyContent: "your key content" //私钥证书的内容
  285. MchID: "your mch ID" //商户ID
  286. MchAPIKey: "your mch API Key" //商户平台设置的api key
  287. //------ End 商户平台设置
  288. }
  289. wc := gowechat.NewWechat(config)
  290. //微信商户平台
  291. mch , err := wc.MchMgr()
  292. if err != nil {
  293. return
  294. }
  295. ----
  296. === 2.支付订单
  297. [source,golang]
  298. ----
  299. var order = pay.OrderInput {
  300. OpenID: "your openID", //trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识
  301. Body: "购物支付", //String(128)
  302. OutTradeNum: "your trade num", //String(32) 20150806125346 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
  303. TotalFee: your_pay_number, //分为单位
  304. IP: "your_ip",
  305. NotifyURL: "your_notify_URL", //异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数
  306. ProductID:"" //trade_type=NATIVE时(即扫码支付),此参数必传
  307. tradeType: "JSAPI" //JSAPI,NATIVE,APP
  308. }
  309. ----
  310. 公众号支付 H5中调用jssdk支付:
  311. [source,go]
  312. ----
  313. //公众号支付(jssdk支付数据)
  314. cfg, err := mch.GetPay().GetJsAPIConfig(order)
  315. ----
  316. 扫码支付:
  317. [source,go]
  318. ----
  319. qrcodeImageURL, err := mch.GetPay().GetNativePayQrcodePicURL(order)
  320. ----
  321. === 3.为两种支付方式生成JS配置
  322. ==== a.WeixinJSBridge:
  323. 支付数据,json格式,这些数据可以传递到前端模板中使用
  324. [source,go]
  325. ----
  326. //公众号支付(jssdk支付数据)
  327. cfg, err := mch.GetPay().GetJsAPIConfig(order)
  328. json := cfg.ToJSON()
  329. ----
  330. 前端的JS代码例子
  331. [source,javascript]
  332. ----
  333. ...
  334. WeixinJSBridge.invoke(
  335. 'getBrandWCPayRequest', {{$json}},
  336. function(res){
  337. if(res.err_msg == "get_brand_wcpay_request:ok" ) {
  338. // 使用以上方式判断前端返回,微信团队郑重提示:
  339. // res.err_msg将在用户支付成功后返回
  340. // ok,但并不保证它绝对可靠。
  341. }
  342. }
  343. );
  344. ...
  345. ----
  346. ==== b.JSSDK:
  347. 支付数据,map格式,这些数据可以传递到前端模板中使用
  348. [source,go]
  349. ----
  350. //公众号支付(jssdk支付数据)
  351. cfg, err := mch.GetPay().GetJsAPIConfig(order)
  352. mapData := cfg.ToMap()
  353. ----
  354. 前端的JS代码例子
  355. [source,javascript]
  356. ----
  357. wx.chooseWXPay({
  358. timestamp: {{$timestamp}},
  359. nonceStr: {{$nonceStr}},
  360. package: {{$package}},
  361. signType: {{$signType}},
  362. paySign: {{$paySign}}, // 支付签名
  363. success: function (res) {
  364. // 支付成功后的回调函数
  365. }
  366. });
  367. ----
  368. === 4.支付通知
  369. 微信支付后,微信服务器会将支付结果回调到你的服务器,服务器地址是在订单参数中设置的NotifyURL,为了安全,过来的数据需要检验正确。
  370. [source,go]
  371. ----
  372. wc := gowechat.NewWechat(config)
  373. //微信商户平台
  374. mch , err := wc.MchMgr()
  375. if err != nil {
  376. return
  377. }
  378. //回调的数据检查,例子
  379. req := c.Ctx.Request
  380. data, err := ioutil.ReadAll(req.Body)
  381. if err != nil {
  382. return
  383. }
  384. isSuccess, err := mch.GetPay().CheckPayNotifyData(data)
  385. if err != nil {
  386. return
  387. }
  388. //成功后,你自己的处理
  389. ----
  390. === 5.查询订单
  391. 该接口提供所有微信支付订单的查询,商户可以通过该接口主动查询订单状态,完成下一步的业务逻辑。
  392. 需要调用查询接口的情况:
  393. * 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
  394. * 调用支付接口后,返回系统错误或未知交易状态情况;
  395. * 调用被扫支付API,返回USERPAYING的状态;
  396. * 调用关单或撤销接口API之前,需确认支付状态;
  397. === 6.关闭订单
  398. === 7.退款
  399. === 8.账单
  400. === 9.发红包
  401. 前提条件:发红包前,你必须在商户平台中充值
  402. [source,go]
  403. ----
  404. var input paytool.RedPackInput
  405. input.ToOpenID = "your openID"
  406. input.MoneyFen = int(your_money * 100)
  407. input.SendName = "your send Name"
  408. input.ActName = "佣金提现"
  409. input.Wishing = "您的分销佣金"
  410. input.Remark = fmt.Sprintf("佣金提现 User:%s Weixin:%s", "your nickname", "your openID")
  411. input.IP = "your IP"
  412. input.SceneID = paytool.SceneIDAgentBonous
  413. //商户平台接口
  414. mch , err := wc.MchMgr()
  415. if err != nil {
  416. return
  417. }
  418. _, err = mch.GetPayTool().SendRedPack(input)
  419. ----
  420. [[open,open]]
  421. == 三、开放平台
  422. [[corp,corp]]
  423. == 四、企业微信
  424. [[mini,mini]]
  425. == 五、小程序
  426. [[code,code]]
  427. == 六、谁正在使用
  428. [果真免费微社区及推广平台](http://84u6.com)
  429. [新课堂360教育云平台](http://xkt360.com)
  430. 如果您正在使用GoWechat,请在github内留言
  431. == 七、微信官方文档参考
  432. .Windtrainer workouts
  433. [width="100%",cols="1,^4,10",options="header"]
  434. |=========================================================
  435. |目录 | 对应 |官方文档
  436. |/mp | 微信公众平台(订阅号,服务号)| [文档](https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432)
  437. |/mch | 微信商家平台 | [文档](https://pay.weixin.qq.com/wiki/doc/api/index.html)
  438. |/open| 微信开放平台| [文档](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&lang=zh_CN)
  439. |/corp | 微信企业号 | [文档](http://qydev.weixin.qq.com/wiki/index.php?title=%E9%A6%96%E9%A1%B5)
  440. |=========================================================