删除Weixin4jSettings配置类 & fixed #89 #90 #91

This commit is contained in:
jinyu
2016-08-22 13:07:06 +08:00
parent 4420adca99
commit 0356484f44
42 changed files with 1098 additions and 853 deletions
@@ -1,7 +1,5 @@
package com.foxinmy.weixin4j.api;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
@@ -48,8 +46,6 @@ public class CashApi extends MchApi {
/**
* 发放红包 企业向微信用户个人发现金红包
*
* @param certificate
* 后缀为*.p12的证书文件
* @param redpacket
* 红包信息
* @return 发放结果
@@ -63,27 +59,16 @@ public class CashApi extends MchApi {
* 发放裂变红包接口</a>
* @throws WeixinException
*/
public RedpacketSendResult sendRedpack(InputStream certificate,
Redpacket redpacket) throws WeixinException {
public RedpacketSendResult sendRedpack(Redpacket redpacket)
throws WeixinException {
super.declareMerchant(redpacket);
JSONObject obj = (JSONObject) JSON.toJSON(redpacket);
obj.put("wxappid", obj.remove("appid"));
obj.put("sign", weixinSignature.sign(obj));
String param = XmlStream.map2xml(obj);
WeixinResponse response = null;
try {
response = createSSLRequestExecutor(certificate)
.post(redpacket.getTotalNum() > 1 ? getRequestUri("groupredpack_send_uri")
: getRequestUri("redpack_send_uri"), param);
} finally {
if (certificate != null) {
try {
certificate.close();
} catch (IOException e) {
;
}
}
}
WeixinResponse response = createSSLRequestExecutor()
.post(redpacket.getTotalNum() > 1 ? getRequestUri("groupredpack_send_uri")
: getRequestUri("redpack_send_uri"), param);
String text = response.getAsString()
.replaceFirst("<wxappid>", "<appid>")
.replaceFirst("</wxappid>", "</appid>");
@@ -93,8 +78,6 @@ public class CashApi extends MchApi {
/**
* 查询红包记录
*
* @param certificate
* 后缀为*.p12的证书文件
* @param outTradeNo
* 商户发放红包的商户订单号
* @return 红包记录
@@ -107,26 +90,15 @@ public class CashApi extends MchApi {
* 查询裂变红包接口</a>
* @throws WeixinException
*/
public RedpacketRecord queryRedpack(InputStream certificate,
String outTradeNo) throws WeixinException {
public RedpacketRecord queryRedpack(String outTradeNo)
throws WeixinException {
Map<String, String> para = createBaseRequestMap(null);
para.put("bill_type", "MCHT");
para.put("mch_billno", outTradeNo);
para.put("sign", weixinSignature.sign(para));
String param = XmlStream.map2xml(para);
WeixinResponse response = null;
try {
response = createSSLRequestExecutor(certificate).post(
getRequestUri("redpack_query_uri"), param);
} finally {
if (certificate != null) {
try {
certificate.close();
} catch (IOException e) {
;
}
}
}
WeixinResponse response = createSSLRequestExecutor().post(
getRequestUri("redpack_query_uri"), param);
return response.getAsObject(new TypeReference<RedpacketRecord>() {
});
}
@@ -143,8 +115,6 @@ public class CashApi extends MchApi {
* <li>每个用户每天最多可付款10次,可以在商户平台--API安全进行设置
* <li>给同一个用户付款时间间隔不得低于15秒
*
* @param certificate
* 后缀为*.p12的证书文件
* @param payment
* 付款信息
* @return 付款结果
@@ -155,27 +125,16 @@ public class CashApi extends MchApi {
* 企业付款接口</a>
* @throws WeixinException
*/
public CorpPaymentResult sendCorpPayment(InputStream certificate,
CorpPayment payment) throws WeixinException {
public CorpPaymentResult sendCorpPayment(CorpPayment payment)
throws WeixinException {
super.declareMerchant(payment);
JSONObject obj = (JSONObject) JSON.toJSON(payment);
obj.put("mchid", obj.remove("mch_id"));
obj.put("mch_appid", obj.remove("appid"));
obj.put("sign", weixinSignature.sign(obj));
String param = XmlStream.map2xml(obj);
WeixinResponse response = null;
try {
response = createSSLRequestExecutor(certificate).post(
getRequestUri("corppayment_send_uri"), param);
} finally {
if (certificate != null) {
try {
certificate.close();
} catch (IOException e) {
;
}
}
}
WeixinResponse response = createSSLRequestExecutor().post(
getRequestUri("corppayment_send_uri"), param);
String text = response.getAsString()
.replaceFirst("<mch_appid>", "<appid>")
.replaceFirst("</mch_appid>", "</appid>")
@@ -187,8 +146,6 @@ public class CashApi extends MchApi {
/**
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
*
* @param certificate
* 后缀为*.p12的证书文件
* @param outTradeNo
* 商户调用企业付款API时使用的商户订单号
* @return 付款记录
@@ -198,8 +155,8 @@ public class CashApi extends MchApi {
* 企业付款查询接口</a>
* @throws WeixinException
*/
public CorpPaymentRecord queryCorpPayment(InputStream certificate,
String outTradeNo) throws WeixinException {
public CorpPaymentRecord queryCorpPayment(String outTradeNo)
throws WeixinException {
JSONObject obj = new JSONObject();
obj.put("nonce_str", RandomUtil.generateString(16));
obj.put("mch_id", weixinAccount.getMchId());
@@ -207,19 +164,8 @@ public class CashApi extends MchApi {
obj.put("partner_trade_no", outTradeNo);
obj.put("sign", weixinSignature.sign(obj));
String param = XmlStream.map2xml(obj);
WeixinResponse response = null;
try {
response = createSSLRequestExecutor(certificate).post(
getRequestUri("corppayment_query_uri"), param);
} finally {
if (certificate != null) {
try {
certificate.close();
} catch (IOException e) {
;
}
}
}
WeixinResponse response = createSSLRequestExecutor().post(
getRequestUri("corppayment_query_uri"), param);
return response.getAsObject(new TypeReference<CorpPaymentRecord>() {
});
}
@@ -1,7 +1,5 @@
package com.foxinmy.weixin4j.api;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import com.alibaba.fastjson.TypeReference;
@@ -21,7 +19,8 @@ import com.foxinmy.weixin4j.xml.XmlStream;
* @author jinyu(foxinmy@gmail.com)
* @date 2015年3月25日
* @since JDK 1.6
* @see <a href="https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_1">代金券</a>
* @see <a
* href="https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_1">代金券</a>
*/
public class CouponApi extends MchApi {
@@ -32,8 +31,6 @@ public class CouponApi extends MchApi {
/**
* 发放代金券(需要证书)
*
* @param certificate
* 后缀为*.p12的证书文件
* @param couponStockId
* 代金券批次id
* @param partnerTradeNo
@@ -48,9 +45,8 @@ public class CouponApi extends MchApi {
* href="https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_3">发放代金券接口</a>
* @throws WeixinException
*/
public CouponResult sendCoupon(InputStream certificate,
String couponStockId, String partnerTradeNo, String openId,
String opUserId) throws WeixinException {
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
String openId, String opUserId) throws WeixinException {
Map<String, String> map = createBaseRequestMap(null);
map.put("coupon_stock_id", couponStockId);
map.put("partner_trade_no", partnerTradeNo);
@@ -66,19 +62,8 @@ public class CouponApi extends MchApi {
map.put("type", "XML");
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = null;
try {
response = createSSLRequestExecutor(certificate).post(
getRequestUri("coupon_send_uri"), param);
} finally {
if (certificate != null) {
try {
certificate.close();
} catch (IOException e) {
;
}
}
}
WeixinResponse response = createSSLRequestExecutor().post(
getRequestUri("coupon_send_uri"), param);
return response.getAsObject(new TypeReference<CouponResult>() {
});
}
@@ -1,5 +1,8 @@
package com.foxinmy.weixin4j.api;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
@@ -55,10 +58,22 @@ public class MchApi extends BaseApi {
* @return
* @throws WeixinException
*/
protected WeixinRequestExecutor createSSLRequestExecutor(
InputStream certificate) throws WeixinException {
protected WeixinRequestExecutor createSSLRequestExecutor()
throws WeixinException {
InputStream certificateFile;
try {
File certificate = new File(weixinAccount.getCertificateFile());
if (!certificate.exists() || !certificate.isFile()) {
throw new WeixinException("invalid certificate file : "
+ certificate.toString());
}
certificateFile = new FileInputStream(
weixinAccount.getCertificateFile());
} catch (IOException e) {
throw new WeixinException("IO Error on createSSLRequestExecutor", e);
}
return weixinExecutor.createSSLRequestExecutor(
weixinAccount.getCertificateKey(), certificate);
weixinAccount.getCertificateKey(), certificateFile);
}
/**
@@ -2,11 +2,9 @@ package com.foxinmy.weixin4j.api;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@@ -213,7 +211,7 @@ public class PayApi extends MchApi {
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一
* </a>
*/
public String createNativePayRequestURL(String productId) {
public String createNativePayRequest(String productId) {
Map<String, String> map = new HashMap<String, String>();
String timestamp = DateUtil.timestamp2string();
String noncestr = RandomUtil.generateString(16);
@@ -435,8 +433,6 @@ public class PayApi extends MchApi {
* ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
* </p>
*
* @param certificate
* 后缀为*.p12的证书文件
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -458,36 +454,28 @@ public class PayApi extends MchApi {
* @since V3
* @throws WeixinException
*/
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery,
String outRefundNo, double totalFee, double refundFee,
CurrencyType refundFeeType, String opUserId) throws WeixinException {
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
double totalFee, double refundFee, CurrencyType refundFeeType,
String opUserId) throws WeixinException {
WeixinResponse response = null;
try {
Map<String, String> map = createBaseRequestMap(idQuery);
map.put("out_refund_no", outRefundNo);
map.put("total_fee", Integer.toString(DateUtil.formatYuan2Fen(totalFee)));
map.put("refund_fee", Integer.toString(DateUtil.formatYuan2Fen(refundFee)));
if (StringUtil.isBlank(opUserId)) {
opUserId = weixinAccount.getMchId();
}
map.put("op_user_id", opUserId);
if (refundFeeType == null) {
refundFeeType = CurrencyType.CNY;
}
map.put("refund_fee_type", refundFeeType.name());
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
response = createSSLRequestExecutor(certificate).post(
getRequestUri("refund_apply_uri"), param);
} finally {
if (certificate != null) {
try {
certificate.close();
} catch (IOException e) {
;
}
}
Map<String, String> map = createBaseRequestMap(idQuery);
map.put("out_refund_no", outRefundNo);
map.put("total_fee",
Integer.toString(DateUtil.formatYuan2Fen(totalFee)));
map.put("refund_fee",
Integer.toString(DateUtil.formatYuan2Fen(refundFee)));
if (StringUtil.isBlank(opUserId)) {
opUserId = weixinAccount.getMchId();
}
map.put("op_user_id", opUserId);
if (refundFeeType == null) {
refundFeeType = CurrencyType.CNY;
}
map.put("refund_fee_type", refundFeeType.name());
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
response = createSSLRequestExecutor().post(
getRequestUri("refund_apply_uri"), param);
return response.getAsObject(new TypeReference<RefundResult>() {
});
}
@@ -495,8 +483,6 @@ public class PayApi extends MchApi {
/**
* 退款申请(全额退款)
*
* @param certificate
* 后缀为*.p12的证书文件
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -504,12 +490,11 @@ public class PayApi extends MchApi {
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
* @param totalFee
* 订单总金额,单位为元
* @see {@link #applyRefund(InputStream, IdQuery, String, double, double,CurrencyType, String)}
* @see {@link #applyRefund(IdQuery, String, double, double,CurrencyType, String)}
*/
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery,
String outRefundNo, double totalFee) throws WeixinException {
return applyRefund(certificate, idQuery, outRefundNo, totalFee,
totalFee, null, null);
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
double totalFee) throws WeixinException {
return applyRefund(idQuery, outRefundNo, totalFee, totalFee, null, null);
}
/**
@@ -518,8 +503,6 @@ public class PayApi extends MchApi {
* 如需实现相同功能请调用退款接口</font></br> <font
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font> </br>
*
* @param certificate
* 后缀为*.p12的证书文件
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -527,25 +510,14 @@ public class PayApi extends MchApi {
* @since V3
* @throws WeixinException
*/
public MerchantResult reverseOrder(InputStream certificate, IdQuery idQuery)
throws WeixinException {
try {
Map<String, String> map = createBaseRequestMap(idQuery);
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = createSSLRequestExecutor(certificate)
.post(getRequestUri("order_reverse_uri"), param);
return response.getAsObject(new TypeReference<MerchantResult>() {
});
} finally {
if (certificate != null) {
try {
certificate.close();
} catch (IOException e) {
;
}
}
}
public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException {
Map<String, String> map = createBaseRequestMap(idQuery);
map.put("sign", weixinSignature.sign(map));
String param = XmlStream.map2xml(map);
WeixinResponse response = createSSLRequestExecutor().post(
getRequestUri("order_reverse_uri"), param);
return response.getAsObject(new TypeReference<MerchantResult>() {
});
}
/**
@@ -614,17 +586,16 @@ public class PayApi extends MchApi {
* @param billType
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
* REFUND,返回当日退款订单
* @param billPath
* 对账单保存路径
* @return excel表格
* @param outputStream
* 输出流
* @since V3
* @see <a href=
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6">
* 下载对账单API</a>
* @throws WeixinException
*/
public File downloadBill(Date billDate, BillType billType, String billPath)
throws WeixinException {
public void downloadBill(Date billDate, BillType billType,
OutputStream outputStream) throws WeixinException {
if (billDate == null) {
Calendar now = Calendar.getInstance();
now.add(Calendar.DAY_OF_MONTH, -1);
@@ -634,14 +605,6 @@ public class PayApi extends MchApi {
billType = BillType.ALL;
}
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
String fileName = String.format("weixin4j_bill_%s_%s_%s.txt",
formatBillDate, billType.name().toLowerCase(),
weixinAccount.getId());
File file = new File(String.format("%s%s%s", billPath, File.separator,
fileName));
if (file.exists()) {
return file;
}
Map<String, String> map = createBaseRequestMap(null);
map.put("bill_date", formatBillDate);
map.put("bill_type", billType.name());
@@ -653,8 +616,8 @@ public class PayApi extends MchApi {
BufferedReader reader = null;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file), Consts.UTF_8));
writer = new BufferedWriter(new OutputStreamWriter(outputStream,
Consts.UTF_8));
reader = new BufferedReader(new InputStreamReader(
response.getBody(), Consts.UTF_8));
String line = null;
@@ -676,7 +639,6 @@ public class PayApi extends MchApi {
;
}
}
return file;
}
/**
@@ -21,6 +21,18 @@ public class FileCacheStorager<T extends Cacheable> implements CacheStorager<T>
private final File tmpdir;
private final String SEPARATOR = File.separator;
/**
* 默认缓存路径:java.io.tmpdir
*/
public FileCacheStorager() {
this(System.getProperty("java.io.tmpdir"));
}
/**
*
* @param path
* 缓存文件报错
*/
public FileCacheStorager(String path) {
this.tmpdir = new File(String.format("%s%s%s", path, SEPARATOR, ALLKEY));
this.tmpdir.mkdirs();
@@ -28,14 +40,17 @@ public class FileCacheStorager<T extends Cacheable> implements CacheStorager<T>
@Override
public T lookup(String key) {
File cacheFile = new File(String.format("%s%s%s", tmpdir.getAbsolutePath(), SEPARATOR, key));
File cacheFile = new File(String.format("%s%s%s",
tmpdir.getAbsolutePath(), SEPARATOR, key));
try {
if (cacheFile.exists()) {
T cache = SerializationUtils.deserialize(new FileInputStream(cacheFile));
T cache = SerializationUtils.deserialize(new FileInputStream(
cacheFile));
if (cache.getCreateTime() < 0) {
return cache;
}
if ((cache.getCreateTime() + cache.getExpires() - CUTMS) > System.currentTimeMillis()) {
if ((cache.getCreateTime() + cache.getExpires() - CUTMS) > System
.currentTimeMillis()) {
return cache;
}
}
@@ -48,8 +63,10 @@ public class FileCacheStorager<T extends Cacheable> implements CacheStorager<T>
@Override
public void caching(String key, T cache) {
try {
SerializationUtils.serialize(cache,
new FileOutputStream(new File(String.format("%s%s%s", tmpdir.getAbsolutePath(), SEPARATOR, key))));
SerializationUtils.serialize(
cache,
new FileOutputStream(new File(String.format("%s%s%s",
tmpdir.getAbsolutePath(), SEPARATOR, key))));
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -58,10 +75,12 @@ public class FileCacheStorager<T extends Cacheable> implements CacheStorager<T>
@Override
public T evict(String key) {
T cache = null;
File cacheFile = new File(String.format("%s%s%s", tmpdir.getAbsolutePath(), SEPARATOR, key));
File cacheFile = new File(String.format("%s%s%s",
tmpdir.getAbsolutePath(), SEPARATOR, key));
try {
if (cacheFile.exists()) {
cache = SerializationUtils.deserialize(new FileInputStream(cacheFile));
cache = SerializationUtils.deserialize(new FileInputStream(
cacheFile));
cacheFile.delete();
}
} catch (IOException e) {
@@ -124,8 +124,7 @@ public class WeixinRequestExecutor {
* @return 微信响应
* @throws WeixinException
*/
public WeixinResponse doRequest(HttpRequest request)
throws WeixinException {
public WeixinResponse doRequest(HttpRequest request) throws WeixinException {
try {
if (logger.isEnabled(InternalLogLevel.DEBUG)) {
logger.debug("weixin request >> " + request.getMethod() + " "
@@ -227,6 +226,12 @@ public class WeixinRequestExecutor {
new java.security.SecureRandom());
return createSSLRequestExecutor(sslContext);
} catch (Exception e) {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException ignore) {
}
}
throw new WeixinException("Key load error", e);
}
}
@@ -95,10 +95,6 @@ public class Token implements Cacheable {
return extra;
}
public void setExtra(Map<String, String> extra) {
this.extra = extra;
}
public Token pushExtra(String name, String value) {
this.extra.put(name, value);
return this;
@@ -21,11 +21,11 @@ public class WeixinAccount implements Serializable {
/**
* 唯一的身份标识
*/
private String id;
private final String id;
/**
* 调用接口的密钥
*/
private String secret;
private final String secret;
@JSONCreator
public WeixinAccount(@JSONField(name = "id") String id,
@@ -3,6 +3,7 @@ package com.foxinmy.weixin4j.model;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
/**
* 微信支付账户
@@ -19,20 +20,23 @@ public class WeixinPayAccount extends WeixinAccount {
/**
* 公众号支付请求中用于加密的密钥
*/
private String paySignKey;
private final String paySignKey;
/**
* 微信支付分配的商户号
*/
private String mchId;
private final String mchId;
/**
* 加载支付证书文件的密码(默认为商户号)
*/
private String certificateKey;
/**
* 商户证书文件(默认加载classpath:ca.p12)
*/
private String certificateFile;
/**
* 微信支付分配的设备号
*/
private String deviceInfo;
/**
* 财付通商户身份的标识
*/
@@ -58,7 +62,27 @@ public class WeixinPayAccount extends WeixinAccount {
* 微信支付分配的商户号(必填)
*/
public WeixinPayAccount(String id, String paySignKey, String mchId) {
this(id, null, paySignKey, mchId, null, null, null, null, null);
this(id, paySignKey, mchId, mchId, "classpath:ca.p12");
}
/**
* 支付商户信息
*
* @param id
* 公众号唯一的身份ID(必填)
* @param paySignKey
* 支付密钥字符串(必填)
* @param mchId
* 微信支付分配的商户号(必填)
* @param certificateKey
* 加载支付证书文件的密码(默认为商户号)
* @param certificateFile
* 商户证书文件(默认加载classpath:ca.p12)
*/
public WeixinPayAccount(String id, String paySignKey, String mchId,
String certificateKey, String certificateFile) {
this(id, null, paySignKey, mchId, certificateKey, certificateFile,
null, null, null, null);
}
/**
@@ -74,6 +98,8 @@ public class WeixinPayAccount extends WeixinAccount {
* 微信支付分配的商户号(必填)
* @param certificateKey
* 加载支付证书文件的密码(默认为商户号)
* @param certificateFile
* 商户证书文件(默认加载classpath:ca.p12)
* @param deviceInfo
* 微信支付分配的设备号(非必填)
* @param partnerId
@@ -89,6 +115,7 @@ public class WeixinPayAccount extends WeixinAccount {
@JSONField(name = "paySignKey") String paySignKey,
@JSONField(name = "mchId") String mchId,
@JSONField(name = "certificateKey") String certificateKey,
@JSONField(name = "certificateFile") String certificateFile,
@JSONField(name = "deviceInfo") String deviceInfo,
@JSONField(name = "partnerId") String partnerId,
@JSONField(name = "subId") String subId,
@@ -97,6 +124,7 @@ public class WeixinPayAccount extends WeixinAccount {
this.paySignKey = paySignKey;
this.mchId = mchId;
this.certificateKey = certificateKey;
this.certificateFile = certificateFile;
this.deviceInfo = deviceInfo;
this.partnerId = partnerId;
this.subId = subId;
@@ -131,12 +159,40 @@ public class WeixinPayAccount extends WeixinAccount {
return subMchId;
}
public void setCertificateKey(String certificateKey) {
this.certificateKey = certificateKey;
}
public String getCertificateFile() {
return Weixin4jConfigUtil.replaceClassPathValue(certificateFile);
}
public void setCertificateFile(String certificateFile) {
this.certificateFile = certificateFile;
}
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public void setPartnerId(String partnerId) {
this.partnerId = partnerId;
}
public void setSubId(String subId) {
this.subId = subId;
}
public void setSubMchId(String subMchId) {
this.subMchId = subMchId;
}
@Override
public String toString() {
return "WeixinPayAccount [" + super.toString() + ", paySignKey="
+ paySignKey + ", mchId=" + mchId + ", certificateKey="
+ certificateKey + ", deviceInfo=" + deviceInfo
+ ", partnerId=" + partnerId + ", subId=" + subId
+ ", subMchId=" + subMchId + "]";
+ certificateKey + ",certificateFile =" + certificateFile
+ ", deviceInfo=" + deviceInfo + ", partnerId=" + partnerId
+ ", subId=" + subId + ", subMchId=" + subMchId + "]";
}
}
@@ -23,7 +23,7 @@ public class MediaCounter implements Serializable {
@JSONField(name = "total_count")
private int totalCount;
/**
* 文件素材总数目(企业号有)
* 文件素材总数目(企业号有)
*/
@JSONField(name = "file_count")
private int fileCount;
@@ -1,9 +1,7 @@
package com.foxinmy.weixin4j.payment;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import com.alibaba.fastjson.JSON;
@@ -37,7 +35,6 @@ import com.foxinmy.weixin4j.payment.mch.RedpacketSendResult;
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
import com.foxinmy.weixin4j.payment.mch.RefundResult;
import com.foxinmy.weixin4j.payment.mch.SettlementRecord;
import com.foxinmy.weixin4j.setting.Weixin4jSettings;
import com.foxinmy.weixin4j.sign.WeixinSignature;
import com.foxinmy.weixin4j.type.CurrencyType;
import com.foxinmy.weixin4j.type.CustomsCity;
@@ -73,32 +70,34 @@ public class WeixinPayProxy {
*/
private final CustomsApi customsApi;
/**
* 配置信息
* 商户信息
*/
private final Weixin4jSettings<WeixinPayAccount> settings;
private final WeixinPayAccount weixinPayAccount;
/**
* 使用weixin4j.properties配置的支付账号信息
* 微信支付接口实现(使用weixin4j.properties配置的account商户信息)
*/
public WeixinPayProxy() {
this(
new Weixin4jSettings<WeixinPayAccount>(JSON.parseObject(
Weixin4jConfigUtil.getValue("account"),
WeixinPayAccount.class)));
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
WeixinPayAccount.class));
}
/**
*
* @param settings
* 支付相关配置信息
* @see com.foxinmy.weixin4j.setting.Weixin4jSettings
* 微信支付接口实现
*
* @param weixinPayAccount
* 微信商户信息
*/
public WeixinPayProxy(Weixin4jSettings<WeixinPayAccount> settings) {
this.settings = settings;
this.payApi = new PayApi(settings.getAccount());
this.couponApi = new CouponApi(settings.getAccount());
this.cashApi = new CashApi(settings.getAccount());
this.customsApi = new CustomsApi(settings.getAccount());
public WeixinPayProxy(WeixinPayAccount weixinPayAccount) {
if (weixinPayAccount == null) {
throw new IllegalArgumentException(
"weixinPayAccount must not be empty");
}
this.weixinPayAccount = weixinPayAccount;
this.payApi = new PayApi(weixinPayAccount);
this.couponApi = new CouponApi(weixinPayAccount);
this.cashApi = new CashApi(weixinPayAccount);
this.customsApi = new CustomsApi(weixinPayAccount);
}
/**
@@ -107,7 +106,7 @@ public class WeixinPayProxy {
* @return
*/
public WeixinPayAccount getWeixinPayAccount() {
return settings.getAccount();
return weixinPayAccount;
}
/**
@@ -227,8 +226,8 @@ public class WeixinPayProxy {
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一
* </a>
*/
public String createNativePayRequestURL(String productId) {
return payApi.createNativePayRequestURL(productId);
public String createNativePayRequest(String productId) {
return payApi.createNativePayRequest(productId);
}
/**
@@ -431,8 +430,6 @@ public class WeixinPayProxy {
* ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
* </p>
*
* @param certificate
* 后缀为*.p12的证书文件
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -456,11 +453,11 @@ public class WeixinPayProxy {
* @since V3
* @throws WeixinException
*/
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery,
String outRefundNo, double totalFee, double refundFee,
CurrencyType refundFeeType, String opUserId) throws WeixinException {
return payApi.applyRefund(certificate, idQuery, outRefundNo, totalFee,
refundFee, refundFeeType, opUserId);
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
double totalFee, double refundFee, CurrencyType refundFeeType,
String opUserId) throws WeixinException {
return payApi.applyRefund(idQuery, outRefundNo, totalFee, refundFee,
refundFeeType, opUserId);
}
/**
@@ -468,13 +465,11 @@ public class WeixinPayProxy {
*
* @throws IOException
*
* @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String,CurrencyType)}
* @see {@link #applyRefund(IdQuery, String, double, double, String,CurrencyType)}
*/
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
double totalFee) throws WeixinException, IOException {
return payApi.applyRefund(
new FileInputStream(settings.getCertificateFile0()), idQuery,
outRefundNo, totalFee);
double totalFee) throws WeixinException {
return payApi.applyRefund(idQuery, outRefundNo, totalFee);
}
/**
@@ -512,7 +507,7 @@ public class WeixinPayProxy {
* @param billType
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
* REFUND,返回当日退款订单
* @return excel表格
* @para outputStream 输出流
* @since V2 & V3
* @see com.foxinmy.weixin4j.api.PayApi
* @see <a href=
@@ -520,9 +515,9 @@ public class WeixinPayProxy {
* 下载对账单API</a>
* @throws WeixinException
*/
public File downloadBill(Date billDate, BillType billType)
throws WeixinException {
return payApi.downloadBill(billDate, billType, settings.getTmpdir0());
public void downloadBill(Date billDate, BillType billType,
OutputStream outputStream) throws WeixinException {
payApi.downloadBill(billDate, billType, outputStream);
}
/**
@@ -531,8 +526,6 @@ public class WeixinPayProxy {
* 如需实现相同功能请调用退款接口</font></br> <font
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font> </br>
*
* @param certificate
* 证书文件(V2版本后缀为*.pfx,V3版本后缀为*.p12)
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -541,25 +534,8 @@ public class WeixinPayProxy {
* @since V3
* @throws WeixinException
*/
public MerchantResult reverseOrder(InputStream certificate, IdQuery idQuery)
throws WeixinException {
return payApi.reverseOrder(certificate, idQuery);
}
/**
* 冲正撤销
*
* @param idQuery
* transaction_id、out_trade_no 二选一
* @return 撤销结果
* @see {@link #reverseOrder(InputStream, IdQuery)}
* @throws WeixinException
* @throws IOException
*/
public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException,
IOException {
return payApi.reverseOrder(
new FileInputStream(settings.getCertificateFile0()), idQuery);
public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException {
return payApi.reverseOrder(idQuery);
}
/**
@@ -634,8 +610,6 @@ public class WeixinPayProxy {
/**
* 发放代金券(需要证书)
*
* @param certificate
* 后缀为*.p12的证书文件
* @param couponStockId
* 代金券批次id
* @param partnerTradeNo
@@ -652,23 +626,10 @@ public class WeixinPayProxy {
* 发放代金券接口</a>
* @throws WeixinException
*/
public CouponResult sendCoupon(InputStream certificate,
String couponStockId, String partnerTradeNo, String openId,
String opUserId) throws WeixinException {
return couponApi.sendCoupon(certificate, couponStockId, partnerTradeNo,
openId, opUserId);
}
/**
* 发放代金券
*
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#sendCoupon(InputStream, String, String, String, String)}
*/
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
String openId) throws WeixinException, IOException {
return couponApi.sendCoupon(
new FileInputStream(settings.getCertificateFile0()),
couponStockId, partnerTradeNo, openId, null);
String openId, String opUserId) throws WeixinException {
return couponApi.sendCoupon(couponStockId, partnerTradeNo, openId,
opUserId);
}
/**
@@ -710,8 +671,6 @@ public class WeixinPayProxy {
/**
* 发放红包 企业向微信用户个人发现金红包
*
* @param certificate
* 后缀为*.p12的证书文件
* @param redpacket
* 红包信息
* @return 发放结果
@@ -726,27 +685,14 @@ public class WeixinPayProxy {
* 发放裂变红包接口</a>
* @throws WeixinException
*/
public RedpacketSendResult sendRedpack(InputStream certificate,
Redpacket redpacket) throws WeixinException {
return cashApi.sendRedpack(certificate, redpacket);
}
/**
* 发放红包
*
* @see {@link #sendRedpack(InputStream, Redpacket)}
*/
public RedpacketSendResult sendRedpack(Redpacket redpacket)
throws WeixinException, IOException {
return cashApi.sendRedpack(
new FileInputStream(settings.getCertificateFile0()), redpacket);
throws WeixinException {
return cashApi.sendRedpack(redpacket);
}
/**
* 查询红包记录
*
* @param certificate
* 后缀为*.p12的证书文件
* @param outTradeNo
* 商户发放红包的商户订单号
* @return 红包记录
@@ -760,22 +706,9 @@ public class WeixinPayProxy {
* 查询裂变红包接口</a>
* @throws WeixinException
*/
public RedpacketRecord queryRedpack(InputStream certificate,
String outTradeNo) throws WeixinException {
return cashApi.queryRedpack(certificate, outTradeNo);
}
/**
* 查询红包
*
* @see {@link #queryRedpack(InputStream,String)}
*/
public RedpacketRecord queryRedpack(String outTradeNo)
throws WeixinException, IOException {
return cashApi
.queryRedpack(
new FileInputStream(settings.getCertificateFile0()),
outTradeNo);
throws WeixinException {
return cashApi.queryRedpack(outTradeNo);
}
/**
@@ -790,8 +723,6 @@ public class WeixinPayProxy {
* <li>每个用户每天最多可付款10次,可以在商户平台--API安全进行设置
* <li>给同一个用户付款时间间隔不得低于15秒
*
* @param certificate
* 后缀为*.p12的证书文件
* @param payment
* 付款信息
* @return 付款结果
@@ -803,27 +734,14 @@ public class WeixinPayProxy {
* 企业付款接口</a>
* @throws WeixinException
*/
public CorpPaymentResult sendCorpPayment(InputStream certificate,
CorpPayment payment) throws WeixinException {
return cashApi.sendCorpPayment(certificate, payment);
}
/**
* 企业付款
*
* @see {@link #sendCorpPayment(InputStream, CorpPayment)}
*/
public CorpPaymentResult sendCorpPayment(CorpPayment payment)
throws WeixinException, IOException {
return cashApi.sendCorpPayment(
new FileInputStream(settings.getCertificateFile0()), payment);
throws WeixinException {
return cashApi.sendCorpPayment(payment);
}
/**
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
*
* @param certificate
* 后缀为*.p12的证书文件
* @param outTradeNo
* 商户调用企业付款API时使用的商户订单号
* @return 付款记录
@@ -834,22 +752,9 @@ public class WeixinPayProxy {
* 企业付款查询接口</a>
* @throws WeixinException
*/
public CorpPaymentRecord queryCorpPayment(InputStream certificate,
String outTradeNo) throws WeixinException {
return cashApi.queryCorpPayment(certificate, outTradeNo);
}
/**
* 企业付款查询
*
* @see {@link #CorpPaymentRecord(InputStream, String)}
*/
public CorpPaymentRecord queryCorpPayment(String outTradeNo)
throws WeixinException, IOException {
return cashApi
.queryCorpPayment(
new FileInputStream(settings.getCertificateFile0()),
outTradeNo);
throws WeixinException {
return cashApi.queryCorpPayment(outTradeNo);
}
/**
@@ -1,97 +0,0 @@
package com.foxinmy.weixin4j.setting;
import com.foxinmy.weixin4j.cache.CacheStorager;
import com.foxinmy.weixin4j.cache.FileCacheStorager;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
/**
* 微信配置相关
*
* @className Weixin4jSettings
* @author jinyu(foxinmy@gmail.com)
* @date 2016年1月28日
* @since JDK 1.6
* @see
*/
public class Weixin4jSettings<T> {
/**
* 账号信息
*/
private final T account;
/**
* 系统临时目录
*/
private String tmpdir;
/**
* Token的存储方式 默认为FileCacheStorager
*/
private CacheStorager<Token> cacheStorager;
/**
* 支付接口需要的证书文件(*.p12)
*/
private String certificateFile;
public Weixin4jSettings(T account) {
this.account = account;
}
public T getAccount() {
return account;
}
public String getTmpdir() {
return tmpdir;
}
public void setTmpdir(String tmpdir) {
this.tmpdir = tmpdir;
}
public String getTmpdir0() {
if (StringUtil.isBlank(tmpdir)) {
return Weixin4jConfigUtil.getValue("weixin4j.tmpdir",
System.getProperty("java.io.tmpdir"));
}
return tmpdir;
}
public CacheStorager<Token> getCacheStorager() {
return cacheStorager;
}
public CacheStorager<Token> getCacheStorager0() {
if (cacheStorager == null) {
return new FileCacheStorager<Token>(getTmpdir0());
}
return cacheStorager;
}
public void setCacheStorager(CacheStorager<Token> cacheStorager) {
this.cacheStorager = cacheStorager;
}
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 setCertificateFile(String certificateFile) {
this.certificateFile = certificateFile;
}
@Override
public String toString() {
return "Weixin4jSettings [account=" + account + ", tmpdir=" + tmpdir
+ ", cacheStorager=" + cacheStorager + ", certificateFile="
+ certificateFile + "]";
}
}
@@ -13,10 +13,10 @@ import com.foxinmy.weixin4j.model.Token;
* @date 2015年6月12日
* @since JDK 1.6
* @see TokenCreator
* @see com.foxinmy.weixin4j.token.TokenCreator
* @see com.foxinmy.weixin4j.cache.CacheStorager
*/
public class TokenManager extends CacheManager<Token> {
/**
*
* @param tokenCreator
@@ -20,7 +20,8 @@ public class Weixin4jConfigUtil {
private final static String CLASSPATH_VALUE;
private static ResourceBundle weixinBundle;
static {
CLASSPATH_VALUE = Thread.currentThread().getContextClassLoader().getResource("").getPath();
CLASSPATH_VALUE = Thread.currentThread().getContextClassLoader()
.getResource("").getPath();
try {
weixinBundle = ResourceBundle.getBundle(Consts.WEIXIN4J);
} catch (MissingResourceException e) {
@@ -77,7 +78,7 @@ public class Weixin4jConfigUtil {
* @return
*/
public static String getClassPathValue(String key) {
return getValue(key).replaceFirst(CLASSPATH_PREFIX, CLASSPATH_VALUE);
return replaceClassPathValue(getValue(key));
}
/**
@@ -87,7 +88,11 @@ public class Weixin4jConfigUtil {
* @return
*/
public static String getClassPathValue(String key, String defaultValue) {
return getValue(key, defaultValue).replaceFirst(CLASSPATH_PREFIX, CLASSPATH_VALUE);
return replaceClassPathValue(getValue(key, defaultValue));
}
public static String replaceClassPathValue(String value) {
return value.replaceFirst(CLASSPATH_PREFIX, CLASSPATH_VALUE);
}
/**
@@ -98,11 +103,14 @@ public class Weixin4jConfigUtil {
public static WeixinAccount getWeixinAccount() {
WeixinAccount account = null;
try {
account = JSON.parseObject(getValue("account"), WeixinAccount.class);
account = JSON
.parseObject(getValue("account"), WeixinAccount.class);
} catch (NullPointerException e) {
System.err.println("'weixin4j.account' key not found in weixin4j.properties.");
System.err
.println("'weixin4j.account' key not found in weixin4j.properties.");
} catch (MissingResourceException e) {
System.err.println("'weixin4j.account' key not found in weixin4j.properties.");
System.err
.println("'weixin4j.account' key not found in weixin4j.properties.");
}
return account;
}