新增企业号工程并完成【部门管理】【成员管理】【标签管理】三个接口
This commit is contained in:
@@ -25,4 +25,8 @@ weixin4j-base
|
||||
|
||||
* 2014-11-15
|
||||
|
||||
+ 新增`aes加密解密`函数
|
||||
+ 新增`aes加密解密`函数
|
||||
|
||||
* 2014-11-19
|
||||
|
||||
+ 新增`WeixinQyAccount`企业号账号信息类
|
||||
@@ -11,7 +11,7 @@
|
||||
<desc>system error</desc>
|
||||
<text>系统繁忙</text>
|
||||
</error>
|
||||
<!-- 公众平台API错误 -->
|
||||
<!-- 公众平台&企业号API错误 -->
|
||||
<error>
|
||||
<code>40001</code>
|
||||
<desc>invalid credential</desc>
|
||||
@@ -32,6 +32,14 @@
|
||||
<desc>invalid media type</desc>
|
||||
<text>不合法的媒体文件类型</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40005</code>
|
||||
<text>不合法的文件类型</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40006</code>
|
||||
<text>不合法的文件大小</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40007</code>
|
||||
<desc>invalid media_id</desc>
|
||||
@@ -102,6 +110,14 @@
|
||||
<desc>invalid button url size</desc>
|
||||
<text>不合法的url长度</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40021</code>
|
||||
<text>不合法的菜单版本号</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40022</code>
|
||||
<text>不合法的子菜单级数</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40023</code>
|
||||
<desc>invalid sub button size</desc>
|
||||
@@ -127,6 +143,10 @@
|
||||
<desc>invalid sub button url size</desc>
|
||||
<text>不合法的子菜单按钮url长度</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40028</code>
|
||||
<text>不合法的自定义菜单使用员工</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40029</code>
|
||||
<desc>invalid code</desc>
|
||||
@@ -137,6 +157,22 @@
|
||||
<desc>invalid refresh_token</desc>
|
||||
<text>不合法的refresh_token</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40031</code>
|
||||
<text>不合法的UserID列表</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40032</code>
|
||||
<text>不合法的UserID列表长度</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40033</code>
|
||||
<text>不合法的请求字符,不能包含\uxxxx格式的字符</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40035</code>
|
||||
<text>不合法的参数</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40036</code>
|
||||
<desc>invalid template_id size</desc>
|
||||
@@ -147,11 +183,27 @@
|
||||
<desc>invalid template_id</desc>
|
||||
<text>不合法的template_id</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40038</code>
|
||||
<text>不合法的请求格式</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40039</code>
|
||||
<desc>invalid url size</desc>
|
||||
<text>不合法的url长度</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40040</code>
|
||||
<text>不合法的插件token</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40041</code>
|
||||
<text>不合法的插件id</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40042</code>
|
||||
<text>不合法的插件会话</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40048</code>
|
||||
<desc>invalid url domain</desc>
|
||||
@@ -167,10 +219,82 @@
|
||||
<desc>invalid button url domain</desc>
|
||||
<text>不合法的菜单按钮url域名</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40056</code>
|
||||
<text>不合法的agentid</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40057</code>
|
||||
<text>不合法的callbackurl</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40058</code>
|
||||
<text>不合法的红包参数</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40059</code>
|
||||
<text>不合法的上报地理位置标志位</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40060</code>
|
||||
<text>设置上报地理位置标志位时没有设置callbackurl</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40061</code>
|
||||
<text>设置应用头像失败</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40062</code>
|
||||
<text>不合法的应用模式</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40063</code>
|
||||
<text>红包参数为空</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40064</code>
|
||||
<text>管理组名字已存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40065</code>
|
||||
<text>不合法的管理组名字长度</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40066</code>
|
||||
<desc>invalid url</desc>
|
||||
<text>不合法的url</text>
|
||||
<desc>invalid url/department</desc>
|
||||
<text>不合法的url/不合法的部门列表</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40067</code>
|
||||
<text>标题长度不合法</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40068</code>
|
||||
<text>不合法的标签ID</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40069</code>
|
||||
<text>不合法的标签ID列表</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40070</code>
|
||||
<text>列表中所有标签(用户)ID都不合法</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40071</code>
|
||||
<text>不合法的标签名字,标签名字已经存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40072</code>
|
||||
<text>不合法的标签名字长度</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40073</code>
|
||||
<text>不合法的openid</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>40074</code>
|
||||
<text>news消息不支持指定为高保密消息</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>41001</code>
|
||||
@@ -222,6 +346,38 @@
|
||||
<desc>missing url</desc>
|
||||
<text>缺失url参数</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>41011</code>
|
||||
<text>缺少agentid</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>41012</code>
|
||||
<text>缺少应用头像mediaid</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>41013</code>
|
||||
<text>缺少应用名字</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>41014</code>
|
||||
<text>缺少应用描述</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>41015</code>
|
||||
<text>缺少Content</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>41016</code>
|
||||
<text>缺少标题</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>41017</code>
|
||||
<text>缺少标签ID</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>41018</code>
|
||||
<text>缺少标签名字</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>42001</code>
|
||||
<desc>access_token expired</desc>
|
||||
@@ -237,6 +393,10 @@
|
||||
<desc>code expired</desc>
|
||||
<text>code超时</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>42004</code>
|
||||
<text>插件token超时</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>43001</code>
|
||||
<desc>require GET method</desc>
|
||||
@@ -257,6 +417,34 @@
|
||||
<desc>require subscribe</desc>
|
||||
<text>需要订阅关系</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>43005</code>
|
||||
<text>需要好友关系</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>43006</code>
|
||||
<text>需要订阅</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>43007</code>
|
||||
<text>需要授权</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>43008</code>
|
||||
<text>需要支付授权</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>43009</code>
|
||||
<text>需要员工已关注</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>43010</code>
|
||||
<text>需要处于回调模式</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>43011</code>
|
||||
<text>需要企业授权</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>44001</code>
|
||||
<desc>empty media data</desc>
|
||||
@@ -342,6 +530,10 @@
|
||||
<desc>template size out of limit</desc>
|
||||
<text>模板大小超过限制</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>45015</code>
|
||||
<text>回复时间超过限制</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>45016</code>
|
||||
<desc>can't modify sys group</desc>
|
||||
@@ -357,11 +549,176 @@
|
||||
<desc>too many group now, no need to add new</desc>
|
||||
<text>组数量过多</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>45024</code>
|
||||
<text>账号数量超过上限</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>46001</code>
|
||||
<text>不存在媒体数据</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>46002</code>
|
||||
<text>不存在的菜单版本</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>46003</code>
|
||||
<text>不存在的菜单数据</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>46004</code>
|
||||
<text>不存在的员工</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>47001</code>
|
||||
<text>解析JSON/XML内容错误</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>48002</code>
|
||||
<text>Api禁用</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>50001</code>
|
||||
<desc>api unauthorized</desc>
|
||||
<desc>api/redirect_uri unauthorized</desc>
|
||||
<text>接口未授权</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>50002</code>
|
||||
<text>员工不在权限范围</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>50003</code>
|
||||
<text>应用已停用</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>50004</code>
|
||||
<text>员工状态不正确(未关注状态)</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>50005</code>
|
||||
<text>企业已禁用</text>
|
||||
</error>
|
||||
<!-- 企业号API错误 -->
|
||||
<error>
|
||||
<code>60001</code>
|
||||
<text>部门长度不符合限制</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60002</code>
|
||||
<text>部门层级深度超过限制</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60003</code>
|
||||
<text>部门不存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60004</code>
|
||||
<text>父亲部门不存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60005</code>
|
||||
<text>不允许删除有成员的部门</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60006</code>
|
||||
<text>不允许删除有子部门的部门</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60007</code>
|
||||
<text>不允许删除根部门</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60008</code>
|
||||
<text>部门名称已存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60009</code>
|
||||
<text>部门名称含有非法字符</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60010</code>
|
||||
<text>部门存在循环关系</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60011</code>
|
||||
<text>管理员权限不足(user/department/agent)无权限</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60012</code>
|
||||
<text>不允许删除默认应用</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60013</code>
|
||||
<text>不允许关闭应用</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60014</code>
|
||||
<text>不允许开启应用</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60015</code>
|
||||
<text>不允许修改默认应用可见范围</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60016</code>
|
||||
<text>不允许删除存在成员的标签</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60017</code>
|
||||
<text>不允许设置企业</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60102</code>
|
||||
<text>UserID已存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60103</code>
|
||||
<text>手机号码不合法</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60104</code>
|
||||
<text>手机号码已存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60105</code>
|
||||
<text>邮箱不合法</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60106</code>
|
||||
<text>邮箱已存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60107</code>
|
||||
<text>微信号不合法</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60108</code>
|
||||
<text>微信号已存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60109</code>
|
||||
<text>QQ号已存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60110</code>
|
||||
<text>部门个数超出限制</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60111</code>
|
||||
<text>UserID不存在</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60112</code>
|
||||
<text>成员姓名不合法</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60113</code>
|
||||
<text>身份认证信息(微信号/手机/邮箱)不能同时为空</text>
|
||||
</error>
|
||||
<error>
|
||||
<code>60114</code>
|
||||
<text>性别不合法</text>
|
||||
</error>
|
||||
<!-- 语义理解API错误 -->
|
||||
<error>
|
||||
<code>7000000</code>
|
||||
|
||||
@@ -11,4 +11,12 @@ public final class Consts {
|
||||
public static final String AES = "AES";
|
||||
public static final String PROTOCOL_FILE = "file";
|
||||
public static final String PROTOCOL_JAR = "jar";
|
||||
|
||||
public static final String MP_ASSESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
||||
public static final String QY_ASSESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s";
|
||||
|
||||
public static final String UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
||||
public static final String MICROPAYURL = "https://api.mch.weixin.qq.com/pay/micropay";
|
||||
public static final String NATIVEURLV2 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s";
|
||||
public static final String NATIVEURLV3 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
/**
|
||||
* 用户性别
|
||||
*
|
||||
* @className Gender
|
||||
* @author jy
|
||||
* @date 2014年11月5日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum Gender {
|
||||
male, female, unknown;
|
||||
}
|
||||
@@ -2,48 +2,51 @@ package com.foxinmy.weixin4j.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 微信账户信息
|
||||
* 微信账号信息
|
||||
*
|
||||
* @className WeixinAccount
|
||||
* @author jy
|
||||
* @date 2014年8月17日
|
||||
* @date 2014年11月18日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class WeixinAccount implements Serializable {
|
||||
private static final long serialVersionUID = 3689999353867189585L;
|
||||
public abstract class WeixinAccount implements Serializable {
|
||||
private static final long serialVersionUID = -6001008896414323534L;
|
||||
|
||||
// 唯一的身份标识
|
||||
private String id;
|
||||
// 调用接口的密钥
|
||||
private String secret;
|
||||
private String token;
|
||||
// 支付场景下为用户的openid 其余情况可能是公众号的原始ID
|
||||
private String openId;
|
||||
// 公众号身份的唯一标识
|
||||
private String appId;
|
||||
// 公众平台接口 API 的权限获取所需密钥 Key
|
||||
private String appSecret;
|
||||
// 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值
|
||||
private String paySignKey;
|
||||
// 安全模式下的加密密钥
|
||||
private String encodingAesKey;
|
||||
// 财付通商户身份的标识
|
||||
private String partnerId;
|
||||
// 财付通商户权限密钥Key
|
||||
private String partnerKey;
|
||||
// 微信支付商户号V3.x版本
|
||||
private String mchId;
|
||||
// 微信支付分配的设备号
|
||||
private String deviceInfo;
|
||||
// 微信支付版本号(如果无则按照mchId来做判断)
|
||||
private int version;
|
||||
|
||||
// 是否已经认证
|
||||
private boolean isAlive;
|
||||
// 是否是服务号
|
||||
private boolean isService;
|
||||
// 是否是订阅号
|
||||
private boolean isSubscribe;
|
||||
public abstract String getTokenUrl();
|
||||
|
||||
public WeixinAccount() {
|
||||
}
|
||||
|
||||
public WeixinAccount(String id, String secret) {
|
||||
this.id = id;
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
@@ -53,30 +56,6 @@ public class WeixinAccount implements Serializable {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getOpenId() {
|
||||
return openId;
|
||||
}
|
||||
|
||||
public void setOpenId(String openId) {
|
||||
this.openId = openId;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getAppSecret() {
|
||||
return appSecret;
|
||||
}
|
||||
|
||||
public void setAppSecret(String appSecret) {
|
||||
this.appSecret = appSecret;
|
||||
}
|
||||
|
||||
public String getEncodingAesKey() {
|
||||
return encodingAesKey;
|
||||
}
|
||||
@@ -85,130 +64,9 @@ public class WeixinAccount implements Serializable {
|
||||
this.encodingAesKey = encodingAesKey;
|
||||
}
|
||||
|
||||
public String getPaySignKey() {
|
||||
return paySignKey;
|
||||
}
|
||||
|
||||
public void setPaySignKey(String paySignKey) {
|
||||
this.paySignKey = paySignKey;
|
||||
}
|
||||
|
||||
public String getPartnerId() {
|
||||
return partnerId;
|
||||
}
|
||||
|
||||
public void setPartnerId(String partnerId) {
|
||||
this.partnerId = partnerId;
|
||||
}
|
||||
|
||||
public String getPartnerKey() {
|
||||
return partnerKey;
|
||||
}
|
||||
|
||||
public void setPartnerKey(String partnerKey) {
|
||||
this.partnerKey = partnerKey;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public void setMchId(String mchId) {
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
public String getDeviceInfo() {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public void setDeviceInfo(String deviceInfo) {
|
||||
this.deviceInfo = deviceInfo;
|
||||
}
|
||||
|
||||
public boolean getIsAlive() {
|
||||
return isAlive;
|
||||
}
|
||||
|
||||
public void setIsAlive(Boolean isAlive) {
|
||||
this.isAlive = isAlive;
|
||||
}
|
||||
|
||||
public boolean getIsService() {
|
||||
return isService;
|
||||
}
|
||||
|
||||
public void setIsService(Boolean isService) {
|
||||
this.isService = isService;
|
||||
}
|
||||
|
||||
public boolean getIsSubscribe() {
|
||||
return isSubscribe;
|
||||
}
|
||||
|
||||
public void setIsSubscribe(Boolean isSubscribe) {
|
||||
this.isSubscribe = isSubscribe;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
if (version == 0) {
|
||||
return StringUtils.isNotBlank(mchId) ? 3 : 2;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public WeixinAccount() {
|
||||
|
||||
}
|
||||
|
||||
public WeixinAccount(String appId, String appSecret) {
|
||||
this.appId = appId;
|
||||
this.appSecret = appSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* V3版本字段
|
||||
*
|
||||
* @param appId
|
||||
* @param appSecret
|
||||
* @param paySignKey
|
||||
* @param mchId
|
||||
*/
|
||||
public WeixinAccount(String appId, String appSecret, String paySignKey,
|
||||
String mchId) {
|
||||
this(appId, appSecret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
/**
|
||||
* V2版本字段
|
||||
*
|
||||
* @param appId
|
||||
* @param appSecret
|
||||
* @param paySignKey
|
||||
* @param partnerId
|
||||
* @param partnerKey
|
||||
*/
|
||||
public WeixinAccount(String appId, String appSecret, String paySignKey,
|
||||
String partnerId, String partnerKey) {
|
||||
this(appId, appSecret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.partnerId = partnerId;
|
||||
this.partnerKey = partnerKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinAccount [token=" + token + ", openId=" + openId
|
||||
+ ", appId=" + appId + ", appSecret=" + appSecret
|
||||
+ ", encodingAesKey=" + encodingAesKey + ", paySignKey="
|
||||
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey="
|
||||
+ partnerKey + ", mchId=" + mchId + ", deviceInfo="
|
||||
+ deviceInfo + ", isAlive=" + isAlive + ", isService="
|
||||
+ isService + ", isSubscribe=" + isSubscribe + "]";
|
||||
return "WeixinAccount [id=" + id + ", secret=" + secret + ", token="
|
||||
+ token + ", encodingAesKey=" + encodingAesKey + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 微信公众平台信息
|
||||
*
|
||||
* @className WeixinMpAccount
|
||||
* @author jy
|
||||
* @date 2014年8月17日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class WeixinMpAccount extends WeixinAccount {
|
||||
private static final long serialVersionUID = 3689999353867189585L;
|
||||
|
||||
// 支付场景下为用户的openid 其余情况可能是公众号的原始ID
|
||||
private String openId;
|
||||
// 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值
|
||||
private String paySignKey;
|
||||
// 财付通商户身份的标识
|
||||
private String partnerId;
|
||||
// 财付通商户权限密钥Key
|
||||
private String partnerKey;
|
||||
// 微信支付商户号V3.x版本
|
||||
private String mchId;
|
||||
// 微信支付分配的设备号
|
||||
private String deviceInfo;
|
||||
// 微信支付版本号(如果无则按照mchId来做判断)
|
||||
private int version;
|
||||
|
||||
// 是否已经认证
|
||||
private boolean isAlive;
|
||||
// 是否是服务号
|
||||
private boolean isService;
|
||||
// 是否是订阅号
|
||||
private boolean isSubscribe;
|
||||
|
||||
@Override
|
||||
public String getTokenUrl() {
|
||||
return String.format(Consts.MP_ASSESS_TOKEN_URL, getId(), getSecret());
|
||||
}
|
||||
|
||||
public String getOpenId() {
|
||||
return openId;
|
||||
}
|
||||
|
||||
public void setOpenId(String openId) {
|
||||
this.openId = openId;
|
||||
}
|
||||
|
||||
public String getPaySignKey() {
|
||||
return paySignKey;
|
||||
}
|
||||
|
||||
public void setPaySignKey(String paySignKey) {
|
||||
this.paySignKey = paySignKey;
|
||||
}
|
||||
|
||||
public String getPartnerId() {
|
||||
return partnerId;
|
||||
}
|
||||
|
||||
public void setPartnerId(String partnerId) {
|
||||
this.partnerId = partnerId;
|
||||
}
|
||||
|
||||
public String getPartnerKey() {
|
||||
return partnerKey;
|
||||
}
|
||||
|
||||
public void setPartnerKey(String partnerKey) {
|
||||
this.partnerKey = partnerKey;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public void setMchId(String mchId) {
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
public String getDeviceInfo() {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public void setDeviceInfo(String deviceInfo) {
|
||||
this.deviceInfo = deviceInfo;
|
||||
}
|
||||
|
||||
public boolean getIsAlive() {
|
||||
return isAlive;
|
||||
}
|
||||
|
||||
public void setIsAlive(Boolean isAlive) {
|
||||
this.isAlive = isAlive;
|
||||
}
|
||||
|
||||
public boolean getIsService() {
|
||||
return isService;
|
||||
}
|
||||
|
||||
public void setIsService(Boolean isService) {
|
||||
this.isService = isService;
|
||||
}
|
||||
|
||||
public boolean getIsSubscribe() {
|
||||
return isSubscribe;
|
||||
}
|
||||
|
||||
public void setIsSubscribe(Boolean isSubscribe) {
|
||||
this.isSubscribe = isSubscribe;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
if (version == 0) {
|
||||
return StringUtils.isNotBlank(mchId) ? 3 : 2;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public WeixinMpAccount() {
|
||||
|
||||
}
|
||||
|
||||
public WeixinMpAccount(String appId, String appSecret) {
|
||||
super(appId, appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* V3版本字段
|
||||
*
|
||||
* @param appId
|
||||
* @param appSecret
|
||||
* @param paySignKey
|
||||
* @param mchId
|
||||
*/
|
||||
public WeixinMpAccount(String appId, String appSecret, String paySignKey,
|
||||
String mchId) {
|
||||
this(appId, appSecret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
/**
|
||||
* V2版本字段
|
||||
*
|
||||
* @param appId
|
||||
* @param appSecret
|
||||
* @param paySignKey
|
||||
* @param partnerId
|
||||
* @param partnerKey
|
||||
*/
|
||||
public WeixinMpAccount(String appId, String appSecret, String paySignKey,
|
||||
String partnerId, String partnerKey) {
|
||||
this(appId, appSecret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.partnerId = partnerId;
|
||||
this.partnerKey = partnerKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinMpAccount [openId=" + openId + ", paySignKey="
|
||||
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey="
|
||||
+ partnerKey + ", mchId=" + mchId + ", deviceInfo="
|
||||
+ deviceInfo + ", version=" + version + ", isAlive=" + isAlive
|
||||
+ ", isService=" + isService + ", isSubscribe=" + isSubscribe
|
||||
+ ", getId()=" + getId() + ", getSecret()=" + getSecret()
|
||||
+ ", getToken()=" + getToken() + ", getEncodingAesKey()="
|
||||
+ getEncodingAesKey() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
/**
|
||||
* 微信企业号信息
|
||||
*
|
||||
* @className WeixinQyAccount
|
||||
* @author jy
|
||||
* @date 2014年11月18日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class WeixinQyAccount extends WeixinAccount {
|
||||
private static final long serialVersionUID = 3689999353867189585L;
|
||||
|
||||
public WeixinQyAccount() {
|
||||
}
|
||||
|
||||
public WeixinQyAccount(String corpid, String corpsecret) {
|
||||
super(corpid, corpsecret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTokenUrl() {
|
||||
return String.format(Consts.QY_ASSESS_TOKEN_URL, getId(), getSecret());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinQyAccount [getTokenUrl()=" + getTokenUrl() + ", getId()="
|
||||
+ getId() + ", getSecret()=" + getSecret() + ", getToken()="
|
||||
+ getToken() + ", getEncodingAesKey()=" + getEncodingAesKey()
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,8 @@
|
||||
package com.foxinmy.weixin4j.msg;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import com.foxinmy.weixin4j.model.BaseMsg;
|
||||
import com.foxinmy.weixin4j.type.MessageType;
|
||||
import com.foxinmy.weixin4j.util.ClassUtil;
|
||||
import com.foxinmy.weixin4j.xml.XStream;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
|
||||
import com.thoughtworks.xstream.io.json.JsonWriter;
|
||||
|
||||
/**
|
||||
* 普通消息基类
|
||||
@@ -26,32 +19,12 @@ import com.thoughtworks.xstream.io.json.JsonWriter;
|
||||
public class BaseMessage extends BaseMsg {
|
||||
|
||||
private static final long serialVersionUID = 7761192742840031607L;
|
||||
private final static XStream xmlStream = XStream.get();
|
||||
private final static XStream jsonStream = new XStream(
|
||||
new JsonHierarchicalStreamDriver() {
|
||||
public HierarchicalStreamWriter createWriter(Writer writer) {
|
||||
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
|
||||
}
|
||||
});
|
||||
|
||||
@XStreamAlias("MsgType")
|
||||
private MessageType msgType; // 消息类型
|
||||
@XStreamAlias("MsgId")
|
||||
private long msgId; // 消息ID
|
||||
|
||||
static {
|
||||
Class<?>[] classes = ClassUtil.getClasses(
|
||||
TextMessage.class.getPackage()).toArray(new Class[0]);
|
||||
|
||||
xmlStream.processAnnotations(classes);
|
||||
xmlStream.omitField(BaseMessage.class, "msgId");
|
||||
|
||||
jsonStream.setMode(XStream.NO_REFERENCES);
|
||||
jsonStream.autodetectAnnotations(true);
|
||||
jsonStream.processAnnotations(classes);
|
||||
jsonStream.omitField(BaseMessage.class, "msgId");
|
||||
}
|
||||
|
||||
public BaseMessage(MessageType msgType) {
|
||||
this.msgType = msgType;
|
||||
}
|
||||
@@ -79,25 +52,4 @@ public class BaseMessage extends BaseMsg {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息对象转换为微信服务器接受的xml格式消息
|
||||
*
|
||||
* @return xml字符串
|
||||
*/
|
||||
public String toXml() {
|
||||
Class<? extends BaseMessage> targetClass = getMsgType()
|
||||
.getMessageClass();
|
||||
xmlStream.alias("xml", targetClass);
|
||||
return xmlStream.toXML(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息对象转换为微信服务器接受的json格式字符串
|
||||
*
|
||||
* @return json字符串
|
||||
*/
|
||||
public String toJson() {
|
||||
return jsonStream.toXML(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ package com.foxinmy.weixin4j.token;
|
||||
|
||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.type.AccountType;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
* 获取weixin.properties中的appid&appsecret信息
|
||||
* 获取weixin.properties中的id&secret信息
|
||||
*
|
||||
* @className AbstractTokenHolder
|
||||
* @author jy
|
||||
@@ -14,12 +15,18 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
* @see
|
||||
*/
|
||||
public abstract class AbstractTokenHolder implements TokenHolder {
|
||||
protected final String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
||||
protected final HttpRequest request = new HttpRequest();
|
||||
private final WeixinAccount weixinAccount;
|
||||
|
||||
public AbstractTokenHolder() {
|
||||
this.weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
protected final HttpRequest request = new HttpRequest();
|
||||
protected final WeixinAccount weixinAccount;
|
||||
|
||||
public AbstractTokenHolder(AccountType accountType) {
|
||||
if (accountType == AccountType.MP) {
|
||||
this.weixinAccount = ConfigUtil.getWeixinMpAccount();
|
||||
} else if (accountType == AccountType.QY) {
|
||||
this.weixinAccount = ConfigUtil.getWeixinQyAccount();
|
||||
} else {
|
||||
this.weixinAccount = null;
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractTokenHolder(WeixinAccount weixinAccount) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.type.AccountType;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.xml.XStream;
|
||||
|
||||
@@ -24,23 +25,20 @@ import com.foxinmy.weixin4j.xml.XStream;
|
||||
* @date 2014年9月27日
|
||||
* @since JDK 1.7
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">获取token说明</a>
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">微信公众平台获取token说明</a>
|
||||
* @see <a href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8">微信企业号获取token说明</a>
|
||||
* @see com.foxinmy.weixin4j.model.Token
|
||||
*/
|
||||
public class FileTokenHolder extends AbstractTokenHolder {
|
||||
|
||||
public FileTokenHolder() {
|
||||
super();
|
||||
public FileTokenHolder(AccountType accountType) {
|
||||
super(accountType);
|
||||
}
|
||||
|
||||
public FileTokenHolder(WeixinAccount weixinAccount) {
|
||||
super(weixinAccount);
|
||||
}
|
||||
|
||||
public FileTokenHolder(String appid, String appsecret) {
|
||||
this(new WeixinAccount(appid, appsecret));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token
|
||||
* <p>
|
||||
@@ -55,14 +53,13 @@ public class FileTokenHolder extends AbstractTokenHolder {
|
||||
*/
|
||||
@Override
|
||||
public Token getToken() throws WeixinException {
|
||||
String appid = getAccount().getAppId();
|
||||
String appsecret = getAccount().getAppSecret();
|
||||
if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) {
|
||||
String id = weixinAccount.getId();
|
||||
if (StringUtils.isBlank(id) || StringUtils.isBlank(weixinAccount.getSecret())) {
|
||||
throw new IllegalArgumentException(
|
||||
"appid or appsecret not be null!");
|
||||
"id or secret not be null!");
|
||||
}
|
||||
File token_file = new File(String.format("%s/token_%s.xml",
|
||||
ConfigUtil.getValue("token_path"), appid));
|
||||
ConfigUtil.getValue("token_path"), id));
|
||||
Token token = null;
|
||||
Calendar ca = Calendar.getInstance();
|
||||
long now_time = ca.getTimeInMillis();
|
||||
@@ -78,8 +75,7 @@ public class FileTokenHolder extends AbstractTokenHolder {
|
||||
} else {
|
||||
token_file.createNewFile();
|
||||
}
|
||||
String api_token_uri = String.format(tokenUrl, appid, appsecret);
|
||||
Response response = request.get(api_token_uri);
|
||||
Response response = request.get(weixinAccount.getTokenUrl());
|
||||
token = response.getAsObject(new TypeReference<Token>() {
|
||||
});
|
||||
token.setTime(now_time);
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.type.AccountType;
|
||||
|
||||
/**
|
||||
* 基于redis保存的Token获取类
|
||||
@@ -20,7 +21,10 @@ import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
* @date 2014年9月27日
|
||||
* @since JDK 1.7
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">获取token说明</a>
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">微信公众平台获取token说明</a>
|
||||
* @see <a href=
|
||||
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8"
|
||||
* >微信企业号获取token说明</a>
|
||||
* @see com.foxinmy.weixin4j.model.Token
|
||||
*/
|
||||
public class RedisTokenHolder extends AbstractTokenHolder {
|
||||
@@ -37,47 +41,39 @@ public class RedisTokenHolder extends AbstractTokenHolder {
|
||||
this.jedisPool = new JedisPool(poolConfig, host, port);
|
||||
}
|
||||
|
||||
public RedisTokenHolder() {
|
||||
this("localhost", 6379);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(String host, int port) {
|
||||
super();
|
||||
public RedisTokenHolder(String host, int port, AccountType accountType) {
|
||||
super(accountType);
|
||||
createPool(host, port);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(AccountType accountType) {
|
||||
this("localhost", 6379, accountType);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(WeixinAccount weixinAccount) {
|
||||
this(weixinAccount, "localhost", 6379);
|
||||
this("localhost", 6379, weixinAccount);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(String appId, String appSecret, String host,
|
||||
int port) {
|
||||
this(new WeixinAccount(appId, appSecret), host, port);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(WeixinAccount weixinAccount, String host, int port) {
|
||||
public RedisTokenHolder(String host, int port, WeixinAccount weixinAccount) {
|
||||
super(weixinAccount);
|
||||
createPool(host, port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token getToken() throws WeixinException {
|
||||
String appid = getAccount().getAppId();
|
||||
String appsecret = getAccount().getAppSecret();
|
||||
if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) {
|
||||
throw new IllegalArgumentException(
|
||||
"appid or appsecret not be null!");
|
||||
String id = weixinAccount.getId();
|
||||
if (StringUtils.isBlank(id)
|
||||
|| StringUtils.isBlank(weixinAccount.getSecret())) {
|
||||
throw new IllegalArgumentException("id or secret not be null!");
|
||||
}
|
||||
Token token = null;
|
||||
Jedis jedis = null;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
String key = String.format("token:%s", appid);
|
||||
String key = String.format("token:%s", id);
|
||||
String accessToken = jedis.get(key);
|
||||
if (StringUtils.isBlank(accessToken)) {
|
||||
String api_token_uri = String
|
||||
.format(tokenUrl, appid, appsecret);
|
||||
token = request.get(api_token_uri).getAsObject(
|
||||
token = request.get(weixinAccount.getTokenUrl()).getAsObject(
|
||||
new TypeReference<Token>() {
|
||||
});
|
||||
jedis.setex(key, token.getExpiresIn() - 3,
|
||||
|
||||
@@ -18,6 +18,5 @@ import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
*/
|
||||
public interface TokenHolder {
|
||||
public WeixinAccount getAccount();
|
||||
|
||||
public Token getToken() throws WeixinException;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 账号类型
|
||||
*
|
||||
* @className AccountType
|
||||
* @author jy
|
||||
* @date 2014年11月18日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum AccountType {
|
||||
MP, QY
|
||||
}
|
||||
@@ -5,7 +5,8 @@ import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.model.WeixinMpAccount;
|
||||
import com.foxinmy.weixin4j.model.WeixinQyAccount;
|
||||
|
||||
/**
|
||||
* 商户配置工具类
|
||||
@@ -33,8 +34,13 @@ public class ConfigUtil {
|
||||
return weixinBundle.getString(key);
|
||||
}
|
||||
|
||||
public static WeixinAccount getWeixinAccount() {
|
||||
public static WeixinMpAccount getWeixinMpAccount() {
|
||||
String text = getValue("account");
|
||||
return JSON.parseObject(text, WeixinAccount.class);
|
||||
return JSON.parseObject(text, WeixinMpAccount.class);
|
||||
}
|
||||
|
||||
public static WeixinQyAccount getWeixinQyAccount() {
|
||||
String text = getValue("account");
|
||||
return JSON.parseObject(text, WeixinQyAccount.class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user