第三方企業號對接工作


第三方企業號對接, 大概做了有一個月的時間, 過程還是非常艱辛的, 遇到了很多坑, 從不明所以, 到流程的理解的一個過程, 網上大多數的過程都很過程化, 把官方文檔一貼, 基本上作用不大, 有幾篇有幫助的, 但是忘記在哪里找到的了, 再者,

微信第三方文檔的掛臉型和跳躍性非常強, 要串起來自我感覺還是挺費勁的, 如此, 簡單的記錄一下整體的對接流程和一些概念性的東西

成為第三方服務商, 首先必須是一個實體主體, 截止到目前, 微信不允許個人開發者測試開發第三方資源, 本文會引用大量官方文檔原話, 就不做出特殊標記了, 

在這里, 第三方這個此非常容易造成混淆, 一下稱第三方服務商簡稱為服務商, 使用服務商提供服務的企業, 稱為普通企業

按照微信官方的流程

一, 首先應用提供商注冊應用

  針對第二點, 創建應用套件, (分兩類  通訊錄套件和普通應用套件)

  通訊錄套件: 用於第三方維護企業通訊錄的場景。此類套件對企業的通訊錄擁有根部門的修改權限,但無讀權限。為避免通訊錄被多方寫亂的問題,一家企業只能授權一個通訊錄套件。額外的,通訊錄套件可包括最多一個普通應用

  普通應用套件: 套件可包含最多10個應用,應用具有讀通訊錄、發消息等權限  , 

  這里需要注意的是, 通訊錄套件, 是套件對普通企業的通訊錄具有修改權限, 然后通訊錄套件下允許有一個應用, 這個應用其實和普通應用套件的應用是一樣的

  關於套件(以及套件下應用)的授權, 分兩種, 授權方式的作用在於區分應用套件是否可以直接從企業號第三方官網發起授權,線上自助注冊授權使用是指該應用套件可以直接從企業號第三方官網發起授權,而不跳轉服務商網站,該類型的應用套件還可以支持移動端發起應用套件授權;服務商輔助授權使用是指該應用套件必須跳轉服務商網站,從服務商網站發起應用套件的授權,該類型的應用套件不支持移動端發起應用套件授權

用我的話說就是一種必須要到服務商那邊才能發起授權, 另一種在微信企業號后台搜出來直接授權就可以了

套件開發信息, 直接貼官方的

 

開發信息:

 

套件參數內容 說明
發起授權域名 在該域名下發起的授權請求才可被通過,企業點擊授權鏈接時,企業號會檢查該域名是否已登記。
授權完成回調域名 在第三方應用授權流程中,授權成功后會302跳轉到該域名下的url,返回臨時code。你需用此code換取永久授權碼。請盡量將此域名與發起授權域名保持一致。
系統事件接收URL 系統將會把此套件的授權變更事件以及ticket參數推送給此URL,ticket說明詳見API接口說明。(填寫URL時需要正確響應微信驗證URL的請求,具體說明請閱讀“回調模式”)
Token 可任意填寫,用於生成簽名,校驗回調請求的合法性。后續所有托管的企業產生的回調消息都使用該值來計算簽名。
EncodingAESKey 回調消息加解密參數,是AES密鑰的Base64編碼,用於解密回調消息內容對應的密文。后續所有托管的企業產生的回調消息都使用該值來解密。
應用套件ID 應用套件的編號,相關的接口調用需要使用,由系統生成,不可更改。
應用套件secret 應用套件的密鑰,相關的接口調用需要使用。
白名單IP列表 應用套件調用企業號第三方應用API時的合法IP列表,只有白名單內的IP才能正常調用企業號API,后續IP若有修改,需要及時進行列表更新。

 

創建完成之后,系統會告知開發者該應用套件的Suiteid和Suitesecret。(詳見第三方應用接口說明)

發起授權域名,授權完成回調域名,保持一致就行了, 

系統時間接收URL這個非常重要比如  http://xxx.com/wx/api/index?corpid=$CORPID$  微信給服務商推送信息的時候, 會帶着服務商的corpid參數, 另, 這個url就相當於公眾號配置的服務器url

token, EncodingAESKey沒什么好說的, 隨機生成然后就別變了, 記錄下來就行了

應用套件ID和應用套件secret  套件新建成功后就由微信官方分配, 不可變更, 應用套件ID, 用到的地方非常多

第三點

套件添加應用

基本信息部分, 注意一下

通訊錄權限等級,(建議選擇通訊錄基本信息只讀)

通訊錄權限范圍(建議選用需要額外通訊錄范圍, 因為我們是服務商, 自然希望我們有最大的獲得權限)

開發信息

CallbackURL  這個和套件的系統回調一致, 也要能相應token的加密

新建應用完成后再回來看應用的開發信息, 有個agentid, 這只是一個當前應用在套件里的一個順序id, 應該是自增長的, 到現在為止還不知道有什么用

針對創建套件和創建套件應用, 這時就需要使用到一些代碼了,如下

  1 <?php
  2 
  3 namespace Wx\Controller;
  4 
  5 use Common\Common\LogException;
  6 use Common\Common\WxApi;
  7 use Common\Common\Utils\AES256;
  8 use Common\Common\Service\AppService;
  9 
 10 class ApiController extends BaseController
 11 {
 12 
 13     //套件的EncodingAESKey
 14     private $encoding_aes_key;
 15     //套件的Token
 16     private $token;
 17     //服務商的企業號corpid,不要問我在哪, 百度里面一把
 18     private $corp_id;
 19     //這里配置多個是為了多套件授權時, 並不知道到底哪個套件來的, 或者你可以再封裝一個類, 每個套件的系統回調地址都不一樣,
 20     //這就看你也許需求,我這里就是用的循環每個套件信息, 有任何一個能得到正確的解析, 就算接入成功, 
 21     //其實你如果做過公眾號, 知道這里很多人都不做驗簽, 直接返回了$_GET['echostr']
 22     private $suite_id; //所有應用套件的應用id , 數據類型是array
 23     private $wxcpt;//wx的消息解密類實例變量
 24 
 25     public function _initialize()
 26     {
 27         header("Content-Type:text/html; charset=utf-8");
 28         $this->corp_id = 'wx04fsdeb6f6ef0w56';
 29         $this->suite_id         = array(
 30             'suiteid'=>array('suite_token'=>,'suite_encoding_aes_key'=>,),
 31             'suiteid'=>array('suite_token'=>,'suite_encoding_aes_key'=>,),
 32             );
 33     }
 34 
 35     public function index()
 36     {
 37 
 38         $get        = $_GET;
 39         $msg_sig    = $get['msg_signature'];
 40         $time_stamp = $get['timestamp'];
 41         $nonce      = $get['nonce'];
 42         $corpid     = $get['corpid'];
 43         
 44         //如果是接入驗證
 45         if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($get['echostr'])) {
 46 
 47             $sVerifyEchoStr = $get['echostr']; //單獨獲取校驗echostr
 48             $sEchoStr       = "";
 49             foreach($this->suite_id as $k=>$v){
 50                 $this->encoding_aes_key = $v['suite_encoding_aes_key'];
 51                 $this->token = $v['suite_token'];
 52                 $this->wxcpt = new WXBizMsgCrypt($this->token, $this->encoding_aes_key, $this->corp_id);
 53                 $err_code    = $this->wxcpt->VerifyURL($msg_sig, $time_stamp, $nonce, $sVerifyEchoStr, $sEchoStr);//VerifyURL方法的最后一個參數是帶取地址的, 
 54                 //如果err_code === 0 的時候, $sEchoStr肯定不是""
 55                 if ($err_code == 0) {
 56                     echo $sEchoStr;
 57                     exit;
 58                 }
 59             }
 60             LogException::write('注冊套件失敗');
 61         }
 62         //如果是微信推送消息
 63         else if ($_SERVER['REQUEST_METHOD'] === 'POST') {
 64             
 65             
 66         }
 67         //如果是從服務商網站發起的授權, 授權完成后是get請求指直接302到服務商網站, 
 68         else if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($get['auth_code'])) {
 69             
 70         }
 71         //其他請求, 不處理
 72         else {
 73             LogException::write("otherrequest\n\n");
 74         }
 75     }
 76     
 77 
 78     /**
 79      * 解析內容, 第三方企業號專用
 80      */
 81     public function exceDec($sMsg, $type = 'online')
 82     {
 83         
 84     }
 85 
 86     /**
 87      * 在微信推送取消授權和變更授權操作時, 重新獲得授權信息, 並更新授權應用, 會在exceDec方法中調用
 88      */
 89     private function doChangeCancelAuth($suite_id, $auth_corp_id)
 90     {
 91         
 92     }
 93 
 94     /**
 95      * 解析事件推送和普通消息推送
 96      * @param String(xml) $sMsg
 97      */
 98     public function exceDecInfo($sMsg)
 99     {
100         
101     }
102 
103 
104 }

這個只是示例代碼, 具體的還需要你來補充, 比如wx的驗簽類, 按照自己框架的載入方式, 然后看看怎么引用

 

單純的對接的話, 其實現在已經完成了, 但是坑現在才剛剛開始

 

企業號管理員授權流程

這是官方文檔使用的標題, 但是用本文的語言理解應該是普通企業管理員授權流程

 所以這里如上述的兩種授權流程, 分為  線上自助注冊授權使用, 就是普通企業在自己的企業微信后台直接授權安裝一個應用,

服務商網站發起授權流程

這塊就不做太詳細的介紹了, 直接看文檔

http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%AE%A1%E7%90%86%E5%91%98%E6%8E%88%E6%9D%83%E6%B5%81%E7%A8%8B

 

接下來就是普通企業號和服務商授權應用或授權套件的過程, 這里面要在文檔中的三個部分來回穿插着看

1.企業號管理員授權和流程, 這里面沒有什么接口, 主要是讓開發者明白一個過程

2.第三方應用接口說明, 關於服務商(第三方)獲得普通企業的企業號信息, 最主要的還是access_token

第三方應用接口說明

 

3.第三方回調協議, 當普通企業在其后台對套件做了一些變動或者一些操作, 微信官方會給服務商推送一些消息, 包括

  授權取消: 特指套件授權取消, 有兩種方式觸發這個回調, 普通企業直接對套件進行取消授權, 普通企業取消授權某個套件下的應用,如果這個應用是最后一個, 那么也會觸發這個回調

  授權變更: 應用授權取消, 應用授權權限變更, 都會觸發這個回調, 

  授權成功推送auth_code -- 在線上自助授權方式, 由於和服務商五交互, 所以這種授權完成之后, 會觸發這個回調, 讓服務商知道有那個企業授權了什么套件的什么應用,

  推送suite_ticket協議: 這個接口微信會每十分鍾給服務商推送一次, 服務商有多少套件就會同時推送多少個suite_ticket, 這東西只和套件有關, 

 

推送suite_ticket這個接口非常重要, 沒記錯的話, 所有的套件授權都要獲得suite_access_token, 獲得suite_access_token的參數就又suite_ticket, 所以這個接口要先對接上

所以先就推送suite_ticket這接口開始我們的對接之坑

 

推送suite_ticket協議

微信服務器會向套件的“系統事件接收URL”定時(每十分鍾)推送ticket:

https://127.0.0.1/suite/receive?msg_signature=3a7b08bb8e6dbce3c9671d6fdb69d15066227608&timestamp=1403610513&nonce=380320359

POST數據示例

{
	<xml>
		<SuiteId><![CDATA[wxfc918a2d200c9a4c]]></SuiteId>
		<InfoType> <![CDATA[suite_ticket]]></InfoType>
		<TimeStamp>1403610513</TimeStamp>
		<SuiteTicket><![CDATA[asdfasfdasdfasdf]]></SuiteTicket>
	</xml>	
}

應用提供商在收到ticket推送后需要返回字符串success。

字段說明

參數 說明
SuiteId 應用套件的SuiteId
InfoType suite_ticket
TimeStamp 時間戳
SuiteTicket Ticket內容

為了加強安全性,postdata中的xml將使用應用套件申請時的加解密key來進行加密,具體請見“使用回調模式”,注意需要將corpid替換為suiteid,並忽略AgentID參數

上面的這一段是微信官方給出的對接文檔, 要注意看最后的小字部分, postdata中的xml將使用應用套件申請時的加解密key來進行加密

所以在對接這個接口的時候, 對於php要使用file_get_contents('php://input', 'r'); 你要是喜歡用別的方式也無所謂, 反正能獲取出來就行

$postData = file_get_contents('php://input', 'r');

接收下來的數據是這樣的

<xml> 
   <ToUserName><![CDATA[toUser]]</ToUserName>
   <AgentID><![CDATA[toAgentID]]</AgentID>
   <Encrypt><![CDATA[msg_encrypt]]</Encrypt>
</xml>

 

其中ToUserName對應的其實就是微信要發送給那個套件所以真實的數據就是<ToUserName><![CDATA[服務商某個套件的suite_id]]></ToUserName>

文檔說注意需要將corpid替換為suiteid就是用這時候解析出來的這個toUserName標簽來實例化解密類

如果是交互類的推送, ToUserName的內容就是corpid反正, 那還是用toUserName這個參數來實例化, 這時Agentid參數來確定請求的是哪個套件下的哪個應用, 

通過DecryptMsg方法解密Encrypt會得到真實的請求信息代碼如下

 

  1 <?php
  2 
  3 namespace Wx\Controller;
  4 
  5 use Common\Common\LogException;
  6 use Common\Common\WxApi;
  7 use Common\Common\Utils\AES256;
  8 use Common\Common\Service\AppService;
  9 
 10 class ApiController extends BaseController
 11 {
 12 
 13     //套件的EncodingAESKey
 14     private $encoding_aes_key;
 15     //套件的Token
 16     private $token;
 17     //服務商的企業號corpid,不要問我在哪, 百度里面一把
 18     private $corp_id;
 19     //這里配置多個是為了多套件授權時, 並不知道到底哪個套件來的, 或者你可以再封裝一個類, 每個套件的系統回調地址都不一樣,
 20     //這就看你也許需求,我這里就是用的循環每個套件信息, 有任何一個能得到正確的解析, 就算接入成功, 
 21     //其實你如果做過公眾號, 知道這里很多人都不做驗簽, 直接返回了$_GET['echostr']
 22     private $suite_id; //所有應用套件的應用id , 數據類型是array
 23     private $wxcpt;//wx的消息解密類實例變量
 24 
 25     public function _initialize()
 26     {
 27         header("Content-Type:text/html; charset=utf-8");
 28         $this->corp_id = 'wx04fsdeb6f6ef0w56';
 29         $this->suite_id         = array(
 30             'suiteid'=>array('suiteid'=>,'suite_token'=>,'suite_encoding_aes_key'=>,),
 31             'suiteid'=>array('suiteid'=>,'suite_token'=>,'suite_encoding_aes_key'=>,),
 32             );
 33     }
 34 
 35     public function index()
 36     {
 37 
 38         $get        = $_GET;
 39         $msg_sig    = $get['msg_signature'];
 40         $time_stamp = $get['timestamp'];
 41         $nonce      = $get['nonce'];
 42         $corpid     = $get['corpid'];
 43         
 44         //如果是接入驗證
 45         if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($get['echostr'])) {
 46 
 47             $sVerifyEchoStr = $get['echostr']; //單獨獲取校驗echostr
 48             $sEchoStr       = "";
 49             foreach($this->suite_id as $k=>$v){
 50                 $this->encoding_aes_key = $v['suite_encoding_aes_key'];
 51                 $this->token = $v['suite_token'];
 52                 $this->wxcpt = new WXBizMsgCrypt($this->token, $this->encoding_aes_key, $this->corp_id);
 53                 $err_code    = $this->wxcpt->VerifyURL($msg_sig, $time_stamp, $nonce, $sVerifyEchoStr, $sEchoStr);//VerifyURL方法的最后一個參數是帶取地址的, 
 54                 //如果err_code === 0 的時候, $sEchoStr肯定不是""
 55                 if ($err_code == 0) {
 56                     echo $sEchoStr;
 57                     exit;
 58                 }
 59             }
 60             LogException::write('注冊套件失敗');
 61         }
 62         //如果是微信推送消息
 63         else if ($_SERVER['REQUEST_METHOD'] === 'POST') {
 64             // post請求的密文數據
 65             // $sReqData = HttpUtils.PostData();
 66             $sReqData = file_get_contents("php://input"); //必須通過輸入流方式獲取post數據, 數據頭為{"Content-Type":"application/xml"}
 67             $xml       = new \DOMDocument();
 68             $xml->loadXML($sReqData);
 69             $ToUserName  = $xml->getElementsByTagName('ToUserName')->item(0)->nodeValue;//其實就是目標套件的suiteid
 70             $ToUserNameType = '';
 71             
 72             $sassInfo = array();//存儲當前推送回調這個套件的信息, 用來實例化
 73             foreach($this->suite_id as $k => $v){
 74                 if($v['suite_id'] == $ToUserName){
 75                     $sassInfo = $v;
 76                     $ToUserNameType = 'sutieid';
 77                     break;
 78                 }
 79             }
 80             
 81             //和上面的實例化對比就體現出來這個用suite_ticket替換corpid
 82             $this->wxcpt = new WXBizMsgCrypt($sassInfo['suite_token'], $sassInfo['suite_encoding_aes_key'], $ToUserName);
 83             $err_code = -1;
 84             $sMsg     = "";  // 解析之后的明文
 85             $err_code = $this->wxcpt->DecryptMsg($msg_sig, $time_stamp, $nonce, $sReqData, $sMsg);//解密方法內部對$sMsg進行賦值
 86             if($err_code == 0){
 87                 if ($ToUserNameType == 'sutieid') {
 88                     $this->exceDec($sMsg);
 89                 } else if ($ToUserNameType == 'corpid') {
 90                     $this->exceDecInfo($sMsg);
 91                 }
 92                 
 93             }
 94         }
 95         //如果是從服務商網站發起的授權, 授權完成后是get請求指直接302到服務商網站, 
 96         else if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($get['auth_code'])) {
 97             
 98         }
 99         //其他請求, 不處理
100         else {
101             LogException::write("otherrequest\n\n");
102         }
103     }
104     
105 
106     /**
107      * 解析內容, 第三方企業號專用
108      */
109     public function exceDec($sMsg, $type = 'online')
110     {
111         $xml       = new DOMDocument();
112         $xml->loadXML($sMsg);
113         $suite_id  = $xml->getElementsByTagName('SuiteId')->item(0)->nodeValue;
114         $info_type = $xml->getElementsByTagName('InfoType')->item(0)->nodeValue; //echo $info_type;exit;
115         $echoStr = 'success';//注意這里的success, 微信默認會在5分鍾內(如果你沒有正確的響應)給你推送三次, 
116         //所謂的正確響應就是返回一個success字符串
117         switch ($info_type) {
118             case 'suite_ticket'://推送suite_ticket協議每十分鍾微信推送一次
119                 $suite_ticket = $xml->getElementsByTagName('SuiteTicket')->item(0)->nodeValue;
120                 //剩下的就是你自己的業務看看要存到什么地方, 
121                 break;
122             case 'change_auth'://變更授權的通知 需要調用 獲取企業號的授權信息, 更改企業號授權信息
123                 
124                 break;
125             case 'cancel_auth'://取消授權的通知 -- 特指套件取消授權
126                 
127                 break;
128             case 'create_auth'://授權成功推送auth_code事件
129                 
130                 break;
131             default:
132                 break;
133         }
134         echo $echoStr;
135     }
136 
137     /**
138      * 在微信推送取消授權和變更授權操作時, 重新獲得授權信息, 並更新授權應用, 會在exceDec方法中調用
139      */
140     private function doChangeCancelAuth($suite_id, $auth_corp_id)
141     {
142         
143     }
144 
145     /**
146      * 解析事件推送和普通消息推送
147      * @param String(xml) $sMsg
148      */
149     public function exceDecInfo($sMsg)
150     {
151         
152     }
153 
154 
155 }

 

 

 

到了這一步完成, 后面, 跟着企業授權應用的流程走, 用哪個接口就對接哪個接口即可, 主要是處理一些業務上的需求, 取消變更套件的定義, 什么時候推送授權成功的信息, 還有就是線上自助授權方式微信會直接跳到服務商主頁, ,參數里面有一個auth_code

想要做服務商輔助授權的方式, 你的應用必須要上線才行, 否則只能在你應用的管理后台最后我上一個我自己的比較完整的controller, 使用tp3.2寫的, 

 

  1 <?php
  2 
  3 namespace Wx\Controller;
  4 
  5 use Common\Common\LogException;
  6 use Common\Common\WxApi;
  7 use Common\Common\Utils\AES256;
  8 use Common\Common\Service\AppService;
  9 
 10 class ApiController extends BaseController
 11 {
 12 
 13     private $encoding_aes_key;
 14     private $token;
 15     private $corp_id;
 16     private $suite_id; //所有應用套件的應用id , 數據類型是array
 17     private $wxcpt;
 18 
 19     public function _initialize()
 20     {
 21         header("Content-Type:text/html; charset=utf-8");
 22         $this->corp_id = '你的corpid';
 23         $this->suite_id         = array(
 24               'suiteid'=>array('suiteid'=>,'suite_token'=>,'suite_encoding_aes_key'=>,),
 25               'suiteid'=>array('suiteid'=>,'suite_token'=>,'suite_encoding_aes_key'=>,),
 26               );//我是從數據庫取的 ,這里只是一個示例
 27     }
 28 
 29     public function index()
 30     {
 31 
 32         $get        = I("get.");
 33         $msg_sig    = $get['msg_signature'];
 34         $time_stamp = $get['timestamp'];
 35         $nonce      = $get['nonce'];
 36         $corpid     = $get['corpid'];
 37         
 38         if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($get['echostr'])) {
 39 
 40             $sVerifyEchoStr = $get['echostr']; //單獨獲取校驗echostr
 41             $sEchoStr       = "";
 42             foreach($this->suite_id as $k=>$v){
 43                 $this->encoding_aes_key = $v['suite_encoding_aes_key'];
 44                 $this->token = $v['suite_token'];
 45                 $this->wxcpt = new \WXBizMsgCrypt($this->token, $this->encoding_aes_key, $this->corp_id);
 46                 $err_code       = $this->wxcpt->VerifyURL($msg_sig, $time_stamp, $nonce, $sVerifyEchoStr, $sEchoStr);
 47                 
 48                 if ($err_code == 0) {
 49                     echo $sEchoStr;
 50                     exit;
 51                 }
 52             }
 53             
 54         }
 55         else if ($_SERVER['REQUEST_METHOD'] === 'POST') {
 56             // post請求的密文數據
 57             // $sReqData = HttpUtils.PostData();
 58             $sReqData = file_get_contents("php://input"); //必須通過輸入流方式獲取post數據, 數據頭為{"Content-Type":"application/xml"}
 59             $xml       = new \DOMDocument();
 60             $xml->loadXML($sReqData);
 61             $ToUserName  = $xml->getElementsByTagName('ToUserName')->item(0)->nodeValue;
 62             $ToUserNameType = '';
 63             $sassInfo = array();
 64             
 65             foreach($this->suite_id as $k => $v){
 66                 if($v['suite_id'] == $ToUserName){
 67                     $sassInfo = $v;
 68                     $ToUserNameType = 'sutieid';
 69                     break;
 70                 }
 71             }
 72             //如果以上for循環不能得到套件結果, 說明不是回調接口來的請求, ToUserName對應的肯定是一個普通企業的corpid, 這時還要通過Agentid參數來獲得
 73             //到底是哪個應用來的請求數據
 74             if(empty($sassInfo)){
 75                 //通過corpid和Agentid反推來得到到底是哪個套件, 因為實例化解密類的時候, 需要token和encoding_aes_key
 76                 $ToUserNameType = 'corpid';
 77             }
 78             
 79             $this->wxcpt = new \WXBizMsgCrypt($sassInfo['suite_token'], $sassInfo['suite_encoding_aes_key'], $ToUserName);
 80             $err_code = -1;
 81             $sMsg     = "";  // 解析之后的明文
 82             $err_code = $this->wxcpt->DecryptMsg($msg_sig, $time_stamp, $nonce, $sReqData, $sMsg);//var_dump($get,$err_code,$sMsg);//exit;
 83             if($err_code == 0){
 84                 if ($ToUserNameType == 'sutieid') {
 85                     $this->exceDec($sMsg);
 86                 } else if ($ToUserNameType == 'corpid') {
 87                     $this->exceDecInfo($sMsg);
 88                 }
 89                 
 90             }
 91             
 92         }
 93         //這種情況是在服務商輔助授權方式授權的應用, 微信沒有回調, 只會在回調url里面有auth_code這個參數, 也就是臨時授權碼, 這樣就相當於模擬了一個請求, 交給相同的方法來處理授權
 94         else if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($get['auth_code'])) {
 95             $auth_code = $get['auth_code'];
 96             $state     = $get['state'];//var_dump($state);
 97             $suite_id  = '';//解密$state獲得suiteid, 我在授權請求的state參數, 把suiteid加密了
 98             $time      = time();
 99             $sMsg      = <<<EOD
100 <xml>
101   <SuiteId><![CDATA[$suite_id]]></SuiteId>
102   <AuthCode><![CDATA[$auth_code]]></AuthCode>
103   <InfoType><![CDATA[create_auth]]></InfoType>
104   <TimeStamp>$time</TimeStamp>
105 </xml>
106 EOD;
107 
108             $this->exceDec($sMsg, 'server');
109         }
110         else {
111             LogException::write("otherrequest\n\n");
112         }
113     }
114     
115 
116     /**
117      * 解析內容, 第三方企業號專用
118      */
119     public function exceDec($sMsg, $type = 'online')
120     {
121         $xml       = new \DOMDocument();
122         $xml->loadXML($sMsg);
123         $suite_id  = $xml->getElementsByTagName('SuiteId')->item(0)->nodeValue;
124         $info_type = $xml->getElementsByTagName('InfoType')->item(0)->nodeValue;
125         $echoStr = 'success';
126         $global_options = get_option('ft_global_options');
127         switch ($info_type) {
128             case 'suite_ticket'://推送suite_ticket協議每十分鍾微信推送一次
129                 $suite_ticket = $xml->getElementsByTagName('SuiteTicket')->item(0)->nodeValue;
130                 
131                 if (!empty($suite_ticket)) {//echo $suite_ticket;exit;
132                     //存suite_ticket
133                 }
134                 else {
135                     //錯誤信息
136                 }
137 
138                 break;
139             case 'change_auth'://變更授權的通知 需要調用 獲取企業號的授權信息, 更改企業號授權信息
140                 $auth_corp_id = $xml->getElementsByTagName('AuthCorpId')->item(0)->nodeValue;//普通企業的corpid
141                 //業務需求
142                 break;
143             case 'cancel_auth'://取消授權的通知 -- 特指套件取消授權
144                 $auth_corp_id = $xml->getElementsByTagName('AuthCorpId')->item(0)->nodeValue;//普通企業的corpid
145                 //自己的業務需求
146                 break;
147             case 'create_auth'://授權成功推送auth_code事件
148                 //獲取AuthCode
149                 $auth_code    = $xml->getElementsByTagName('AuthCode')->item(0)->nodeValue;
150                 if (!empty($auth_code)) {
151                     
152                     //服務商輔助授權方式安裝應用
153                     if ('online' !== $type && 'server' === $type) {
154                         
155                     } 
156                     //線上自助授權安裝應用
157                     else if ('online' == $type) {
158                         
159                     }
160                         
161                     
162                     
163                 }
164                 break;
165             default:
166                 break;
167         }
168         echo $echoStr;
169     }
170 
171 
172     /**
173      * 解析事件推送和普通消息推送
174      * @param String(xml) $sMsg
175      */
176     public function exceDecInfo($sMsg)
177     {
178         $xml       = new \DOMDocument();
179         $xml->loadXML($sMsg);
180         $toUserName = $corpid = $xml->getElementsByTagName('ToUserName')->item(0)->nodeValue;
181         $fromUserName = $userid = $xml->getElementsByTagName('FromUserName')->item(0)->nodeValue;
182         $msgType = $xml->getElementsByTagName('MsgType')->item(0)->nodeValue;
183         $agentID = $xml->getElementsByTagName('AgentID')->item(0)->nodeValue;
184         
185         //TODO
186         $data = array(
187             'corpid'=>$corpid,
188             'userid'=>$userid,
189             'msgType'=>$msgType,
190             'agentid'=>$agentID,
191         );
192         
193     }
194 
195 }

 


免責聲明!

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



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