主要新增了企业号的第三方应用API

This commit is contained in:
jinyu
2015-06-21 22:20:19 +08:00
parent 692a2b8129
commit dd1fcaa598
44 changed files with 850 additions and 250 deletions
@@ -3,12 +3,12 @@ package com.foxinmy.weixin4j.mp;
import java.io.File;
import java.util.Date;
import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.JsonResult;
import com.foxinmy.weixin4j.http.weixin.XmlResult;
import com.foxinmy.weixin4j.mp.api.CashApi;
import com.foxinmy.weixin4j.mp.api.CouponApi;
import com.foxinmy.weixin4j.mp.api.MpApi;
import com.foxinmy.weixin4j.mp.api.Pay2Api;
import com.foxinmy.weixin4j.mp.api.Pay3Api;
import com.foxinmy.weixin4j.mp.api.PayApi;
@@ -28,7 +28,6 @@ import com.foxinmy.weixin4j.mp.type.CurrencyType;
import com.foxinmy.weixin4j.mp.type.IdQuery;
import com.foxinmy.weixin4j.mp.type.IdType;
import com.foxinmy.weixin4j.mp.type.RefundType;
import com.foxinmy.weixin4j.token.FileTokenStorager;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.token.TokenStorager;
import com.foxinmy.weixin4j.util.ConfigUtil;
@@ -52,32 +51,35 @@ public class WeixinPayProxy {
private final CouponApi couponApi;
private final CashApi cashApi;
private final TokenHolder tokenHolder;
/**
* 默认使用文件保存token、使用weixin4j.properties配置的账号信息
*/
public WeixinPayProxy() {
this(new FileTokenStorager());
this(MpApi.DEFAULT_TOKEN_STORAGER);
}
/**
* 使用weixin4j.properties配置的账号信息
*/
public WeixinPayProxy(TokenStorager tokenStorager) {
this(tokenStorager, JSON.parseObject(ConfigUtil.getValue("account"),
WeixinMpAccount.class));
this(MpApi.DEFAULT_WEIXIN_ACCOUNT, tokenStorager);
}
/**
*
* @param weixinAccount
* 公众号账号信息
*
* @param tokenStorager
* token的存储策略
* @param weixinAccount
* 公众号账号信息
*/
public WeixinPayProxy(TokenStorager tokenStorager,
WeixinMpAccount weixinAccount) {
TokenHolder tokenHolder = new TokenHolder(new WeixinTokenCreator(
weixinAccount), tokenStorager);
public WeixinPayProxy(WeixinMpAccount weixinAccount,
TokenStorager tokenStorager) {
this.tokenHolder = new TokenHolder(new WeixinTokenCreator(
weixinAccount.getId(), weixinAccount.getSecret()),
tokenStorager);
this.pay2Api = new Pay2Api(weixinAccount, tokenHolder);
this.pay3Api = new Pay3Api(weixinAccount, tokenHolder);
int version = weixinAccount.getVersion();
@@ -92,6 +94,10 @@ public class WeixinPayProxy {
this.cashApi = new CashApi(weixinAccount);
}
public TokenHolder getTokenHolder() {
return this.tokenHolder;
}
/**
* 发货通知
*
@@ -8,7 +8,6 @@ import java.util.List;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.JsonResult;
import com.foxinmy.weixin4j.model.Button;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.mp.api.CustomApi;
import com.foxinmy.weixin4j.mp.api.DataApi;
import com.foxinmy.weixin4j.mp.api.GroupApi;
@@ -16,6 +15,7 @@ import com.foxinmy.weixin4j.mp.api.HelperApi;
import com.foxinmy.weixin4j.mp.api.MassApi;
import com.foxinmy.weixin4j.mp.api.MediaApi;
import com.foxinmy.weixin4j.mp.api.MenuApi;
import com.foxinmy.weixin4j.mp.api.MpApi;
import com.foxinmy.weixin4j.mp.api.NotifyApi;
import com.foxinmy.weixin4j.mp.api.QrApi;
import com.foxinmy.weixin4j.mp.api.TmplApi;
@@ -40,7 +40,6 @@ import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator;
import com.foxinmy.weixin4j.mp.type.DatacubeType;
import com.foxinmy.weixin4j.mp.type.IndustryType;
import com.foxinmy.weixin4j.mp.type.Lang;
import com.foxinmy.weixin4j.token.FileTokenStorager;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.token.TokenStorager;
import com.foxinmy.weixin4j.tuple.MassTuple;
@@ -48,7 +47,6 @@ import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.tuple.Tuple;
import com.foxinmy.weixin4j.tuple.Video;
import com.foxinmy.weixin4j.type.MediaType;
import com.foxinmy.weixin4j.util.ConfigUtil;
/**
* 微信公众平台接口实现
@@ -73,19 +71,23 @@ public class WeixinProxy {
private final HelperApi helperApi;
private final DataApi dataApi;
private final TokenHolder tokenHolder;
/**
* 默认使用文件方式保存token、使用weixin4j.properties配置的账号信息
*/
public WeixinProxy() {
this(new FileTokenStorager());
this(MpApi.DEFAULT_TOKEN_STORAGER);
}
/**
* 默认使用weixin4j.properties配置的账号信息
*
* @param tokenStorager
*/
public WeixinProxy(TokenStorager tokenStorager) {
this(tokenStorager, ConfigUtil.getWeixinAccount());
this(MpApi.DEFAULT_WEIXIN_ACCOUNT.getId(), MpApi.DEFAULT_WEIXIN_ACCOUNT
.getSecret(), tokenStorager);
}
/**
@@ -94,19 +96,13 @@ public class WeixinProxy {
* @param appsecret
*/
public WeixinProxy(String appid, String appsecret) {
this(new FileTokenStorager(), new WeixinAccount(appid, appsecret));
this(appid, appsecret, MpApi.DEFAULT_TOKEN_STORAGER);
}
/**
*
* @param tokenStorager
* token存储策略
* @param weixinAccount
* 公众号账号信息
*/
public WeixinProxy(TokenStorager tokenStorager, WeixinAccount weixinAccount) {
TokenHolder tokenHolder = new TokenHolder(new WeixinTokenCreator(
weixinAccount), tokenStorager);
public WeixinProxy(String appid, String appsecret,
TokenStorager tokenStorager) {
this.tokenHolder = new TokenHolder(new WeixinTokenCreator(appid,
appsecret), tokenStorager);
this.mediaApi = new MediaApi(tokenHolder);
this.notifyApi = new NotifyApi(tokenHolder);
this.customApi = new CustomApi(tokenHolder);
@@ -120,6 +116,10 @@ public class WeixinProxy {
this.dataApi = new DataApi(tokenHolder);
}
public TokenHolder getTokenHolder() {
return this.tokenHolder;
}
/**
* 上传媒体文件
*
@@ -2,7 +2,10 @@ package com.foxinmy.weixin4j.mp.api;
import java.util.ResourceBundle;
import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.api.BaseApi;
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
import com.foxinmy.weixin4j.util.ConfigUtil;
/**
* 微信公众平台API
@@ -15,14 +18,22 @@ import com.foxinmy.weixin4j.api.BaseApi;
* @see <a href="http://mp.weixin.qq.com/wiki/index.php">api文档</a>
*/
public class MpApi extends BaseApi {
private final static ResourceBundle weixinBundle;
private final static ResourceBundle WEIXIN_BUNDLE;
/**
* 默认使用weixin4j.properties文件中的公众号信息
*/
public final static WeixinMpAccount DEFAULT_WEIXIN_ACCOUNT;
static {
weixinBundle = ResourceBundle
WEIXIN_BUNDLE = ResourceBundle
.getBundle("com/foxinmy/weixin4j/mp/api/weixin");
DEFAULT_WEIXIN_ACCOUNT = JSON.parseObject(
ConfigUtil.getValue("account"), WeixinMpAccount.class);
}
@Override
protected ResourceBundle getWeixinBundle() {
return weixinBundle;
protected String getConfigValue(String key) {
return WEIXIN_BUNDLE.getString(key);
}
}
@@ -7,7 +7,6 @@ import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.mp.model.OauthToken;
import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.util.ConfigUtil;
@@ -24,13 +23,14 @@ import com.foxinmy.weixin4j.util.StringUtil;
* href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&lang=zh_CN">微信登陆</a>
*/
public class OauthApi extends MpApi {
/**
* @see {@link com.foxinmy.weixin4j.mp.api.OauthApi#getAuthorizeURL(String, String,String)}
*
* @return 请求授权的URL
*/
public String getAuthorizeURL() {
String appId = ConfigUtil.getWeixinAccount().getId();
String appId = DEFAULT_WEIXIN_ACCOUNT.getId();
String redirectUri = ConfigUtil.getValue("redirect_uri");
return getAuthorizeURL(appId, redirectUri, "state", "snsapi_login");
}
@@ -65,8 +65,8 @@ public class OauthApi extends MpApi {
* @return
*/
public OauthToken getOauthToken(String code) throws WeixinException {
WeixinAccount account = ConfigUtil.getWeixinAccount();
return getOauthToken(code, account.getId(), account.getSecret());
return getOauthToken(code, DEFAULT_WEIXIN_ACCOUNT.getId(),
DEFAULT_WEIXIN_ACCOUNT.getSecret());
}
/**
@@ -98,8 +98,7 @@ public class OauthApi extends MpApi {
* @return
*/
public OauthToken refreshToken(String refreshToken) throws WeixinException {
WeixinAccount account = ConfigUtil.getWeixinAccount();
return refreshToken(account.getId(), refreshToken);
return refreshToken(DEFAULT_WEIXIN_ACCOUNT.getId(), refreshToken);
}
/**
@@ -19,6 +19,7 @@ import com.foxinmy.weixin4j.mp.payment.v3.PayRequestV3;
import com.foxinmy.weixin4j.mp.payment.v3.PrePay;
import com.foxinmy.weixin4j.mp.type.SignType;
import com.foxinmy.weixin4j.mp.type.TradeType;
import com.foxinmy.weixin4j.mp.type.URLConsts;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.DigestUtil;
@@ -228,7 +229,7 @@ public class PayUtil {
}
String payJsRequestXml = XmlStream.toXML(payPackage);
try {
WeixinResponse response = httpClient.post(Consts.UNIFIEDORDER,
WeixinResponse response = httpClient.post(URLConsts.UNIFIEDORDER,
payJsRequestXml);
PrePay prePay = response.getAsObject(new TypeReference<PrePay>() {
});
@@ -303,7 +304,7 @@ public class PayUtil {
map.put("productid", productId);
map.put("appkey", weixinAccount.getPaySignKey());
String sign = paysignSha(map);
return String.format(Consts.NATIVEURLV2, sign, weixinAccount.getId(),
return String.format(URLConsts.NATIVEURLV2, sign, weixinAccount.getId(),
productId, timestamp, noncestr);
}
@@ -328,7 +329,7 @@ public class PayUtil {
map.put("nonce_str", noncestr);
map.put("product_id", productId);
String sign = paysignMd5(map, weixinAccount.getPaySignKey());
return String.format(Consts.NATIVEURLV3, sign, weixinAccount.getId(),
return String.format(URLConsts.NATIVEURLV3, sign, weixinAccount.getId(),
weixinAccount.getMchId(), productId, timestamp, noncestr);
}
@@ -408,7 +409,7 @@ public class PayUtil {
String sign = paysignMd5(payPackage, weixinAccount.getPaySignKey());
payPackage.setSign(sign);
String para = XmlStream.toXML(payPackage);
WeixinResponse response = httpClient.post(Consts.MICROPAYURL, para);
WeixinResponse response = httpClient.post(URLConsts.MICROPAYURL, para);
return response
.getAsObject(new TypeReference<com.foxinmy.weixin4j.mp.payment.v3.Order>() {
});
@@ -88,7 +88,7 @@ public class RefundRecord extends ApiResult {
*
* @see com.foxinmy.weixin4j.mp.payment.v3.RefundDetail
*/
@ListsuffixResult({ "out_refund_no(_\\d)$", "^refund_.*(_\\d)$" })
@ListsuffixResult({ "^out_refund_no(_\\d)$", "^refund_.*(_\\d)$" })
private List<RefundDetail> refundList;
protected RefundRecord() {
@@ -4,11 +4,10 @@ import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.type.URLConsts;
import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.util.ConfigUtil;
/**
* 微信公众平台JSTICKET创建者
@@ -27,21 +26,11 @@ public class WeixinJSTicketCreator implements TokenCreator {
private final TokenHolder weixinTokenHolder;
private final WeixinHttpClient httpClient;
/**
* jssdk
*
* @param weixinTokenHolder
* <font color="red">公众平台的access_token</font>
*/
public WeixinJSTicketCreator(TokenHolder weixinTokenHolder) {
this(ConfigUtil.getWeixinAccount().getId(), weixinTokenHolder);
}
/**
* jssdk
*
* @param appid
* appid
* 公众号的appid
* @param weixinTokenHolder
* <font color="red">公众平台的access_token</font>
*/
@@ -59,7 +48,7 @@ public class WeixinJSTicketCreator implements TokenCreator {
@Override
public Token createToken() throws WeixinException {
WeixinResponse response = httpClient.get(String.format(
Consts.MP_JS_TICKET_URL, weixinTokenHolder.getToken()
URLConsts.JS_TICKET_URL, weixinTokenHolder.getToken()
.getAccessToken()));
JSONObject result = response.getAsJson();
Token token = new Token(result.getString("ticket"));
@@ -4,11 +4,9 @@ import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.mp.type.URLConsts;
import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.util.ConfigUtil;
/**
* 微信公众平台TOKEN创建者
@@ -27,14 +25,13 @@ public class WeixinTokenCreator implements TokenCreator {
private final String appid;
private final String secret;
public WeixinTokenCreator() {
this(ConfigUtil.getWeixinAccount());
}
public WeixinTokenCreator(WeixinAccount weixinAccount) {
this(weixinAccount.getId(), weixinAccount.getSecret());
}
/**
*
* @param appid
* 公众号ID
* @param secret
* 公众号secret
*/
public WeixinTokenCreator(String appid, String secret) {
this.appid = appid;
this.secret = secret;
@@ -48,7 +45,7 @@ public class WeixinTokenCreator implements TokenCreator {
@Override
public Token createToken() throws WeixinException {
String tokenUrl = String.format(Consts.MP_ASSESS_TOKEN_URL, appid,
String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, appid,
secret);
WeixinResponse response = httpClient.get(tokenUrl);
Token token = response.getAsObject(new TypeReference<Token>() {
@@ -0,0 +1,38 @@
package com.foxinmy.weixin4j.mp.type;
/**
* URL常量类
*
* @className URLConsts
* @author jy
* @date 2014年12月3日
* @since JDK 1.7
* @see
*/
public final class URLConsts {
/**
* 公众平台获取token的url
*/
public static final String ASSESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
/**
* 公众平台jssdk获取token的url
*/
public static final String JS_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
/**
* 商户平台下统一订单生成的url
*/
public static final String UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";
/**
* 商户平台下刷卡支付的url
*/
public static final String MICROPAYURL = "https://api.mch.weixin.qq.com/pay/micropay";
/**
* V2支付下natvie支付的url
*/
public static final String NATIVEURLV2 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s&timestamp=%s&noncestr=%s";
/**
* 商户平台(V3)下native支付的url
*/
public static final String NATIVEURLV3 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s";
}
@@ -9,7 +9,7 @@ account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\
"partnerKey":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u5546\u6237\u6743\u9650\u5bc6\u94a5Key \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
"paySignKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5 \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165"}
# \u4f7f\u7528FileTokenHolder\u65f6token\u7684\u5b58\u653e\u8def\u5f84
# \u4f7f\u7528FileTokenStorager\u65f6token\u7684\u5b58\u653e\u8def\u5f84
token_path=/tmp/weixin4j/token
# \u4e8c\u7ef4\u7801\u4fdd\u5b58\u8def\u5f84
qr_path=/tmp/weixin4j/qrcode