2018-12-05 17:11:40 li3839 阅读数 255
  • 微信公众号生成带参数二维码一学就会Java版

    为了满足用户渠道推广分析和用户帐号绑定等场景的需要,也就是推广和微商城分销的一个知识点,当你需要知道你的这个客户是谁推广的时候,当你为你的商城设计了分销的模式的时候,你就会发现这个知识点很好用

    3667 人正在学习 去看看 朱祚华

 

一、账号管理 ----- 生成带参数的二维码

总结下关于微信公众号开发,生成带参数的二维码:

我在网上找了挺多资料来看,经过自己理解,然后进行了改进。

简单说一下,关于做生成二维码的步骤:

1) 通过appid 和 appsecret 获取到 access_token

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

2) 然后 再通过 access_token 获取 ticket

 分别有临时二维码和永久二维码 : 

 临时二维码的ticket:

URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN

post 数据方式:json 

{"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}

 

永久二维码的ticket:

URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN

post 数据方式:json 

{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}

 好了,下面就开始动手了。

二、

为了满足用户渠道推广分析和用户帐号绑定等场景的需要,公众平台提供了生成带参数二维码的接口。使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送。

目前有2种类型的二维码:

1、临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量。临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景
2、永久二维码,是无过期时间的,但数量较少(目前为最多10万个)。永久二维码主要用于适用于帐号绑定、用户来源统计等场景。

临时二维码请求说明

http请求方式: POST
URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
POST数据格式:json
POST数据例子:{"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}

或者也可以使用以下POST数据创建字符串形式的二维码参数:
{"expire_seconds": 604800, "action_name": "QR_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}

永久二维码请求说明

http请求方式: POST
URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
POST数据格式:json
POST数据例子:{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}

或者也可以使用以下POST数据创建字符串形式的二维码参数:
{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}

 三、下面建一个ticket.php文件,放在你服务器上。

<?php
@header('Content-type: text/plain;charset=UTF-8');
function https_request($url, $data = null,$time_out=60,$out_level="s",$headers=array())
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_NOSIGNAL, 1);
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    if (!empty($data)){
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    if($out_level=="s")
    {
        //超时以秒设置
        curl_setopt($curl, CURLOPT_TIMEOUT,$time_out);//设置超时时间
    }elseif ($out_level=="ms") 
    {
        curl_setopt($curl, CURLOPT_TIMEOUT_MS,$time_out);  //超时毫秒,curl 7.16.2中被加入。从PHP 5.2.3起可使用 
    }
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    if($headers)
    {
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);//如果有header头 就发送header头信息
    }
    $output = curl_exec($curl);
    curl_close($curl);
    return $output;
}

$access_token = "16_uHF0JVZKC56cG4JcEUOUX_PWua3FmWDwF0nYvp3NsKFNw29xCvFYifqRmnTwewdVwjVA76-9qD4K7D4XvgHQeG90r-0F2VFyW1JTKK16UD2jETDNMnjB3mubHW4k7hsoxxIuOIkZxgY34VtRBWTfAJANIF";
$data = '{
    "expire_seconds": 604800,
    "action_name": "QR_SCENE",
    "action_info": {
        "scene": {
            "scene_id": 100
        }
    }
}';
$url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?"
    ."access_token=" . $access_token;
$result=https_request($url, $data);
$result=json_decode($result,true);
echo $result;

然后输出 :

 然后复制ticket 那段字符串 ,在一下这个地址就显示二维码了。

最后结果如下:

我做的这个是永久生成参数二维码,你也可以参数做临时的。。。

 

2018-03-08 14:59:55 shuxing520 阅读数 726
  • 微信公众号生成带参数二维码一学就会Java版

    为了满足用户渠道推广分析和用户帐号绑定等场景的需要,也就是推广和微商城分销的一个知识点,当你需要知道你的这个客户是谁推广的时候,当你为你的商城设计了分销的模式的时候,你就会发现这个知识点很好用

    3667 人正在学习 去看看 朱祚华

就在今年春节期间,有个我不愿提及的人说要做个使用微信扫描二维码的方式实现会议签到的功能,当时还没接触任何的微信开发,也就只说自己不会微信开发。直到今天才直到应该怎么实现。现在很多东西都用php来开发微信,我就用java做了几个项目居然被php的鄙视,二话没说直接把这种好友拉入黑名单。语言本身无优劣之分,没有糟糕的语言只有糟糕的不想学习的懒惰程序员。好了废话不多说进入今天的主题———–微信带参二维码的使用


一 为什么会有这样的要求

前些年二维码主要是为了扫描之后出现链接,点击之后进行下载各类APP的场合。二维码也就这样流行起来,微信也不甘落后,扫一扫的这种功能就来了。


二  微信带参二维码的分类

微信带参二维码主要分临时二维码、永久二维码两种,下面是微信开发文档的解释:

1、临时二维码,是有过期时间的,最长可以设置为在二维码生成后的7天(即604800秒)后过期,但能够生成较多数量。临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景
2、永久二维码,是无过期时间的,但数量较少(目前为最多10万个)。永久二维码主要用于适用于帐号绑定、用户来源统计等场景。

看过之后对带参二维码应该有了比较全面的认识了,接下来就是重头戏—Java代码


三  使用程序生成并换取二维码

要获取到最终的二维码只需要简单的两步分别是创建二维码ticket、通过ticket换取二维码,接下来就是贴代码了:


1  创建二维码ticket

  1. public static WeixinQRCode createTemporaryQRCode(String token,int expireSeconds,int sceneId){  
  2.           
  3.           
  4.         String requestUrl=”https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN”;  
  5.         requestUrl=requestUrl.replace(”TOKEN”, token);  
  6.         String jsonMsg=”{\”expire_seconds\”: %d, \”action_name\”: \”QR_SCENE\”, \”action_info\”: {\”scene\”: {\”scene_id\”: %d}}}”;  
  7.         JSONObject json=CommonUtil.httpsRequest(requestUrl, ”POST”, String.format(jsonMsg, expireSeconds,sceneId));  
  8.           
  9.         WeixinQRCode w=null;  
  10.         if(json!=null){  
  11.             try{  
  12.                 w=new WeixinQRCode();  
  13.                 w.setExpire_seconds(json.getInt(”expire_seconds”));  
  14.                 w.setTicket(json.getString(”ticket”));  
  15.                 w.setUrl(json.getString(”url”));  
  16.             }catch(Exception e){  
  17.                 //e.printStackTrace();  
  18.                 int errorCode=json.getInt(“errorcode”);  
  19.                 String errorMsg=json.getString(”errmsg”);  
  20.                 System.out.println(errorCode+”:”+errorMsg);  
  21.             }  
  22.               
  23.         }  
  24.         return w;  
  25.           
  26. }  
public static WeixinQRCode createTemporaryQRCode(String token,int expireSeconds,int sceneId){


        String requestUrl="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
        requestUrl=requestUrl.replace("TOKEN", token);
        String jsonMsg="{\"expire_seconds\": %d, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": %d}}}";
        JSONObject json=CommonUtil.httpsRequest(requestUrl, "POST", String.format(jsonMsg, expireSeconds,sceneId));

        WeixinQRCode w=null;
        if(json!=null){
            try{
                w=new WeixinQRCode();
                w.setExpire_seconds(json.getInt("expire_seconds"));
                w.setTicket(json.getString("ticket"));
                w.setUrl(json.getString("url"));
            }catch(Exception e){
                //e.printStackTrace();
                int errorCode=json.getInt("errorcode");
                String errorMsg=json.getString("errmsg");
                System.out.println(errorCode+":"+errorMsg);
            }

        }
        return w;

}
上面的代码是用于临时二维码,下面在贴上永久二维码的代码:

  1. public static WeixinQRCode createPermanentQRCode(String token,int sceneId){  
  2.           
  3.           
  4.         String requestUrl=”https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN”;  
  5.         requestUrl=requestUrl.replace(”TOKEN”, token);  
  6.         String jsonMsg=”{\”action_name\”: \”QR_LIMIT_SCENE\”, \”action_info\”: {\”scene\”: {\”scene_id\”: %d}}}”;  
  7.         JSONObject json=CommonUtil.httpsRequest(requestUrl, ”POST”, String.format(jsonMsg, sceneId));  
  8.           
  9.         WeixinQRCode w=null;  
  10.         if(json!=null){  
  11.             try{  
  12.                 w=new WeixinQRCode();  
  13.                 //w.setExpire_seconds(json.getInt(“expire_seconds”));  
  14.                 w.setTicket(json.getString(”ticket”));  
  15.                 w.setUrl(json.getString(”url”));  
  16.             }catch(Exception e){  
  17.                 //e.printStackTrace();  
  18.                 int errorCode=json.getInt(“errorcode”);  
  19.                 String errorMsg=json.getString(”errmsg”);  
  20.                 System.out.println(errorCode+”:”+errorMsg);  
  21.             }  
  22.               
  23.         }  
  24.         return w;  
  25.           
  26. }  
public static WeixinQRCode createPermanentQRCode(String token,int sceneId){


        String requestUrl="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
        requestUrl=requestUrl.replace("TOKEN", token);
        String jsonMsg="{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": %d}}}";
        JSONObject json=CommonUtil.httpsRequest(requestUrl, "POST", String.format(jsonMsg, sceneId));

        WeixinQRCode w=null;
        if(json!=null){
            try{
                w=new WeixinQRCode();
                //w.setExpire_seconds(json.getInt("expire_seconds"));
                w.setTicket(json.getString("ticket"));
                w.setUrl(json.getString("url"));
            }catch(Exception e){
                //e.printStackTrace();
                int errorCode=json.getInt("errorcode");
                String errorMsg=json.getString("errmsg");
                System.out.println(errorCode+":"+errorMsg);
            }

        }
        return w;

}

2  通过ticket换取二维码

  1. public static void  getImageQRCode(String ticket,String savePath) throws Exception{  
  2.         String requestUrl=”https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET”;  
  3.         requestUrl=requestUrl.replace(”TICKET”, URLEncoder.encode(ticket, “UTF-8”));  
  4.         try{  
  5.             URL url = new URL(requestUrl);    
  6.             HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();    
  7.              
  8.     
  9.             httpUrlConn.setDoOutput(true);    
  10.             httpUrlConn.setDoInput(true);    
  11.             httpUrlConn.setUseCaches(false);    
  12.             // 设置请求方式(GET/POST)    
  13.             httpUrlConn.setRequestMethod(”GET”);    
  14.             httpUrlConn.connect();    
  15.          
  16.             // 将返回的输入流转换成字符串    
  17.             InputStream inputStream = httpUrlConn.getInputStream();    
  18.             BufferedInputStream bis=new BufferedInputStream(inputStream);  
  19.             FileOutputStream bos=new FileOutputStream(new File(savePath));  
  20.             int temp=0;  
  21.             while ((temp=bis.read())!=-1) {    
  22.                 bos.write(temp);  
  23.             }    
  24.             bos.close();    
  25.             bis.close();    
  26.             // 释放资源    
  27.             inputStream.close();    
  28.             inputStream = null;    
  29.             httpUrlConn.disconnect();    
  30.     }catch(Exception e){  
  31.        e.printStackTrace();  
  32.     }  
  33. }  
public static void  getImageQRCode(String ticket,String savePath) throws Exception{
        String requestUrl="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
        requestUrl=requestUrl.replace("TICKET", URLEncoder.encode(ticket, "UTF-8"));
        try{
            URL url = new URL(requestUrl);  
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  


            httpUrlConn.setDoOutput(true);  
            httpUrlConn.setDoInput(true);  
            httpUrlConn.setUseCaches(false);  
            // 设置请求方式(GET/POST)  
            httpUrlConn.setRequestMethod("GET");  
            httpUrlConn.connect();  

            // 将返回的输入流转换成字符串  
            InputStream inputStream = httpUrlConn.getInputStream();  
            BufferedInputStream bis=new BufferedInputStream(inputStream);
            FileOutputStream bos=new FileOutputStream(new File(savePath));
            int temp=0;
            while ((temp=bis.read())!=-1) {  
                bos.write(temp);
            }  
            bos.close();  
            bis.close();  
            // 释放资源  
            inputStream.close();  
            inputStream = null;  
            httpUrlConn.disconnect();  
    }catch(Exception e){
       e.printStackTrace();
    }
}

下面是WeixinQRCode,直接上代码:

  1. package com.debug.weixin.pojo;  
  2.   
  3. public class WeixinQRCode {  
  4.     private String ticket;  
  5.     private int expire_seconds;  
  6.     private String url;  
  7.   
  8.     public String getTicket() {  
  9.         return ticket;  
  10.     }  
  11.   
  12.     public void setTicket(String ticket) {  
  13.         this.ticket = ticket;  
  14.     }  
  15.   
  16.     public int getExpire_seconds() {  
  17.         return expire_seconds;  
  18.     }  
  19.   
  20.     public void setExpire_seconds(int expireSeconds) {  
  21.         expire_seconds = expireSeconds;  
  22.     }  
  23.   
  24.     public String getUrl() {  
  25.         return url;  
  26.     }  
  27.   
  28.     public void setUrl(String url) {  
  29.         this.url = url;  
  30.     }  
  31. }  
package com.debug.weixin.pojo;

public class WeixinQRCode {
    private String ticket;
    private int expire_seconds;
    private String url;

    public String getTicket() {
        return ticket;
    }

    public void setTicket(String ticket) {
        this.ticket = ticket;
    }

    public int getExpire_seconds() {
        return expire_seconds;
    }

    public void setExpire_seconds(int expireSeconds) {
        expire_seconds = expireSeconds;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

下面是运行效果图:



2015-03-18 19:23:00 xiongkai327 阅读数 1301
  • 微信公众号生成带参数二维码一学就会Java版

    为了满足用户渠道推广分析和用户帐号绑定等场景的需要,也就是推广和微商城分销的一个知识点,当你需要知道你的这个客户是谁推广的时候,当你为你的商城设计了分销的模式的时候,你就会发现这个知识点很好用

    3667 人正在学习 去看看 朱祚华

微信公众平台开发 批量生成及下载带参二维码图片

最近在做微信二次开发时经常会使用到场景二维码,所以就把相关的批量生成并保存二维码图片的代码整理了一下。
文章的主要内容:

  1. 提供批量生成及下载二维码图片的php代码(对accessToken做了本地保存处理,不会出现请求次数饱和的现象)
  2. 制作二维码过程中需要注意的小细节

在微信公众平台上如何使用高级接口开发生成带参数二维码的功能,网上有很多相关教程。可以参考微信官方文档_生成带参数的二维码 和方倍老师的博客 微信公众平台开发(83) 生成带参数二维码 来了解制作的原理和流程。
获取ticket流程图

Talk is cheap , show you the code now:

  1. 执行方法:
    /**
     * 参数说明:
     * type:二维码类型  1:永久 2:临时
     * from:二维码所带参数开始值
     * to :二维码所带参数结束值
     */
    public function creat_qrcode_image() {
        $scene_type = $_REQUEST ['type'];
        switch($scene_type)
        {
            case '1': //永久
                $data = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": '.$scene_id.'}}}';
                break;
            case '2': //临时
                $data = '{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": '.$scene_id.'}}}';
                break;
            default:
                $data = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": '.$scene_id.'}}}';
                break;
        }
        $access_token = $this->getAccessToken();
        for($scene_id = 101; $scene_id <= 120; $scene_id ++) {
            $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" . $access_token;
            $res = $this->https_request ( $url, $data );
            $result = json_decode ( $res, true );
            $ret [$scene_id] = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" . urlencode ( $result ["ticket"] );
            $imageInfo = $this->downloadQrImage ( $ret [$scene_id] );
            // 写入,生成图片
            $filename = ROOT . "/Files/Wechat/qrcode_".$scene_id.".jpg";
            $local_file = fopen ( $filename, 'w' );
            if (false !== $local_file) {
                if (false !== fwrite ( $local_file, $imageInfo ["body"] )) {
                    fclose ( $local_file );
                }
            }
        }
    }

2 . 获取accessToken (需填入你的appId 和 appSecret)

public function getAccessToken() {
        $appId='等你来填';
        $appSecret='等你来填';
        $filename='access_token.json';
        $data = json_decode(file_get_contents(ROOT ."/Files/Wechat/".$filename));
        if ($data->expire_time < time()) {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appId&secret=$appSecret";
            $res = json_decode($this->https_request($url));
            $access_token = $res->access_token;
            if ($access_token) {
                $data->expire_time = time() + 7000;
                $data->access_token = $access_token;
                $fp = fopen(ROOT ."/Files/Wechat/".$filename, "w");
                fwrite($fp, json_encode($data));
                fclose($fp);
            }
        } else {
            $access_token = $data->access_token;
        }
        return $access_token;
    }

使用说明:

1.在getAccessToken()方法中填入你的appId 和 appSecret。

2.执行creat_qrcode_image()方法。

eg. 地址栏输入 http://www.abcd.com/creat_qrcode_image?type=1&from=100&to=120
二维码图片会自动保存在你设置的目录下。

    值得注意的是,scene_id不能改成其他键名,如m_id等,否则生成的二维码被扫描后,得到$object->EventKey就是qrscene_0
    scene_id只能为**数字**,出现字母则结果为0
    "scene_id":0001  ,得到的结果为qrscene_1

这里提供一个实用的封装过的echo()方法:

function e(){
        echo "<pre>";
        $objs = func_get_args();
        foreach($objs as $obj) {print_r($obj);echo "<br>";}
        echo "</pre>";
    }

function _e(){
    echo "<pre>";
    $objs = func_get_args();
    foreach($objs as $obj) {print_r($obj);echo "<br>";}
    echo "</pre>";
    exit;
}

使用方法:e ($ret); _e($ret);
这两个对象输出方法可以自动按格式输出string、array、object等类型的对象。
e()方法只做打印输出操作。_e()方法的在打印输出操作后停止执行该方法。


2018-08-27 23:40:33 qq_37968920 阅读数 141
  • 微信公众号生成带参数二维码一学就会Java版

    为了满足用户渠道推广分析和用户帐号绑定等场景的需要,也就是推广和微商城分销的一个知识点,当你需要知道你的这个客户是谁推广的时候,当你为你的商城设计了分销的模式的时候,你就会发现这个知识点很好用

    3667 人正在学习 去看看 朱祚华

4.6.2 创建二维码ticket

输出结果如下:
这里写图片描述

qrcode.php 如图所示代码如下

<?php

    $appid = "wxd1fc65357aca6efa";
    $appsecret = "55a5a3a73b3f1603240a1c27cb0b270f";
    $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    $jsoninfo = json_decode($output, true);
    $access_token = $jsoninfo["access_token"]; //获取access_token

    //临时
    $qrcode = '{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 10000}}}';
    //永久
    //$qrcode = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 1000}}}';

    $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$access_token";
    $result = https_request($url,$qrcode);
    $jsoninfo = json_decode($result, true);
    $ticket = $jsoninfo["ticket"];
    echo $ticket;

    function https_request($url, $data = null){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }


?>

4.6.3 通过ticket换取二维码

换取二维码请求接口https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET

注意:TICKET必须是UrlEncode

ticket正确的情况下,http返回码是200,一张图片,可以直接展示或者下载。

获取代码如下:
这里写图片描述


    $appid = "wxd1fc65357aca6efa";
    $appsecret = "55a5a3a73b3f1603240a1c27cb0b270f";
    $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    $jsoninfo = json_decode($output, true);
    $access_token = $jsoninfo["access_token"]; //获取access_token

    //临时
    //$qrcode = '{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 10000}}}';
    //永久
    $qrcode = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 7000}}}';

    $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$access_token";
    $result = https_request($url,$qrcode);
    $jsoninfo = json_decode($result, true);
    $ticket = $jsoninfo["ticket"];
    //echo $ticket;

    function https_request($url, $data = null){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }


   // $ticket = "gQHi8DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0UweTNxNi1sdlA3RklyRnNKbUFvAAIELdnUUgMEAAAAAA==";

    $url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".urlencode($ticket);
    //$imageInfo = downloadWeixinFile($url);
    echo $url;
?>

4.6.4 下载二维码

  • 二维码生成后,可以在浏览器中右击另存为本地图片,但如果有很多二维码的时候,用程序来下载就比较方便

  • 我们使用CURL获取图片的所有信息,并将图片保存为一个文件。

一个完整的下载代码如下:

在程序的当前目录就会生成一个包含二维码的图片文件

<?php

    $appid = "wxd1fc65357aca6efa";
    $appsecret = "55a5a3a73b3f1603240a1c27cb0b270f";
    $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    $jsoninfo = json_decode($output, true);
    $access_token = $jsoninfo["access_token"]; //获取access_token

    //临时
    $qrcode = '{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 10000}}}';
    //永久
    //$qrcode = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 1000}}}';

    $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$access_token";
    $result = https_request($url,$qrcode);
    $jsoninfo = json_decode($result, true);
    $ticket = $jsoninfo["ticket"];
    //echo $ticket;

    function https_request($url, $data = null){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }


   // $ticket = "gQHi8DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0UweTNxNi1sdlA3RklyRnNKbUFvAAIELdnUUgMEAAAAAA==";

    $url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".urlencode($ticket);
    $imageInfo = downloadWeixinFile($url);
    echo $url;
    //var_dump($imageInfo["body"]);

    $filename = "qrcode.jpg";
    $local_file = fopen($filename, "w");
    if (false !== $local_file){
        if (false !== fwrite($local_file, $imageInfo["body"])) {
            fclose($local_file);
        }
    }


    function downloadWeixinFile($url)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);    
        curl_setopt($ch, CURLOPT_NOBODY, 0);    //只取body头
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $package = curl_exec($ch);
        $httpinfo = curl_getinfo($ch);
        curl_close($ch);
        return array_merge(array('body' => $package), array('header' => $httpinfo)); 
    }


?>

4.6.5 扫描带参数二维码事件

  • 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
  • 如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者。

这里写图片描述
1. 用户未关注时,进行关注后的事件推送

<xml>
    <ToUserName>
        < ![CDATA[toUser] ]>
    </ToUserName>
    <FromUserName>
        < ![CDATA[FromUser] ]>
    </FromUserName>
    <CreateTime>123456789</CreateTime>
    <MsgType>
        < ![CDATA[event] ]>
    </MsgType>
    <Event>
        < ![CDATA[subscribe] ]>
    </Event>
    <EventKey>
        < ![CDATA[qrscene_123123] ]>
    </EventKey>
    <Ticket>
        < ![CDATA[TICKET] ]>
    </Ticket>
</xml>

这里写图片描述

2. 用户已关注时的事件推送

<xml>
    <ToUserName>
        < ![CDATA[toUser] ]>
    </ToUserName>
    <FromUserName>
        < ![CDATA[FromUser] ]>
    </FromUserName>
    <CreateTime>123456789</CreateTime>
    <MsgType>
        < ![CDATA[event] ]>
    </MsgType>
    <Event>
        < ![CDATA[SCAN] ]>
    </Event>
    <EventKey>
        < ![CDATA[SCENE_VALUE] ]>
    </EventKey>
    <Ticket>
        < ![CDATA[TICKET] ]>
    </Ticket>
</xml>

这里写图片描述

代码如下所示:

<?php
//
// 关注/取消关注事件消息
// 微信公众账号关注与取消关注事件消息
//

define("TOKEN", "weixin");

$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
    $wechatObj->responseMsg();
}else{
    $wechatObj->valid();
}

class wechatCallbackapiTest
{
    public function valid()
    {
        $echoStr = $_GET["echostr"];
        if($this->checkSignature()){
            echo $echoStr;
            exit;
        }
    }

    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;
        }
    }

    public function responseMsg()
    {
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        if (!empty($postStr)){
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $RX_TYPE = trim($postObj->MsgType);

            switch ($RX_TYPE)
            {
                case "event":
                    $result = $this->receiveEvent($postObj);
                    break;
            }
            echo $result;
        }else {
            echo "";
            exit;
        }
    }

    private function receiveEvent($object)
    {
        $contentStr = "";
        switch ($object->Event)
        {
            case "subscribe":
                $contentStr = "欢迎关注 ";
                if (isset($object->EventKey)){
                    $contentStr .= "\n来自二维码场景 ".$object->EventKey;
                }
                break;
            case "SCAN":
                $contentStr = "扫描二维码场景 ".$object->EventKey;
                break;
            default:
                break;      

        }
        $resultStr = $this->transmitText($object, $contentStr);
        return $resultStr;
    }

    private function transmitText($object, $content)
    {
        $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[text]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                    </xml>";
        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
        return $result;
    }
}
?>
2019-05-24 18:01:49 weixin_42720002 阅读数 341
  • 微信公众号生成带参数二维码一学就会Java版

    为了满足用户渠道推广分析和用户帐号绑定等场景的需要,也就是推广和微商城分销的一个知识点,当你需要知道你的这个客户是谁推广的时候,当你为你的商城设计了分销的模式的时候,你就会发现这个知识点很好用

    3667 人正在学习 去看看 朱祚华

前面已经搞好了微信服务器配置,和生成了带参二维码,现在就是微信扫码事件的实现,未关注的先关注在推送,关注过公众号的直接推送。
之前也是在配置好的微信服务器,下面的扫码事件也要写那个方法里,这样才可以和微信服务器 “交流” 推送消息。
下面是代码

@Controller
@RequestMapping(value = "/vatToken")
public class VatifyToken {
	@ResponseBody
    @RequestMapping(method = RequestMethod.POST)
    public String toVatifyTokenPost(HttpServletRequest request, HttpServletResponse response, ModelMap map) {
        String returnXml = "";
        String respMessage= "";
        try {
            String xmlData = null;
            try {
                xmlData = StreamUtils.copyToString(request.getInputStream(), Charset.forName("utf-8"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            Map<String, String> mapData = XMLConverUtil.convertToMap(xmlData);
            String event = mapData.get("Event");
            // 发送方帐号(open_id)
            String fromUserName = mapData.get("FromUserName");
            // 公众帐号
            String toUserName = mapData.get("ToUserName");
            if ("event".equals(msgType)) { // 事件消息
                // 区分事件推送
                String event = mapData.get("Event");
                System.out.println("****区分事件推送****"+event);
                if ("subscribe".equals(event)) { // 订阅事件 或 未关注扫描二维码事件
                    List<Article> articleList = new ArrayList<Article>();
                    NewsMessage newsMessage = new NewsMessage();
                    newsMessage.setToUserName(fromUserName);
                    newsMessage.setFromUserName(toUserName);
                    newsMessage.setCreateTime(new Date().getTime());
                    newsMessage.setMsgType("news");
                    newsMessage.setFuncFlag(0);

                    Article article1 = new Article();
                    article1.setTitle("我是一条多图文消息");
                    article1.setDescription("");
                    article1.setPicUrl("http://pic37.nipic.com/20140113/8800276_184927469000_2.png");
                    article1.setUrl("https://www.baidu.com/");

                    Article article2 = new Article();
                    article2.setTitle("微信公众平台开发教程Java版(二)接口配置 ");
                    article2.setDescription("");
                    article2.setPicUrl("https://www.baidu.com/img/bd_logo1.png?where=super");
                    article2.setUrl("http://tuposky.iteye.com/blog/2008655");

                    /*Article article3 = new Article();
                    article3.setTitle("微信公众平台开发教程Java版(三) 消息接收和发送");
                    article3.setDescription("");
                    article3.setPicUrl("https://www.baidu.com/img/bd_logo1.png?where=super");
                    article3.setUrl("http://tuposky.iteye.com/blog/2017429");*/

                    articleList.add(article1);
                    articleList.add(article2);
                    //articleList.add(article3);
                    newsMessage.setArticleCount(articleList.size());
                    newsMessage.setArticles(articleList);
                    respMessage=MessageUtil.newsMessageToXml(newsMessage);

                } else if ("SCAN".equals(event)) { // 已关注扫描二维码事件
                    List<Article> articleList = new ArrayList<Article>();
                    NewsMessage newsMessage = new NewsMessage();
                    newsMessage.setToUserName(fromUserName);
                    newsMessage.setFromUserName(toUserName);
                    newsMessage.setCreateTime(new Date().getTime());
                    newsMessage.setMsgType("news");
                    newsMessage.setFuncFlag(0);


                    Article article1 = new Article();
                    article1.setTitle("显示名称");
                    article1.setDescription("");
                    article1.setPicUrl("http://img5.imgtn.bdimg.com/it/u=3300305952,1328708913&fm=26&gp=0.jpg");
                    article1.setUrl("http://tuposky.iteye.com/blog/2008583");

                    Article article2 = new Article();
                    article2.setTitle("这里是测试 ");
                    article2.setDescription("");
                    article2.setPicUrl("http://img5.imgtn.bdimg.com/it/u=1337727530,4187567521&fm=26&gp=0.jpg");
                    article2.setUrl("http://tuposky.iteye.com/blog/2008655");

                    Article article3 = new Article();
                    article3.setTitle("这里是测试1");
                    article3.setDescription("");
                    article3.setPicUrl("https://www.baidu.com/img/bd_logo1.png?where=super");
                    article3.setUrl("http://tuposky.iteye.com/blog/2017429");

                    articleList.add(article1);
                    articleList.add(article2);
                    articleList.add(article3);
                    newsMessage.setArticleCount(articleList.size());
                    newsMessage.setArticles(articleList);

                    respMessage=MessageUtil.newsMessageToXml(newsMessage);
                    System.out.println("---------------xml------"+respMessage);

                } else if ("LOCATION".equals(event)) { // 上报地理位置事件
                    // todo 处理上报地理位置事件
                } else if ("CLICK".equals(event)) { // 点击菜单拉取消息时的事件推送事件
                    // todo 处理点击菜单拉取消息时的事件推送事件
                } else if ("VIEW".equals(event)) { // 点击菜单跳转链接时的事件推送
                    // todo 处理点击菜单跳转链接时的事件推送
                }
            }
        }catch (Exception e){
          LOG.info("接收事件推送:"+e.toString());
        }
        return "";
    }
}

下面是封装的方法

public static String copyToString(InputStream in, Charset charset) throws IOException {
		StringBuilder out = new StringBuilder();
		InputStreamReader reader = new InputStreamReader(in, charset);
		char[] buffer = new char[BUFFER_SIZE];
		int bytesRead = -1;
		while ((bytesRead = reader.read(buffer)) != -1) {
			out.append(buffer, 0, bytesRead);
		}
		return out.toString();
	}

XML转map

public static Map<String,String> convertToMap(String xml){
		Map<String, String> map = new LinkedHashMap<String,String>();
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			StringReader sr = new StringReader(xml);
			InputSource is = new InputSource(sr);
			Document document = db.parse(is);

			Element root = document.getDocumentElement();
			if(root != null){
				NodeList childNodes = root.getChildNodes();
				if(childNodes != null && childNodes.getLength()>0){
					for(int i = 0;i < childNodes.getLength();i++){
						Node node = childNodes.item(i); 
						if( node != null && node.getNodeType() == Node.ELEMENT_NODE){
							map.put(node.getNodeName(), node.getTextContent());
						}
					}
				}
			}
		} catch (DOMException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return map;
	}

图文消息实体类 Article

package com.wechat.model.wxMsgRes;

/**
 * 图文消息
 *
 */
public class Article {
    /**
     * 图文消息名称
     */
    private String Title;

    /**
     * 图文消息描述
     */
    private String Description;

    /**
     * 图片链接,支持JPG、PNG格式,<br>
     * 较好的效果为大图640*320,小图80*80
     */
    private String PicUrl;

    /**
     * 点击图文消息跳转链接
     */
    private String Url;

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getDescription() {
        return null == Description ? "" : Description;
    }

    public void setDescription(String description) {
        Description = description;
    }

    public String getPicUrl() {
        return null == PicUrl ? "" : PicUrl;
    }

    public void setPicUrl(String picUrl) {
        PicUrl = picUrl;
    }

    public String getUrl() {
        return null == Url ? "" : Url;
    }

    public void setUrl(String url) {
        Url = url;
    }
}

封装多个图文消息 NewsMessage

package com.wechat.model.wxMsgRes;
import java.util.List;

/**
 * 多图文消息,
 * 单图文的时候 Articles 只放一个就行了
 */
public class NewsMessage extends BaseMessage {
    /**
     * 图文消息个数,限制为10条以内
     */
    private int ArticleCount;
    /**
     * 多条图文消息信息,默认第一个item为大图
     */
    private List<Article> Articles;

    public int getArticleCount() {
        return ArticleCount;
    }

    public void setArticleCount(int articleCount) {
        ArticleCount = articleCount;
    }

    public List<Article> getArticles() {
        return Articles;
    }

    public void setArticles(List<Article> articles) {
        Articles = articles;
    }
}

BaseMessage

package com.wechat.model.wxMsgRes;

/**
 * 消息基类(公众帐号 -> 用户)
 */
public class BaseMessage {
    /**
     * 接收方帐号(收到的OpenID)
     */
    private String ToUserName;
    /**
     * 开发者微信号
     */
    private String FromUserName;
    /**
     * 消息创建时间 (整型)
     */
    private long CreateTime;

    /**
     * 消息类型
     */
    private String MsgType;

    /**
     * 位0x0001被标志时,星标刚收到的消息
     */
    private int FuncFlag;

    public String getToUserName() {
        return ToUserName;
    }

    public void setToUserName(String toUserName) {
        ToUserName = toUserName;
    }

    public String getFromUserName() {
        return FromUserName;
    }

    public void setFromUserName(String fromUserName) {
        FromUserName = fromUserName;
    }

    public long getCreateTime() {
        return CreateTime;
    }

    public void setCreateTime(long createTime) {
        CreateTime = createTime;
    }

    public String getMsgType() {
        return MsgType;
    }

    public void setMsgType(String msgType) {
        MsgType = msgType;
    }

    public int getFuncFlag() {
        return FuncFlag;
    }

    public void setFuncFlag(int funcFlag) {
        FuncFlag = funcFlag;
    }
}

图文消息对象转换成xml

/**
     * 图文消息对象转换成xml
     *
     * @param newsMessage 图文消息对象
     * @return xml
     */
    public static String newsMessageToXml(NewsMessage newsMessage) {
        xstream.alias("xml", newsMessage.getClass());
        xstream.alias("item", new Article().getClass());
        return xstream.toXML(newsMessage);
    }

这样的话应该就可以接收到推送的消息了。

博文 来自: p5866280
没有更多推荐了,返回首页