微信公衆平臺是基於HTTP請求和響應javascript
<
xml
>
<
ToUserName
><![CDATA[gh_a96a4a619366]]></
ToUserName
>
<
FromUserName
><![CDATA[olPjZjsXuQPJoV0HlruZkNzKc91E]]></
FromUserName
>
<
CreateTime
>1357986928</
CreateTime
>
<
MsgType
><![CDATA[text]]></
MsgType
>
<
Content
><![CDATA[TNT2]]></
Content
>
<
MsgId
>5832509444155992350</
MsgId
>
</
xml
>
|
{ "subscribe": 1, "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", "nickname": "Band", "sex": 1, "language": "zh_CN", "city": "廣州", "province": "廣東", "country": "中國", "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", "subscribe_time": 1382694957 }
幾乎擁有全部權限,無支付權限,不能推送消息
目前市場上常見的對微信所作的開發主要分爲兩部分:html
XX公司把微信官方提供的全部API都進行了封裝並開源,使開發人員能夠面向對象進行微信開發,避免了請求和調試微信的接口,從而節約大量時間java
官網地址:http://weixin.senparc.com/node
Nuget地址:https://www.nuget.org/packages/Senparc.Weixin.MP算法
舒適提醒:雖然SDK封裝好了不少的東西,但微信開發最終仍是以微信的官方文檔爲準,在須要時多看看微信文檔瀏覽器
public class WeiXinController : Controller { public static readonly string Token = WeixinInfo.Token;//與微信公衆帳號後臺的Token設置保持一致,區分大小寫。 /// <summary> /// 微信後臺驗證地址(使用Get),微信後臺的「接口配置信息」的Url填寫如:http://weixin.senparc.com/weixin /// </summary> [HttpGet] [ActionName("Index")] public ActionResult Get(string signature, string timestamp, string nonce, string echostr) { if (CheckSignature.Check(signature, timestamp, nonce, Token)) { return Content(echostr); //返回隨機字符串則表示驗證經過 } else { return Content("failed:" + signature + "," + Senparc.Weixin.MP.CheckSignature.GetSignature(timestamp, nonce, Token) + "。" + "若是你在瀏覽器中看到這句話,說明此地址能夠被做爲微信公衆帳號後臺的Url,請注意保持Token一致。"); } } /// <summary> /// 用戶發送消息後,微信平臺自動Post一個請求到這裏,並等待響應XML。 /// PS:此方法爲簡化方法,效果與OldPost一致。 /// v0.8以後的版本能夠結合Senparc.Weixin.MP.MvcExtension擴展包,使用WeixinResult,見MiniPost方法。 /// </summary> [HttpPost] [ActionName("Index")] public ActionResult Post(PostModel postModel) { if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token)) { return Content("參數錯誤!"); } postModel.Token = Token; postModel.EncodingAESKey = WeixinInfo.EncodingAESKey;//根據本身後臺的設置保持一致 postModel.AppId = WeixinInfo.AppId;//根據本身後臺的設置保持一致 //v4.2.2以後的版本,能夠設置每一個人上下文消息儲存的最大數量,防止內存佔用過多,若是該參數小於等於0,則不限制 var maxRecordCount = 10; //自定義MessageHandler,對微信請求的詳細判斷操做都在這裏面。 var messageHandler = new CustomMessageHandler(Request.InputStream, postModel, maxRecordCount); var logger = EngineContext.Current.Resolve<DefaultLogger>(); try { /* 若是須要添加消息去重功能,只需打開OmitRepeatedMessage功能,SDK會自動處理。 * 收到重複消息一般是由於微信服務器沒有及時收到響應,會持續發送2-5條不等的相同內容的RequestMessage*/ messageHandler.OmitRepeatedMessage = false; //執行微信處理過程 messageHandler.Execute(); return new WeixinResult(messageHandler);//v0.8+ } catch (Exception ex) { logger.Error("微信請求錯誤:" + DateTime.Now.Ticks, ex); return Content(""); } } }
重寫MessageHandler中的相應方法安全
public partial class CustomMessageHandler : MessageHandler<CustomMessageContext> { //some Code }
因爲是微信服務器直接發送請求到開發者服務器,故Session、Cookie均沒法在微信公衆平臺開發中正常使用,SDK提供了WeixinContext用來處理上下文,能夠在MessageHandle中使用。服務器
public class CustomMessageContext : MessageContext<IRequestMessageBase, IResponseMessageBase> { public CustomMessageContext() { base.MessageContextRemoved += CustomMessageContext_MessageContextRemoved; } /// <summary> /// 當上下文過時,被移除時觸發的時間 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void CustomMessageContext_MessageContextRemoved(object sender, Senparc.Weixin.Context.WeixinContextRemovedEventArgs<IRequestMessageBase, IResponseMessageBase> e) { /* 注意,這個事件不是實時觸發的(固然你也能夠專門寫一個線程監控) * 爲了提升效率,根據WeixinContext中的算法,這裏的過時消息會在過時後下一條請求執行以前被清除 */ var messageContext = e.MessageContext as CustomMessageContext; if (messageContext == null) { return;//若是是正常的調用,messageContext不會爲null } } }
OnTextRequest微信 |
文字消息網絡 |
OnLocationRequest |
位置消息 |
OnVoiceRequest |
語音消息 |
OnVideoRequest |
視頻消息 |
OnImageRequest |
圖片消息 |
OnEvent_ClickRequest |
點擊菜單 |
OnEvent_SubscribeRequest |
用戶關注 |
OnEvent_UnsubscribeRequest |
取消關注 |
OnEvent_ScanRequest |
掃描二維碼 |
JS地址:http://res.wx.qq.com/open/js/jweixin-1.0.0.js
文檔地址:http://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html
在須要調用JS接口的頁面引入以下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
引用後,調用相應接口就ok了。
微信支付分爲V2 和V3 版本,V2版本嵌入在其JSSDK中,V3版本直接嵌入在微信中,無需引用任何文件。
支付方式分爲JS支付和掃碼支付,我只嘗試過JS支付,並無嘗試掃碼支付,因此下面所說的都是JS支付(V3),掃碼支付聽說是還簡單一些。JS支付最終效果跟你用微信衝話費的流程是同樣的,你能夠腦海中YY一下。
測試號沒有微信支付接口,這是很是噁心的地方,你想玩玩支付?那你去註冊個公司吧~而後交點錢,註冊個服務號,再覈對公司公賬,而後!@#¥#¥%此處省略一萬步~
特別須要注意的是,在開發過程當中,微信的文檔是僅供參考的,他們目前對文檔管理的很是混亂,你根本不知道哪一個文檔是給哪裏用的,我也沒有太好的辦法,只能是多折騰吧~
前提假設咱們已經弄到了一個有支付功能的帳號,下面的
登錄微信公衆平臺後臺,進入公衆號設置頁面,找到功能設置,下面有個JS接口安全域名(貌似必定要是備案過的域名才能夠)
進入左側微信支付,找到開發配置,配置測試受權目錄,並把本身的微信帳號添加到測試白名單
MVC,若是支付頁面的Action是Index的話,測試受權目錄配置要配置到上一級,親測的結果是,個人支付目錄是:http://xxx.com/payment/(payment是Controller,Action是index,可是url中沒有體現)因此配置的時候,只須要配置到域名就能夠了,可是要加上/,我這個最終配置的測試受權目錄是:http://xxx.com/
代碼要處理的流程有:
- 生成支付商品頁面
- 生成appId、timeStamp、nonceStr、package、paySign等一系列的支付簽名須要的東西,並提供給支付頁面
- JS調用微信的接口(V3)
<script language="javascript" type="text/javascript"> // 當微信內置瀏覽器完成內部初始化後會觸發WeixinJSBridgeReady事件。 function jsApiCall() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId": "@ViewData["appId"]", //公衆號名稱,由商戶傳入 "timeStamp": "@ViewData["timeStamp"]", //時間戳 "nonceStr": "@ViewData["nonceStr"]", //隨機串 "package": "@Html.Raw(ViewData["package"])",//擴展包 "signType": "MD5", //微信簽名方式:MD5 "paySign": "@ViewData["paySign"]" //微信簽名 },//josn串 function (res) { if (res.err_msg === "get_brand_wcpay_request:ok") { window.location.href = '@Url.Action("PaySuccess", new { orderNumber = Model.OrderNum })'; } } ); } function callpay() { if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } } else { jsApiCall(); } } </script>
- 接受支付成功後微信發回的確認信息,同時修改訂單狀態
這個過程細說有點複雜,下面是微信團隊提供的支付流程圖: