微信公众号,带参二维码/推广二维码的使用

最近做微信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

发布了106 篇原创文章 · 获赞 65 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/xialong_927/article/details/90297473