2016-10-09 17:18:01 qq342063618 阅读数 864
  • 自己开发一套微信支付接口(SDK)-微信开发15(PHP)

    会员免费看,http://edu.csdn.net/lecturer/842 边栏可办理会员卡。自己开发一套微信支付接口(SDK)是子恒老师《子恒说微信开发》视频教程的第15部。详细讲解了用php开发一套自己的微信支付接口。内容包含微信支付开发思路,基础类开发,微信支付接口应用,公众号发红包,企业付款等等。欢迎反馈,微信号:QQ68183131

    5396 人正在学习 去看看 秦子恒

话说这个https真是搞了我半个多月,今天终于搞定了,本来不熟悉https现在都知道一二了

https协议,在http基础上多了层加密协议ssl,一般单向认证(浏览器直接请求https网站),和双向认证(使用U盾通过https访问银行)

但微信服务器是不会管你第三方服务器的证书的!也就是不会跟你要公钥!所以直接自生成一个就可以了!

有一点要注意的是,最好先实现微信的消息加密登其他业务逻辑,最后再来配置https

1.用jdk/bin下的keytool

keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "f:\tomcat.keystore"

2.tomcat/conf下的server.xml

<Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" keystoreFile="f:\tomcat.keystore" keystorePass="
password" />

2019-12-20 16:40:51 u013255337 阅读数 23
  • 自己开发一套微信支付接口(SDK)-微信开发15(PHP)

    会员免费看,http://edu.csdn.net/lecturer/842 边栏可办理会员卡。自己开发一套微信支付接口(SDK)是子恒老师《子恒说微信开发》视频教程的第15部。详细讲解了用php开发一套自己的微信支付接口。内容包含微信支付开发思路,基础类开发,微信支付接口应用,公众号发红包,企业付款等等。欢迎反馈,微信号:QQ68183131

    5396 人正在学习 去看看 秦子恒

1、网页授权:(参阅:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

  • 登陆公众号,开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息 设置 授权回调域名(请勿加 http:// 等协议头),假设为www.test.com

注意:这里额外需要传一个txt文件到域名对应的服务器上(微信的安全考虑)

  • 微信访问以下地址:(以下仅APPID需替换公众号的APPID),目的是获取code以换取token

 

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=https://www.test.com&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
  • 第2步成功后,页面会自动跳转到以下地址,这就开始进入具体的业务页面了。

 

https://www.test.com/?code=CODE&state=STATE

注意:如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE

  • 在业务代码中,用JS获取code参数,然后访问以下地址:

 

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

成功后的返回数据如下:(主要是拿access_token和openid字段)

 

{ 
    "access_token":"ACCESS_TOKEN",
    "expires_in":7200,
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID",
    "scope":"SCOPE" 
}
  • 用access_token和openid字段访问以下地址:

 

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

返回值如下:

 

{   
    "openid":" OPENID",
    " nickname": NICKNAME,
    "sex":"1",  //男
    "province":"PROVINCE"
    "city":"CITY",
    "country":"COUNTRY",
    "headimgurl":    "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
    "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

2、JS-SDK接入步骤:

  • 绑定域名

登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

注意:1、至多绑定3个域名,一个月内只能改3次;2、需要分别传一个txt文件(可直接下载)到域名对应的服务器上

  • 业务代码中引入以下脚本:

 

http://res.wx.qq.com/open/js/jweixin-1.2.0.js

3、业务代码中用config接口注入权限验证配置

 

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名
    jsApiList: [] // 必填,需要使用的JS接口列表
});

4、通过ready接口处理成功验证

 

wx.ready(function(){
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});

5、通过error接口处理失败验证

 

wx.error(function(res){
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});

以下主要说说第3步的配置问题,这里需要服务端和前端共同参与。

  • 服务端(提供获取token和ticket的接口,前端也可以自己做,但是会暴露secret信息,不安全)

 

    //access_token是公众号的全局唯一票据

    public function getTokenForJS() {
        $appid = "不告诉你";
        $secret = "不告诉你";
        $url = "https://api.weixin.qq.com/cgi-bin/token?appid=".$appid."&secret=".$secret."&grant_type=client_credential";
        $result = http_request($url);
        echo $result;exit;
    }
    
    //获取ticket
    public function getTicket(){
        $access_token = I("get.access_token");
        $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".$access_token."&type=jsapi";
        //$this->ajaxJSON($url);
        $result = http_request($url);
        echo $result;exit;
    }
    
    function http_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);
        $info = curl_exec($curl);
        curl_close($curl);
        return $info;
    }

token获取

 

ticket获取

  • 前端

 

function setWechatJS() {
    //wx配置参数
    var jsapi_ticket = $.cookie('jsapi_ticket');
    var wxConfig = function () {
        //获取当前url,不含#以及之后的部分
        var timestamp = new Date().getTime();  //生成签名的时间戳(当前时间)
        var noncestr = randomString(20);
        var signature = '';       //签名
        var url = window.location.href;
        var index = url.indexOf('#');
        if(index !== -1 ) {
            url = url.slice(0,index);
        }
        var temp = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;
        var signature = hex_sha1(temp);
        console.log("signature="+signature);
        wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: 'wx0875a197e0e5bcd7', // 必填,公众号的唯一标识
            timestamp: timestamp, // 必填,生成签名的时间戳
            nonceStr: noncestr, // 必填,生成签名的随机串
            signature: signature,// 必填,签名,见附录1
            jsApiList: [
                'checkJsApi',
                'onMenuShareTimeline',
                'onMenuShareAppMessage',
                'onMenuShareQQ',
                'onMenuShareWeibo',
                'onMenuShareQZone'
            ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
        });

        wx.ready(function () {
            //配置成功之后回调
            console.log("微信JS SDK配置成功!");   
        });
        wx.error(function(res){
            console.log("微信JS SDK配置错误!");
            // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
        });
    };

    //待分享生成的标题、链接、缩略图
    var title,url,imgUrl,description;
    //本地cookie查找不到缓存再去请求网络
    if(typeof (jsapi_ticket) == 'undefined' || jsapi_ticket == ''){
        //alert('aaa='+jsapi_ticket);
        //以下步骤分别获取全局access_token、jsapi_ticket、signature
        $.get(MyUrl+"getTokenForJS",function (data) {
            var access_token = data['access_token'];
            //获取全局access_token,以及7200秒之后刷新的问题
            //先出cookie中取,如果没有,
            $.get(MyUrl+"getTicket?access_token="+access_token,function(data){
                jsapi_ticket = data['ticket'];
                //保存当前jsapi_ticket
                var date = new Date();
                date.setTime(date.getTime()+7200*1000);//只能这么写,10表示10秒钟
                //?替换成分钟数如果为60分钟则为 60 * 60 *1000
                $.cookie('jsapi_ticket',jsapi_ticket,{expires:date,path:'/'}); //有效期7200秒
                wxConfig();
            },'json');

        },'json');
    }else {
        //alert('bbb='+jsapi_ticket);
        wxConfig();
    }
}


// 以下是辅助函数:
//1、生成随机字符串
var randomString = function(len) {
    len = len || 32;
    var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';    /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
    var maxPos = $chars.length;
    var pwd = '';
    for (var i = 0; i < len; i++) {
        pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
};
// 2、hex_sha1的定义(用第三方模块:[https://github.com/Caligatio/jsSHA](https://github.com/Caligatio/jsSHA))

 

2016-03-24 18:42:05 lamboo_cn 阅读数 11475
  • 自己开发一套微信支付接口(SDK)-微信开发15(PHP)

    会员免费看,http://edu.csdn.net/lecturer/842 边栏可办理会员卡。自己开发一套微信支付接口(SDK)是子恒老师《子恒说微信开发》视频教程的第15部。详细讲解了用php开发一套自己的微信支付接口。内容包含微信支付开发思路,基础类开发,微信支付接口应用,公众号发红包,企业付款等等。欢迎反馈,微信号:QQ68183131

    5396 人正在学习 去看看 秦子恒
  如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。

1. 授权回调域名的说明:
(1)、这里填写的是域名(是一个字符串),而不是URL,因此请勿加http://等协议头;
(2)、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com;
(3)、如果公众号登录授权给了第三方开发者来进行管理,则不必做任何设置,由第三方代替公众号实现网页授权即可

  1. 关于网页授权的两种scope的区别说明:
    (1)、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面);
    (2)、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

  2. 网页授权access_token和普通access_token的区别:
    (1)、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;
    (2)、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用;

  3. 网页授权流程分为三步:
    (1)、第一步:用户同意授权,获取code,

 String appId="微信公众号的APPID";
 String url="微信回调的URL";
 String redirect_uri=URLEncoder.encode(url,"utf-8");
 String state="重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 ";//带这个参数的好处就是防止非法的请求。
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?";
        url = url + "appid=" + this.wxMpConfigStorage.getAppId();
        url = url + "&redirect_uri=" + URIUtil.encodeURIComponent(redirectURI);
        url = url + "&response_type=code";
        url = url + "&scope=" + scope;
        if (state != null) {
            url = url + "&state=" + state;
        }
        url = url + "#wechat_redirect";//进行URL的拼接
response.sendRedirect(url);//调用http请求的,进行微信授权

(2)、第二步:通过code换取网页授权access_token:

//这段代码在你回调的指定的url的Servlet或者action:
String code = request.getParameter("code");
loggerWx.info("code=" + code.toString());
String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid="微信公众号的APPID"&secret="微信公众号的secret"&code=CODE&grant_type=authorization_code";//url的拼接
String wxMpOAuth2AccessToken=httpclient.post(url);//进行网络请求

(3)、第三步:拉取用户信息(需scope为 snsapi_userinfo):

String url="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";//url的拼接
String wx_User_string=httpclient.post(url);//进行网络请求

最后寄语,有什么问题可以沟通,其实微信的官方文档解释的挺全面的,官方文档的网址:http://mp.weixin.qq.com/wiki/1/8a5ce6257f1d3b2afb20f83e72b72ce9.html

2018-10-22 10:44:25 qq_37392757 阅读数 633
  • 自己开发一套微信支付接口(SDK)-微信开发15(PHP)

    会员免费看,http://edu.csdn.net/lecturer/842 边栏可办理会员卡。自己开发一套微信支付接口(SDK)是子恒老师《子恒说微信开发》视频教程的第15部。详细讲解了用php开发一套自己的微信支付接口。内容包含微信支付开发思路,基础类开发,微信支付接口应用,公众号发红包,企业付款等等。欢迎反馈,微信号:QQ68183131

    5396 人正在学习 去看看 秦子恒

 

接入过程

首先,如果你没有企业微信的话,需要在企业微信官网注册一个企业。

自建应用详情页,点击“接收消息”的“设置API接收”按钮,进入配置页面。

按要求填写应用的URL、Token以及EncodingAESKey:

  • URL 是企业后台接收企业微信推送请求的访问协议和地址,支持http或https协议
  • Token 可由企业任意填写,用于生成签名
  • EncodingAESKey 用于消息体的加密,是AES密钥的Base64编码

随后记录这些参数,将其填写到 config.js 的对应字段。

初始化node项目

在命令行窗口执行以下命令:

git clone https://github.com/evinvie/weworkapi_nodejs.git wework_server
cd wework_server
npm install

随后可在 app.js 中更改项目的路由配置。以应用配置URL为 http://api.3dept.com/wechat/qy/ 为例,app.js 中的代码为:

var wechatRouter= require('./routes/wechat')

app.use('/wechat/qy', wechatRouter)

项目主要逻辑封装在 routes/wechat.js,我们可以根据实际场景修改其中逻辑。

项目配置完成后,我们可以使用以下命令运行server:

npm start

在设置API接收页面点击保存,回调完成,此时在应用中发送一条文本消息,应用会回复 你好,同学!

其他代码逻辑,根据业务需求,修改对应的函数或模块。

侵删!

GitHub地址:https://github.com/evinvie/weworkapi_nodejs

项目目录结构

.
├── bin           -- express的配置,可修改对应的端口以及启动信息
├── node_modules  -- nodejs模块
├── public        -- 静态资源文件
├── routes        -- 路由
├── views         -- 视图
├── app.js        -- 应用核心配置文件
├── package.json  -- 相关nodejs模板以及作者信息
└── config.js     -- 项目依赖配置及开发者信息
2016-05-13 15:36:56 qq877507054 阅读数 5097
  • 自己开发一套微信支付接口(SDK)-微信开发15(PHP)

    会员免费看,http://edu.csdn.net/lecturer/842 边栏可办理会员卡。自己开发一套微信支付接口(SDK)是子恒老师《子恒说微信开发》视频教程的第15部。详细讲解了用php开发一套自己的微信支付接口。内容包含微信支付开发思路,基础类开发,微信支付接口应用,公众号发红包,企业付款等等。欢迎反馈,微信号:QQ68183131

    5396 人正在学习 去看看 秦子恒
连接将使你的企业号更具价值,你可以使用以下三种方式,连接你的企业号及企业应用:

1、企业应用调用企业号提供的接口,管理或查询企业号后台所管理的资源、或给成员发送消息等,以下称主动调用模式

2、企业号把用户发送的消息或用户触发的事件推送给企业应用,由企业应用处理,以下称回调模式

3、用户在微信中阅读企业应用下发的H5页面,该页面可以调用微信提供的原生接口,使用微信开放的终端能力,以下称JSAPI模式

通过这三种连接方式的结合,你可以在企业号中建立功能强大的移动轻应用,并依托微信数亿活跃用户,帮助企业方便、快捷地实现应用的部署,并确保应用的活跃度。

一、主动调用

1、简述

主动调用是最基本的连接模式,当你的应用调用企业号时,需使用https协议、Json数据格式、UTF8编码,访问域名为https://qyapi.weixin.qq.com,数据包不需要加密

在每次主动调用企业号接口时需要带上AccessToken参数。AccessToken参数由CorpIDSecret换取。

CorpID是企业号的标识,每个企业号拥有一个唯一的CorpID;Secret是管理组凭证密钥。

系统管理员可通过管理端的权限管理功能创建管理组,分配管理组对应用、通讯录、接口的访问权限。完成后,管理组即可获得唯一的secret。系统管理员可通过权限管理查看所有管理组的secret,其他管理员可通过设置中的开发者凭据查看。

当企业应用调用企业号接口时,企业号后台为根据此次访问的AccessToken,校验访问的合法性以及所对应的管理组的管理权限以返回相应的结果。

注:你应该审慎配置管理组的权限,够用即好,权限过大会增加误操作可能性及信息安全隐患。

2、获取AccessToken

AccessToken是企业号的全局唯一票据,调用接口时需携带AccessToken。

AccessToken需要用CorpIDSecret来换取,不同的Secret会返回不同的AccessToken。正 常情况下AccessToken有效期为7200秒,有效期内重复获取返回相同结果,并自动续期。由于获取access_token的api调用次数非常 有限,建议企业全局存储与更新access_token,频繁刷新access_token会导致api调用受限,影响自身业务

  • 请求说明

Https请求方式: GET

https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=id&corpsecret=secrect

  • 参数说明
参数必须说明
corpid 企业Id
corpsecret 管理组的凭证密钥
  • 权限说明

每个secret代表了对应用、通讯录、接口的不同权限;不同的管理组拥有不同的secret。

  • 返回说明

a)正确的Json返回结果:

  1.    "access_token": "accesstoken000001", 
参数说明
access_token 获取到的凭证

b)错误的Json返回示例:

  1.    "errcode": 43003, 
  2.    "errmsg": "require https" 

3、主动调用的频率限制

当你获取到AccessToken时,你的应用就可以成功调用企业号后台所提供的各种接口以管理或访问企业号后台的资源或给企业号成员发消息。

为了防止企业应用的程序错误而引发企业号服务器负载异常,默认情况下,每个企业号调用接口都有一定的频率限制,当超过此限制时,调用对应接口会收到相应错误码。

以下是当前默认的频率限制,企业号后台可能会根据运营情况调整此阈值:

  • 基础频率

每企业调用单个cgi/api不可超过1000次/分,30000次/小时

每ip调用单个cgi/api不可超过2000次/分,60000次/小时

每ip获取AccessToken不可超过300次/小时

  • 发消息频率

每企业不可超过200次/分钟;不可超过帐号上限数*30人次/天

  • 创建帐号频率

每企业创建帐号数不可超过帐号上限数*3/月

 

二、回调模式

官方解释

1开启应用的回调模式

  在回调模式下,企业不仅可以主动调用企业号接口,还可以接收用户的消息或事件。接收的信息使用XML数据格式、UTF8编码,并以AES方式加密.

  企业号的每个应用都有自己的回调模式开关。在管理端开启并设置好相关参数后,此应用的回调模式才生效。

  针对加解密的处理,微信提供了各种语言的库,企业可以在附录中下载。

  当你开启应用的回调模式时,企业号会要求你填写应用的URL、Token、EncodingAESKey三个参数。

  URL是企业应用接收企业号推送请求的访问协议和地址,支持http或https协议。

  Token可由企业任意填写,用于生成签名。

  EncodingAESKey用于消息体的加密,是AES密钥的Base64编码。

  验证URL、Token以及加密的详细处理请参考后续'接收消息时的加解密处理'的部分。

验证URL有效性

当你提交以上信息时,企业号将发送GET请求到填写的URL上,GET请求携带四个参数,企业在获取时需要做urldecode处理,否则会验证不成功

参数描述是否必带
msg_signature 微信加密签名,msg_signature结合了企业填写的token、请求中的timestamp、nonce参数、加密的消息体
timestamp 时间戳
nonce 随机数
echostr 加密的随机字符串,以msg_encrypt格式提供。需要解密并返回echostr明文,解密后有random、msg_len、msg、$CorpID四个字段,其中msg即为echostr明文 首次校验时必带

企业通过参数msg_signature对请求进行校验,如果确认此次GET请求来自企业号,那么企业应用对echostr参数解密并原样返回echostr明文(不能加引号),则接入验证生效,回调模式才能开启。

后续回调企业时都会在请求URL中带上以上参数(echostr除外),校验方式与首次验证URL一致。

2、使用回调模式

企业号在回调企业URL时,会对消息体本身做AES加密,以XML格式POST到企业应用的URL上;企业在被动回复时,也需要对数据加密,以XML格式返回给微信。企业的回复支持文本、图片、语音、视频、图文等格式

微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。如果在调试中,发现员工无法收到响应的消息,可以检查是否消息处理超时。

关于重试的消息排重,有msgid的消息推荐使用msgid排重。事件类型消息推荐使用FromUserName + CreateTime排重。

假如企业无法保证在五秒内处理并回复,可以直接回复空串,企业号不会对此作任何处理,并且不会发起重试。这种情况下,可以使用发消息接口进行异步回复。

假设企业回调URL为http://api.3dept.com

  • 请求说明:

http://api.3dept.com/?msg_signature=ASDFQWEXZCVAQFASDFASDFSS&timestamp=13500001234&nonce=123412323

    • 回调数据格式:
  1. <xml>  
  2.    <ToUserName><![CDATA[toUser]]</ToUserName
  3.    <AgentID><![CDATA[toAgentID]]</AgentID
  4.    <Encrypt><![CDATA[msg_encrypt]]</Encrypt
  5. </xml
1.msg_encrypt为经过加密的密文
2.AgentID为接收的应用id,可在应用的设置页面获取
3.ToUserName为企业号的CorpID

企业需要对msg_signature进行校验,并解密msg_encrypt,得出msg的原文。

    • 回复给微信的数据格式:
  1. <xml
  2.    <Encrypt><![CDATA[msg_encrypt]]></Encrypt
  3.    <MsgSignature><![CDATA[msg_signature]]></MsgSignature
  4.    <TimeStamp>timestamp</TimeStamp
  5.    <Nonce><![CDATA[nonce]]></Nonce
  6. </xml

3、接收消息时的加解密处理

企业可以直接使用微信提供的库进行加解密的处理,目前提供的有c++/python/php/java/c#等语言版本。代码提供了解密、加密、验 证URL三个接口,企业可根据自身需要下载(参见附录)。以下为库函数的使用说明(以c++为例),更详细的加解密方案请参考附录。

1)解密函数

  1. int DecryptMsg(const string &sMsgSignature, const string &sTimeStamp, const string &sNonce, const string &sPostData, string &sMsg); 
  • 参数说明
参数必须说明
sMsgSignature 从回调URL中获取的msg_signature参数
sTimeStamp 从回调URL中获取的timestamp参数
sNonce 从回调URL中获取的nonce参数
sPostData 从回调URL中获取的整个post数据
sMsg 用于返回解密后的msg,以xml组织
  • 返回说明

请参阅附录加密部分。

2)加密函数

  1. int EncryptMsg(const string &sReplyMsg, const string &sTimeStamp, const string &sNonce, string &sEncryptMsg); 
  • 参数说明
参数必须说明
sReplyMsg 返回的消息体原文
sTimeStamp 时间戳,调用方生成
sNonce 随机数,调用方生成
sEncryptMsg 用于返回的密文,以xml组织
  • 返回说明

请参阅附录加密部分。

3)验证URL函数

  1. int VerifyURL(const string &sMsgSignature, const string &sTimeStamp, const string &sNonce, const string &sEchoStr, string &sReplyEchoStr); 
  • 参数说明
参数必须说明
sMsgSignature 从回调URL中获取的msg_signature参数
sTimeStamp 从回调URL中获取的timestamp参数
sNonce 从回调URL中获取的nonce参数
sEchoStr 从回调URL中获取的echostr参数。注意,此参数必须是urldecode后的值
sReplyEchoStr 解密后的echostr,用于回包。注意,必须原样返回,不要做加引号或其它处理
  • 返回说明

请参阅附录加密部分。

详细步骤

在配置上有几个注意的地方。

1、首要要有一个ICP备案的域名,一定要有ICP备案,后面需要;

2、EncodeAESKey不能随机生成,之前官网提供是不能使用的,目前不知道,EncodeAESKey生成规则是32位明文经过base64加密后,去掉“=”,形成的43位密钥;

3、替换JCE包,重启服务

4、JDK版本要大于等于1.6

5、回调模式和主动调用模式在消息发送上也有很大不同:

          A:回调模式下,被动发送的消息需要时xml格式并进行加密,加密规则是首先进行AES加密,然后进行base64加密。

          B:主动发送消息,格式为json格式,不需要加密,但需要token

6、回调模式接受到真正的消息内容之后,注意回复,空消息即可,否则微信会认为消息接受失败,会再次发送同一消息

7、在接受消息上,回调模式先通过配置的链接,以Get形式发送一个密文,我们需要在Get中解析密文,返回给微信,微信接受消息无误之后,才会以Post形式将加密的真正内容发送过来,

8、主动调用模式是企业号给员工发消息,回调模式则是员工向企业号发送消息,

消息通过第三方服务器处理,最后经过微信服务器把消息发送给用户

要开启企业号的回调模式,首先要进行URL验证,也就是说,你必须要有一个服务器,来保证在公网环境下能够访问你的这个URL,然后才能接着往下走。(如果没有服务器的话,建议使用BAE比较好)。


2. 创建一个web项目,(注意必须是Dynamic Web Project项目),然后创建一个servlet类,来处理企业号发送的请求,命名任意,代码如下:

Java code

package org.yhxz.weixin.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.qq.weixin.mp.aes.AesException;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;

/**
* 核心请求处理类
*/
public class CoreServlet extends HttpServlet {
private static final long serialVersionUID = 4440739483644821986L;
String sToken = "5XaQ8cG6x2pULd";//这个Token是随机生成,但是必须跟企业号上的相同
String sCorpID = "wx4edd47d3a6r4r991";//这里是你企业号的CorpID
String sEncodingAESKey = "jWmYm7qjusnxu65ZRjGtBxmz3KA1tkAj3ykkR6q2B2C";//这个EncodingAESKey是随机生成,但是必须跟企业号上的相同
/**
* 确认请求来自微信服务器
* @throws IOException
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
// 微信加密签名
String sVerifyMsgSig = request.getParameter("msg_signature");
// 时间戳
String sVerifyTimeStamp = request.getParameter("timestamp");
// 随机数
String sVerifyNonce = request.getParameter("nonce");
// 随机字符串
String sVerifyEchoStr = request.getParameter("echostr");
String sEchoStr; //需要返回的明文
PrintWriter out = response.getWriter();
WXBizMsgCrypt wxcpt;
try {
wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,sVerifyNonce, sVerifyEchoStr);
// 验证URL成功,将sEchoStr返回
out.print(sEchoStr);
} catch (AesException e1) {
e1.printStackTrace();
}
}

/**
* 处理微信服务器发来的消息
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO 消息的接收、处理、响应
}

}

联系QQ877507054索要完整版代码


 
3. 接下来就要导入官方的业务类了,然后将其导入到你的项目中。这个可以在官方文档上下载到(注意,虽然官方下载的实例代码中也有验证的代码,但是不建议使用哪个Sample.java,如果不信的可以试试看,反正我用这个是没通)
    下载地址是:
http://qydev.weixin.qq.com/java.zip,
请开发者使用jdk1.6或以上的版本。针对org.apache.commons.codec.binary.Base64,需要导入jar包commons-codec-1.9(或comm ons-codec-1.8等其他版本),我们有提供,官方下载地址:
http://commons.apache.org/proper/commons-codec/download_codec.cgi

4. 如果出现异常java.security.InvalidKeyException:illegal Key Size的解决方案:

在官方网站下载JCE无限制权限策略文件(JDK7的下载地址:

http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。如果安装了JRE,将两个jar文件放到%JRE_HOME% \lib\security目录下覆盖原来的文件,如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件。

5. 下来就是对web.xml文件的配置,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>coreServlet</servlet-name>
        <servlet-class>
            org.yhxz.course.servlet.CoreServlet
        </servlet-class>
    </servlet>
 
    <!-- url-pattern中配置的/coreServlet用于指定该Servlet的访问路径 -->
    <servlet-mapping>
        <servlet-name>coreServlet</servlet-name>
        <url-pattern>/coreServlet</url-pattern>
    </servlet-mapping>
 
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>



6. 然后将你的项目发布到服务器上,在浏览器中输入URL,如果在你的Tomcat的控制台上出现NullPointException异常,就说明没有问题(出现的原因是:请求的数据为空,这个你懂得)。
7. 接下来就在企业号后台上的操作了,开启回调模式,输入你的URL,随机生成token和EncodingAESKey,点击提交就可以验证通过,注意一定要代码中的和企业号上的token和EncodingAESKey是要一致的。

 

 

三、Weixin JS接口

Weixin JS接口是微信为你的H5应用提供开放原生能力的接口,你的应用可以利用这些接口使用更多的微信原生能力和微信的操控能力, 以使得你的应用有更强大的智能,更好的用户体验。

除了以下章节所描述的各类接口。拍照、上传图片、扫码、微信支付、地理位置上报等更多的接口已经或正在抓紧开放中,更多信息也请参考微信相关网站了解.

1、隐藏微信中网页右上角按钮

企业号在有需要时(如不需要用户分享某个页面),可在网页中通过JavaScript代码隐藏网页右上角按钮。

  • 接口调用代码(JavaScript)
  1. function onBridgeReady(){ 
  2.  WeixinJSBridge.call('hideOptionMenu'); 
  3.  
  4. if (typeof WeixinJSBridge == "undefined"){ 
  5.     if( document.addEventListener ){ 
  6.         document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); 
  7.     }else if (document.attachEvent){ 
  8.         document.attachEvent('WeixinJSBridgeReady', onBridgeReady);  
  9.         document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); 
  10.     } 
  11. }else{ 
  12.     onBridgeReady(); 
  • 返回说明

隐藏底部导航栏没有返回值。(需要显示请把hideOptionMenu换成showOptionMenu)

2、隐藏微信中网页底部导航栏

企业号在有需要时(如认为用户在该页面不会用到浏览器前进后退功能),可在网页中通过JavaScript代码隐藏网页底部导航栏。

  • 接口调用代码(JavaScript)
  1. function onBridgeReady(){ 
  2.    WeixinJSBridge.call('hideToolbar'); 
  3.  
  4. if (typeof WeixinJSBridge == "undefined"){ 
  5.     if( document.addEventListener ){ 
  6.         document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); 
  7.     }else if (document.attachEvent){ 
  8.         document.attachEvent('WeixinJSBridgeReady', onBridgeReady);  
  9.         document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); 
  10.     } 
  11. }else{ 
  12.     onBridgeReady(); 
  • 返回说明

隐藏底部导航栏没有返回值。(需要显示顶部导航栏,请把hideToolbar换成showToolbar)

3、网页获取用户网络状态

为了方便开发者根据用户的网络状态来提供不同质量的服务,企业号可以在企业号内部的网页中使用JavaScript代码调用来获取网络状态。

  • 接口调用代码(JavaScript)
  1. function onBridgeReady(){ 
  2.  WeixinJSBridge.invoke('getNetworkType',{}, 
  3.         function(e){ 
  4.             WeixinJSBridge.log(e.err_msg); 
  5.         }); 
  6.  
  7. if (typeof WeixinJSBridge == "undefined"){ 
  8.     if( document.addEventListener ){ 
  9.         document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); 
  10.     }else if (document.attachEvent){ 
  11.         document.attachEvent('WeixinJSBridgeReady', onBridgeReady);  
  12.         document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); 
  13.     } 
  14. }else{ 
  15.     onBridgeReady(); 
  • 返回说明

获取用户网络状态的返回值如下:

  1. network_type:wifi wifi网络 
  2. network_type:edge 非wifi,包含3G/2G 
  3. network_type:fail 网络断开连接 
  4. network_type:wwan(2g或者3g) 

4、关闭当前网页窗口

在微信内置浏览器中被访问的网页,可使用该JavaScript代码关闭当前网页。

主要使用场景: 微信用户在企业号会话中点击外链到达企业号的网页,在用户完成操作后,企业号(网页方)可调用此接口关闭当前网页窗口,使用户返回会话。

  • 接口调用代码(JavaScript)
  1. WeixinJSBridge.invoke('closeWindow',{},function(res){ 
  2.  
  3.     //alert(res.err_msg); 
  4.  
  5. }); 
  • 返回说明

 

返回值说明
err_msg 关闭成功返回“close_window:ok”,关闭失败返回“close_window:error”。

 

 

【编辑推荐】

没有更多推荐了,返回首页