微信公眾平台開發概述


本文大概介紹了使用asp.net mvc+entity framework 開發微信平台公眾號(訂閱號、服務號)的大概流程。

目錄:

  1. 微信公眾平台基本知識介紹
  2. 開發步驟
  3. Senparc.Weixin SDK 介紹
  4. 微信菜單介紹
  5. 微信JS SDK介紹
  6. 微信支付介紹
  7. Code First設計微信公眾平台后台實體
  8. BootStrap設計響應式布局介紹

一、微信公眾平台基本知識介紹

1.1請求流程

微信公眾平台是基於HTTP請求和響應

  

1.2 通訊格式

1.2.1消息 XML

< 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 >
 

1.2.2其他接口 JSON

{ "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 }

1.3 可能會踩到的一些坑

  1. 每條XML信息都有大小限制,如文本信息,建議Content內容不要超過600字。
  2. 上圖中,步驟2開始之后,微信服務器有一個等待時間:5秒,如果在這個時間內沒有進行到步驟4,那么這個請求將會被關閉(包括數據傳輸的時間)。也就是說如果超過時間,即使網站服務器返回了數據,客戶端也無法收到回復。
  3. 在文本消息中,是允許添加<a>標簽來放置連接的,但是有許多朋友測試之后發現iOS沒問題,Android上鏈接無法點擊,其實原因是(至少目前為止):Android的微信客戶端對<a>標簽格式的判定比較嚴格,請嚴格按照這個格式書寫:<a href="http://xxxx">內容</a>,href后不要使用單引號,也不要添加其他屬性。
  4. 上面XML節點中的FromUserName即微信用戶的OpenId,對於同一個公眾賬號,這個OpenId的前6位是一致的,並且在整個公眾平台的記錄中也是唯一的。也就是說同一個用戶關注了兩個不同的公眾賬號,他會有兩個不同的OpenId。
  5. CreateTime使用的是Unix時間,因此如果使用C#的話,需要做一個轉換。
  6. 盡量保持官方API中XML節點的順序,以前微信服務器是使用節點位置的方式讀取信息的(node[0]),而非節點名稱,現在這個問題似乎有好轉,不過還是要小心(¥…………&%&……)。
  7. 由於這種特殊的通訊方式,(至少目前為止)所有請求必須從客戶端先發起,不要指望光使用API或SDK可以實現由網站服務器主動推送消息到客戶端(當然其他辦法還是有的,比如模擬登陸)。
  8. 微信的網頁中的Cookie是比較特殊的,僅會短暫的存在,貌似是不能設置它在很長的時間內不過期的,所以,慎用!

1.4 微信公眾平台分類

1.4.1 服務號

  • 一個月可以推送4條消息
  • 擁有一些高級接口(Oauth、微信支付等)
  • 推送的消息如好友消息一樣單獨展示

1.4.2 訂閱號

  • 每天可以推送1條消息
  • 只擁有一些基本的權限
  • 推送的消息在訂閱號“文件夾”中展示

1.4.3 企業號

  沒有研究過

1.4.4 開發者測試號

幾乎擁有所有權限,無支付權限,不能推送消息

1.5微信開發概況

目前市場上常見的對微信所做的開發主要分為兩部分:

1.5.1微網站

  • 其實就是一個手機網站,只是很多時候需要調用微信的Oauth授權接口替代傳統的用戶登錄和注冊
  • 可以調用微信JS SDK的相關功能
  • 可以嵌入微信支付功能

1.5.2自動回復消息

  • 用戶主動向微信公眾平台發送內容時,平台自動響應
  • 獲取用戶的地理位置信息,做一些響應
  • 用戶點擊菜單時的響應
  • 多客服系統

開發步驟

•定義好處理微信請求的URL
•微信后台啟用開發者模式,填寫相關URL
•查看微信相關文檔,進行開發
•開發完成,部署到外網服務器中測試

三、Senparc.Weixin.MP SDK

3.1簡介

XX公司把微信官方提供的所有API都進行了封裝並開源,使開發人員可以面向對象進行微信開發,避免了請求和調試微信的接口,從而節約大量時間

官網地址:http://weixin.senparc.com/

Nuget地址:https://www.nuget.org/packages/Senparc.Weixin.MP

溫馨提醒:雖然SDK封裝好了很多的東西,但微信開發最終還是以微信的官方文檔為准,在需要時多看看微信文檔

3.2 使用SDK

  • 新建ASP.NET MVC 解決方案
  • 引用SDK(Nuget/項目/dll方式均可)
  • 新建一個WeixinController來接收來自微信服務器的請求,新建Index Action,提供GET/POST兩種請求方式,以GET方式請求時,調用SDK的CheckSignature.Check方法,返回隨機字符串(合法性驗證),在后台配置URL時,會需要這個GET,以POST方式請求時,先調用CheckSignature.Check方法,然后定義一個MessageHandler對接收到的消息使用處理,最后返回一個MessageHandler。
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(""); 
            }
        }
    }

3.3 處理用戶發來的消息

•基本思路

重寫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
            }
        }
    }

3.4 SDK提供的常用消息事件列表

 

OnTextRequest

文字消息

OnLocationRequest

位置消息

OnVoiceRequest

語音消息

OnVideoRequest

視頻消息

OnImageRequest

圖片消息

OnEvent_ClickRequest

點擊菜單

OnEvent_SubscribeRequest

用戶關注

OnEvent_UnsubscribeRequest

取消關注

OnEvent_ScanRequest

掃描二維碼

四、微信菜單介紹

4.1 基本介紹

  • 自定義菜單分為一級菜單和二級菜單
  • 一級菜單數量為1-3個,即打開公眾賬號直接可以看到排列在最下方的最多3個按鈕。一級菜單的文字最多不能超過16字節(相當於8個漢字)
  • 二級菜單從屬於一級菜單,數量為1-5個。二級菜單的文字不最多不能超過40字節(相當於20個漢字)
  • 當一個一級菜單下有二級菜單存在的時候,這個一級菜單按鈕被點擊不會有任何事件發生
  • 可以根據后台設置的用戶分組不同,定制不同的菜單(new)

4.2菜單類型

  • click:點擊推事件
  • view:跳轉URL
  • scancode_push:掃碼推事
  • scancode_waitmsg:掃碼推事件且彈出“消息接收中”提示框
  • pic_sysphoto:彈出系統拍照發圖、pic_photo_or_album:彈出拍照或者相冊發圖
  • location_select:彈出地理位置選擇器
  • media_id:下發消息(除文本消息)
  • view_limited:跳轉圖文消息URL

五、微信JS SDK

地址:

JS地址:http://res.wx.qq.com/open/js/jweixin-1.0.0.js

文檔地址:http://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html

常用功能:

  • 分享接口監聽
  • 圖片接口(上傳、預覽、拍照等)
  • 判斷網絡狀態
  • 操作右上角菜單
  • 微信支付 V2

使用步驟:

  • 綁定域名
     先登錄微信公眾平台進入“公眾號設置”的“功能設置”里填寫“JS接口安全域名”。
  • 引入JS文件

        在需要調用JS接口的頁面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js

  • 調用接口

         引用后,調用相應接口就ok了。

六、微信支付介紹

6.1 簡介

微信支付分為V2 和V3 版本,V2版本嵌入在其JSSDK中,V3版本直接嵌入在微信中,無需引用任何文件。

支付方式分為JS支付和掃碼支付,我只嘗試過JS支付,並沒有嘗試掃碼支付,所以下面所說的都是JS支付(V3),掃碼支付據說是還簡單一些。JS支付最終效果跟你用微信沖話費的流程是一樣的,你可以腦海中YY一下。

測試號沒有微信支付接口,這是非常惡心的地方,你想玩玩支付?那你去注冊個公司吧~然后交點錢,注冊個服務號,再核對公司公帳,然后!@#¥#¥%此處省略一萬步~

特別需要注意的是,在開發過程中,微信的文檔是僅供參考的,他們目前對文檔管理的非常混亂,你根本不知道哪個文檔是給哪里用的,我也沒有太好的辦法,只能是多折騰吧~

6.2 准備工作

前提假設我們已經弄到了一個有支付功能的賬號,下面的

6.2.1 配置JS接口安全域名

登陸微信公眾平台后台,進入公眾號設置頁面,找到功能設置,下面有個JS接口安全域名(貌似一定要是備案過的域名才可以)

6.2.2 配置微信支付配置項

進入左側微信支付,找到開發配置,配置測試授權目錄,並把自己的微信賬號添加到測試白名單

MVC,如果支付頁面的Action是Index的話,測試授權目錄配置要配置到上一級,親測的結果是,我的支付目錄是:http://xxx.com/payment/(payment是Controller,Action是index,但是url中沒有體現)所以配置的時候,只需要配置到域名就可以了,但是要加上/,我這個最終配置的測試授權目錄是:http://xxx.com/

6.2.3 Codding

代碼要處理的流程有:

  • 生成支付商品頁面
  • 生成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>
  • 接受支付成功后微信發回的確認信息,同時修改訂單狀態

這個過程細說有點復雜,下面是微信團隊提供的支付流程圖:

chapter7_4_1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM