第一步:填写服务器配置
主要填写服务器地址(URL)、Token和EncodingAESKey,其中URL是开发者用来接收微信消息和事件的接口URL。Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。
第二步:验证消息的确来自微信服务器
开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:
参数 | 描述 |
---|---|
signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
1)将token、timestamp、nonce三个参数进行字典序排序 2)将三个参数字符串拼接成一个字符串进行sha1加密 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
检验signature的PHP示例代码:
private function checkSignature() { $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } }
第三步:依据接口文档实现业务逻辑
1)验证URL有效性成功后即接入生效,成为开发者。
2)成为开发者后,用户每次向公众号发送消息、或者产生自定义菜单、或产生微信支付订单等情况时,开发者填写的服务器配置URL将得到微信服务器推送过来的消息和事件,开发者可以依据自身业务逻辑进行响应
扫描二维码关注公众号,回复:
490773 查看本文章
3)用户向公众号发送消息时,公众号方收到的消息发送者是一个OpenID,是使用用户微信号加密后的结果,每个用户对每个公众号有一个唯一的OpenID
消息回复的代码如下:
public function responseMsg() { //get post data, May be due to the different environments $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; file_put_contents("msg.txt", $postStr,FILE_APPEND); //extract post data if (!empty($postStr)){ $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $time = time(); $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; if(!empty( $keyword )) { $msgType = "text"; // $contentStr="123"; $contentStr =$this->responsekeyword($keyword) ; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType,$contentStr ); echo $resultStr; }else{ echo "Input something..."; } }else { echo ""; exit; } } //关键字回复 public function responsekeyword($keywords){ if($keywords == "天气"){ $content="今天天气阴天"; return $content; }else if($keywords == "放假"){ $content="今年不放假"; return $content; // echo "123"; }else{ $content="sorry I do not know!"; return $content; } }
具体完整的代码如下:
<?php /** * wechat php test */ //define your token define("TOKEN", "weixin"); $wechatObj = new wechatCallbackapiTest(); $wechatObj->run(); class wechatCallbackapiTest { public function run() { //验证是否是接受的腾讯 if($this->checkSignature()==false){ die("非法请求"); } if (isset($_GET["echostr"])) { $echoStr = $_GET["echostr"]; echo $echoStr; exit; } else { $this->responseMsg(); } //valid signature , option } public function responseMsg() { //get post data, May be due to the different environments $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; file_put_contents("msg.txt", $postStr,FILE_APPEND);//将信息写入文件 //extract post data if (!empty($postStr)){ $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $time = time(); $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; if(!empty( $keyword )) { $msgType = "text"; // $contentStr="123"; $contentStr =$this->responsekeyword($keyword) ; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType,$contentStr ); echo $resultStr; }else{ echo "Input something..."; } }else { echo ""; exit; } } //关键字回复 public function responsekeyword($keywords){ if($keywords == "天气"){ $content="今天天气阴天"; return $content; }else if($keywords == "放假"){ $content="今年不放假"; return $content; // echo "123"; }else{ $content="sorry I do not know!"; return $content; } } private function checkSignature() { $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } } ?>