微信消息處理

配置

首先登陸微信公衆平臺 https://mp.weixin.qq.com,在開發->基本配置中填寫服務器配置(接收處理微信消息的地址)
圖片描述
保存好你的配置,在加解密時須要使用。php

驗證

開發者提交信息後,微信服務器將發送GET請求到填寫的服務器地址URL上,GET請求攜帶參數以下表所示:服務器

參數 描述
signature 微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。
timestamp 時間戳
nonce 隨機數
echostr 隨機字符串

開發者經過檢驗 signature 對請求進行校驗(下面有校驗方式)。若確認這次GET請求來自微信服務器,請原樣返回 echostr 參數內容,則接入生效,成爲開發者成功,不然接入失敗。微信

加密/校驗流程以下:微信公衆平臺

  1. tokentimestampnonce 三個參數進行字典序排序
  2. 將三個參數字符串拼接成一個字符串進行 sha1 加密
  3. 開發者得到加密後的字符串可與 signature 對比,標識該請求來源於微信
public function validate() {
    $echoStr = Input::get('echostr');
    if (!empty($echoStr)) {
        $signature = Input::get('signature');
        $timestamp = Input::get('timestamp');
        $nonce = Input::get('nonce');
        $tmpArr = [
            '你配置的Token',
            $timestamp,
            $nonce
        ];
        sort($tmpArr);
        $tmpStr = implode('', $tmpArr);
        $tmpStr = sha1($tmpStr);
        if ($tmpStr == $signature) {
            echo $echoStr;
            exit;
        }
    }
}

PHP示例代碼下載:下載dom

消息加解密

微信官方文檔:加密解密技術方案異步

首先獲取微信發送的XML數據:加密

$xmlString = file_get_contents("php://input");

使用下載的示例代碼解密消息:spa

//提供提取消息格式中的密文 XmlParse類在xmlparse.php裏
$secretData = (new XmlParse())->extract($xmlString);
//對密文進行解密 Prpcrypt類在pkcs7Encoder.php裏
$result = (new PrpCrypt('你配置的EncodingAESKey'))->decrypt($secretData[1]);

以後就根據具體業務來實現了:code

$xmlFormatData = simplexml_load_string($result[1], 'SimpleXMLElement', LIBXML_NOCDATA);
$event = (string)$xmlFormatData->Event;
$eventKey = isset($xmlFormatData->EventKey) ? (string)$xmlFormatData->EventKey : '';
$openId = (string)$xmlFormatData->FromUserName;
$toUserName = (string)$xmlFormatData->ToUserName;

//事件處理
if ($event === 'VIEW' || $event == "CLICK") {
    //自定義菜單事件
}
if (!$eventKey && $event == "subscribe") {
    //掃描公衆號二維碼關注事件
}
if ($eventKey && $event == "subscribe") {
    //掃描二維碼關注事件
}
if ($eventKey && $event == "SCAN") {
    //掃描生成的二維碼
}
if ($event == "unsubscribe") {
    //取消關注事件
}
if ($event === 'card_pass_check' || $event === 'card_not_pass_check') {
    //卡券審覈經過或審覈未經過事件
}
if ($event === 'user_get_card') {
    //卡券領取事件
}
if ($event === 'user_consume_card') {
    //卡券覈銷事件
}

//其餘事件不處理
return false;

須要發送加密消息時:orm

$wxBizMsg = new WxBizMsgCrypt('你配置的Token', '你配置的EncodingAESKey', '你公衆號的APPID');
//加密後的消息,傳引用
$encryptMsg = '';
//未加密的消息爲XML格式的字符串
echo $wxBizMsg->encryptMsg('未加密的消息', time(), str_random(16), $encryptMsg);

假如服務器沒法保證在五秒內處理並回復,必須作出下述回覆,這樣微信服務器纔不會對此做任何處理,而且不會發起重試(這種狀況下,可使用客服消息接口進行異步回覆),不然,將出現嚴重的錯誤提示。
詳見下面說明:

  1. 直接回復success(推薦方式)
  2. 直接回復空串(指字節長度爲0的空字符串,而不是XML結構體中content字段的內容爲空)

一旦遇到如下狀況,微信都會在公衆號會話中,向用戶下發系統提示「該公衆號暫時沒法提供服務,請稍後再試」:

  1. 開發者在5秒內未回覆任何內容
  2. 開發者回覆了異常數據,好比JSON數據等

具體的各類XML格式見:被動回覆用戶消息

相關文章
相關標籤/搜索