重构Weixin4jSettings...
This commit is contained in:
parent
baff97e9db
commit
8a9f93e54e
@ -17,6 +17,10 @@
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
|
||||
@ -12,6 +12,7 @@ import java.nio.charset.Charset;
|
||||
* @see
|
||||
*/
|
||||
public final class Consts {
|
||||
public static final String WEIXIN4J = "weixin4j";
|
||||
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
public static final Charset GBK = Charset.forName("GBK");
|
||||
public static final String SUCCESS = "SUCCESS";
|
||||
|
||||
@ -49,9 +49,9 @@ public class WeixinPayAccount extends WeixinAccount {
|
||||
* 商户平台版本(V3)字段
|
||||
*
|
||||
* @param appId
|
||||
* 公众号唯一的身份ID
|
||||
* 公众号唯一的身份ID(必填)
|
||||
* @param appSecret
|
||||
* 调用接口的凭证
|
||||
* 调用接口的凭证(最好填写)
|
||||
* @param paySignKey
|
||||
* 支付密钥字符串(必填)
|
||||
* @param mchId
|
||||
@ -68,7 +68,7 @@ public class WeixinPayAccount extends WeixinAccount {
|
||||
* @param appId
|
||||
* 公众号唯一的身份ID(必填)
|
||||
* @param appSecret
|
||||
* 调用接口的凭证(必填)
|
||||
* 调用接口的凭证(最好填写)
|
||||
* @param paySignKey
|
||||
* 支付密钥字符串(必填)
|
||||
* @param mchId
|
||||
|
||||
@ -30,11 +30,11 @@ import com.foxinmy.weixin4j.payment.mch.Redpacket;
|
||||
import com.foxinmy.weixin4j.payment.mch.RedpacketRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.RedpacketSendResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jPaySettings;
|
||||
import com.foxinmy.weixin4j.type.BillType;
|
||||
import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jSettings;
|
||||
|
||||
/**
|
||||
* 微信支付接口实现
|
||||
@ -52,26 +52,26 @@ public class WeixinPayProxy {
|
||||
private final CouponApi couponApi;
|
||||
private final CashApi cashApi;
|
||||
|
||||
private final Weixin4jPaySettings settings;
|
||||
private final Weixin4jSettings settings;
|
||||
|
||||
/**
|
||||
* 使用weixin4j.properties配置的支付账号信息
|
||||
*/
|
||||
public WeixinPayProxy() {
|
||||
this(new Weixin4jPaySettings());
|
||||
this(new Weixin4jSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param settings
|
||||
* 支付相关配置信息
|
||||
* @see com.foxinmy.weixin4j.settings.Weixin4jPaySettings
|
||||
* @see com.foxinmy.weixin4j.util.Weixin4jSettings
|
||||
*/
|
||||
public WeixinPayProxy(Weixin4jPaySettings settings) {
|
||||
public WeixinPayProxy(Weixin4jSettings settings) {
|
||||
this.settings = settings;
|
||||
this.pay3Api = new Pay3Api(settings.getPayAccount());
|
||||
this.couponApi = new CouponApi(settings.getPayAccount());
|
||||
this.cashApi = new CashApi(settings.getPayAccount());
|
||||
this.pay3Api = new Pay3Api(settings.getWeixinPayAccount());
|
||||
this.couponApi = new CouponApi(settings.getWeixinPayAccount());
|
||||
this.cashApi = new CashApi(settings.getWeixinPayAccount());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,7 +80,7 @@ public class WeixinPayProxy {
|
||||
* @return
|
||||
*/
|
||||
public WeixinPayAccount getPayAccount() {
|
||||
return this.settings.getPayAccount();
|
||||
return this.settings.getWeixinPayAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -467,7 +467,7 @@ public class WeixinPayProxy {
|
||||
IdQuery idQuery, String outRefundNo, double totalFee)
|
||||
throws WeixinException, IOException {
|
||||
return pay3Api.refundApply(
|
||||
new FileInputStream(settings.getCertificatePath()), idQuery,
|
||||
new FileInputStream(settings.getCertificateFile0()), idQuery,
|
||||
outRefundNo, totalFee);
|
||||
}
|
||||
|
||||
@ -514,7 +514,7 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public File downloadBill(Date billDate, BillType billType)
|
||||
throws WeixinException {
|
||||
return pay3Api.downloadBill(billDate, billType, settings.getBillPath());
|
||||
return pay3Api.downloadBill(billDate, billType, settings.getTmpdir0());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -551,7 +551,7 @@ public class WeixinPayProxy {
|
||||
public ApiResult reverseOrder(IdQuery idQuery) throws WeixinException,
|
||||
IOException {
|
||||
return pay3Api.reverseOrder(
|
||||
new FileInputStream(settings.getCertificatePath()), idQuery);
|
||||
new FileInputStream(settings.getCertificateFile0()), idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -655,7 +655,7 @@ public class WeixinPayProxy {
|
||||
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
|
||||
String openId) throws WeixinException, IOException {
|
||||
return couponApi.sendCoupon(
|
||||
new FileInputStream(settings.getCertificatePath()),
|
||||
new FileInputStream(settings.getCertificateFile0()),
|
||||
couponStockId, partnerTradeNo, openId, null);
|
||||
}
|
||||
|
||||
@ -721,7 +721,7 @@ public class WeixinPayProxy {
|
||||
public RedpacketSendResult sendRedpack(Redpacket redpacket)
|
||||
throws WeixinException, IOException {
|
||||
return cashApi.sendRedpack(
|
||||
new FileInputStream(settings.getCertificatePath()), redpacket);
|
||||
new FileInputStream(settings.getCertificateFile0()), redpacket);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -750,8 +750,10 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public RedpacketRecord queryRedpack(String outTradeNo)
|
||||
throws WeixinException, IOException {
|
||||
return cashApi.queryRedpack(
|
||||
new FileInputStream(settings.getCertificatePath()), outTradeNo);
|
||||
return cashApi
|
||||
.queryRedpack(
|
||||
new FileInputStream(settings.getCertificateFile0()),
|
||||
outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -782,7 +784,7 @@ public class WeixinPayProxy {
|
||||
public MPPaymentResult mpPayment(MPPayment mpPayment)
|
||||
throws WeixinException, IOException {
|
||||
return cashApi.mchPayment(
|
||||
new FileInputStream(settings.getCertificatePath()), mpPayment);
|
||||
new FileInputStream(settings.getCertificateFile0()), mpPayment);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -811,8 +813,10 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public MPPaymentRecord mpPaymentQuery(String outTradeNo)
|
||||
throws WeixinException, IOException {
|
||||
return cashApi.mchPaymentQuery(
|
||||
new FileInputStream(settings.getCertificatePath()), outTradeNo);
|
||||
return cashApi
|
||||
.mchPaymentQuery(
|
||||
new FileInputStream(settings.getCertificateFile0()),
|
||||
outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
package com.foxinmy.weixin4j.settings;
|
||||
|
||||
/**
|
||||
* 微信请求配置相关(待实现
|
||||
*
|
||||
* @className Weixin4jHttpSettings
|
||||
* @author jy
|
||||
* @date 2016年1月28日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class Weixin4jHttpSettings {
|
||||
|
||||
}
|
||||
@ -1,108 +0,0 @@
|
||||
package com.foxinmy.weixin4j.settings;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信支付配置相关
|
||||
*
|
||||
* @className Weixin4jPaySettings
|
||||
* @author jy
|
||||
* @date 2016年1月28日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class Weixin4jPaySettings {
|
||||
|
||||
private final WeixinPayAccount payAccount;
|
||||
|
||||
public Weixin4jPaySettings() {
|
||||
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
|
||||
WeixinPayAccount.class));
|
||||
}
|
||||
|
||||
public Weixin4jPaySettings(WeixinPayAccount payAccount) {
|
||||
this.payAccount = payAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付账号信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public WeixinPayAccount getPayAccount() {
|
||||
return this.payAccount;
|
||||
}
|
||||
|
||||
private String billPath;
|
||||
|
||||
/**
|
||||
* 对账单保存路径
|
||||
*
|
||||
* @param billPath
|
||||
* 硬盘目录
|
||||
*/
|
||||
public Weixin4jPaySettings billPath(String billPath) {
|
||||
this.billPath = billPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认对账单保存路径
|
||||
*/
|
||||
public static final String DEFAULT_BILL_PATH = "/tmp/weixin4j/bill";
|
||||
|
||||
/**
|
||||
* 对账单保存路径,默认值为{@link #DEFAULT_BILL_PATH}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getBillPath() {
|
||||
if (StringUtil.isBlank(billPath)) {
|
||||
this.billPath = Weixin4jConfigUtil.getClassPathValue("bill.path",
|
||||
DEFAULT_BILL_PATH);
|
||||
}
|
||||
return this.billPath;
|
||||
}
|
||||
|
||||
private String certificatePath;
|
||||
|
||||
/**
|
||||
* ca证书存放路径
|
||||
*
|
||||
* @param certificatePath
|
||||
* 硬盘目录
|
||||
* @return
|
||||
*/
|
||||
public Weixin4jPaySettings certificatePath(String certificatePath) {
|
||||
this.certificatePath = certificatePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认ca证书存放路径
|
||||
*/
|
||||
public static final String DEFAULT_CAFILE_PATH = "classpath:ca.p12";
|
||||
|
||||
/**
|
||||
* ca证书存放路径,默认值为{@link #DEFAULT_CAFILE_PATH}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getCertificatePath() {
|
||||
if (StringUtil.isBlank(certificatePath)) {
|
||||
this.certificatePath = Weixin4jConfigUtil.getClassPathValue(
|
||||
"certificate.path", DEFAULT_CAFILE_PATH);
|
||||
}
|
||||
return this.certificatePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Weixin4jPaySettings [payAccount=" + payAccount + ", billPath="
|
||||
+ getBillPath() + ", certificatePath=" + getCertificatePath()
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@ -1,168 +0,0 @@
|
||||
package com.foxinmy.weixin4j.settings;
|
||||
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信基础配置相关
|
||||
*
|
||||
* @className Weixin4jSettings
|
||||
* @author jy
|
||||
* @date 2016年1月28日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class Weixin4jSettings {
|
||||
|
||||
private final WeixinAccount account;
|
||||
|
||||
public Weixin4jSettings() {
|
||||
this(Weixin4jConfigUtil.getWeixinAccount());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
* 应用唯一标识 appid/corpid
|
||||
* @param secret
|
||||
* 应用接口密钥
|
||||
*/
|
||||
public Weixin4jSettings(String id, String secret) {
|
||||
this(new WeixinAccount(id, secret));
|
||||
}
|
||||
|
||||
public Weixin4jSettings(WeixinAccount account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信账号信息
|
||||
*/
|
||||
public WeixinAccount getAccount() {
|
||||
return this.account;
|
||||
}
|
||||
|
||||
private String tokenPath;
|
||||
|
||||
/**
|
||||
* 使用FileTokenStorager时token的存放路径
|
||||
*
|
||||
* @param tokenPath
|
||||
* 硬盘目录
|
||||
* @return
|
||||
*/
|
||||
public Weixin4jSettings setTokenPath(String tokenPath) {
|
||||
this.tokenPath = tokenPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认token的存放路径
|
||||
*/
|
||||
public static final String DEFAULT_TOKEN_PATH = "/tmp/weixin4j/token";
|
||||
|
||||
/**
|
||||
* 使用FileTokenStorager时token的存放路径,默认值为{@link #DEFAULT_TOKEN_PATH}
|
||||
*/
|
||||
public String getTokenPath() {
|
||||
if (StringUtil.isBlank(tokenPath)) {
|
||||
tokenPath = Weixin4jConfigUtil.getClassPathValue("token.path",
|
||||
DEFAULT_TOKEN_PATH);
|
||||
}
|
||||
return tokenPath;
|
||||
}
|
||||
|
||||
private String qrcodePath;
|
||||
|
||||
/**
|
||||
* 二维码保存路径
|
||||
*
|
||||
* @param qrcodePath
|
||||
* 硬盘目录
|
||||
*/
|
||||
public Weixin4jSettings setQrcodePath(String qrcodePath) {
|
||||
this.qrcodePath = qrcodePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认二维码保存路径
|
||||
*/
|
||||
public static final String DEFAULT_QRCODE_PATH = "/tmp/weixin4j/qrcode";
|
||||
|
||||
/**
|
||||
* 二维码保存路径,默认值为{@link #DEFAULT_QRCODE_PATH}
|
||||
*/
|
||||
public String getQrcodePath() {
|
||||
if (StringUtil.isBlank(qrcodePath)) {
|
||||
this.qrcodePath = Weixin4jConfigUtil.getClassPathValue(
|
||||
"qrcode.path", DEFAULT_QRCODE_PATH);
|
||||
}
|
||||
return this.qrcodePath;
|
||||
}
|
||||
|
||||
private String mediaPath;
|
||||
|
||||
/**
|
||||
* 媒体文件保存路径
|
||||
*
|
||||
* @param mediaPath
|
||||
* 硬盘目录
|
||||
*/
|
||||
public Weixin4jSettings setMediaPath(String mediaPath) {
|
||||
this.mediaPath = mediaPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认媒体文件保存路径
|
||||
*/
|
||||
public static final String DEFAULT_MEDIA_PATH = "/tmp/weixin4j/media";
|
||||
|
||||
/**
|
||||
* 媒体文件保存路径,默认值为{@link #DEFAULT_MEDIA_PATH}
|
||||
*/
|
||||
public String getMediaPath() {
|
||||
if (StringUtil.isBlank(mediaPath)) {
|
||||
this.mediaPath = Weixin4jConfigUtil.getClassPathValue("media.path",
|
||||
DEFAULT_MEDIA_PATH);
|
||||
}
|
||||
return this.mediaPath;
|
||||
}
|
||||
|
||||
private TokenStorager tokenStorager;
|
||||
|
||||
/**
|
||||
* token存储
|
||||
*
|
||||
* @param tokenStorager
|
||||
* @return
|
||||
*/
|
||||
public Weixin4jSettings setTokenStorager(TokenStorager tokenStorager) {
|
||||
this.tokenStorager = tokenStorager;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token存储方式 默认为FileTokenStorager
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public TokenStorager getTokenStorager() {
|
||||
if (tokenStorager == null) {
|
||||
this.tokenStorager = new FileTokenStorager(getTokenPath());
|
||||
}
|
||||
return this.tokenStorager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Weixin4jSettings [account=" + account + ", tokenPath="
|
||||
+ getTokenPath() + ", qrcodePath=" + getQrcodePath()
|
||||
+ ", mediaPath=" + getMediaPath() + ", tokenStorager="
|
||||
+ getTokenStorager() + "]";
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@ -25,18 +24,6 @@ public class Weixin4jConfigUtil {
|
||||
.getResource("").getPath();
|
||||
try {
|
||||
weixinBundle = ResourceBundle.getBundle("weixin4j");
|
||||
File file = null;
|
||||
for (String key : weixinBundle.keySet()) {
|
||||
if (!key.endsWith(".path")) {
|
||||
continue;
|
||||
}
|
||||
file = new File(getValue(key).replaceFirst(CLASSPATH_PREFIX,
|
||||
CLASSPATH_VALUE));
|
||||
if (!file.exists() && !file.mkdirs()) {
|
||||
System.err.append(String.format("%s create fail.%n",
|
||||
file.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
} catch (MissingResourceException e) {
|
||||
;
|
||||
}
|
||||
|
||||
@ -0,0 +1,155 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.http.HttpParams;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
|
||||
/**
|
||||
* 微信配置相关
|
||||
*
|
||||
* @className Weixin4jSettings
|
||||
* @author jy
|
||||
* @date 2016年1月28日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class Weixin4jSettings {
|
||||
/**
|
||||
* 微信支付账号信息
|
||||
*/
|
||||
private WeixinPayAccount weixinPayAccount;
|
||||
/**
|
||||
* 微信账号信息
|
||||
*/
|
||||
private WeixinAccount weixinAccount;
|
||||
/**
|
||||
* Http参数
|
||||
*/
|
||||
private HttpParams httpParams;
|
||||
/**
|
||||
* token存储方式 默认为FileTokenStorager
|
||||
*/
|
||||
private TokenStorager tokenStorager;
|
||||
/**
|
||||
* 系统临时目录
|
||||
*/
|
||||
private String tmpdir;
|
||||
/**
|
||||
* 支付接口需要的证书文件(*.p12)
|
||||
*/
|
||||
private String certificateFile;
|
||||
|
||||
/**
|
||||
* 默认使用weixin4j.properties配置的信息
|
||||
*/
|
||||
public Weixin4jSettings() {
|
||||
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
|
||||
WeixinPayAccount.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付代理接口
|
||||
*
|
||||
* @param weixinPayAccount
|
||||
* 商户信息
|
||||
* @param certificateFile
|
||||
* 支付接口需要的证书文件(*.p12),比如退款接口
|
||||
*/
|
||||
public Weixin4jSettings(WeixinPayAccount weixinPayAccount,
|
||||
String certificateFile) {
|
||||
this.weixinPayAccount = weixinPayAccount;
|
||||
this.certificateFile = certificateFile;
|
||||
this.weixinAccount = new WeixinAccount(weixinPayAccount.getId(),
|
||||
weixinPayAccount.getSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通代理接口
|
||||
*
|
||||
* @param weixinAccount
|
||||
*/
|
||||
public Weixin4jSettings(WeixinAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
}
|
||||
|
||||
public WeixinPayAccount getWeixinPayAccount() {
|
||||
return weixinPayAccount;
|
||||
}
|
||||
|
||||
public WeixinAccount getWeixinAccount() {
|
||||
return weixinAccount;
|
||||
}
|
||||
|
||||
public HttpParams getHttpParams() {
|
||||
return httpParams;
|
||||
}
|
||||
|
||||
public HttpParams getHttpParams0() {
|
||||
if (httpParams == null) {
|
||||
return new HttpParams();
|
||||
}
|
||||
return httpParams;
|
||||
}
|
||||
|
||||
public String getTmpdir() {
|
||||
return tmpdir;
|
||||
}
|
||||
|
||||
public String getTmpdir0() {
|
||||
if (StringUtil.isBlank(tmpdir)) {
|
||||
return Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir",
|
||||
System.getProperty("java.io.tmpdir"));
|
||||
}
|
||||
return tmpdir;
|
||||
}
|
||||
|
||||
public TokenStorager getTokenStorager() {
|
||||
return tokenStorager;
|
||||
}
|
||||
|
||||
public TokenStorager getTokenStorager0() {
|
||||
if (tokenStorager == null) {
|
||||
return new FileTokenStorager(getTmpdir0());
|
||||
}
|
||||
return tokenStorager;
|
||||
}
|
||||
|
||||
public String getCertificateFile() {
|
||||
return certificateFile;
|
||||
}
|
||||
|
||||
public String getCertificateFile0() {
|
||||
if (StringUtil.isBlank(certificateFile)) {
|
||||
return Weixin4jConfigUtil.getClassPathValue(
|
||||
"weixin4j.certificate.file", "classpath:ca.p12");
|
||||
}
|
||||
return certificateFile;
|
||||
}
|
||||
|
||||
public void setHttpParams(HttpParams httpParams) {
|
||||
this.httpParams = httpParams;
|
||||
}
|
||||
|
||||
public void setTmpdir(String tmpdir) {
|
||||
this.tmpdir = tmpdir;
|
||||
}
|
||||
|
||||
public void setTokenStorager(TokenStorager tokenStorager) {
|
||||
this.tokenStorager = tokenStorager;
|
||||
}
|
||||
|
||||
public void setCertificateFile(String certificateFile) {
|
||||
this.certificateFile = certificateFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Weixin4jSettings [weixinAccount=" + weixinAccount
|
||||
+ ", httpParams=" + httpParams + ",tokenStorager="
|
||||
+ tokenStorager + ", tmpdir=" + tmpdir + ", certificateFile= "
|
||||
+ certificateFile + "]";
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.test;
|
||||
package com.foxinmy.weixin4j.base.test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.test;
|
||||
package com.foxinmy.weixin4j.base.test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
@ -0,0 +1,156 @@
|
||||
package com.foxinmy.weixin4j.base.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.exception.WeixinPayException;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.WeixinPayProxy;
|
||||
import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
|
||||
import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.payment.mch.PrePay;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.type.IdType;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jSettings;
|
||||
|
||||
/**
|
||||
* 支付测试(商户平台)
|
||||
*
|
||||
* @className PayTest
|
||||
* @author jy
|
||||
* @date 2016年1月30日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class PayTest {
|
||||
protected final static WeixinPayProxy PAY3;
|
||||
protected final static WeixinPayAccount ACCOUNT3;
|
||||
static {
|
||||
ACCOUNT3 = new WeixinPayAccount("wx5518c745065b1f95",
|
||||
"请填入v3版本的appSecret", "DTYUNJKL1234fghjkRTGHJNM345678fc",
|
||||
"1298173301", null, null, null, null, null);
|
||||
PAY3 = new WeixinPayProxy(new Weixin4jSettings(ACCOUNT3));
|
||||
}
|
||||
/**
|
||||
* 商户证书文件
|
||||
*/
|
||||
protected File caFile = new File("证书文件,如12333.p12");
|
||||
|
||||
@Test
|
||||
public void orderQueryV3() throws WeixinException {
|
||||
Order order = PAY3.orderQuery(new IdQuery("BY2016010800025",
|
||||
IdType.TRADENO));
|
||||
System.err.println(order);
|
||||
String sign = order.getSign();
|
||||
order.setSign(null);
|
||||
String valiSign = DigestUtil
|
||||
.paysignMd5(order, ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refundQueryV3() throws WeixinException {
|
||||
com.foxinmy.weixin4j.payment.mch.RefundRecord record = PAY3
|
||||
.refundQuery(new IdQuery("TT_1427183696238", IdType.TRADENO));
|
||||
System.err.println(record);
|
||||
// 这里的验证签名需要把details循环拼接
|
||||
String sign = record.getSign();
|
||||
record.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(record,
|
||||
ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downbillV3() throws WeixinException {
|
||||
Calendar c = Calendar.getInstance();
|
||||
System.err.println(c.getTime());
|
||||
c.set(Calendar.YEAR, 2015);
|
||||
c.set(Calendar.MONTH, 2);
|
||||
c.set(Calendar.DAY_OF_MONTH, 24);
|
||||
System.err.println(c.getTime());
|
||||
File file = PAY3.downloadBill(c.getTime(), null);
|
||||
System.err.println(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refundV3() throws WeixinException, IOException {
|
||||
IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO);
|
||||
com.foxinmy.weixin4j.payment.mch.RefundResult result = PAY3
|
||||
.refundApply(new FileInputStream(caFile), idQuery, "TT_R"
|
||||
+ System.currentTimeMillis(), 0.01d, 0.01d, null,
|
||||
"10020674");
|
||||
System.err.println(result);
|
||||
String sign = result.getSign();
|
||||
result.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(result,
|
||||
ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nativeV3() throws WeixinException {
|
||||
MchPayPackage payPackageV3 = new MchPayPackage(ACCOUNT3,
|
||||
"oyFLst1bqtuTcxK-ojF8hOGtLQao", "native测试", "T0001", 0.1d,
|
||||
"notify_url", "127.0.0.1", TradeType.NATIVE);
|
||||
payPackageV3.setProductId("0001");
|
||||
PrePay prePay = null;
|
||||
try {
|
||||
prePay = PAY3.createPrePay(payPackageV3);
|
||||
} catch (WeixinPayException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.err.println(prePay);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void closeOrder() throws WeixinException {
|
||||
ApiResult result = PAY3.closeOrder("D111");
|
||||
System.err.println(result);
|
||||
String sign = result.getSign();
|
||||
result.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(result,
|
||||
ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shortUrl() throws WeixinException {
|
||||
String url = "weixin://wxpay/bizpayurl?xxxxxx";
|
||||
String shortUrl = PAY3.getPayShorturl(url);
|
||||
System.err.println(shortUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interfaceReport() throws WeixinException {
|
||||
String interfaceUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
||||
int executeTime = 2500;
|
||||
String outTradeNo = null;
|
||||
String ip = "127.0.0.1";
|
||||
Date time = new Date();
|
||||
XmlResult returnXml = new XmlResult("SUCCESS", "");
|
||||
returnXml.setResultCode("SUCCESS");
|
||||
returnXml = PAY3.interfaceReport(interfaceUrl, executeTime, outTradeNo,
|
||||
ip, time, returnXml);
|
||||
System.err.println(returnXml);
|
||||
}
|
||||
}
|
||||
@ -35,70 +35,6 @@ weixin4j-mp
|
||||
|
||||
如何使用
|
||||
--------
|
||||
0.maven依赖(1.6.6,2015-12-31 released)
|
||||
|
||||
<dependency>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j-mp</artifactId>
|
||||
<version>1.6.6</version>
|
||||
</dependency>
|
||||
1.需新增或拷贝`weixin4j.properties`文件到项目的`classpath`中
|
||||
|
||||
weixin4j.properties说明
|
||||
|
||||
| 属性名 | 说明 |
|
||||
| :---------- | :-------------- |
|
||||
| weixin4j.account | 微信公众号信息 `json格式`(使用new WeixinProxy()缺省构造器时须填写) |
|
||||
| weixin4j.token.path | 使用FileTokenStorager时token保存的物理路径(非必须填写) |
|
||||
| weixin4j.qrcode.path | 调用二维码接口时保存二维码图片的物理路径(非必须填写) |
|
||||
| weixin4j.media.path | 调用媒体接口时保存媒体文件的物理路径(非必须填写) |
|
||||
| weixin4j.bill.path | 调用下载对账单接口保存文件的物理路径(非必须填写) |
|
||||
| weixin4j.certificate.file | 调用某些接口(支付相关)强制需要auth的ca授权文件(按须填写) |
|
||||
| weixin4j.user.oauth.redirect.uri | 调用OauthApi接口时需要填写的重定向路径(非必须填写) |
|
||||
|
||||
完整填写示例(properties中换行用右斜杆\\)
|
||||
|
||||
weixin4j.account={"id":"appid","secret":"appsecret",\
|
||||
"mchId":"V3.x版本下的微信商户号 微信支付时需要填入",\
|
||||
"certificateKey":"加载支付证书文件的密码 如果不填写则默认获取mchId作为密码",\
|
||||
"partnerId":"V2版本下的财付通的商户号 微信支付时需要填入",\
|
||||
"partnerKey":"V2版本下的财付通商户权限密钥Key 微信支付时需要填入",\
|
||||
"paySignKey":"微信支付中调用API的密钥 微信支付时需要填入"}
|
||||
|
||||
# 使用FileTokenStorager时token的存放路径(如果不填则默认为Weixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.token.path=/tmp/weixin4j/token
|
||||
# 二维码保存路径(如果不填则默认为Weixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.qrcode.path=/tmp/weixin4j/qrcode
|
||||
# 媒体文件保存路径(如果不填则默认为Weixin4jConst#DEFAULT_MEDIA_PATH)
|
||||
weixin4j.media.path=/tmp/weixin4j/media
|
||||
# 对账单保存路径(如果不填则默认为Weixin4jConst#DEFAULT_BILL_PATH)
|
||||
weixin4j.bill.path=/tmp/weixin4j/bill
|
||||
# ca证书存放的完整路径 (V2版本后缀为*.pfx,V3版本后缀为*.p12)
|
||||
weixin4j.certificate.file=/tmp/weixin4j/xxxxx.p12
|
||||
# classpath路径下可以这么写(如果不填则默认为Weixin4jConst#DEFAULT_CAFILE_PATH)
|
||||
# weixin4j.certificate.file=classpath:xxxxx.pfx
|
||||
|
||||
# 用户oauth授权后重定向的url(在使用OauthApi时填写)
|
||||
weixin4j.user.oauth.redirect.uri=http://xxx
|
||||
|
||||
2.实例化微信公众号接口代理对象,调用具体的API方法
|
||||
|
||||
// 微信公众号API 使用classpath的weixin4j.properties
|
||||
WeixinProxy weixinProxy = new WeixinProxy();
|
||||
// 直接传入公众号信息
|
||||
// weixinProxy = new WeixinProxy(appid,appsecret);
|
||||
weixinProxy.getUser(openId);
|
||||
// 微信支付API 使用classpath的weixin4j.properties
|
||||
WeixinPayProxy weixinPayProxy = new WeixinPayProxy();
|
||||
// 直接构造WexinAccount对象
|
||||
// weixinPayProxy = new WeixinPayProxy(weixinAccount);
|
||||
weixinPayProxy.orderQuery(idQuery);
|
||||
|
||||
> 针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenStorager`,默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用[RedisTokenStorager](../weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenStorager.java).
|
||||
>
|
||||
> WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenStorager());
|
||||
|
||||
> // weixinProxy = new WeixinProxy(new RedisTokenStorager(appid,appsecret));
|
||||
|
||||
[更新LOG](./CHANGE.md)
|
||||
----------------------
|
||||
@ -47,7 +47,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.settings.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.tuple.MassTuple;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
@ -55,6 +54,7 @@ import com.foxinmy.weixin4j.tuple.MpVideo;
|
||||
import com.foxinmy.weixin4j.tuple.Tuple;
|
||||
import com.foxinmy.weixin4j.type.MediaType;
|
||||
import com.foxinmy.weixin4j.type.TicketType;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jSettings;
|
||||
|
||||
/**
|
||||
* 微信公众平台接口实现
|
||||
@ -92,13 +92,13 @@ public class WeixinProxy {
|
||||
/**
|
||||
*
|
||||
* @param settings
|
||||
* 配置信息
|
||||
* @see com.foxinmy.weixin4j.settings.Weixin4jSettings
|
||||
* 微信配置信息
|
||||
* @see com.foxinmy.weixin4j.util.Weixin4jSettings
|
||||
*/
|
||||
public WeixinProxy(Weixin4jSettings settings) {
|
||||
this(new TokenHolder(new WeixinTokenCreator(settings.getAccount()
|
||||
.getId(), settings.getAccount().getSecret()),
|
||||
settings.getTokenStorager()));
|
||||
this(new TokenHolder(new WeixinTokenCreator(settings.getWeixinAccount()
|
||||
.getId(), settings.getWeixinAccount().getSecret()),
|
||||
settings.getTokenStorager0()));
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ public class WeixinProxy {
|
||||
* @return
|
||||
*/
|
||||
public WeixinAccount getWeixinAccount() {
|
||||
return this.settings.getAccount();
|
||||
return this.settings.getWeixinAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -222,29 +222,6 @@ public class WeixinProxy {
|
||||
return mediaApi.uploadMedia(isMaterial, is, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载媒体文件
|
||||
* <p>
|
||||
* 正常情况下返回表头如Content-Type: image/jpeg,否则抛出异常.
|
||||
* </p>
|
||||
*
|
||||
* @param mediaId
|
||||
* 存储在微信服务器上的媒体标识
|
||||
* @param isMaterial
|
||||
* 是否下载永久素材
|
||||
* @return 写入硬盘后的文件对象
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html">上传下载说明</a>
|
||||
* @see com.foxinmy.weixin4j.mp.api.MediaApi
|
||||
* @see {@link #downloadMedia(String)}
|
||||
*/
|
||||
public File downloadMediaFile(String mediaId, boolean isMaterial)
|
||||
throws WeixinException {
|
||||
return mediaApi.downloadMediaFile(mediaId, isMaterial,
|
||||
settings.getMediaPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载媒体文件
|
||||
*
|
||||
@ -1192,19 +1169,6 @@ public class WeixinProxy {
|
||||
return qrApi.createQR(parameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成带参数的二维码
|
||||
*
|
||||
* @return 硬盘存储的文件对象
|
||||
* @param parameter
|
||||
* 二维码参数
|
||||
* @throws WeixinException
|
||||
* @see {@link #createQR(QRParameter)}
|
||||
*/
|
||||
public File createQRFile(QRParameter parameter) throws WeixinException {
|
||||
return qrApi.createQRFile(parameter, settings.getQrcodePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置所属行业(每月可修改行业1次,账号仅可使用所属行业中相关的模板)
|
||||
*
|
||||
|
||||
@ -1,12 +1,8 @@
|
||||
package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
@ -228,63 +224,6 @@ public class MediaApi extends MpApi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载媒体素材
|
||||
* <p>
|
||||
* 正常情况下返回表头如Content-Type: image/jpeg,否则抛出异常.
|
||||
* </p>
|
||||
*
|
||||
* @param mediaId
|
||||
* 存储在微信服务器上的媒体标识
|
||||
* @param isMaterial
|
||||
* 是否下载永久素材
|
||||
* @param mediaPath
|
||||
* 媒体素材保存路径
|
||||
* @return 写入硬盘后的文件对象
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/11/07b6b76a6b6e8848e855a435d5e34a5f.html">下载临时媒体文件</a>
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/4/b3546879f07623cb30df9ca0e420a5d0.html">下载永久媒体素材</a>
|
||||
* @see {@link #downloadMedia(String,boolean)}
|
||||
*/
|
||||
public File downloadMediaFile(String mediaId, boolean isMaterial,
|
||||
String mediaPath) throws WeixinException {
|
||||
final String prefixName = String.format("%s.", mediaId);
|
||||
File[] files = new File(mediaPath).listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.startsWith(prefixName);
|
||||
}
|
||||
});
|
||||
if (files.length > 0) {
|
||||
return files[0];
|
||||
}
|
||||
MediaDownloadResult result = downloadMedia(mediaId, isMaterial);
|
||||
File file = new File(mediaPath + File.separator + result.getFileName());
|
||||
OutputStream os = null;
|
||||
try {
|
||||
if (file.createNewFile()) {
|
||||
os = new FileOutputStream(file);
|
||||
os.write(result.getContent());
|
||||
} else {
|
||||
throw new WeixinException(String.format("create file fail:%s",
|
||||
file.getAbsolutePath()));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载媒体素材
|
||||
*
|
||||
|
||||
@ -40,11 +40,7 @@ import com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.RefundResultV2;
|
||||
import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator;
|
||||
import com.foxinmy.weixin4j.payment.PayRequest;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jPaySettings;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.type.BillType;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.type.RefundType;
|
||||
@ -54,6 +50,7 @@ import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
|
||||
/**
|
||||
@ -67,27 +64,22 @@ import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
*/
|
||||
public class Pay2Api extends MpApi {
|
||||
|
||||
private final Weixin4jPaySettings settings;
|
||||
private final Weixin4jSettings settings;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public Pay2Api() {
|
||||
this(new Weixin4jPaySettings());
|
||||
this(new Weixin4jSettings());
|
||||
}
|
||||
|
||||
public Pay2Api(Weixin4jPaySettings settings) {
|
||||
this(settings, new FileTokenStorager(
|
||||
Weixin4jSettings.DEFAULT_TOKEN_PATH));
|
||||
}
|
||||
|
||||
public Pay2Api(Weixin4jPaySettings settings, TokenStorager tokenStorager) {
|
||||
public Pay2Api(Weixin4jSettings settings) {
|
||||
this.tokenHolder = new TokenHolder(new WeixinTokenCreator(settings
|
||||
.getWeixinAccount().getId(), settings.getWeixinAccount()
|
||||
.getSecret()), settings.getTokenStorager0());
|
||||
this.settings = settings;
|
||||
this.tokenHolder = new TokenHolder(
|
||||
new WeixinTokenCreator(settings.getPayAccount().getId(),
|
||||
settings.getPayAccount().getSecret()), tokenStorager);
|
||||
}
|
||||
|
||||
public WeixinPayAccount getPayAccount() {
|
||||
return this.settings.getPayAccount();
|
||||
return this.settings.getWeixinPayAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,7 +134,7 @@ public class Pay2Api extends MpApi {
|
||||
double totalFee, String notifyUrl, String createIp, String attach,
|
||||
Date timeStart, Date timeExpire, double transportFee,
|
||||
double productFee, String goodsTag) {
|
||||
PayPackageV2 payPackage = new PayPackageV2(settings.getPayAccount()
|
||||
PayPackageV2 payPackage = new PayPackageV2(getPayAccount()
|
||||
.getPartnerId(), body, outTradeNo, totalFee, notifyUrl,
|
||||
createIp);
|
||||
payPackage.setAttach(attach);
|
||||
@ -458,8 +450,8 @@ public class Pay2Api extends MpApi {
|
||||
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
|
||||
String fileName = String.format("%s_%s_%s.txt", formatBillDate,
|
||||
billType.name().toLowerCase(), getPayAccount().getId());
|
||||
File file = new File(String.format("%s/%s", settings.getBillPath(),
|
||||
fileName));
|
||||
File file = new File(String.format("%s/weixin4j_bill_%s",
|
||||
settings.getTmpdir0(), fileName));
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
@ -62,49 +59,4 @@ public class QrApi extends MpApi {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成带参数的二维码
|
||||
* <p>
|
||||
* 二维码分为临时跟永久两种,扫描时触发推送带参数事件
|
||||
* </p>
|
||||
*
|
||||
* @param parameter
|
||||
* 二维码参数
|
||||
* @param qrcodePath
|
||||
* 二维码保存路径
|
||||
* @return 硬盘存储的文件对象
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="mp.weixin.qq.com/wiki/18/28fc21e7ed87bec960651f0ce873ef8a.html">二维码</a>
|
||||
* @see #createQR(QRParameter)
|
||||
* @see com.foxinmy.weixin4j.mp.model.QRParameter
|
||||
*/
|
||||
public File createQRFile(QRParameter parameter, String qrcodePath)
|
||||
throws WeixinException {
|
||||
String filename = String.format("%s_%s_%d.jpg", parameter.getQrType()
|
||||
.name(), parameter.getSceneValue(), parameter
|
||||
.getExpireSeconds());
|
||||
File file = new File(qrcodePath + File.separator + filename);
|
||||
if (parameter.getQrType().ordinal() > 0 && file.exists()) {
|
||||
return file;
|
||||
}
|
||||
QRResult qrResult = createQR(parameter);
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(file);
|
||||
os.write(qrResult.getContent());
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
NotifyMessage: (客服消息)[http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html#.E5.AE.A2.E6.9C.8D.E6.8E.A5.E5.8F.A3-.E5.8F.91.E6.B6.88.E6.81.AF]
|
||||
|
||||
TemplateMessage: (模板消息)[http://mp.weixin.qq.com/wiki/17/304c1885ea66dbedf7dc170d84999a9d.html]
|
||||
@ -48,7 +48,7 @@ public class WeixinTicketCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("wx_mp_ticket_%s_%s", appid, ticketType.name());
|
||||
return String.format("weixin4j_mp_ticket_%s_%s", appid, ticketType.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -40,7 +40,7 @@ public class WeixinTokenCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("wx_mp_token_%s", appid);
|
||||
return String.format("weixin4j_mp_token_%s", appid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,24 +1,22 @@
|
||||
# \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath
|
||||
# \u516c\u4f17\u53f7\u4fe1\u606f
|
||||
|
||||
# \u516c\u4f17\u53f7\u4fe1\u606f \u8bf7\u6309\u9700\u586b\u5199
|
||||
weixin4j.account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\
|
||||
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"mchId":"\u5fae\u4fe1\u5546\u6237\u53f7 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"certificateKey":"\u52a0\u8f7d\u652f\u4ed8\u8bc1\u4e66\u6587\u4ef6\u7684\u5bc6\u7801 \u5982\u679c\u4e0d\u586b\u5199\u5219\u9ed8\u8ba4\u83b7\u53d6mchId\u4f5c\u4e3a\u5bc6\u7801",\
|
||||
"partnerId":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u7684\u5546\u6237\u53f7 \u8001\u7248\u672c\u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"partnerKey":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u5546\u6237\u6743\u9650\u5bc6\u94a5Key \u8001\u7248\u672c\u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"paySignKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165"}
|
||||
|
||||
# \u4f7f\u7528FileTokenStorager\u65f6token\u7684\u5b58\u653e\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.token.path=/tmp/weixin4j/token
|
||||
# \u4e8c\u7ef4\u7801\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.qrcode.path=/tmp/weixin4j/qrcode
|
||||
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_MEDIA_PATH)
|
||||
weixin4j.media.path=/tmp/weixin4j/media
|
||||
# \u5bf9\u8d26\u5355\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_BILL_PATH)
|
||||
weixin4j.bill.path=/tmp/weixin4j/bill
|
||||
# ca\u8bc1\u4e66\u5b58\u653e\u7684\u5b8c\u6574\u8def\u5f84 (V2\u7248\u672c\u540e\u7f00\u4e3a*.pfx,V3\u7248\u672c\u540e\u7f00\u4e3a*.p12)
|
||||
# weixin4j\u7684\u4e34\u65f6\u76ee\u5f55
|
||||
# \u53ef\u80fd\u5b58\u653etoken\u6587\u4ef6\u3001\u4e8c\u7ef4\u7801\u6587\u4ef6\u3001\u5a92\u4f53\u6587\u4ef6\u3001\u5bf9\u8d26\u5355\u6587\u4ef6\u7b49
|
||||
# \u4e3a\u7a7a\u65f6\u5219\u83b7\u53d6java.io.tmpdir\u4e34\u65f6\u76ee\u5f55
|
||||
weixin4j.tmpdir=
|
||||
# \u5fae\u4fe1\u652f\u4ed8\u67d0\u4e9b\u63a5\u53e3\u9700\u8981\u7684ca\u8bc1\u4e66\u5b58\u653e\u7684\u5b8c\u6574\u8def\u5f84
|
||||
# classpath\u8def\u5f84\u4e0b\u53ef\u4ee5\u8fd9\u4e48\u5199
|
||||
# weixin4j.certificate.file=classpath:xxxxx.p12
|
||||
# \u4e3a\u7a7a\u65f6\u5219\u83b7\u53d6classpath\u6839\u76ee\u5f55\u4e0b\u7684ca.p12\u6587\u4ef6
|
||||
weixin4j.certificate.file=/tmp/weixin4j/xxxxx.p12
|
||||
# classpath\u8def\u5f84\u4e0b\u53ef\u4ee5\u8fd9\u4e48\u5199(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_CAFILE_PATH)
|
||||
# weixin4j.certificate.file=classpath:xxxxx.pfx
|
||||
|
||||
# \u7528\u6237oauth\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url(\u5728\u4f7f\u7528OauthApi\u65f6\u586b\u5199)
|
||||
weixin4j.user.oauth.redirect.uri=
|
||||
@ -92,13 +92,6 @@ public class MediaTest extends TokenTest {
|
||||
System.err.println(mediaId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void download2() throws WeixinException, IOException {
|
||||
File file = mediaApi.downloadMediaFile("8790403529", true,
|
||||
"/tmp/weixin4j/media");
|
||||
Assert.assertTrue(file.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downloadArticle() throws WeixinException {
|
||||
List<MpArticle> articles = mediaApi.downloadArticle("17385064953");
|
||||
|
||||
@ -1,44 +1,34 @@
|
||||
package com.foxinmy.weixin4j.mp.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.exception.WeixinPayException;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.mp.api.Pay2Api;
|
||||
import com.foxinmy.weixin4j.payment.WeixinPayProxy;
|
||||
import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
|
||||
import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.payment.mch.PrePay;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jPaySettings;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.type.IdType;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jSettings;
|
||||
|
||||
/**
|
||||
* 支付测试(V2版本 2014年9月之前申请微信支付的公众号)
|
||||
*
|
||||
* @className PayTest
|
||||
* @author jy
|
||||
* @date 2016年1月30日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class PayTest {
|
||||
protected final static Pay2Api PAY2;
|
||||
protected final static WeixinPayProxy PAY3;
|
||||
protected final static WeixinPayAccount ACCOUNT2;
|
||||
protected final static WeixinPayAccount ACCOUNT3;
|
||||
static {
|
||||
ACCOUNT2 = new WeixinPayAccount("请填入v2版本的appid", "请填入v2版本的appSecret",
|
||||
"请填入v2版本的paysignkey", null, null, null, null,
|
||||
"请填入v2版本的partnerId", "请填入v2版本的partnerKey");
|
||||
PAY2 = new Pay2Api(new Weixin4jPaySettings(ACCOUNT2));
|
||||
ACCOUNT3 = new WeixinPayAccount("请填入v3版本的appid", "请填入v3版本的appSecret",
|
||||
"请填入v3版本的paysignkey", "请填入v3版本的mchid", null, null, null, null,
|
||||
null);
|
||||
PAY3 = new WeixinPayProxy(new Weixin4jPaySettings(ACCOUNT3));
|
||||
PAY2 = new Pay2Api(new Weixin4jSettings(ACCOUNT2));
|
||||
}
|
||||
/**
|
||||
* 商户证书文件
|
||||
@ -62,7 +52,6 @@ public class PayTest {
|
||||
public void refundQueryV2() throws WeixinException {
|
||||
System.err.println(PAY2.refundQuery(new IdQuery("D14123000004",
|
||||
IdType.TRADENO)));
|
||||
refundQueryV3();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -74,110 +63,4 @@ public class PayTest {
|
||||
File file = PAY2.downloadBill(c.getTime(), null);
|
||||
System.err.println(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orderQueryV3() throws WeixinException {
|
||||
Order order = PAY3.orderQuery(new IdQuery("T0002", IdType.TRADENO));
|
||||
System.err.println(order);
|
||||
String sign = order.getSign();
|
||||
order.setSign(null);
|
||||
String valiSign = DigestUtil
|
||||
.paysignMd5(order, ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refundQueryV3() throws WeixinException {
|
||||
com.foxinmy.weixin4j.payment.mch.RefundRecord record = PAY3
|
||||
.refundQuery(new IdQuery("TT_1427183696238", IdType.TRADENO));
|
||||
System.err.println(record);
|
||||
// 这里的验证签名需要把details循环拼接
|
||||
String sign = record.getSign();
|
||||
record.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(record,
|
||||
ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downbillV3() throws WeixinException {
|
||||
Calendar c = Calendar.getInstance();
|
||||
System.err.println(c.getTime());
|
||||
c.set(Calendar.YEAR, 2015);
|
||||
c.set(Calendar.MONTH, 2);
|
||||
c.set(Calendar.DAY_OF_MONTH, 24);
|
||||
System.err.println(c.getTime());
|
||||
File file = PAY3.downloadBill(c.getTime(), null);
|
||||
System.err.println(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refundV3() throws WeixinException, IOException {
|
||||
IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO);
|
||||
com.foxinmy.weixin4j.payment.mch.RefundResult result = PAY3
|
||||
.refundApply(new FileInputStream(caFile), idQuery, "TT_R"
|
||||
+ System.currentTimeMillis(), 0.01d, 0.01d, null,
|
||||
"10020674");
|
||||
System.err.println(result);
|
||||
String sign = result.getSign();
|
||||
result.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(result,
|
||||
ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nativeV3() throws WeixinException {
|
||||
MchPayPackage payPackageV3 = new MchPayPackage(ACCOUNT3,
|
||||
"oyFLst1bqtuTcxK-ojF8hOGtLQao", "native测试", "T0001", 0.1d,
|
||||
"notify_url", "127.0.0.1", TradeType.NATIVE);
|
||||
payPackageV3.setProductId("0001");
|
||||
PrePay prePay = null;
|
||||
try {
|
||||
prePay = PAY3.createPrePay(payPackageV3);
|
||||
} catch (WeixinPayException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.err.println(prePay);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void closeOrder() throws WeixinException {
|
||||
ApiResult result = PAY3.closeOrder("D111");
|
||||
System.err.println(result);
|
||||
String sign = result.getSign();
|
||||
result.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(result,
|
||||
ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shortUrl() throws WeixinException {
|
||||
String url = "weixin://wxpay/bizpayurl?xxxxxx";
|
||||
String shortUrl = PAY3.getPayShorturl(url);
|
||||
System.err.println(shortUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interfaceReport() throws WeixinException {
|
||||
String interfaceUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
||||
int executeTime = 2500;
|
||||
String outTradeNo = null;
|
||||
String ip = "127.0.0.1";
|
||||
Date time = new Date();
|
||||
XmlResult returnXml = new XmlResult("SUCCESS", "");
|
||||
returnXml.setResultCode("SUCCESS");
|
||||
returnXml = PAY3.interfaceReport(interfaceUrl, executeTime, outTradeNo,
|
||||
ip, time, returnXml);
|
||||
System.err.println(returnXml);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.foxinmy.weixin4j.mp.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Assert;
|
||||
@ -10,6 +9,7 @@ import org.junit.Test;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.mp.api.QrApi;
|
||||
import com.foxinmy.weixin4j.mp.model.QRParameter;
|
||||
import com.foxinmy.weixin4j.mp.model.QRResult;
|
||||
|
||||
/**
|
||||
* 二维码相关测试
|
||||
@ -29,23 +29,21 @@ public class QRTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void temp_qr() throws WeixinException, IOException {
|
||||
File file = qrApi.createQRFile(QRParameter.createTemporary(1200, 1200),
|
||||
"/tmp/weixin4j/qrcode");
|
||||
Assert.assertTrue(file.exists());
|
||||
QRResult result = qrApi.createQR(QRParameter
|
||||
.createTemporary(1200, 1200));
|
||||
Assert.assertTrue(!result.getTicket().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forever_qr_int() throws WeixinException, IOException {
|
||||
File file = qrApi.createQRFile(QRParameter.createPermanenceInt(2),
|
||||
"/tmp/weixin4j/qrcode");
|
||||
Assert.assertTrue(file.exists());
|
||||
QRResult result = qrApi.createQR(QRParameter.createPermanenceInt(2));
|
||||
Assert.assertTrue(!result.getTicket().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forever_qr_str() throws WeixinException, IOException {
|
||||
File file = qrApi.createQRFile(
|
||||
QRParameter.createPermanenceStr("1200中文"),
|
||||
"/tmp/weixin4j/qrcode");
|
||||
Assert.assertTrue(file.exists());
|
||||
QRResult result = qrApi.createQR(QRParameter
|
||||
.createPermanenceStr("1200中文"));
|
||||
Assert.assertTrue(!result.getTicket().isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,81 +36,6 @@ weixin4j-qy
|
||||
|
||||
如何使用
|
||||
--------
|
||||
0.maven依赖(1.6.6,2015-12-31 released)
|
||||
|
||||
<dependency>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j-qy</artifactId>
|
||||
<version>1.6.6</version>
|
||||
</dependency>
|
||||
1.需新增或拷贝`weixin4j.properties`文件到项目的`classpath`中
|
||||
|
||||
weixin4j.properties说明
|
||||
|
||||
| 属性名 | 说明 |
|
||||
| :---------- | :-------------- |
|
||||
| weixin4j.account | 微信企业号信息 `json格式`(使用new WeixinProxy()缺省构造器时须填写) |
|
||||
| weixin4j.token.path | 使用FileTokenStorager时token保存的物理路径(非必须填写) |
|
||||
| weixin4j.media.path | 调用媒体接口时保存媒体文件的物理路径(非必须填写) |
|
||||
| weixin4j.bill.path | 调用下载对账单接口保存文件的物理路径(非必须填写) |
|
||||
| weixin4j.certificate.file | 调用某些接口(支付相关)强制需要auth的ca授权文件(非必须填写) |
|
||||
| weixin4j.user.oauth.redirect.uri | 企业号用户身份授权后重定向的url(OauthApi接口) |
|
||||
| weixin4j.third.oauth.redirect.uri | 企业号第三方提供商授权后重定向的url(OauthApi接口) |
|
||||
| weixin4j.suite.oauth.redirect.uri | 企业号第三方应用套件授权后重定向的url(OauthApi接口) |
|
||||
|
||||
示例(properties中换行用右斜杆\\)
|
||||
|
||||
weixin4j.account={"id":"corpid","secret":"corpsecret",\
|
||||
"suites":[{"id":"应用套件的id","secret":"应用套件的secret"}],\
|
||||
"providerSecret":"第三方提供商secret(企业号登陆)",\
|
||||
"chatSecret":"消息服务secret(企业号消息服务,暂时没用到)",\
|
||||
"mchId":"微信商户号 微信支付时需要填入",\
|
||||
"certificateKey":"加载支付证书文件的密码 如果不填写则默认获取mchId作为密码",\
|
||||
"paySignKey":"微信支付中调用API的密钥 微信支付时需要填入"}
|
||||
|
||||
# 使用FileTokenStorager时token的存放路径(如果不填则默认为Weixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.token.path=/tmp/weixin4j/token
|
||||
# 二维码保存路径(如果不填则默认为Weixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.qrcode.path=/tmp/weixin4j/qrcode
|
||||
# 媒体文件保存路径(如果不填则默认为Weixin4jConst#DEFAULT_MEDIA_PATH)
|
||||
weixin4j.media.path=/tmp/weixin4j/media
|
||||
# 对账单保存路径(如果不填则默认为Weixin4jConst#DEFAULT_BILL_PATH)
|
||||
weixin4j.bill.path=/tmp/weixin4j/bill
|
||||
# ca证书存放的完整路径
|
||||
weixin4j.certificate.file=/tmp/weixin4j/xxxxx.p12
|
||||
# classpath路径下可以这么写(如果不填则默认为Weixin4jConst#DEFAULT_CAFILE_PATH)
|
||||
# weixin4j.certificate.file=classpath:xxxxx.pfx
|
||||
|
||||
# 企业号用户身份授权后重定向的url(在使用OauthApi时填写)
|
||||
weixin4j.user.oauth.redirect.uri=
|
||||
# 企业号第三方提供商授权后重定向的url(在使用OauthApi时填写)
|
||||
weixin4j.third.oauth.redirect.uri=
|
||||
# 企业号第三方应用套件授权后重定向的url(在使用OauthApi时填写)
|
||||
weixin4j.suite.oauth.redirect.uri=
|
||||
|
||||
2.实例化微信企业号接口代理对象,调用具体的API方法
|
||||
|
||||
// 微信企业号API 使用classpath的weixin4j.properties
|
||||
WeixinProxy weixinProxy = new WeixinProxy();
|
||||
// 直接传入企业号信息
|
||||
// weixinProxy = new WeixinProxy(corpid,corpsecret);
|
||||
weixinProxy.getUser(userid);
|
||||
// 微信支付API 使用classpath的weixin4j.properties
|
||||
WeixinPayProxy weixinPayProxy = new WeixinPayProxy();
|
||||
// 直接构造WexinAccount对象
|
||||
// weixinPayProxy = new WeixinPayProxy(weixinAccount);
|
||||
weixinPayProxy.orderQuery(idQuery);
|
||||
// 微信第三方应用API 使用classpath的weixin4j.properties
|
||||
WeixinSuiteProxy weixinSuiteProxy = new WeixinSuiteProxy();
|
||||
// 直接传入套件信息
|
||||
//weixinSuiteProxy = new WeixinSuiteProxy(suiteId,suiteSecret);
|
||||
weixinSuiteProxy.api().getOAuthInfo(authCorpid);
|
||||
|
||||
> 针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenStorager`,默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用[RedisTokenStorager](../weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenStorager.java).
|
||||
|
||||
> WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenStorager());
|
||||
|
||||
> // weixinProxy = new WeixinProxy(new RedisTokenStorager(corpid,corpsecret));
|
||||
|
||||
[更新LOG](./CHANGE.md)
|
||||
----------------------
|
||||
@ -1,6 +1,5 @@
|
||||
package com.foxinmy.weixin4j.qy;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
@ -48,11 +47,11 @@ import com.foxinmy.weixin4j.qy.type.ChatType;
|
||||
import com.foxinmy.weixin4j.qy.type.InviteType;
|
||||
import com.foxinmy.weixin4j.qy.type.KfType;
|
||||
import com.foxinmy.weixin4j.qy.type.UserStatus;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
import com.foxinmy.weixin4j.type.MediaType;
|
||||
import com.foxinmy.weixin4j.type.TicketType;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jSettings;
|
||||
|
||||
/**
|
||||
* 微信企业号接口实现
|
||||
@ -90,13 +89,13 @@ public class WeixinProxy {
|
||||
/**
|
||||
*
|
||||
* @param settings
|
||||
* 配置信息
|
||||
* @see com.foxinmy.weixin4j.settings.Weixin4jSettings
|
||||
* 微信配置信息
|
||||
* @see com.foxinmy.weixin4j.util.Weixin4jSettings
|
||||
*/
|
||||
public WeixinProxy(Weixin4jSettings settings) {
|
||||
this(new TokenHolder(new WeixinTokenCreator(settings.getAccount()
|
||||
.getId(), settings.getAccount().getSecret()),
|
||||
settings.getTokenStorager()));
|
||||
this(new TokenHolder(new WeixinTokenCreator(settings.getWeixinAccount()
|
||||
.getId(), settings.getWeixinAccount().getSecret()),
|
||||
settings.getTokenStorager0()));
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@ -116,8 +115,8 @@ public class WeixinProxy {
|
||||
TokenHolder suiteTokenHolder) {
|
||||
this(new TokenHolder(new WeixinTokenSuiteCreator(perCodeHolder,
|
||||
suiteTokenHolder), suiteTokenHolder.getTokenStorager()));
|
||||
this.settings = new Weixin4jSettings(perCodeHolder.getAuthCorpId(),
|
||||
null);
|
||||
this.settings = new Weixin4jSettings(new WeixinAccount(
|
||||
perCodeHolder.getAuthCorpId(), null));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -156,7 +155,7 @@ public class WeixinProxy {
|
||||
* @return
|
||||
*/
|
||||
public WeixinAccount getWeixinAccount() {
|
||||
return this.settings.getAccount();
|
||||
return this.settings.getWeixinAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -345,25 +344,6 @@ public class WeixinProxy {
|
||||
return mediaApi.uploadMedia(agentid, is, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载媒体文件
|
||||
*
|
||||
* @param agentid
|
||||
* 企业应用Id(<font color="red">大于0时视为获取永久媒体文件</font>)
|
||||
* @param mediaId
|
||||
* 存储在微信服务器上的媒体标识
|
||||
* @return 写入硬盘后的文件对象
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.qy.api.MediaApi
|
||||
* @see com.foxinmy.weixin4j.type.MediaType
|
||||
* @see {@link #downloadMedia(int,String)}
|
||||
*/
|
||||
public File downloadMediaFile(int agentid, String mediaId)
|
||||
throws WeixinException {
|
||||
return mediaApi.downloadMediaFile(agentid, mediaId,
|
||||
settings.getMediaPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载媒体文件
|
||||
*
|
||||
|
||||
@ -3,7 +3,6 @@ package com.foxinmy.weixin4j.qy;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.qy.api.ProviderApi;
|
||||
@ -11,14 +10,11 @@ import com.foxinmy.weixin4j.qy.api.SuiteApi;
|
||||
import com.foxinmy.weixin4j.qy.model.OUserInfo;
|
||||
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
|
||||
import com.foxinmy.weixin4j.qy.suite.SuiteTicketHolder;
|
||||
import com.foxinmy.weixin4j.qy.suite.Weixin4jSuiteSettings;
|
||||
import com.foxinmy.weixin4j.qy.token.WeixinProviderTokenCreator;
|
||||
import com.foxinmy.weixin4j.qy.type.LoginTargetType;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信第三方应用接口实现
|
||||
@ -36,72 +32,52 @@ public class WeixinSuiteProxy {
|
||||
private Map<String, SuiteApi> suiteMap;
|
||||
private ProviderApi providerApi;
|
||||
|
||||
private final Weixin4jSuiteSettings suiteSettings;
|
||||
|
||||
public WeixinSuiteProxy() {
|
||||
this(Weixin4jSettings.DEFAULT_TOKEN_PATH);
|
||||
this(new Weixin4jSuiteSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tokenPath
|
||||
* 使用文件存储token的保存路径
|
||||
* @param suiteSettings
|
||||
* 套件信息配置
|
||||
*/
|
||||
public WeixinSuiteProxy(String tokenPath) {
|
||||
this(new FileTokenStorager(tokenPath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tokenStorager
|
||||
* token存储
|
||||
*/
|
||||
public WeixinSuiteProxy(TokenStorager tokenStorager) {
|
||||
this(tokenStorager, JSON.parseObject(
|
||||
Weixin4jConfigUtil.getValue("account"), WeixinQyAccount.class));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tokenStorager
|
||||
* token存储
|
||||
* @param suites
|
||||
* 套件信息 必填项
|
||||
*/
|
||||
public WeixinSuiteProxy(TokenStorager tokenStorager,
|
||||
WeixinQyAccount weixinAccount) {
|
||||
this(tokenStorager, weixinAccount.getId(), weixinAccount
|
||||
.getProviderSecret(), weixinAccount.suitesToArray());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tokenStorager
|
||||
* token存储
|
||||
* @param providerCorpId
|
||||
* 服务商的企业号ID <font color="red">使用服务商API时必填项</font>
|
||||
* @param providerSecret
|
||||
* 服务商secret <font color="red">使用服务商API时必填项</font>
|
||||
* @param suites
|
||||
* 套件信息 <font color="red">使用套件API时必填项</font>
|
||||
*/
|
||||
public WeixinSuiteProxy(TokenStorager tokenStorager, String providerCorpId,
|
||||
String providerSecret, WeixinAccount... suites) {
|
||||
if (suites != null) {
|
||||
public WeixinSuiteProxy(Weixin4jSuiteSettings suiteSettings) {
|
||||
this.suiteSettings = suiteSettings;
|
||||
if (suiteSettings.getWeixinAccount().getSuiteAccounts() != null) {
|
||||
this.suiteMap = new HashMap<String, SuiteApi>();
|
||||
for (WeixinAccount suite : suites) {
|
||||
for (WeixinAccount suite : suiteSettings.getWeixinAccount()
|
||||
.getSuiteAccounts()) {
|
||||
this.suiteMap.put(suite.getId(), new SuiteApi(
|
||||
new SuiteTicketHolder(suite.getId(), suite.getSecret(),
|
||||
tokenStorager)));
|
||||
this.suiteMap.put(null, suiteMap.get(suites[0].getId()));
|
||||
suiteSettings.getTokenStorager0())));
|
||||
this.suiteMap.put(
|
||||
null,
|
||||
suiteMap.get(suiteSettings.getWeixinAccount()
|
||||
.getSuiteAccounts().get(0).getId()));
|
||||
}
|
||||
}
|
||||
if (StringUtil.isNotBlank(providerCorpId)
|
||||
&& StringUtil.isNotBlank(providerSecret)) {
|
||||
if (StringUtil.isNotBlank(suiteSettings.getWeixinAccount().getId())
|
||||
&& StringUtil.isNotBlank(suiteSettings.getWeixinAccount()
|
||||
.getProviderSecret())) {
|
||||
this.providerApi = new ProviderApi(new TokenHolder(
|
||||
new WeixinProviderTokenCreator(providerCorpId,
|
||||
providerSecret), tokenStorager));
|
||||
new WeixinProviderTokenCreator(suiteSettings
|
||||
.getWeixinAccount().getId(), suiteSettings
|
||||
.getWeixinAccount().getProviderSecret()),
|
||||
suiteSettings.getTokenStorager0()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业号信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public WeixinQyAccount getWeixinAccount() {
|
||||
return this.suiteSettings.getWeixinAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
* 只关注第一个套件获取API(如果只有一个套件
|
||||
*
|
||||
|
||||
@ -1,12 +1,8 @@
|
||||
package com.foxinmy.weixin4j.qy.api;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -190,57 +186,6 @@ public class MediaApi extends QyApi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载媒体文件
|
||||
*
|
||||
* @param agentid
|
||||
* 企业应用Id(<font color="red">大于0时视为获取永久媒体文件</font>)
|
||||
* @param mediaId
|
||||
* 存储在微信服务器上的媒体标识
|
||||
* @param mediaPath
|
||||
* 媒体素材保存路径
|
||||
* @return 写入硬盘后的文件对象
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.type.MediaType
|
||||
* @see {@link #downloadMedia(int,String)}
|
||||
*/
|
||||
public File downloadMediaFile(int agentid, String mediaId, String mediaPath)
|
||||
throws WeixinException {
|
||||
final String prefixName = String.format("%d_%s.", agentid, mediaId);
|
||||
File[] files = new File(mediaPath).listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.startsWith(prefixName);
|
||||
}
|
||||
});
|
||||
if (files.length > 0) {
|
||||
return files[0];
|
||||
}
|
||||
MediaDownloadResult result = downloadMedia(agentid, mediaId);
|
||||
File file = new File(mediaPath + File.separator + result.getFileName());
|
||||
OutputStream os = null;
|
||||
try {
|
||||
if (file.createNewFile()) {
|
||||
os = new FileOutputStream(file);
|
||||
os.write(result.getContent());
|
||||
} else {
|
||||
throw new WeixinException(String.format("create file fail:%s",
|
||||
file.getAbsolutePath()));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载媒体文件
|
||||
*
|
||||
|
||||
@ -23,7 +23,7 @@ public class WeixinQyAccount extends WeixinAccount {
|
||||
/**
|
||||
* 多个应用套件信息
|
||||
*/
|
||||
private List<WeixinAccount> suites;
|
||||
private List<WeixinAccount> suiteAccounts;
|
||||
/**
|
||||
* 第三方提供商secret(企业号登陆)
|
||||
*/
|
||||
@ -36,32 +36,30 @@ public class WeixinQyAccount extends WeixinAccount {
|
||||
/**
|
||||
*
|
||||
* @param corpid
|
||||
* 企业ID
|
||||
* 企业ID 必填
|
||||
* @param corpsecret
|
||||
* 管理组的凭证密钥
|
||||
* @param suiteId
|
||||
* 应用套件的id
|
||||
* @param suiteSecret
|
||||
* 应用套件的secret
|
||||
* 管理组的凭证密钥 使用普通接口(WeixinProxy对象)必须填写
|
||||
* @param suites
|
||||
* 应用套件集合 使用套件接口(WeixinSuiteProxy#SuiteApi)必须填写
|
||||
* @param providerSecret
|
||||
* 第三方提供商secret(企业号登陆)
|
||||
* 第三方提供商secret(企业号登陆) 使用服务商接口(WeixinSuiteProxy#ProviderApi)必填项
|
||||
* @param chatSecret
|
||||
* 消息服务secret(企业号聊天)
|
||||
* 消息服务secret(企业号聊天) 暂无用途
|
||||
*/
|
||||
@JSONCreator
|
||||
public WeixinQyAccount(@JSONField(name = "id") String corpid,
|
||||
@JSONField(name = "secret") String corpsecret,
|
||||
@JSONField(name = "suites") List<WeixinAccount> suites,
|
||||
@JSONField(name = "suites") List<WeixinAccount> suiteAccounts,
|
||||
@JSONField(name = "providerSecret") String providerSecret,
|
||||
@JSONField(name = "chatSecret") String chatSecret) {
|
||||
super(corpid, corpsecret);
|
||||
this.suites = suites;
|
||||
this.suiteAccounts = suiteAccounts;
|
||||
this.providerSecret = providerSecret;
|
||||
this.chatSecret = chatSecret;
|
||||
}
|
||||
|
||||
public List<WeixinAccount> getSuites() {
|
||||
return suites;
|
||||
public List<WeixinAccount> getSuiteAccounts() {
|
||||
return suiteAccounts;
|
||||
}
|
||||
|
||||
public String getProviderSecret() {
|
||||
@ -72,15 +70,15 @@ public class WeixinQyAccount extends WeixinAccount {
|
||||
return chatSecret;
|
||||
}
|
||||
|
||||
public WeixinAccount[] suitesToArray() {
|
||||
return suites != null ? suites
|
||||
.toArray(new WeixinAccount[suites.size()]) : null;
|
||||
public WeixinAccount[] suiteAccountsToArray() {
|
||||
return suiteAccounts != null ? suiteAccounts
|
||||
.toArray(new WeixinAccount[suiteAccounts.size()]) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinQyAccount [" + super.toString() + ", suites=" + suites
|
||||
+ ", providerSecret=" + providerSecret + ", chatSecret="
|
||||
+ chatSecret + "]";
|
||||
return "WeixinQyAccount [" + super.toString() + ", suiteAccounts="
|
||||
+ suiteAccounts + ", providerSecret=" + providerSecret
|
||||
+ ", chatSecret=" + chatSecret + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
package com.foxinmy.weixin4j.qy.suite;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.http.HttpParams;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信第三方套件配置相关
|
||||
*
|
||||
* @className Weixin4jSuiteSettings
|
||||
* @author jy
|
||||
* @date 2016年1月28日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class Weixin4jSuiteSettings {
|
||||
/**
|
||||
* 微信企业号信息
|
||||
*/
|
||||
private final WeixinQyAccount weixinAccount;
|
||||
/**
|
||||
* Http参数
|
||||
*/
|
||||
private HttpParams httpParams;
|
||||
/**
|
||||
* token存储方式 默认为FileTokenStorager
|
||||
*/
|
||||
private TokenStorager tokenStorager;
|
||||
/**
|
||||
* 系统临时目录
|
||||
*/
|
||||
private String tmpdir;
|
||||
|
||||
/**
|
||||
* 默认使用weixin4j.properties配置的信息
|
||||
*/
|
||||
public Weixin4jSuiteSettings() {
|
||||
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
|
||||
WeixinQyAccount.class));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param providerCorpId
|
||||
* 服务商的企业号ID <font color="red">使用服务商API时必填项</font>
|
||||
* @param providerSecret
|
||||
* 服务商secret <font color="red">使用服务商API时必填项</font>
|
||||
* @param suites
|
||||
* 套件信息 <font color="red">使用套件API时必填项</font>
|
||||
*/
|
||||
public Weixin4jSuiteSettings(String providerCorpId, String providerSecret,
|
||||
WeixinAccount... suites) {
|
||||
this.weixinAccount = new WeixinQyAccount(providerCorpId, null,
|
||||
Arrays.asList(suites), providerSecret, null);
|
||||
}
|
||||
|
||||
private Weixin4jSuiteSettings(WeixinQyAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
}
|
||||
|
||||
public WeixinQyAccount getWeixinAccount() {
|
||||
return weixinAccount;
|
||||
}
|
||||
|
||||
public HttpParams getHttpParams() {
|
||||
return httpParams;
|
||||
}
|
||||
|
||||
public HttpParams getHttpParams0() {
|
||||
if (httpParams == null) {
|
||||
return new HttpParams();
|
||||
}
|
||||
return httpParams;
|
||||
}
|
||||
|
||||
public String getTmpdir() {
|
||||
return tmpdir;
|
||||
}
|
||||
|
||||
public String getTmpdir0() {
|
||||
if (StringUtil.isBlank(tmpdir)) {
|
||||
return Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir",
|
||||
System.getProperty("java.io.tmpdir"));
|
||||
}
|
||||
return tmpdir;
|
||||
}
|
||||
|
||||
public TokenStorager getTokenStorager() {
|
||||
return tokenStorager;
|
||||
}
|
||||
|
||||
public TokenStorager getTokenStorager0() {
|
||||
if (tokenStorager == null) {
|
||||
return new FileTokenStorager(getTmpdir0());
|
||||
}
|
||||
return tokenStorager;
|
||||
}
|
||||
|
||||
public void setHttpParams(HttpParams httpParams) {
|
||||
this.httpParams = httpParams;
|
||||
}
|
||||
|
||||
public void setTmpdir(String tmpdir) {
|
||||
this.tmpdir = tmpdir;
|
||||
}
|
||||
|
||||
public void setTokenStorager(TokenStorager tokenStorager) {
|
||||
this.tokenStorager = tokenStorager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Weixin4jSuiteSettings [weixinAccount=" + weixinAccount
|
||||
+ ", httpParams=" + httpParams + ",tokenStorager="
|
||||
+ tokenStorager + ", tmpdir=" + tmpdir + "]";
|
||||
}
|
||||
}
|
||||
@ -42,7 +42,7 @@ public class WeixinSuitePreCodeCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("wx_qy_suite_precode_%s", suiteId);
|
||||
return String.format("weixin4j_qy_suite_precode_%s", suiteId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -36,7 +36,7 @@ public class WeixinSuiteTokenCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("wx_qy_suite_token_%s", ticketHolder.getSuiteId());
|
||||
return String.format("weixin4j_qy_suite_token_%s", ticketHolder.getSuiteId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -42,7 +42,7 @@ public class WeixinTokenSuiteCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("wx_qy_token_suite_%s:%s",
|
||||
return String.format("weixin4j_qy_token_suite_%s:%s",
|
||||
perCodeHolder.getSuiteId(), perCodeHolder.getAuthCorpId()
|
||||
|
||||
);
|
||||
|
||||
@ -40,7 +40,7 @@ public class WeixinProviderTokenCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("wx_qy_provider_token_%s", corpid);
|
||||
return String.format("weixin4j_qy_provider_token_%s", corpid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -45,7 +45,7 @@ public class WeixinTicketCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("wx_qy_ticket_%s_%s", corpid, ticketType.name());
|
||||
return String.format("weixin4j_qy_ticket_%s_%s", corpid, ticketType.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -40,7 +40,7 @@ public class WeixinTokenCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("wx_qy_token_%s", corpid);
|
||||
return String.format("weixin4j_qy_token_%s", corpid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
# \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath
|
||||
# \u4f01\u4e1a\u53f7\u4fe1\u606f
|
||||
|
||||
# \u4f01\u4e1a\u53f7\u4fe1\u606f \u8bf7\u6309\u9700\u586b\u5199
|
||||
weixin4j.account={"id":"wx5132afc5da26d661","secret":"GsnKLVDI1pWArdB60Ze4iP2cwFvcW5KCAs2vLJldipilmSYxtbkcAiBcGSHHvu_I",\
|
||||
"suites":[{"id":"\u5e94\u7528\u5957\u4ef6\u7684id","secret":"\u5e94\u7528\u5957\u4ef6\u7684secret"}],\
|
||||
"providerSecret":"\u7b2c\u4e09\u65b9\u63d0\u4f9b\u5546secret(\u4f01\u4e1a\u53f7\u767b\u9646)",\
|
||||
@ -8,16 +9,15 @@ weixin4j.account={"id":"wx5132afc5da26d661","secret":"GsnKLVDI1pWArdB60Ze4iP2cwF
|
||||
"certificateKey":"\u52a0\u8f7d\u652f\u4ed8\u8bc1\u4e66\u6587\u4ef6\u7684\u5bc6\u7801 \u5982\u679c\u4e0d\u586b\u5199\u5219\u9ed8\u8ba4\u83b7\u53d6mchId\u4f5c\u4e3a\u5bc6\u7801",\
|
||||
"paySignKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165"}
|
||||
|
||||
# \u4f7f\u7528FileTokenStorager\u65f6token\u7684\u5b58\u653e\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.token.path=/tmp/weixin4j/token
|
||||
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_MEDIA_PATH)
|
||||
weixin4j.media.path=/tmp/weixin4j/media
|
||||
# \u5bf9\u8d26\u5355\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_BILL_PATH)
|
||||
weixin4j.bill.path=/tmp/weixin4j/bill
|
||||
# ca\u8bc1\u4e66\u5b58\u653e\u7684\u5b8c\u6574\u8def\u5f84 (V2\u7248\u672c\u540e\u7f00\u4e3a*.pfx,V3\u7248\u672c\u540e\u7f00\u4e3a*.p12)
|
||||
# weixin4j\u7684\u4e34\u65f6\u76ee\u5f55
|
||||
# \u53ef\u80fd\u5b58\u653etoken\u6587\u4ef6\u3001\u4e8c\u7ef4\u7801\u6587\u4ef6\u3001\u5a92\u4f53\u6587\u4ef6\u3001\u5bf9\u8d26\u5355\u6587\u4ef6\u7b49
|
||||
# \u4e3a\u7a7a\u65f6\u5219\u83b7\u53d6java.io.tmpdir\u4e34\u65f6\u76ee\u5f55
|
||||
weixin4j.tmpdir=
|
||||
# \u5fae\u4fe1\u652f\u4ed8\u67d0\u4e9b\u63a5\u53e3\u9700\u8981\u7684ca\u8bc1\u4e66\u5b58\u653e\u7684\u5b8c\u6574\u8def\u5f84
|
||||
# classpath\u8def\u5f84\u4e0b\u53ef\u4ee5\u8fd9\u4e48\u5199
|
||||
# weixin4j.certificate.file=classpath:xxxxx.p12
|
||||
# \u4e3a\u7a7a\u65f6\u5219\u83b7\u53d6classpath\u6839\u76ee\u5f55\u4e0b\u7684ca.p12\u6587\u4ef6
|
||||
weixin4j.certificate.file=/tmp/weixin4j/xxxxx.p12
|
||||
# classpath\u8def\u5f84\u4e0b\u53ef\u4ee5\u8fd9\u4e48\u5199(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_CAFILE_PATH)
|
||||
# weixin4j.certificate.file=classpath:xxxxx.pfx
|
||||
|
||||
# \u4f01\u4e1a\u53f7\u7528\u6237\u8eab\u4efd\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url(\u5728\u4f7f\u7528OauthApi\u65f6\u586b\u5199)
|
||||
weixin4j.user.oauth.redirect.uri=
|
||||
|
||||
@ -44,12 +44,11 @@ public class MediaTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void download() throws WeixinException, IOException {
|
||||
File file = mediaApi
|
||||
.downloadMediaFile(
|
||||
MediaDownloadResult result = mediaApi
|
||||
.downloadMedia(
|
||||
0,
|
||||
"1y0NWE5ochkfOoiyJsPwQ3Wg7gsyRHNp8SveqhGXY_1rOH7OcOMwfHDg8KH6s88osq59AfS3BX-MBBKvERB7Bvw",
|
||||
"/tmp/weixin4j/media");
|
||||
Assert.assertTrue(file.exists());
|
||||
"1y0NWE5ochkfOoiyJsPwQ3Wg7gsyRHNp8SveqhGXY_1rOH7OcOMwfHDg8KH6s88osq59AfS3BX-MBBKvERB7Bvw");
|
||||
Assert.assertTrue(result.getContent().length > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -1,39 +1,39 @@
|
||||
package com.foxinmy.weixin4j.qy.test;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.qy.token.WeixinTokenCreator;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* token测试
|
||||
*
|
||||
* @className TokenTest
|
||||
* @author jy.hu
|
||||
* @date 2014年4月10日
|
||||
* @since JDK 1.6
|
||||
*/
|
||||
public class TokenTest {
|
||||
|
||||
protected TokenHolder tokenHolder;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
WeixinAccount weixinAccount = Weixin4jConfigUtil.getWeixinAccount();
|
||||
tokenHolder = new TokenHolder(new WeixinTokenCreator(
|
||||
weixinAccount.getId(), weixinAccount.getSecret()),
|
||||
new FileTokenStorager(Weixin4jConfigUtil.getValue("token.path",
|
||||
"/tmp/weixin4j/token")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws WeixinException {
|
||||
Assert.assertNotNull(tokenHolder.getToken());
|
||||
}
|
||||
}
|
||||
package com.foxinmy.weixin4j.qy.test;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.qy.token.WeixinTokenCreator;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* token测试
|
||||
*
|
||||
* @className TokenTest
|
||||
* @author jy.hu
|
||||
* @date 2014年4月10日
|
||||
* @since JDK 1.6
|
||||
*/
|
||||
public class TokenTest {
|
||||
|
||||
protected TokenHolder tokenHolder;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
WeixinAccount weixinAccount = Weixin4jConfigUtil.getWeixinAccount();
|
||||
tokenHolder = new TokenHolder(new WeixinTokenCreator(
|
||||
weixinAccount.getId(), weixinAccount.getSecret()),
|
||||
new FileTokenStorager(Weixin4jConfigUtil.getValue("token.path",
|
||||
"/tmp/weixin4j/token")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws WeixinException {
|
||||
Assert.assertNotNull(tokenHolder.getToken());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user