新增Weixin4jSettings配置类

This commit is contained in:
jinyu
2016-01-29 09:38:47 +08:00
parent c4bf06d372
commit 2e2d207e76
46 changed files with 717 additions and 464 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId>
<version>1.6.6</version>
<version>1.6.7</version>
</parent>
<artifactId>weixin4j-base</artifactId>
<name>weixin4j-base</name>
@@ -5,11 +5,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.token.FileTokenStorager;
import com.foxinmy.weixin4j.token.TokenStorager;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
import com.foxinmy.weixin4j.util.Weixin4jConst;
/**
* API基础
@@ -45,21 +40,4 @@ public abstract class BaseApi {
m.appendTail(sb);
return sb.toString();
}
/**
* 默认使用weixin4j.properties文件中的公众号信息
*/
public final static WeixinAccount DEFAULT_WEIXIN_ACCOUNT;
/**
* 默认token使用File的方式存储
*/
public final static TokenStorager DEFAULT_TOKEN_STORAGER;
static {
DEFAULT_WEIXIN_ACCOUNT = Weixin4jConfigUtil.getWeixinAccount();
DEFAULT_TOKEN_STORAGER = new FileTokenStorager(
Weixin4jConfigUtil.getValue("token.path",
Weixin4jConst.DEFAULT_TOKEN_PATH));
}
}
@@ -48,7 +48,7 @@ public class CashApi {
* 发放红包 企业向微信用户个人发现金红包
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param redpacket
* 红包信息
* @return 发放结果
@@ -71,7 +71,7 @@ public class CashApi {
WeixinResponse response = null;
try {
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
weixinAccount.getMchId(), ca);
weixinAccount.getCertificateKey(), ca);
response = weixinExecutor
.post(redpacket.getTotalNum() > 1 ? PayURLConsts.MCH_REDPACK_GROUPSEND_URL
: PayURLConsts.MCH_REDPACKSEND_URL, param);
@@ -92,7 +92,7 @@ public class CashApi {
* 查询红包记录
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param outTradeNo
* 商户发放红包的商户订单号
* @return 红包记录
@@ -116,7 +116,7 @@ public class CashApi {
WeixinResponse response = null;
try {
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
weixinAccount.getMchId(), ca);
weixinAccount.getCertificateKey(), ca);
response = weixinExecutor.post(PayURLConsts.MCH_REDPACKQUERY_URL,
param);
} finally {
@@ -136,7 +136,7 @@ public class CashApi {
* 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param mpPayment
* 付款信息
* @return 付款结果
@@ -160,7 +160,7 @@ public class CashApi {
WeixinResponse response = null;
try {
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
weixinAccount.getMchId(), ca);
weixinAccount.getCertificateKey(), ca);
response = weixinExecutor.post(PayURLConsts.MCH_ENPAYMENT_URL,
param);
} finally {
@@ -184,7 +184,7 @@ public class CashApi {
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param outTradeNo
* 商户调用企业付款API时使用的商户订单号
* @return 付款记录
@@ -206,7 +206,7 @@ public class CashApi {
WeixinResponse response = null;
try {
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
weixinAccount.getMchId(), ca);
weixinAccount.getCertificateKey(), ca);
response = weixinExecutor.post(PayURLConsts.MCH_ENPAYQUERY_URL,
param);
} finally {
@@ -44,7 +44,7 @@ public class CouponApi {
* 发放代金券(需要证书)
*
* @param ca
* 证书文件(后缀为*.p12)
* 后缀为*.p12的证书文件
* @param couponStockId
* 代金券批次id
* @param partnerTradeNo
@@ -81,7 +81,7 @@ public class CouponApi {
WeixinResponse response = null;
try {
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
weixinAccount.getMchId(), ca);
weixinAccount.getCertificateKey(), ca);
response = weixinExecutor.post(PayURLConsts.MCH_COUPONSEND_URL,
param);
} finally {
@@ -29,12 +29,12 @@ import com.foxinmy.weixin4j.payment.MicroPayPackage;
import com.foxinmy.weixin4j.payment.PayURLConsts;
import com.foxinmy.weixin4j.payment.mch.APPPayRequest;
import com.foxinmy.weixin4j.payment.mch.ApiResult;
import com.foxinmy.weixin4j.payment.mch.AuthCodeOpenIdResult;
import com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest;
import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
import com.foxinmy.weixin4j.payment.mch.MchPayRequest;
import com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest;
import com.foxinmy.weixin4j.payment.mch.NativePayResponse;
import com.foxinmy.weixin4j.payment.mch.OpenIdResult;
import com.foxinmy.weixin4j.payment.mch.Order;
import com.foxinmy.weixin4j.payment.mch.PrePay;
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
@@ -51,8 +51,6 @@ 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.Weixin4jConfigUtil;
import com.foxinmy.weixin4j.util.Weixin4jConst;
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
import com.foxinmy.weixin4j.xml.XmlStream;
@@ -496,7 +494,7 @@ public class Pay3Api {
* </p>
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -539,7 +537,7 @@ public class Pay3Api {
map.put("sign", sign);
String param = XmlStream.map2xml(map);
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
weixinAccount.getMchId(), ca);
weixinAccount.getCertificateKey(), ca);
response = weixinExecutor.post(PayURLConsts.MCH_REFUNDAPPLY_URL,
param);
} finally {
@@ -559,7 +557,7 @@ public class Pay3Api {
* 退款申请(全额退款)
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -582,7 +580,7 @@ public class Pay3Api {
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font></br>
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -594,7 +592,7 @@ public class Pay3Api {
throws WeixinException {
try {
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
weixinAccount.getMchId(), ca);
weixinAccount.getCertificateKey(), ca);
Map<String, String> map = baseMap(idQuery);
String sign = DigestUtil.paysignMd5(map,
weixinAccount.getPaySignKey());
@@ -681,13 +679,15 @@ public class Pay3Api {
* @param billType
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
* REFUND,返回当日退款订单
* @param billPath
* 对账单保存路径
* @return excel表格
* @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)
public File downloadBill(Date billDate, BillType billType, String billPath)
throws WeixinException {
if (billDate == null) {
Calendar now = Calendar.getInstance();
@@ -698,11 +698,9 @@ public class Pay3Api {
billType = BillType.ALL;
}
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
String bill_path = Weixin4jConfigUtil.getValue("bill.path",
Weixin4jConst.DEFAULT_BILL_PATH);
String fileName = String.format("%s_%s_%s.txt", formatBillDate,
billType.name().toLowerCase(), weixinAccount.getId());
File file = new File(String.format("%s/%s", bill_path, fileName));
File file = new File(String.format("%s/%s", billPath, fileName));
if (file.exists()) {
return file;
}
@@ -820,13 +818,12 @@ public class Pay3Api {
* @param authCode
* 扫码支付授权码,设备读取用户微信中的条码或者二维码信息
* @return 查询结果
* @see com.foxinmy.weixin4j.payment.mch.AuthCodeOpenIdResult
* @see com.foxinmy.weixin4j.payment.mch.OpenIdResult
* @see <a
* href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9">授权码查询OPENID</a>
* @throws WeixinException
*/
public AuthCodeOpenIdResult authCode2openId(String authCode)
throws WeixinException {
public OpenIdResult authCode2openId(String authCode) throws WeixinException {
Map<String, String> map = baseMap(null);
map.put("auth_code", authCode);
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
@@ -834,7 +831,7 @@ public class Pay3Api {
String param = XmlStream.map2xml(map);
WeixinResponse response = weixinExecutor.post(
PayURLConsts.MCH_AUTHCODE_OPENID_URL, param);
return response.getAsObject(new TypeReference<AuthCodeOpenIdResult>() {
return response.getAsObject(new TypeReference<OpenIdResult>() {
});
}
@@ -32,6 +32,10 @@ public class WeixinPayAccount extends WeixinAccount {
* 微信支付分配的商户号(商户平台版)
*/
private String mchId;
/**
* 加载支付证书文件的密码(商户平台版)
*/
private String certificateKey;
/**
* 微信支付分配的子商户号,受理模式下必填(商户平台版)
*/
@@ -40,10 +44,6 @@ public class WeixinPayAccount extends WeixinAccount {
* 微信支付分配的设备号(商户平台版)
*/
private String deviceInfo;
/**
* 微信支付版本号(如果无则按照mchId来做判断)
*/
private int version;
/**
* 商户平台版本(V3)字段
@@ -57,8 +57,9 @@ public class WeixinPayAccount extends WeixinAccount {
* @param mchId
* 微信支付分配的商户号(必填)
*/
public WeixinPayAccount(String appId, String appSecret, String paySignKey, String mchId) {
this(appId, appSecret, paySignKey, mchId, null, null, null, null);
public WeixinPayAccount(String appId, String appSecret, String paySignKey,
String mchId) {
this(appId, appSecret, paySignKey, mchId, null, null, null, null, null);
}
/**
@@ -72,6 +73,8 @@ public class WeixinPayAccount extends WeixinAccount {
* 支付密钥字符串(必填)
* @param mchId
* 微信支付分配的商户号(V3商户平台版必填)
* @param certificateKey
* 加载支付证书文件的密码(商户平台版)
* @param subMchId
* 微信支付分配的子商户号,受理模式下必填(V3商户平台版 非必须)
* @param deviceInfo
@@ -82,13 +85,19 @@ public class WeixinPayAccount extends WeixinAccount {
* 财付通商户权限密钥Key(V2版本必填)
*/
@JSONCreator
public WeixinPayAccount(@JSONField(name = "id") String appId, @JSONField(name = "secret") String appSecret,
@JSONField(name = "paySignKey") String paySignKey, @JSONField(name = "mchId") String mchId,
@JSONField(name = "subMchId") String subMchId, @JSONField(name = "deviceInfo") String deviceInfo,
@JSONField(name = "partnerId") String partnerId, @JSONField(name = "partnerKey") String partnerKey) {
public WeixinPayAccount(@JSONField(name = "id") String appId,
@JSONField(name = "secret") String appSecret,
@JSONField(name = "paySignKey") String paySignKey,
@JSONField(name = "mchId") String mchId,
@JSONField(name = "certificateKey") String certificateKey,
@JSONField(name = "subMchId") String subMchId,
@JSONField(name = "deviceInfo") String deviceInfo,
@JSONField(name = "partnerId") String partnerId,
@JSONField(name = "partnerKey") String partnerKey) {
super(appId, appSecret);
this.paySignKey = paySignKey;
this.mchId = mchId;
this.certificateKey = certificateKey;
this.subMchId = subMchId;
this.deviceInfo = deviceInfo;
this.partnerId = partnerId;
@@ -119,17 +128,16 @@ public class WeixinPayAccount extends WeixinAccount {
return deviceInfo;
}
public int getVersion() {
if (version == 0) {
return StringUtil.isNotBlank(mchId) ? 3 : 2;
}
return version;
public String getCertificateKey() {
return StringUtil.isBlank(certificateKey) ? mchId : certificateKey;
}
@Override
public String toString() {
return "WeixinPayAccount [" + super.toString() + ", paySignKey=" + paySignKey + ", partnerId=" + partnerId
+ ", partnerKey=" + partnerKey + ", mchId=" + mchId + ", subMchId=" + subMchId + ", deviceInfo="
+ deviceInfo + ", version=" + getVersion() + "]";
return "WeixinPayAccount [" + super.toString() + ", paySignKey="
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey="
+ partnerKey + ", mchId=" + mchId + ", certificateKey="
+ getCertificateKey() + ", subMchId=" + subMchId
+ ", deviceInfo=" + deviceInfo + "]";
}
}
@@ -6,7 +6,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.api.CashApi;
import com.foxinmy.weixin4j.api.CouponApi;
import com.foxinmy.weixin4j.api.Pay3Api;
@@ -18,25 +17,24 @@ import com.foxinmy.weixin4j.payment.coupon.CouponDetail;
import com.foxinmy.weixin4j.payment.coupon.CouponResult;
import com.foxinmy.weixin4j.payment.coupon.CouponStock;
import com.foxinmy.weixin4j.payment.mch.ApiResult;
import com.foxinmy.weixin4j.payment.mch.AuthCodeOpenIdResult;
import com.foxinmy.weixin4j.payment.mch.MPPayment;
import com.foxinmy.weixin4j.payment.mch.MPPaymentRecord;
import com.foxinmy.weixin4j.payment.mch.MPPaymentResult;
import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
import com.foxinmy.weixin4j.payment.mch.MchPayRequest;
import com.foxinmy.weixin4j.payment.mch.NativePayResponse;
import com.foxinmy.weixin4j.payment.mch.OpenIdResult;
import com.foxinmy.weixin4j.payment.mch.Order;
import com.foxinmy.weixin4j.payment.mch.PrePay;
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.Weixin4jConfigUtil;
import com.foxinmy.weixin4j.util.Weixin4jConst;
/**
* 微信支付接口实现
@@ -54,26 +52,26 @@ public class WeixinPayProxy {
private final CouponApi couponApi;
private final CashApi cashApi;
private final WeixinPayAccount payAccount;
private final Weixin4jPaySettings settings;
/**
* 使用weixin4j.properties配置的账号信息
* 使用weixin4j.properties配置的支付账号信息
*/
public WeixinPayProxy() {
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
WeixinPayAccount.class));
this(new Weixin4jPaySettings());
}
/**
*
* @param weixinAccount
* 支付相关的公众号账号信息
* @param settings
* 支付相关配置信息
* @see com.foxinmy.weixin4j.settings.Weixin4jPaySettings
*/
public WeixinPayProxy(WeixinPayAccount payAccount) {
this.payAccount = payAccount;
this.pay3Api = new Pay3Api(payAccount);
this.couponApi = new CouponApi(payAccount);
this.cashApi = new CashApi(payAccount);
public WeixinPayProxy(Weixin4jPaySettings settings) {
this.settings = settings;
this.pay3Api = new Pay3Api(settings.getPayAccount());
this.couponApi = new CouponApi(settings.getPayAccount());
this.cashApi = new CashApi(settings.getPayAccount());
}
/**
@@ -82,9 +80,7 @@ public class WeixinPayProxy {
* @return
*/
public WeixinPayAccount getPayAccount() {
// clone ...
String text = JSON.toJSONString(payAccount);
return JSON.parseObject(text, WeixinPayAccount.class);
return this.settings.getPayAccount();
}
/**
@@ -429,7 +425,7 @@ public class WeixinPayProxy {
* </p>
*
* @param ca
* 证书文件(后缀为*.p12)
* 后缀为*.p12的证书文件
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
@@ -461,7 +457,7 @@ public class WeixinPayProxy {
}
/**
* 退款申请(全额退款)采用properties中配置的ca文件
* 退款申请(全额退款)
*
* @throws IOException
*
@@ -470,12 +466,9 @@ public class WeixinPayProxy {
public com.foxinmy.weixin4j.payment.mch.RefundResult refundApply(
IdQuery idQuery, String outRefundNo, double totalFee)
throws WeixinException, IOException {
return pay3Api
.refundApply(
new FileInputStream(Weixin4jConfigUtil
.getClassPathValue("certificate.file",
Weixin4jConst.DEFAULT_CAFILE_PATH)),
idQuery, outRefundNo, totalFee);
return pay3Api.refundApply(
new FileInputStream(settings.getCertificatePath()), idQuery,
outRefundNo, totalFee);
}
/**
@@ -521,7 +514,7 @@ public class WeixinPayProxy {
*/
public File downloadBill(Date billDate, BillType billType)
throws WeixinException {
return pay3Api.downloadBill(billDate, billType);
return pay3Api.downloadBill(billDate, billType, settings.getBillPath());
}
/**
@@ -546,7 +539,7 @@ public class WeixinPayProxy {
}
/**
* 冲正撤销:默认采用properties中配置的ca文件
* 冲正撤销
*
* @param idQuery
* transaction_id、out_trade_no 二选一
@@ -557,12 +550,8 @@ public class WeixinPayProxy {
*/
public ApiResult reverseOrder(IdQuery idQuery) throws WeixinException,
IOException {
return pay3Api
.reverseOrder(
new FileInputStream(Weixin4jConfigUtil
.getClassPathValue("certificate.file",
Weixin4jConst.DEFAULT_CAFILE_PATH)),
idQuery);
return pay3Api.reverseOrder(
new FileInputStream(settings.getCertificatePath()), idQuery);
}
/**
@@ -635,7 +624,7 @@ public class WeixinPayProxy {
* 发放代金券(需要证书)
*
* @param ca
* 证书文件(后缀为*.p12)
* 后缀为*.p12的证书文件
* @param couponStockId
* 代金券批次id
* @param partnerTradeNo
@@ -659,18 +648,15 @@ public class WeixinPayProxy {
}
/**
* 发放代金券采用properties中配置的ca文件
* 发放代金券
*
* @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(Weixin4jConfigUtil
.getClassPathValue("certificate.file",
Weixin4jConst.DEFAULT_CAFILE_PATH)),
couponStockId, partnerTradeNo, openId, null);
return couponApi.sendCoupon(
new FileInputStream(settings.getCertificatePath()),
couponStockId, partnerTradeNo, openId, null);
}
/**
@@ -711,7 +697,7 @@ public class WeixinPayProxy {
* 发放红包 企业向微信用户个人发现金红包
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param redpacket
* 红包信息
* @return 发放结果
@@ -728,25 +714,21 @@ public class WeixinPayProxy {
}
/**
* 发放红包采用properties中配置的ca文件
* 发放红包
*
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#sendRedpack(InputStream, Redpacket)}
*/
public RedpacketSendResult sendRedpack(Redpacket redpacket)
throws WeixinException, IOException {
return cashApi
.sendRedpack(
new FileInputStream(Weixin4jConfigUtil
.getClassPathValue("certificate.file",
Weixin4jConst.DEFAULT_CAFILE_PATH)),
redpacket);
return cashApi.sendRedpack(
new FileInputStream(settings.getCertificatePath()), redpacket);
}
/**
* 查询红包记录
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param outTradeNo
* 商户发放红包的商户订单号
* @return 红包记录
@@ -762,25 +744,21 @@ public class WeixinPayProxy {
}
/**
* 查询红包采用properties中配置的ca文件
* 查询红包
*
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#queryRedpack(InputStream,String)}
*/
public RedpacketRecord queryRedpack(String outTradeNo)
throws WeixinException, IOException {
return cashApi
.queryRedpack(
new FileInputStream(Weixin4jConfigUtil
.getClassPathValue("certificate.file",
Weixin4jConst.DEFAULT_CAFILE_PATH)),
outTradeNo);
return cashApi.queryRedpack(
new FileInputStream(settings.getCertificatePath()), outTradeNo);
}
/**
* 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param mpPayment
* 付款信息
* @return 付款结果
@@ -797,25 +775,21 @@ public class WeixinPayProxy {
}
/**
* 企业付款采用properties中配置的ca文件
* 企业付款
*
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#mpPayment(InputStream, MPPayment)}
*/
public MPPaymentResult mpPayment(MPPayment mpPayment)
throws WeixinException, IOException {
return cashApi
.mchPayment(
new FileInputStream(Weixin4jConfigUtil
.getClassPathValue("certificate.file",
Weixin4jConst.DEFAULT_CAFILE_PATH)),
mpPayment);
return cashApi.mchPayment(
new FileInputStream(settings.getCertificatePath()), mpPayment);
}
/**
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
*
* @param ca
* 证书文件(V3版本后缀为*.p12)
* 后缀为*.p12的证书文件
* @param outTradeNo
* 商户调用企业付款API时使用的商户订单号
* @return 付款记录
@@ -831,18 +805,14 @@ public class WeixinPayProxy {
}
/**
* 企业付款查询采用properties中配置的ca文件
* 企业付款查询
*
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#mpPaymentQuery(InputStream, String)}
*/
public MPPaymentRecord mpPaymentQuery(String outTradeNo)
throws WeixinException, IOException {
return cashApi
.mchPaymentQuery(
new FileInputStream(Weixin4jConfigUtil
.getClassPathValue("certificate.file",
Weixin4jConst.DEFAULT_CAFILE_PATH)),
outTradeNo);
return cashApi.mchPaymentQuery(
new FileInputStream(settings.getCertificatePath()), outTradeNo);
}
/**
@@ -852,15 +822,14 @@ public class WeixinPayProxy {
* 扫码支付授权码,设备读取用户微信中的条码或者二维码信息
* @return 查询结果
* @see com.foxinmy.weixin4j.api.CashApi
* @see com.foxinmy.weixin4j.payment.mch.AuthCodeOpenIdResult
* @see com.foxinmy.weixin4j.payment.mch.OpenIdResult
* @see <a
* href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9">授权码查询OPENID</a>
* @throws WeixinException
*/
public AuthCodeOpenIdResult authCode2openId(String authCode)
throws WeixinException {
public OpenIdResult authCode2openId(String authCode) throws WeixinException {
return pay3Api.authCode2openId(authCode);
}
public final static String VERSION = "1.6.6";
public final static String VERSION = "1.6.7";
}
@@ -80,7 +80,6 @@ public class CouponDetail extends ApiResult {
@XmlElement(name = "coupon_type")
@JSONField(name = "coupon_type")
private int couponType;
/**
* 代金券描述
*/
@@ -5,8 +5,10 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.alibaba.fastjson.annotation.JSONField;
/**
* Native支付回调时POST的信息
* Native支付回调时POST的信息
*
* @className PayNativeNotify
* @author jy
@@ -16,27 +18,37 @@ import javax.xml.bind.annotation.XmlRootElement;
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class NativePayNotify extends ApiResult {
public class NativePayNotify extends OpenIdResult {
private static final long serialVersionUID = 4515471400239795492L;
/**
* 用户是否关注公众账号,Y- 关注,N-未关注,仅在公众 账号类型支付有效
*/
@XmlElement(name = "is_subscribe")
@JSONField(name = "is_subscribe")
private String isSubscribe;
/**
* 产品ID 可视为订单ID
*/
@XmlElement(name = "product_id")
@JSONField(name = "product_id")
private String productId;
protected NativePayNotify() {
// jaxb required
}
public String getProductId() {
return productId;
}
public String getIsSubscribe() {
return isSubscribe;
}
@Override
public String toString() {
return "NativePayNotify [productId=" + productId + ", "
+ super.toString() + "]";
return "NativePayNotify [productId=" + productId + ", isSubscribe="
+ isSubscribe + ", " + super.toString() + "]";
}
}
@@ -10,7 +10,7 @@ import com.alibaba.fastjson.annotation.JSONField;
/**
* authcode2openid
*
* @className AuthCodeOpenIdResult
* @className OpenIdResult
* @author jy
* @date 2015年7月23日
* @since JDK 1.6
@@ -18,7 +18,7 @@ import com.alibaba.fastjson.annotation.JSONField;
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class AuthCodeOpenIdResult extends ApiResult {
public class OpenIdResult extends ApiResult {
private static final long serialVersionUID = 902743989722741814L;
@@ -35,7 +35,7 @@ public class AuthCodeOpenIdResult extends ApiResult {
@Override
public String toString() {
return "AuthCodeOpenIdResult [openId=" + openId + ", "
return "OpenIdResult [openId=" + openId + ", "
+ super.toString() + "]";
}
}
@@ -144,10 +144,6 @@ public class Redpacket implements Serializable {
return amtType;
}
public void setAmtType(String amtType) {
this.amtType = amtType;
}
public String getClientIp() {
return clientIp;
}
@@ -0,0 +1,14 @@
package com.foxinmy.weixin4j.settings;
/**
* 微信请求配置相关(待实现
*
* @className Weixin4jHttpSettings
* @author jy
* @date 2016年1月28日
* @since JDK 1.6
* @see
*/
public class Weixin4jHttpSettings {
}
@@ -0,0 +1,108 @@
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()
+ "]";
}
}
@@ -0,0 +1,168 @@
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() + "]";
}
}
@@ -44,7 +44,7 @@ public interface CacheStorager<T> {
T evict(String cacheKey);
/**
* 清除所有缓存对象(<font color="red">请慎重</a>)
* 清除所有缓存对象(<font color="red">请慎重</font>)
*/
void clear();
}
@@ -1,11 +1,16 @@
package com.foxinmy.weixin4j.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.payment.mch.NativePayNotify;
import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 签名工具类
@@ -130,4 +135,12 @@ public final class DigestUtil {
return sb.toString();
}
public static void main(String[] args) throws FileNotFoundException {
NativePayNotify notify = XmlStream.fromXML(new FileInputStream(
new File("/Users/jy/Downloads/weixin4j.xml")),
NativePayNotify.class);
notify.setSign(null);
System.err.println(paysignMd5(notify, "GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ"));
}
}
@@ -75,7 +75,7 @@ public class Weixin4jConfigUtil {
value = getValue(key);
} catch (MissingResourceException e) {
;
}catch (NullPointerException e){
} catch (NullPointerException e) {
;
}
return value;
@@ -88,8 +88,7 @@ public class Weixin4jConfigUtil {
* @return
*/
public static String getClassPathValue(String key) {
return new File(getValue(key).replaceFirst(CLASSPATH_PREFIX,
CLASSPATH_VALUE)).getPath();
return getValue(key).replaceFirst(CLASSPATH_PREFIX, CLASSPATH_VALUE);
}
/**
@@ -99,18 +98,18 @@ public class Weixin4jConfigUtil {
* @return
*/
public static String getClassPathValue(String key, String defaultValue) {
return new File(getValue(key, defaultValue).replaceFirst(
CLASSPATH_PREFIX, CLASSPATH_VALUE)).getPath();
return getValue(key, defaultValue).replaceFirst(CLASSPATH_PREFIX,
CLASSPATH_VALUE);
}
public static WeixinAccount getWeixinAccount() {
if (weixinBundle == null) {
return null;
}
WeixinAccount account = null;
try {
account = JSON
.parseObject(getValue("account"), WeixinAccount.class);
} catch (NullPointerException e) {
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.");
@@ -1,33 +0,0 @@
package com.foxinmy.weixin4j.util;
/**
* 常量配置
*
* @className Weixin4jConst
* @author jy
* @date 2015年7月1日
* @since JDK 1.6
* @see
*/
public final class Weixin4jConst {
/**
* 使用FileTokenStorager时token的存放路径
*/
public static final String DEFAULT_TOKEN_PATH = "/tmp/weixin4j/token";
/**
* 二维码保存路径
*/
public static final String DEFAULT_QRCODE_PATH = "/tmp/weixin4j/qrcode";
/**
* 媒体文件保存路径
*/
public static final String DEFAULT_MEDIA_PATH = "/tmp/weixin4j/media";
/**
* 对账单保存路径
*/
public static final String DEFAULT_BILL_PATH = "/tmp/weixin4j/bill";
/**
* ca证书存放的完整路径 (V2版本后缀为*.pfx,V3版本后缀为*.p12)
*/
public static final String DEFAULT_CAFILE_PATH = "classpath:ca.p12";
}
@@ -67,7 +67,9 @@ public class HttpClientTest {
}
public static void main(String[] args) throws Exception {
for(int i=0;i<100000;i++){
test1();
}
System.out.println("---------------------");
test2();
System.out.println("---------------------");