- 登陆微信公众平台
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
-
得到appID和appsecret
-
获取access_token:
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。1、建议公众号开发者使用中控服务器统一获取和刷新access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;
2、目前access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器可对外继续输出的老access_token,此时公众平台后台会保证在5分钟内,新老access_token都可用,这保证了第三方业务的平滑过渡;
3、access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。
公众号和小程序均可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。小程序无需配置IP白名单。
接口调用请求说明
https请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
grant_type | 是 | 获取access_token填写client_credential |
appid | 是 | 第三方用户唯一凭证 |
secret | 是 | 第三方用户唯一凭证密钥,即appsecret |
返回说明
正常情况下,微信会返回下述JSON数据包给公众号:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
参数说明
参数 | 说明 |
---|---|
access_token | 获取到的凭证 |
expires_in | 获取凭证有效时间,单位:秒的凭证 |
错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):
{"errcode":40013,"errmsg":"invalid appid"}
被动回复用户消息
当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。
假如服务器无法保证在五秒内处理并回复,必须做出下述回复,这样微信服务器才不会对此作任何处理,并且不会发起重试(这种情况下,可以使用客服消息接口进行异步回复),否则,将出现严重的错误提示。详见下面说明:
1、直接回复success(推荐方式) 2、直接回复空串(指字节长度为0的空字符串,而不是XML结构体中content字段的内容为空)
一旦遇到以下情况,微信都会在公众号会话中,向用户下发系统提示“该公众号暂时无法提供服务,请稍后再试”:
1、开发者在5秒内未回复任何内容 2、开发者回复了异常数据,比如JSON数据等
回复文本消息
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
参数 | 是否必须 | 描述 |
---|---|---|
ToUserName | 是 | 接收方帐号(收到的OpenID) |
FromUserName | 是 | 开发者微信号 |
CreateTime | 是 | 消息创建时间 (整型) |
MsgType | 是 | 消息类型,文本为text |
Content | 是 | 回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示) |
回复图片消息
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[media_id]]></MediaId>
</Image>
</xml>
参数 | 是否必须 | 描述 |
---|---|---|
ToUserName | 是 | 接收方帐号(收到的OpenID) |
FromUserName | 是 | 开发者微信号 |
CreateTime | 是 | 消息创建时间 (整型) |
MsgType | 是 | 消息类型,图片为image |
MediaId | 是 | 通过素材管理中的接口上传多媒体文件,得到的id。 |
详情请看微信公众平台
具体代码实现
<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
use org\wechat\jssdk;//引入jssdk包,具体的jssdk配置请找度娘
header("Content-type: text/html; charset=utf-8");
define("TOKEN","token");
class Spf extends Controller
{
public function index1()
{
file_put_contents('./log.txt',date('Y-m-d H:i:s').PHP_EOL,FILE_APPEND);
$echoStr = $_GET["echostr"];
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
function index(){
if (isset($_GET['echostr'])) {
$this->index1();
}else{
$this->index2();
}
}
public function index2()
{
// $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; // 虚拟机可能禁止register_globals导致无法获取body数据
$postStr = file_get_contents("php://input");
file_put_contents('./log.txt',date('Y-m-d H:i:s').'�ź������?'.PHP_EOL,FILE_APPEND);
if (!empty($postStr)){
libxml_disable_entity_loader(true);//安全防护
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$time = time();
$msgType = $postObj->MsgType;
$media_id = $postObj->MediaId;
if( $keyword == '图文' ) {
$itemTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>2</ArticleCount>
<Articles>
<item>
<Title><![CDATA[图文回复?]]></Title>
<Description><![CDATA[描述,网址:https://blog.csdn.net/weixin_44269886]]></Description>
<PicUrl><![CDATA[http://guo.shisisi.com/axc.jpg]]></PicUrl>
<Url><![CDATA[https://blog.csdn.net/weixin_44269886]]></Url>
</item>
<item>
<Title><![CDATA[图文回复?]]></Title>
<Description><![CDATA[描述,网址:https://blog.csdn.net/weixin_44269886]]></Description>
<PicUrl><![CDATA[http://guo.shisisi.com/axc.jpg]]></PicUrl>
<Url><![CDATA[https://blog.csdn.net/weixin_44269886]]></Url>
</item>
</Articles>
</xml>
";
}else if($keyword == '哈哈哈'){
$itemTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[php第一?]]></Title>
<Description><![CDATA[描述,网址:https://blog.csdn.net/weixin_44269886]]></Description>
<PicUrl><![CDATA[http://guo.shisisi.com/axc.png]]></PicUrl>
<Url><![CDATA[https://blog.csdn.net/weixin_44269886]]></Url>
</item>
</Articles>
</xml>
";
} else if($keyword == 'XXX'){
$itemTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[XXX]]></Title>
<Description><![CDATA[个人描述,网址:https://www.baidu.com/]]></Description>
<PicUrl><![CDATA[http://guo.shisisi.com/axc.png]]></PicUrl>
<Url><![CDATA[https://blog.csdn.net/weixin_44269886]]></Url>
</item>
</Articles>
</xml>
";
}else if($msgType=='image'){
$itemTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[%s]]></MediaId>
</Image>
</xml>";
$result = sprintf($itemTpl, $fromUsername, $toUsername, $time, $media_id);
echo $result;
die;
}
else{
$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 = "小蛤蟆腿";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}
die;
}
if(!empty( $keyword ))
{
$result = sprintf($itemTpl, $fromUsername, $toUsername, $time);
echo $result;
}else{
echo "Input something...";
}
}else {
echo "";
exit;
}
}
private function checkSignature()
{
if (!defined("TOKEN")) {
throw new Exception('TOKEN is not defined!');
}
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
扫一扫代码实现
和上面是一个控制器,接着上面的
这是方法:
public function index3()
{
$jssdkObj = new Jssdk('wxdd87205eff3d5940', '4f3d7e2f068e59fea2c7c3cedb3dcbd0');
$res = $jssdkObj->getSignPackage();
$appId = $res['appId'];
$timestamp = $res['timestamp'];
$nonceStr = $res['nonceStr'];
$signature = $res['signature'];
$arr=array(
'appId'=>$appId,
'timestamp'=>$timestamp,
'nonceStr'=>$nonceStr,
'signature'=>$signature,
);
print_r($arr);
return view('public/jssdk',['arr'=>$arr]);
}
这是HTML页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>微信</h1>
<button "sys()">扫一扫</button>
</body>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
$(document).ready(function(){
share();
});
</script>
<script>
function sys(){
wx.scanQRCode({
needResult: 0, // 默认�?,扫描结果由微信处理�?则直接返回扫描结果,
scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都�?
success: function (res) {
var result = res.resultStr; // 当needResult �?1 时,扫码返回的结�?
}
});
}
</script>
</html>
在这对代码不做多的解释,直接可以用的,在本地跑通后在上服务器