@@ -164,4 +164,8 @@
|
||||
|
||||
+ type包拆分card/mch
|
||||
|
||||
+ 新增card卡券相关类
|
||||
+ 新增card卡券相关类
|
||||
|
||||
* 2016-08-22
|
||||
|
||||
+ 删除`Weixin4jSettings`配置类
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+26
-7
@@ -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) {
|
||||
|
||||
+7
-2
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package com.foxinmy.weixin4j.base.test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -28,43 +25,39 @@ import com.foxinmy.weixin4j.util.Consts;
|
||||
public class CashTest extends PayTest {
|
||||
|
||||
@Test
|
||||
public void sendRedpacket() throws WeixinException, IOException {
|
||||
public void sendRedpacket() throws WeixinException {
|
||||
Redpacket redpacket = new Redpacket("HB001", "无忧钱庄",
|
||||
"oyFLst1bqtuTcxK-ojF8hOGtLQao", 1d, 1, "红包测试", "127.0.0.1",
|
||||
"快来领取红包吧!", "来就送钱");
|
||||
RedpacketSendResult result = PAY.sendRedpack(
|
||||
new FileInputStream(caFile), redpacket);
|
||||
RedpacketSendResult result = PAY.sendRedpack(redpacket);
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getReturnCode());
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getResultCode());
|
||||
System.err.println(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryRedpacket() throws WeixinException, IOException {
|
||||
public void queryRedpacket() throws WeixinException {
|
||||
String outTradeNo = "HB001";
|
||||
RedpacketRecord result = PAY.queryRedpack(new FileInputStream(caFile),
|
||||
outTradeNo);
|
||||
RedpacketRecord result = PAY.queryRedpack(outTradeNo);
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getReturnCode());
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getResultCode());
|
||||
System.err.println(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendCorpPayment() throws WeixinException, IOException {
|
||||
public void sendCorpPayment() throws WeixinException {
|
||||
CorpPayment payment = new CorpPayment("MP001",
|
||||
"ofW1gwok9vZIyle0YbA-eQe83Uk8",
|
||||
CorpPaymentCheckNameType.NO_CHECK, "企业付款测试", 1d, "127.0.0.1");
|
||||
CorpPaymentResult result = PAY.sendCorpPayment(new FileInputStream(
|
||||
caFile), payment);
|
||||
CorpPaymentResult result = PAY.sendCorpPayment(payment);
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getReturnCode());
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getResultCode());
|
||||
System.err.println(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryCorpPayment() throws WeixinException, IOException {
|
||||
CorpPaymentRecord result = PAY.queryCorpPayment(new FileInputStream(caFile),
|
||||
"MP001");
|
||||
public void queryCorpPayment() throws WeixinException {
|
||||
CorpPaymentRecord result = PAY.queryCorpPayment("MP001");
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getReturnCode());
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getResultCode());
|
||||
System.err.println(result);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.foxinmy.weixin4j.base.test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Assert;
|
||||
@@ -26,11 +24,11 @@ import com.foxinmy.weixin4j.util.DateUtil;
|
||||
public class CouponTest extends PayTest {
|
||||
|
||||
@Test
|
||||
public void sendCoupon() throws WeixinException, IOException {
|
||||
public void sendCoupon() throws WeixinException {
|
||||
String partnerTradeNo = String.format("%s%s%s", ACCOUNT.getMchId(),
|
||||
DateUtil.fortmat2yyyyMMdd(new Date()), "1");
|
||||
CouponResult result = PAY.sendCoupon(new FileInputStream(caFile),
|
||||
"123", partnerTradeNo, "oyFLst1bqtuTcxK-ojF8hOGtLQao", null);
|
||||
CouponResult result = PAY.sendCoupon("123", partnerTradeNo,
|
||||
"oyFLst1bqtuTcxK-ojF8hOGtLQao", null);
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getReturnCode());
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getResultCode());
|
||||
System.err.println(result);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.foxinmy.weixin4j.base.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
@@ -20,12 +20,12 @@ import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.payment.mch.PrePay;
|
||||
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.RefundResult;
|
||||
import com.foxinmy.weixin4j.setting.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
|
||||
import com.foxinmy.weixin4j.sign.WeixinSignature;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.type.IdType;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.type.mch.BillType;
|
||||
import com.foxinmy.weixin4j.util.Consts;
|
||||
|
||||
/**
|
||||
@@ -43,17 +43,15 @@ public class PayTest {
|
||||
protected final static WeixinPayProxy PAY;
|
||||
|
||||
static {
|
||||
ACCOUNT = new WeixinPayAccount("wx0d1d598c0c03c999",
|
||||
"GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ", "10020674");
|
||||
ACCOUNT = new WeixinPayAccount(
|
||||
"appid",
|
||||
"paysignKey",
|
||||
"mchId",
|
||||
"证书密码,为空取mchid",
|
||||
"证书路径,绝对路径&classpath路径:/path/to/certificate.p12,或者填写classpath:path/to/certificate.p12");
|
||||
SIGNATURE = new WeixinPaymentSignature(ACCOUNT.getPaySignKey());
|
||||
PAY = new WeixinPayProxy(
|
||||
new Weixin4jSettings<WeixinPayAccount>(ACCOUNT));
|
||||
PAY = new WeixinPayProxy(ACCOUNT);
|
||||
}
|
||||
/**
|
||||
* 商户证书文件
|
||||
*/
|
||||
protected File caFile = new File(
|
||||
"/Users/jy/workspace/feican/canyi-weixin-parent/canyi-weixin-service/src/main/resources/10020674.p12");
|
||||
|
||||
@Test
|
||||
public void queryOrder() throws WeixinException {
|
||||
@@ -86,22 +84,22 @@ public class PayTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downbill() throws WeixinException {
|
||||
public void downbill() throws WeixinException, IOException {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(Calendar.YEAR, 2016);
|
||||
c.set(Calendar.MONTH, 3);
|
||||
c.set(Calendar.DAY_OF_MONTH, 4);
|
||||
System.err.println(c.getTime());
|
||||
File file = PAY.downloadBill(c.getTime(), null);
|
||||
System.err.println(file);
|
||||
OutputStream os = new FileOutputStream("/tmp/bill20160813.txt");
|
||||
PAY.downloadBill(c.getTime(), BillType.ALL, os);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refund() throws WeixinException, IOException {
|
||||
IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO);
|
||||
RefundResult result = PAY.applyRefund(new FileInputStream(caFile),
|
||||
idQuery, "TT_R" + System.currentTimeMillis(), 0.01d, 0.01d,
|
||||
null, "10020674");
|
||||
RefundResult result = PAY.applyRefund(idQuery,
|
||||
"TT_R" + System.currentTimeMillis(), 0.01d, 0.01d, null,
|
||||
"10020674");
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getReturnCode());
|
||||
Assert.assertEquals(Consts.SUCCESS, result.getResultCode());
|
||||
System.err.println(result);
|
||||
|
||||
Reference in New Issue
Block a user