微信公衆號,帶參二維碼/推廣二維碼的使用

最近做微信PC端網頁微信相關功能的開發,從一個新手的角度來說,微信公衆號的文檔還是不好理解的,網上找的帖子大都也都基本上是複製微信公衆平臺上給的文檔,開發微信帶參數二維碼過程中還是遇到不少坑的,在此把我的開發過程比較詳細的記錄下,希望對大家有所幫助。

  我本次開發使用的是認證服務號。

1 接入

  首先進入微信公衆號 -> 基本配置 

  下面是基本配置的頁面,在URL中填寫服務器地址,這個地址就是接受微信推送事件的一個接口,我是使用thinkPHP框架開發的程序,在其中一個Module(Decoration)的Action目錄下新建一個類,比如叫:  WechatAction.class.php  ,在該Action中新建一個public方法,比如叫:  URLRedirect()  ,那麼在這個URL中填寫的就是  http://[IP]:[port]/index.php/Decoration/Wechat/UrlRedirect  ,然後填寫Token,Token隨意填,EncodingAESKey要不要都行,然後點擊確認,微信會往這個URL上發送一個get請求,裏面包含很多參數,其中大部分都是讓我們自己覈對這次訪問是不是微信服務器請求的,我自己沒有驗證,他的要求是如果我們覈對成功,即原樣返回get請求中的一個參數echostr,這裏的返回不是return,也不是ajaxReturn,而使用echo,如果用thinkPHP開發的話,直接使用  echo I('echostr');  即可。然後接口即驗證成功了。

 

2 帶參數二維碼的作用

  微信的帶參數二維碼有兩種,一種是臨時二維碼,一種是永久二維碼,但是永久二維碼的生成是有個數限制的,我這次要實現的功能是用戶未登錄的情況下在網站上使用產品,比如獲得某商品的詳細報價,但是又不想註冊,然而又想保存這個報價單,這個時候網頁可以生成一張二維碼,用戶只要用微信掃一掃這個二維碼,官方公衆號就會給這個用戶發送一天圖文消息,圖文消息點開後就是用戶剛剛獲得的報價單,而且可以隨時點擊查看並且分享給朋友進行比價。所以臨時二維碼即可正常使用。

  上面是我是怎麼使用的,下面介紹一下整個交互的流程:

  當用戶掃描這個二維碼,如果用戶關注了公衆號,用戶會直接進入與公衆號的會話頁面,微信服務器會給我們在上一步設置的服務器URL中推送一條消息,其中可以攜帶一個我們自定義的參數。如果用戶未關注公衆號,則用戶首先會跳轉到公衆號關注頁面,用戶點擊關注後,會直接進入公衆號的會話頁面,微信服務器這時也會給我們設置的URL推送一個事件消息,攜帶我們自定義參數,我們可以根據這個參數和事件類型做控制下一步動作。

 

3 具體開發過程

3.1 獲取access_token

  這個access_token是我們程序調用微信接口的憑證,目前的有效期是7200秒,所以我們需要定時更新access_token。

  獲得方法:

方法 : GET
url :https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

其中的參數APPID和APPSECRET是我們公衆號的APPID和APPSECRET,在微信公衆號 -> 基本配置中可以查到,調用成功會返回如下JSON數據:

{"access_token":"ACCESS_TOKEN","expires_in":7200}

其中access_token就是調用接口憑證,expire_in是token有效時間。

  我本人是把access_token存在數據庫中,同時保存過期時間,然後封裝公用函數  getWechatAccessToken()  ,每次先檢查access_token是否過期,如果過期則重新獲取,否則直接使用數據庫保存的access_token即可,我忘了在哪兒看加過,這個access_token每天的獲取次數應該是有限制的。下面是  getWechatAccessToken()   的具體實現:

//獲取access_token
function getWechatAccessToken(){
    $wechatInfo = M('wechat_info')->select();
    $wechatInfo = array_reduce($wechatInfo, create_function('$result, $v', '$result[$v["conf_name"]] = $v;return $result;'));
    $expireTime = $wechatInfo['PUBLIC_WECHAT_ACCESSTOKEN_EXPIRES']['conf_value'];                             //前面不用管,是我數據庫相應設置

    if (time() < $expireTime){              //access_token未過期
        return $wechatInfo['PUBLIC_WECHAT_ACCESSTOKEN']['conf_value'];
    }else{                                  //access_token過期,重新獲取
        $baseUrl = C('WECHAT_PUBLIC_GET_ACCESS_TOKEN');
        $url = str_replace("##APPSECRET##", $wechatInfo['PUBLIC_WECHAT_APPSECRET']['conf_value'], str_replace("##APPID##", $wechatInfo['PUBLIC_WECHAT_APPID']['conf_value'], $baseUrl));
        $result = file_get_contents($url);
        $result = json_decode($result, true);

        if (array_key_exists('errorcode', $result)){        //失敗重試一次
            return false;
        }else{
            M('wechat_info')->where(array('conf_name' => 'PUBLIC_WECHAT_ACCESSTOKEN'))->save(array('conf_value' => $result['access_token']));
            M('wechat_info')->where(array('conf_name' => 'PUBLIC_WECHAT_ACCESSTOKEN_EXPIRES'))->save(array('conf_value' => time()+$result['expires_in']-200));
            return $result['access_token'];
        }
    }
}
C('WECHAT_PUBLIC_GET_ACCESS_TOKEN') = https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

封裝好這個之後,我們每次就可以安心的使用了。

3.2 創建臨時二維碼

3.2.1 獲取ticket

請求方式: POST
       接口:https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
        POST數據: {"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}

接口URL中的TOKEN即我們在3.1中獲取的access_token,post數據中expire_seconds是二維碼的有效時間,最多爲30天,action_name臨時二維碼的話固定就是QR_SCENE,scene_id即我們自定義參數,是個32位非0整數,我在應用中把它設爲訂單的ID,微信服務器推送事件的時候會把這個值返回給我們設置的接口中,然後我會根據這個值去拿相應的訂單數據展示在網頁上,這是後話。

  下面是封裝的生成臨時二維碼的方法:

//創建臨時二維碼
function getTemporaryQrcode($orderId){
    $accessToken = getWechatAccessToken();
    $url = str_replace("##TOKEN##", $accessToken, C('WECHAT_PUBLIC_GET_TEMPORARY_TICKET'));
    $qrcode = '{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": '.$orderId.'}}}';
    $result = api_notice_increment($url, $qrcode);
    $result = json_decode($result, true);
    return urldecode($result['url']);
}

其中的方法  api_notice_increment()  是我封裝的一個POST方法函數,我試過很多POST的方法,可能由於微信接口對POST方法和參數的限制比較嚴格,這個浪費了好久時間,最後在網上找到了一個可以使用的封裝好的POST方法,建議大家先自己試試,如果微信返回錯誤嗎,就用這個吧,起碼我測試微信這個接口的時候用postman測試返回的都是錯誤,而且一定要用JSON字符串,一定要是非常嚴格的JSON字符串。下面是這個方法:

其中ticket是讓我們用來進行下一步調用的憑證,expire_seconds是二維碼的有效期,url是我們生成的二維碼掃描後打開的鏈接。所以如果我們自己實現了生成二維碼的方法,就不用再進行下一步調用,我本人即在這一步就停止了,直接返回url的值,然後利用這個url的值生成二維碼存在本地即可。PHP生成二維碼可以使用phpqrcode,挺好用的。下一步也大致提一下:

3.2.2 獲取二維碼地址

請求方式: GET
   接口:https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET

這個接口的返回值是一張圖片,可以直接展示或者下載,我們有具體使用過,所以也不知道應該怎麼展示。

 

3.3 用戶掃描二維碼之後發生的事情

3.3.1 掃描後發生了什麼

  上面提到了,用戶掃描我們生成的臨時二維碼,如果用戶未關注公衆號,則首先會跳轉到公衆號的關注頁面,點擊關注後,會進入公衆號的會話頁面,同時會給我們設置的接口推送一個事件。如果用戶已經關注了,用戶微信會直接跳轉到公衆號會話頁面,然後微信服務器會給我們設置的接口推送一個事件。

  用戶關注與否微信服務器給我們推送的事件是差不多的,只是新關注用戶推送的事件中scene_id前面會加一個前綴。下面是微信公衆平臺文檔的說明:

 用戶未關注時,進行關注後的事件推送
<xml><ToUserName><![CDATA[toUser]]></ToUserName>        //開發者微信號
<FromUserName><![CDATA[FromUser]]></FromUserName>       //發送者賬號(openid)
<CreateTime>123456789</CreateTime>                //消息創建時間(整型)
<MsgType><![CDATA[event]]></MsgType>              //消息類型 event
<Event><![CDATA[subscribe]]></Event>              //事件類型(subscribe)
<EventKey><![CDATA[qrscene_123123]]></EventKey>        //事件KEY值,qrscene_爲前綴,後面爲二維碼參數值
<Ticket><![CDATA[TICKET]]></Ticket>               //二維碼ticke值,可以用來換取二維碼圖片
</xml>

用戶已關注時的事件推送

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>        //開發者微信號
<FromUserName><![CDATA[FromUser]]></FromUserName>     //發送者賬號(openid)
<CreateTime>123456789</CreateTime>             //消息創建時間
<MsgType><![CDATA[event]]></MsgType>                    //消息類型event
<Event><![CDATA[SCAN]]></Event>               //事件類型 event
<EventKey><![CDATA[SCENE_VALUE]]></EventKey>            //事件key值,是一個32位無符號整數,即創建二維碼時的二維碼scene_id
<Ticket><![CDATA[TICKET]]></Ticket>                     //二維碼的ticke,可以用來換取二維碼圖片
</xml>

完!!!

文章轉自:https://www.cnblogs.com/xiaocainiao2hao/p/5731800.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章