热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

微信开发带参数二维码的实例详解

最近做微信PC端网页微信相关功能的开发,从一个新手的角度来说,微信公众号的文档还是不好理解的,网上找的帖子大都也都基本上是复制微信公众平台上给的文档,开发微信带参数二维码过程中还是遇到不少坑的,在此把我的开发过程比较详细的记录下,希望对大家有所帮助。
  最近做微信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() 的具体实现:

 1 //获取access_token
 2 function getWechatAccessToken(){ 3     $wechatInfo = M('wechat_info')->select(); 4     $wechatInfo = array_reduce($wechatInfo, create_function('$result, $v', '$result[$v["conf_name"]] = $v;return $result;')); 5     $expireTime = $wechatInfo['PUBLIC_WECHAT_ACCESSTOKEN_EXPIRES']['conf_value'];                             //前面不用管,是我数据库相应设置
 6 
 7     if (time() <$expireTime){              //access_token未过期
 8         return $wechatInfo[&#39;PUBLIC_WECHAT_ACCESSTOKEN&#39;][&#39;conf_value&#39;]; 9     }else{                                  //access_token过期,重新获取10         $baseUrl = C(&#39;WECHAT_PUBLIC_GET_ACCESS_TOKEN&#39;);11         $url = str_replace("##APPSECRET##", $wechatInfo[&#39;PUBLIC_WECHAT_APPSECRET&#39;][&#39;conf_value&#39;], str_replace("##APPID##", $wechatInfo[&#39;PUBLIC_WECHAT_APPID&#39;][&#39;conf_value&#39;], $baseUrl));12         $result = file_get_contents($url);13         $result = json_decode($result, true);14 
15         if (array_key_exists(&#39;errorcode&#39;, $result)){        //失败重试一次16             return false;17         }else{18             M(&#39;wechat_info&#39;)->where(array(&#39;conf_name&#39; => &#39;PUBLIC_WECHAT_ACCESSTOKEN&#39;))->save(array(&#39;conf_value&#39; => $result[&#39;access_token&#39;]));19             M(&#39;wechat_info&#39;)->where(array(&#39;conf_name&#39; => &#39;PUBLIC_WECHAT_ACCESSTOKEN_EXPIRES&#39;))->save(array(&#39;conf_value&#39; => time()+$result[&#39;expires_in&#39;]-200));20             return $result[&#39;access_token&#39;];21         }22     }23 }
C(&#39;WECHAT_PUBLIC_GET_ACCESS_TOKEN&#39;) = 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(&#39;WECHAT_PUBLIC_GET_TEMPORARY_TICKET&#39;));    $qrcode = &#39;{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": &#39;.$orderId.&#39;}}}&#39;;    $result = api_notice_increment($url, $qrcode);    $result = json_decode($result, true);    return urldecode($result[&#39;url&#39;]);
}

  其中的方法 api_notice_increment() 是我封装的一个POST方法函数,我试过很多POST的方法,可能由于微信接口对POST方法和参数的限制比较严格,这个浪费了好久时间,最后在网上找到了一个可以使用的封装好的POST方法,建议大家先自己试试,如果微信返回错误吗,就用这个吧,起码我测试微信这个接口的时候用postman测试返回的都是错误,而且一定要用JSON字符串,一定要是非常严格的JSON字符串。下面是这个方法:

function api_notice_increment($url, $data){    $ch = curl_init();    $header = "Accept-Charset: utf-8";
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_USERAGENT, &#39;Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)&#39;);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);    $tmpInfo = curl_exec($ch);    if (curl_errno($ch)) {
        curl_close( $ch );        return $ch;
    }else{
        curl_close( $ch );        return $tmpInfo;
    }
}

getTemporaryQrcode() 中有一个在配置文件中的参数给大家看下,其实就是微信接口链接:

C(&#39;WECHAT_PUBLIC_GET_TEMPORARY_TICKET&#39;) = https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=##TOKEN##

  这个接口的返回值是:

{"ticket":"gQH47joAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL2taZ2Z3TVRtNzJXV1Brb3ZhYmJJAAIEZ23sUwMEmm3sUw==","expire_seconds":60,"url":"http:\/\/weixin.qq.com\/q\/kZgfwMTm72WWPkovabbI"}

  其中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前面会加一个前缀。下面是微信公众平台文档的说明:

 用户未关注时,进行关注后的事件推送
        //开发者微信号       //发送者账号(openid)123456789                //消息创建时间(整型)              //消息类型 event              //事件类型(subscribe)        //事件KEY值,qrscene_为前缀,后面为二维码参数值               //二维码ticke值,可以用来换取二维码图片

  用户已关注时的事件推送

         //开发者微信号     //发送者账号(openid)123456789             //消息创建时间                    //消息类型event               //事件类型 event            //事件key值,是一个32位无符号整数,即创建二维码时的二维码scene_id                     //二维码的ticke,可以用来换取二维码图片

3.3.2 我们要做些什么

  我们需要在自己填写的URL接口中接收这个事件,然后拿到我们需要的东西做我们想干的事儿。因为我要实现的功能比较简单,只需要拿到scene_id即可,因为这是我要展示给用户看的订单数据。下面是我写的接收和处理部分,比较简单,主要看一下应该怎么接收微信推送的事件:

public function urlRedirect(){        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];        $postObj = simplexml_load_string($postStr, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA);        $fromUsername = (string)$postObj->FromUserName;        $EventKey = trim((string)$postObj->EventKey);        $keyArray = explode("_", $EventKey);        if (count($keyArray) == 1){         //已关注者扫描
            $this->sendMessage($fromUsername, $EventKey);
        }else{                   //未关注者关注后推送事件
            $this->sendMessage($fromUsername, $keyArray[1]);
        }
    }

  我没有使用其他参数,只是根据不同的推送事件拿到我想要的订单ID,然后这时候其实相当于你在这里用公众号的客服在跟扫码的这个用户对话,上段代码中调用的sendMessage()是使用客户账号给扫码用户发送一个图文消息,因为我在拿scen_id的同时也拿到了用户的openid,可以利用这个给用户发送消息。

  下面是 sendMessage() 方法:

//给用户发送图文消息,点击跳转到报价页面
    public function sendMessage($openid,$orderId){        $url = str_replace(&#39;##TOKEN##&#39;, getWechatAccessToken(), C(&#39;WECHAT_SEND_MESSAGE&#39;));        $redirectUrl = str_replace("##ORDERID##", $orderId, str_replace("##OPENID##", $openid, C(&#39;WECHAT_REDIRECT_URL_PRE&#39;)));        $orderInfo = M(&#39;order&#39;)->where(array(&#39;orderid&#39; => $orderId))->field(array(&#39;totalMoney&#39;, &#39;savedMoney&#39;, &#39;roomarea&#39;))->find();        $description = str_replace("##ROOMAREA##", intval($orderInfo[&#39;roomarea&#39;] * 1.25), C(&#39;WECHAT_MESSAGE_BRIEF&#39;));        $description = str_replace("##TOTALBUDGET##", $orderInfo[&#39;totalMoney&#39;], $description);        $description = str_replace("##MARKETBUDGET##", $orderInfo[&#39;totalMoney&#39;]+$orderInfo[&#39;savedMoney&#39;], $description);        $description = str_replace("##SAVEMONEY##", $orderInfo[&#39;savedMoney&#39;], $description);        $dataStr = &#39;{"touser":"&#39; . $openid . &#39;","msgtype":"news","news":{"articles":[{"title":"&#39; . C(&#39;WECHAT_MESSAGE_TITLE&#39;) .
            &#39;","description":"&#39; . $description . &#39;","url":"&#39; . $redirectUrl . &#39;","picurl":"&#39; . C(&#39;WECHAT_MESSAGE_PICURL&#39;) . &#39;""}]}}&#39;;
        api_notice_increment($url, $dataStr);
    }

  其中 C(&#39;WECHAT_SEND_MESSAGE&#39;) = &#39;https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=##TOKEN##&#39; 至于下面的一大段str_replace,就是在组给用户发送的文字而已,需要注意$dataStr的格式,这里面要求JSON字符串比较严格,必须所有的字符串都用双引号括起来。微信接口对POST参数的限制真心严格。

  下面是微信公众平台开发者文档中要求发送图文消息的POST data格式:

{
    "touser":"OPENID",
    "msgtype":"news",
    "news":{
        "articles": [
         {
             "title":"Happy Day",
             "description":"Is Really A Happy Day",
             "url":"URL",
             "picurl":"PIC_URL"
         },
         {
             "title":"Happy Day",
             "description":"Is Really A Happy Day",
             "url":"URL",
             "picurl":"PIC_URL"
         }
         ]
    }
}

  其中url是用户点击这个消息之后打开的地址,这个时候我就组了一个自己网站的地址,是一个get请求地址,里面携带参数是用户的openid和订单id,这样用户点击开图文消息就可以看到自己刚才下单的内容了,因为需要在网页上展示用户的微信头像和昵称,所以我把openid也放到参数里,在页面加载前先拿到用户的个人信息和订单数据,再展示网页。这样流程:用户未登录下单 -> 生成微信二维码 -> 用户扫码关注公众号 -> 查看订单详细信息 就完成了。而且因为这个图文消息打开后的链接携带的参数是这个用户的额openid和其下单的订单ID,不管分享到哪儿,用什么浏览器打开都是可以访问的,且展示的也是这个用户的头像和昵称信息,这也是我要实现的一个效果。

以上就是微信开发带参数二维码的实例详解的详细内容,更多请关注php中文网其它相关文章!


推荐阅读
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 2016 linux发行版排行_灵越7590 安装 linux (manjarognome)
    RT之前做了一次灵越7590黑苹果炒作业的文章,希望能够分享给更多不想折腾的人。kawauso:教你如何给灵越7590黑苹果抄作业​zhuanlan.z ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
  • 在Android中解析Gson解析json数据是很方便快捷的,可以直接将json数据解析成java对象或者集合。使用Gson解析json成对象时,默认将json里对应字段的值解析到java对象里对应字段的属性里面。然而,当我们自己定义的java对象里的属性名与json里的字段名不一样时,我们可以使用@SerializedName注解来将对象里的属性跟json里字段对应值匹配起来。本文介绍了使用@SerializedName注解解析json数据的方法,并给出了具体的使用示例。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
  • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
  • Linux环境变量$PATH的作用及使用方法
    本文介绍了Linux环境变量$PATH的作用及使用方法。$PATH是一个由多个目录组成的变量,用冒号分隔。当执行一个指令时,系统会按照$PATH定义的目录顺序搜索同名的可执行文件,如果有多个同名指令,则先找到的会被执行。通过设置$PATH变量,可以在任何地方执行指令,无需输入绝对路径。 ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
author-avatar
多米音乐_34026248
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有