主要改动了支付接口:对服务商版进行支持

This commit is contained in:
jinyu 2016-03-26 00:51:39 +08:00
parent e1588bfb53
commit 0897575fe1
20 changed files with 639 additions and 233 deletions

View File

@ -645,4 +645,10 @@
* 2016-03-22 * 2016-03-22
+ weixin4j-base:企业付款相关类更名 + weixin4j-base:企业付款相关类更名
* 2016-03-25
+ weixin4j-base:v2和v3支付改名
+ weixin4j-base:支持服务商版支付

View File

@ -60,14 +60,9 @@ public class CashApi {
*/ */
public RedpacketSendResult sendRedpack(InputStream ca, Redpacket redpacket) public RedpacketSendResult sendRedpack(InputStream ca, Redpacket redpacket)
throws WeixinException { throws WeixinException {
JSONObject obj = (JSONObject) JSON.toJSON(redpacket); redpacket.setSign(DigestUtil.paysignMd5(redpacket,
obj.put("nonce_str", RandomUtil.generateString(16)); weixinAccount.getPaySignKey()));
obj.put("mch_id", weixinAccount.getMchId()); String param = XmlStream.map2xml((JSONObject) JSON.toJSON(redpacket));
obj.put("sub_mch_id", weixinAccount.getSubMchId());
obj.put("wxappid", weixinAccount.getId());
String sign = DigestUtil.paysignMd5(obj, weixinAccount.getPaySignKey());
obj.put("sign", sign);
String param = XmlStream.map2xml(obj);
WeixinResponse response = null; WeixinResponse response = null;
try { try {
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor( WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
@ -184,7 +179,7 @@ public class CashApi {
* 企业付款查询 用于商户的企业付款操作进行结果查询返回付款操作详细结果 * 企业付款查询 用于商户的企业付款操作进行结果查询返回付款操作详细结果
* *
* @param ca * @param ca
* 后缀为*.p12的证书文件 * 后缀为*.p12的证书文件
* @param outTradeNo * @param outTradeNo
* 商户调用企业付款API时使用的商户订单号 * 商户调用企业付款API时使用的商户订单号
* @return 付款记录 * @return 付款记录

View File

@ -63,12 +63,12 @@ import com.foxinmy.weixin4j.xml.XmlStream;
* @since JDK 1.6 * @since JDK 1.6
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/index.html">商户平台API</a> * @see <a href="http://pay.weixin.qq.com/wiki/doc/api/index.html">商户平台API</a>
*/ */
public class Pay3Api { public class PayApi {
private final WeixinRequestExecutor weixinExecutor; private final WeixinRequestExecutor weixinExecutor;
private final WeixinPayAccount weixinAccount; private final WeixinPayAccount weixinAccount;
public Pay3Api(WeixinPayAccount weixinAccount) { public PayApi(WeixinPayAccount weixinAccount) {
this.weixinAccount = weixinAccount; this.weixinAccount = weixinAccount;
this.weixinExecutor = new WeixinRequestExecutor(); this.weixinExecutor = new WeixinRequestExecutor();
} }
@ -88,10 +88,8 @@ public class Pay3Api {
*/ */
public PrePay createPrePay(MchPayPackage payPackage) public PrePay createPrePay(MchPayPackage payPackage)
throws WeixinPayException { throws WeixinPayException {
if (StringUtil.isBlank(payPackage.getSign())) { payPackage.setSign(DigestUtil.paysignMd5(payPackage,
payPackage.setSign(DigestUtil.paysignMd5(payPackage, weixinAccount.getPaySignKey()));
weixinAccount.getPaySignKey()));
}
String payJsRequestXml = XmlStream.toXML(payPackage); String payJsRequestXml = XmlStream.toXML(payPackage);
try { try {
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
@ -126,8 +124,6 @@ public class Pay3Api {
*/ */
public MchPayRequest createPayRequest(MchPayPackage payPackage) public MchPayRequest createPayRequest(MchPayPackage payPackage)
throws WeixinPayException { throws WeixinPayException {
payPackage.setSign(DigestUtil.paysignMd5(payPackage,
weixinAccount.getPaySignKey()));
PrePay prePay = createPrePay(payPackage); PrePay prePay = createPrePay(payPackage);
String tradeType = payPackage.getTradeType(); String tradeType = payPackage.getTradeType();
if (TradeType.APP.name().equalsIgnoreCase(tradeType)) { if (TradeType.APP.name().equalsIgnoreCase(tradeType)) {
@ -140,7 +136,7 @@ public class Pay3Api {
} else if (TradeType.WAP.name().equalsIgnoreCase(tradeType)) { } else if (TradeType.WAP.name().equalsIgnoreCase(tradeType)) {
return new WAPPayRequest(prePay.getPrepayId(), weixinAccount); return new WAPPayRequest(prePay.getPrepayId(), weixinAccount);
} else if (TradeType.MICROPAY.name().equalsIgnoreCase(tradeType)) { } else if (TradeType.MICROPAY.name().equalsIgnoreCase(tradeType)) {
throw new WeixinPayException("maybe use createMicroPay method?"); throw new WeixinPayException("maybe invoke createMicroPay method?");
} else { } else {
throw new WeixinPayException("unknown tradeType:" + tradeType); throw new WeixinPayException("unknown tradeType:" + tradeType);
} }
@ -180,7 +176,7 @@ public class Pay3Api {
* @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付 * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付
* @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付 * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付
* @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付 * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付t * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest WAP支付
* @throws WeixinPayException * @throws WeixinPayException
*/ */
public MchPayRequest createPayRequest(TradeType tradeType, String openId, public MchPayRequest createPayRequest(TradeType tradeType, String openId,
@ -836,7 +832,7 @@ public class Pay3Api {
} }
/** /**
* V3接口请求基本数据 * 支付接口请求基本数据
* *
* @return * @return
*/ */
@ -848,6 +844,12 @@ public class Pay3Api {
if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) { if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) {
map.put("device_info", weixinAccount.getDeviceInfo()); map.put("device_info", weixinAccount.getDeviceInfo());
} }
if (StringUtil.isNotBlank(weixinAccount.getSubId())) {
map.put("sub_appid", weixinAccount.getSubId());
}
if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) {
map.put("sub_mch_id", weixinAccount.getSubMchId());
}
if (idQuery != null) { if (idQuery != null) {
map.put(idQuery.getType().getName(), idQuery.getId()); map.put(idQuery.getType().getName(), idQuery.getId());
} }

View File

@ -2,4 +2,4 @@
* CouponApi `优惠券API` * CouponApi `优惠券API`
* Pay3Api `微信支付API` * PayApi `微信支付API`

View File

@ -17,127 +17,142 @@ public class WeixinPayAccount extends WeixinAccount {
private static final long serialVersionUID = -2791256176906048632L; private static final long serialVersionUID = -2791256176906048632L;
/** /**
* 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey * 公众号支付请求中用于加密的密钥
*/ */
private String paySignKey; private String paySignKey;
/** /**
* 财付通商户身份的标识 * 微信支付分配的商户号
*/
private String partnerId;
/**
* 财付通商户权限密钥Key
*/
private String partnerKey;
/**
* 微信支付分配的商户号(商户平台版)
*/ */
private String mchId; private String mchId;
/** /**
* 加载支付证书文件的密码(商户平台版) * 加载支付证书文件的密码(默认为商户号)
*/ */
private String certificateKey; private String certificateKey;
/** /**
* 微信支付分配的子商户号受理模式下必填(商户平台版) * 微信支付分配的设备号
*/
private String subMchId;
/**
* 微信支付分配的设备号(商户平台版)
*/ */
private String deviceInfo; private String deviceInfo;
/** /**
* 商户平台版本(V3)字段 * 财付通商户身份的标识
*/
private String partnerId;
/**
* 微信分配的子商户公众账号ID
*/
private String subId;
/**
* 微信支付分配的子商户号
*/
private String subMchId;
/**
* 支付商户信息
* *
* @param appId * @param id
* 公众号唯一的身份ID(必填) * 公众号唯一的身份ID(必填)
* @param appSecret
* 调用接口的凭证(最好填写)
* @param paySignKey * @param paySignKey
* 支付密钥字符串(必填) * 支付密钥字符串(必填)
* @param mchId * @param mchId
* 微信支付分配的商户号(必填) * 微信支付分配的商户号(必填)
*/ */
public WeixinPayAccount(String appId, String appSecret, String paySignKey, public WeixinPayAccount(String id, String paySignKey, String mchId) {
String mchId) { this(id, null, paySignKey, mchId, null, null, null, null, null);
this(appId, appSecret, paySignKey, mchId, null, null, null, null, null);
} }
/** /**
* 支付商户信息 * 支付商户信息
* *
* @param appId * @param id
* 公众号唯一的身份ID(必填) * 公众号唯一的身份ID(必填)
* @param appSecret * @param secret
* 调用接口的凭证(最好填写) * 公众号调用接口的凭证(最好填写)
* @param paySignKey * @param paySignKey
* 支付密钥字符串(必填) * 支付密钥字符串(必填)
* @param mchId * @param mchId
* 微信支付分配的商户号(V3商户平台版必填) * 微信支付分配的商户号(必填)
* @param certificateKey * @param certificateKey
* 加载支付证书文件的密码(商户平台版) * 加载支付证书文件的密码(默认为商户号)
* @param subMchId
* 微信支付分配的子商户号受理模式下必填(V3商户平台版 非必须)
* @param deviceInfo * @param deviceInfo
* 微信支付分配的设备号(V3商户平台版 非必须) * 微信支付分配的设备号(非必填)
* @param partnerId * @param partnerId
* 财付通的商户号(V2版本必填) * 财付通的商户号(非必填)
* @param partnerKey * @param subId
* 财付通商户权限密钥Key(V2版本必填) * 微信分配的子商户公众账号ID(非必填)
* @param subMchId
* 微信支付分配的子商户号(非必填)
*/ */
@JSONCreator @JSONCreator
public WeixinPayAccount(@JSONField(name = "id") String appId, public WeixinPayAccount(@JSONField(name = "id") String id,
@JSONField(name = "secret") String appSecret, @JSONField(name = "secret") String secret,
@JSONField(name = "paySignKey") String paySignKey, @JSONField(name = "paySignKey") String paySignKey,
@JSONField(name = "mchId") String mchId, @JSONField(name = "mchId") String mchId,
@JSONField(name = "certificateKey") String certificateKey, @JSONField(name = "certificateKey") String certificateKey,
@JSONField(name = "subMchId") String subMchId,
@JSONField(name = "deviceInfo") String deviceInfo, @JSONField(name = "deviceInfo") String deviceInfo,
@JSONField(name = "partnerId") String partnerId, @JSONField(name = "partnerId") String partnerId,
@JSONField(name = "partnerKey") String partnerKey) { @JSONField(name = "subId") String subId,
super(appId, appSecret); @JSONField(name = "subMchId") String subMchId) {
super(id, secret);
this.paySignKey = paySignKey; this.paySignKey = paySignKey;
this.mchId = mchId; this.mchId = mchId;
this.certificateKey = certificateKey; this.certificateKey = certificateKey;
this.subMchId = subMchId;
this.deviceInfo = deviceInfo; this.deviceInfo = deviceInfo;
this.partnerId = partnerId; this.partnerId = partnerId;
this.partnerKey = partnerKey; this.subId = subId;
this.subMchId = subMchId;
} }
public String getPaySignKey() { public String getPaySignKey() {
return paySignKey; return paySignKey;
} }
public String getPartnerId() {
return partnerId;
}
public String getPartnerKey() {
return partnerKey;
}
public String getMchId() { public String getMchId() {
return mchId; return mchId;
} }
public String getSubMchId() {
return subMchId;
}
public String getDeviceInfo() { public String getDeviceInfo() {
return deviceInfo; return deviceInfo;
} }
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public String getCertificateKey() { public String getCertificateKey() {
return StringUtil.isBlank(certificateKey) ? mchId : certificateKey; return StringUtil.isBlank(certificateKey) ? mchId : certificateKey;
} }
public String getPartnerId() {
return partnerId;
}
public void setPartnerId(String partnerId) {
this.partnerId = partnerId;
}
public String getSubId() {
return subId;
}
public void setSubId(String subId) {
this.subId = subId;
}
public String getSubMchId() {
return subMchId;
}
public void setSubMchId(String subMchId) {
this.subMchId = subMchId;
}
@Override @Override
public String toString() { public String toString() {
return "WeixinPayAccount [" + super.toString() + ", paySignKey=" return "WeixinPayAccount [" + super.toString() + ", paySignKey="
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey=" + paySignKey + ", mchId=" + mchId + ", certificateKey="
+ partnerKey + ", mchId=" + mchId + ", certificateKey=" + certificateKey + ", deviceInfo=" + deviceInfo
+ getCertificateKey() + ", subMchId=" + subMchId + ", partnerId=" + partnerId + ", subId=" + subId
+ ", deviceInfo=" + deviceInfo + "]"; + ", subMchId=" + subMchId + "]";
} }
} }

View File

@ -0,0 +1,75 @@
package com.foxinmy.weixin4j.model;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField;
/**
* 微信支付账户(2014年10月申请支付的老版本)
*
* @className WeixinPayOldAccount
* @author jy
* @date 2015年6月26日
* @since JDK 1.6
* @see
*/
public class WeixinPayOldAccount extends WeixinAccount {
private static final long serialVersionUID = -2791256176906048632L;
/**
* 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey
*/
private String paySignKey;
/**
* 财付通商户身份的标识
*/
private String partnerId;
/**
* 财付通商户权限密钥Key
*/
private String partnerKey;
/**
* 支付商户信息
*
* @param appId
* 公众号唯一的身份ID(必填)
* @param appSecret
* 调用接口的凭证(必填)
* @param paySignKey
* 支付密钥字符串(必填)
* @param partnerId
* 财付通的商户号(必填)
* @param partnerKey
* 财付通商户权限密钥Key(必填)
*/
@JSONCreator
public WeixinPayOldAccount(@JSONField(name = "id") String appId,
@JSONField(name = "secret") String appSecret,
@JSONField(name = "paySignKey") String paySignKey,
@JSONField(name = "partnerId") String partnerId,
@JSONField(name = "partnerKey") String partnerKey) {
super(appId, appSecret);
this.paySignKey = paySignKey;
this.partnerId = partnerId;
this.partnerKey = partnerKey;
}
public String getPaySignKey() {
return paySignKey;
}
public String getPartnerId() {
return partnerId;
}
public String getPartnerKey() {
return partnerKey;
}
@Override
public String toString() {
return "WeixinPayOldAccount [" + super.toString() + ", paySignKey="
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey="
+ partnerKey + "]";
}
}

View File

@ -43,6 +43,18 @@ public class MicroPayPackage extends PayPackage {
@XmlElement(name = "device_info") @XmlElement(name = "device_info")
@JSONField(name = "device_info") @JSONField(name = "device_info")
private String deviceInfo; private String deviceInfo;
/**
* 微信分配的子商户公众账号ID 非必须
*/
@XmlElement(name = "sub_id")
@JSONField(name = "sub_id")
private String subId;
/**
* 微信支付分配的子商户号 非必须
*/
@XmlElement(name = "sub_mch_id")
@JSONField(name = "sub_mch_id")
private String subMchId;
/** /**
* 随机字符串,不长于 32 必须 * 随机字符串,不长于 32 必须
*/ */
@ -70,22 +82,72 @@ public class MicroPayPackage extends PayPackage {
// jaxb required // jaxb required
} }
/**
*
* @param weixinAccount
* 商户信息
* @param authCode
* 授权码
* @param body
* 支付详情
* @param totalFee
* 支付金额(单位元) 必填
* @param createIp
* 发起支付的IP地址
*/
public MicroPayPackage(WeixinPayAccount weixinAccount, String authCode, public MicroPayPackage(WeixinPayAccount weixinAccount, String authCode,
String body, String outTradeNo, double totalFee, String createIp) { String body, String outTradeNo, double totalFee, String createIp) {
this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount
.getDeviceInfo(), authCode, body, outTradeNo, totalFee, .getDeviceInfo(), weixinAccount.getSubId(), weixinAccount
createIp, null, null, null, null, null); .getSubMchId(), authCode, body, outTradeNo, totalFee, createIp,
null, null, null, null, null);
} }
/**
* 完整参数
*
* @param appId
* 公众号唯一标识 必填
* @param mchId
* 微信支付商户号 必填
* @param deviceInfo
* 微信支付设备号 非必填
* @param subId
* 子商户唯一标识 非必填
* @param subMchId
* 子商户商户号 非必填
* @param authCode
* 授权码 必填
* @param body
* 支付详情 必填
* @param outTradeNo
* 商户侧订单号 必填
* @param totalFee
* 支付金额(单位元) 必填
* @param createIp
* 发起支付的IP地址 必填
* @param attach
* 支付时附加信息 非必填
* @param timeStart
* 订单生成时间 非必填
* @param timeExpire
* 订单失效时间 非必填
* @param goodsTag
* 商品标记 非必填
* @param limitPay
* 指定支付方式 非必填
*/
public MicroPayPackage(String appId, String mchId, String deviceInfo, public MicroPayPackage(String appId, String mchId, String deviceInfo,
String authCode, String body, String outTradeNo, double totalFee, String subId, String subMchId, String authCode, String body,
String createIp, String attach, Date timeStart, Date timeExpire, String outTradeNo, double totalFee, String createIp, String attach,
String goodsTag, String limitPay) { Date timeStart, Date timeExpire, String goodsTag, String limitPay) {
super(body, outTradeNo, totalFee, null, createIp, null, timeStart, super(body, outTradeNo, totalFee, null, createIp, null, timeStart,
timeExpire, goodsTag); timeExpire, goodsTag);
this.appId = appId; this.appId = appId;
this.mchId = mchId; this.mchId = mchId;
this.deviceInfo = deviceInfo; this.deviceInfo = deviceInfo;
this.subId = subId;
this.subMchId = subMchId;
this.nonceStr = RandomUtil.generateString(16); this.nonceStr = RandomUtil.generateString(16);
this.authCode = authCode; this.authCode = authCode;
this.limitPay = limitPay; this.limitPay = limitPay;
@ -134,8 +196,9 @@ public class MicroPayPackage extends PayPackage {
@Override @Override
public String toString() { public String toString() {
return "MicroPayPackage [appId=" + appId + ", mchId=" + mchId return "MicroPayPackage [appId=" + appId + ", mchId=" + mchId
+ ", deviceInfo=" + deviceInfo + ", nonceStr=" + nonceStr + ", deviceInfo=" + deviceInfo + ", subId=" + subId
+ ", sign=" + sign + ", authCode=" + authCode + ", " + ", subMchId=" + subMchId + ", nonceStr=" + nonceStr
+ super.toString() + "]"; + ", sign=" + sign + ", authCode=" + authCode + ", limitPay="
+ limitPay + ", " + super.toString() + "]";
} }
} }

View File

@ -61,16 +61,9 @@ public class PayRequest extends PayBaseInfo {
this.prepayId = prepayId; this.prepayId = prepayId;
} }
public String getPartnerId() {
return partnerId;
}
public void setPartnerId(String partnerId) {
this.partnerId = partnerId;
}
@Override @Override
public String toString() { public String toString() {
return "package" + packageInfo + ", " + super.toString(); return "package" + packageInfo + ", prepayId=" + prepayId
+ super.toString();
} }
} }

View File

@ -8,7 +8,7 @@ import java.util.Date;
import com.foxinmy.weixin4j.api.CashApi; import com.foxinmy.weixin4j.api.CashApi;
import com.foxinmy.weixin4j.api.CouponApi; import com.foxinmy.weixin4j.api.CouponApi;
import com.foxinmy.weixin4j.api.Pay3Api; import com.foxinmy.weixin4j.api.PayApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.exception.WeixinPayException; import com.foxinmy.weixin4j.exception.WeixinPayException;
import com.foxinmy.weixin4j.http.weixin.XmlResult; import com.foxinmy.weixin4j.http.weixin.XmlResult;
@ -50,7 +50,7 @@ public class WeixinPayProxy {
/** /**
* 微信支付API:js支付扫码支付等接口 * 微信支付API:js支付扫码支付等接口
*/ */
private final Pay3Api pay3Api; private final PayApi pay3Api;
/** /**
* 代金券API * 代金券API
*/ */
@ -79,7 +79,7 @@ public class WeixinPayProxy {
*/ */
public WeixinPayProxy(Weixin4jSettings settings) { public WeixinPayProxy(Weixin4jSettings settings) {
this.settings = settings; this.settings = settings;
this.pay3Api = new Pay3Api(settings.getWeixinPayAccount()); this.pay3Api = new PayApi(settings.getWeixinPayAccount());
this.couponApi = new CouponApi(settings.getWeixinPayAccount()); this.couponApi = new CouponApi(settings.getWeixinPayAccount());
this.cashApi = new CashApi(settings.getWeixinPayAccount()); this.cashApi = new CashApi(settings.getWeixinPayAccount());
} }
@ -100,7 +100,7 @@ public class WeixinPayProxy {
* *
* @param payPackage * @param payPackage
* 包含订单信息的对象 * 包含订单信息的对象
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.MchPayPackage * @see com.foxinmy.weixin4j.payment.mch.MchPayPackage
* @see com.foxinmy.weixin4j.payment.mch.PrePay * @see com.foxinmy.weixin4j.payment.mch.PrePay
* @see <a * @see <a
@ -118,7 +118,7 @@ public class WeixinPayProxy {
* @param payPackage * @param payPackage
* 支付详情 * 支付详情
* @return 支付请求对象 * @return 支付请求对象
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付 * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付
* @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付 * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付
* @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付 * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付
@ -161,7 +161,7 @@ public class WeixinPayProxy {
* 商品标记代金券或立减优惠功能的参数 非必填项 * 商品标记代金券或立减优惠功能的参数 非必填项
* @param limitPay * @param limitPay
* 指定支付方式:no_credit--指定不能使用信用卡支付 非必填项 * 指定支付方式:no_credit--指定不能使用信用卡支付 非必填项
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付 * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest JS支付
* @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付 * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest 扫码支付
* @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付 * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest APP支付
@ -193,7 +193,7 @@ public class WeixinPayProxy {
* 支付通知地址 * 支付通知地址
* @param createIp * @param createIp
* ip地址 * ip地址
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest * @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest
* @return JSAPI支付对象 * @return JSAPI支付对象
* @throws WeixinPayException * @throws WeixinPayException
@ -220,7 +220,7 @@ public class WeixinPayProxy {
* 当前访问页的URL * 当前访问页的URL
* @param oauthToken * @param oauthToken
* oauth授权时产生的token * oauth授权时产生的token
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see <a * @see <a
* href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_8&index=7">收货地址共享</a> * href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_8&index=7">收货地址共享</a>
* @return 编辑地址请求JSON串 * @return 编辑地址请求JSON串
@ -235,7 +235,7 @@ public class WeixinPayProxy {
* @param productId * @param productId
* 与订单ID等价 * 与订单ID等价
* @return 支付链接 * @return 支付链接
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/native.php">扫码支付</a> * @see <a href="http://pay.weixin.qq.com/wiki/doc/api/native.php">扫码支付</a>
* @see <a * @see <a
* href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一</a> * href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一</a>
@ -260,7 +260,7 @@ public class WeixinPayProxy {
* @param createIp * @param createIp
* 订单生成的机器 IP * 订单生成的机器 IP
* @return Native回调对象 * @return Native回调对象
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.NativePayResponse * @see com.foxinmy.weixin4j.payment.mch.NativePayResponse
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/native.php">扫码支付</a> * @see <a href="http://pay.weixin.qq.com/wiki/doc/api/native.php">扫码支付</a>
* @see <a * @see <a
@ -290,7 +290,7 @@ public class WeixinPayProxy {
* @param createIp * @param createIp
* 订单生成的机器 IP * 订单生成的机器 IP
* @return Native支付对象 * @return Native支付对象
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest * @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/native.php">扫码支付</a> * @see <a href="http://pay.weixin.qq.com/wiki/doc/api/native.php">扫码支付</a>
* @see <a * @see <a
@ -318,7 +318,7 @@ public class WeixinPayProxy {
* @param createIp * @param createIp
* 订单生成的机器 IP * 订单生成的机器 IP
* @return APP支付对象 * @return APP支付对象
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.APPPayRequest * @see com.foxinmy.weixin4j.payment.mch.APPPayRequest
* @see <a * @see <a
* href="https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1">APP支付</a> * href="https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1">APP支付</a>
@ -345,7 +345,7 @@ public class WeixinPayProxy {
* @param createIp * @param createIp
* 订单生成的机器 IP * 订单生成的机器 IP
* @return WAP支付对象 * @return WAP支付对象
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest * @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest
* @see <a * @see <a
* href="https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1">WAP支付</a> * href="https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1">WAP支付</a>
@ -372,7 +372,7 @@ public class WeixinPayProxy {
* @param createIp * @param createIp
* 订单生成的机器 IP * 订单生成的机器 IP
* @return 支付的订单信息 * @return 支付的订单信息
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see {@link #createMicroPay(MicroPayPackage)} * @see {@link #createMicroPay(MicroPayPackage)}
* @throws WeixinException * @throws WeixinException
*/ */
@ -389,7 +389,7 @@ public class WeixinPayProxy {
* 订单信息 * 订单信息
* @return 支付的订单信息 * @return 支付的订单信息
* @throws WeixinException * @throws WeixinException
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.MicroPayPackage * @see com.foxinmy.weixin4j.payment.MicroPayPackage
* @see com.foxinmy.weixin4j.payment.mch.Order * @see com.foxinmy.weixin4j.payment.mch.Order
* @see <a * @see <a
@ -412,7 +412,7 @@ public class WeixinPayProxy {
* transaction_id> out_trade_no * transaction_id> out_trade_no
* @since V3 * @since V3
* @see com.foxinmy.weixin4j.payment.mch.Order * @see com.foxinmy.weixin4j.payment.mch.Order
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see <a * @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2">订单查询API</a> * href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2">订单查询API</a>
* @return 订单详情 * @return 订单详情
@ -452,7 +452,7 @@ public class WeixinPayProxy {
* *
* @return 退款申请结果 * @return 退款申请结果
* @see com.foxinmy.weixin4j.payment.mch.RefundResult * @see com.foxinmy.weixin4j.payment.mch.RefundResult
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see <a * @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4">申请退款API</a> * href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4">申请退款API</a>
* @since V3 * @since V3
@ -492,7 +492,7 @@ public class WeixinPayProxy {
* 四个参数必填一个,优先级为: * 四个参数必填一个,优先级为:
* refund_id>out_refund_no>transaction_id>out_trade_no * refund_id>out_refund_no>transaction_id>out_trade_no
* @return 退款记录 * @return 退款记录
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see com.foxinmy.weixin4j.payment.mch.RefundRecord * @see com.foxinmy.weixin4j.payment.mch.RefundRecord
* @see <a * @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5">退款查询API</a> * href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5">退款查询API</a>
@ -517,7 +517,7 @@ public class WeixinPayProxy {
* REFUND,返回当日退款订单 * REFUND,返回当日退款订单
* @return excel表格 * @return excel表格
* @since V2 & V3 * @since V2 & V3
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see <a * @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6">下载对账单API</a> * href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6">下载对账单API</a>
* @throws WeixinException * @throws WeixinException
@ -539,7 +539,7 @@ public class WeixinPayProxy {
* 商户系统内部的订单号, transaction_id out_trade_no 二选一,如果同时存在优先级: * 商户系统内部的订单号, transaction_id out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no * transaction_id> out_trade_no
* @return 撤销结果 * @return 撤销结果
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @since V3 * @since V3
* @throws WeixinException * @throws WeixinException
*/ */
@ -574,7 +574,7 @@ public class WeixinPayProxy {
* @param outTradeNo * @param outTradeNo
* 商户系统内部的订单号 * 商户系统内部的订单号
* @return 执行结果 * @return 执行结果
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @since V3 * @since V3
* @throws WeixinException * @throws WeixinException
* @see <a * @see <a
@ -591,7 +591,7 @@ public class WeixinPayProxy {
* @param url * @param url
* 具有native标识的支付URL * 具有native标识的支付URL
* @return 转换后的短链接 * @return 转换后的短链接
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see <a * @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_9">转换短链接API</a> * href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_9">转换短链接API</a>
* @since V3 * @since V3
@ -618,7 +618,7 @@ public class WeixinPayProxy {
* @param returnXml * @param returnXml
* 调用接口返回的基本数据 * 调用接口返回的基本数据
* @return 处理结果 * @return 处理结果
* @see com.foxinmy.weixin4j.api.Pay3Api * @see com.foxinmy.weixin4j.api.PayApi
* @see <a * @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_8">接口测试上报API</a> * href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_8">接口测试上报API</a>
* @throws WeixinException * @throws WeixinException

View File

@ -19,7 +19,6 @@ import com.foxinmy.weixin4j.util.MapUtil;
* href="https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1">APP支付</a> * href="https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1">APP支付</a>
*/ */
public class APPPayRequest extends AbstractPayRequest { public class APPPayRequest extends AbstractPayRequest {
public APPPayRequest(String prePayId, WeixinPayAccount payAccount) { public APPPayRequest(String prePayId, WeixinPayAccount payAccount) {
super(prePayId, payAccount); super(prePayId, payAccount);
} }
@ -37,7 +36,6 @@ public class APPPayRequest extends AbstractPayRequest {
PayRequest payRequest = new PayRequest(getPayAccount().getId(), PayRequest payRequest = new PayRequest(getPayAccount().getId(),
"Sign=WXPay"); "Sign=WXPay");
payRequest.setPrepayId(getPrePayId()); payRequest.setPrepayId(getPrePayId());
payRequest.setPartnerId(getPayAccount().getPartnerId());
return payRequest; return payRequest;
} }
@ -53,7 +51,7 @@ public class APPPayRequest extends AbstractPayRequest {
content.append(String.format("<appid><![CDATA[%s]]></appid>", content.append(String.format("<appid><![CDATA[%s]]></appid>",
payRequest.getAppId())); payRequest.getAppId()));
content.append(String.format("<partnerid><![CDATA[%s]]></partnerid>", content.append(String.format("<partnerid><![CDATA[%s]]></partnerid>",
payRequest.getPartnerId())); getPayAccount().getPartnerId()));
content.append(String.format("<prepayid><![CDATA[%s]]></prepayid>", content.append(String.format("<prepayid><![CDATA[%s]]></prepayid>",
payRequest.getPrepayId())); payRequest.getPrepayId()));
content.append(String.format("<package><![CDATA[%s]]></package>", content.append(String.format("<package><![CDATA[%s]]></package>",

View File

@ -36,7 +36,13 @@ public class ApiResult extends XmlResult {
@JSONField(name = "mch_id") @JSONField(name = "mch_id")
private String mchId; private String mchId;
/** /**
* 代理模式下分配的商户号 可能为空 * 微信分配的子商户公众账号ID 非必须
*/
@XmlElement(name = "sub_id")
@JSONField(name = "sub_id")
private String subId;
/**
* 微信支付分配的子商户号 非必须
*/ */
@XmlElement(name = "sub_mch_id") @XmlElement(name = "sub_mch_id")
@JSONField(name = "sub_mch_id") @JSONField(name = "sub_mch_id")
@ -86,6 +92,14 @@ public class ApiResult extends XmlResult {
this.mchId = mchId; this.mchId = mchId;
} }
public String getSubId() {
return subId;
}
public void setSubId(String subId) {
this.subId = subId;
}
public String getSubMchId() { public String getSubMchId() {
return subMchId; return subMchId;
} }
@ -133,9 +147,9 @@ public class ApiResult extends XmlResult {
@Override @Override
public String toString() { public String toString() {
return "appId=" + appId + ", mchId=" + mchId + ", subMchId=" + subMchId return "appId=" + appId + ", mchId=" + mchId + ", subId=" + subId
+ ", nonceStr=" + nonceStr + ", sign=" + sign + ", deviceInfo=" + ", subMchId=" + subMchId + ", nonceStr=" + nonceStr
+ deviceInfo + ", recall=" + getFormatRecall() + ", " + ", sign=" + sign + ", deviceInfo=" + deviceInfo + ", recall="
+ super.toString(); + getFormatRecall() + ", " + super.toString();
} }
} }

View File

@ -14,7 +14,7 @@ import com.foxinmy.weixin4j.type.TradeType;
import com.foxinmy.weixin4j.util.RandomUtil; import com.foxinmy.weixin4j.util.RandomUtil;
/** /**
* JS支付订单详情 * 支付订单详情
* *
* @className MchPayPackage * @className MchPayPackage
* @author jy * @author jy
@ -46,6 +46,24 @@ public class MchPayPackage extends PayPackage {
@XmlElement(name = "device_info") @XmlElement(name = "device_info")
@JSONField(name = "device_info") @JSONField(name = "device_info")
private String deviceInfo; private String deviceInfo;
/**
* 微信分配的子商户公众账号ID 非必须
*/
@XmlElement(name = "sub_id")
@JSONField(name = "sub_id")
private String subId;
/**
* 微信支付分配的子商户号 非必须
*/
@XmlElement(name = "sub_mch_id")
@JSONField(name = "sub_mch_id")
private String subMchId;
/**
* 用户子标识 非必须
*/
@XmlElement(name = "sub_openid")
@JSONField(name = "sub_openid")
private String subOpenId;
/** /**
* 随机字符串,不长于 32 必须 * 随机字符串,不长于 32 必须
*/ */
@ -85,6 +103,25 @@ public class MchPayPackage extends PayPackage {
// jaxb required // jaxb required
} }
/**
*
* @param weixinAccount
* 商户信息 必填
* @param openId
* 用户唯一标识 JSAPI支付必填
* @param body
* 支付详情 必填
* @param outTradeNo
* 商户侧订单号 必填
* @param totalFee
* 支付金额(单位元) 必填
* @param notifyUrl
* 支付回调URL
* @param createIp
* 发起支付的IP地址
* @param tradeType
* 支付类型
*/
public MchPayPackage(WeixinPayAccount weixinAccount, String openId, public MchPayPackage(WeixinPayAccount weixinAccount, String openId,
String body, String outTradeNo, double totalFee, String notifyUrl, String body, String outTradeNo, double totalFee, String notifyUrl,
String createIp, TradeType tradeType) { String createIp, TradeType tradeType) {
@ -92,17 +129,83 @@ public class MchPayPackage extends PayPackage {
createIp, tradeType, null); createIp, tradeType, null);
} }
/**
*
* @param weixinAccount
* 商户信息 必填
* @param openId
* 用户唯一标识 JSAPI支付必填
* @param body
* 支付详情 必填
* @param outTradeNo
* 商户侧订单号 必填
* @param totalFee
* 支付金额(单位元) 必填
* @param notifyUrl
* 支付回调URL
* @param createIp
* 发起支付的IP地址
* @param tradeType
* 支付类型
* @param attach
* 支付时附加信息
*/
public MchPayPackage(WeixinPayAccount weixinAccount, String openId, public MchPayPackage(WeixinPayAccount weixinAccount, String openId,
String body, String outTradeNo, double totalFee, String notifyUrl, String body, String outTradeNo, double totalFee, String notifyUrl,
String createIp, TradeType tradeType, String attach) { String createIp, TradeType tradeType, String attach) {
this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount
.getDeviceInfo(), body, outTradeNo, totalFee, notifyUrl, .getDeviceInfo(), weixinAccount.getSubId(), weixinAccount
.getSubMchId(), null, body, outTradeNo, totalFee, notifyUrl,
createIp, tradeType, openId, attach, null, null, null, null, createIp, tradeType, openId, attach, null, null, null, null,
null); null);
} }
/**
* 完整参数
*
* @param appId
* 公众号唯一标识 必填
* @param mchId
* 微信支付商户号 必填
* @param deviceInfo
* 微信支付设备号 非必填
* @param subId
* 子商户唯一标识 非必填
* @param subMchId
* 子商户商户号 非必填
* @param subOpenId
* 用户在子商户appid下的唯一标识 非必填
* openid和sub_openid可以选传其中之一如果选择传sub_openid ,则必须传sub_appid
* @param body
* 支付详情 必填
* @param outTradeNo
* 商户侧订单号 必填
* @param totalFee
* 支付金额(单位元) 必填
* @param notifyUrl
* 支付回调URL 必填
* @param createIp
* 发起支付的IP地址 必填
* @param tradeType
* 支付类型 必填
* @param openId
* 用户唯一标识 JSAPI支付必填
* @param attach
* 支付时附加信息 非必填
* @param timeStart
* 订单生成时间 非必填
* @param timeExpire
* 订单失效时间 非必填
* @param goodsTag
* 商品标记 非必填
* @param productId
* 商品ID native支付必填
* @param limitPay
* 指定支付方式 非必填
*/
public MchPayPackage(String appId, String mchId, String deviceInfo, public MchPayPackage(String appId, String mchId, String deviceInfo,
String body, String outTradeNo, double totalFee, String notifyUrl, String subId, String subMchId, String subOpenId, String body,
String outTradeNo, double totalFee, String notifyUrl,
String createIp, TradeType tradeType, String openId, String attach, String createIp, TradeType tradeType, String openId, String attach,
Date timeStart, Date timeExpire, String goodsTag, String productId, Date timeStart, Date timeExpire, String goodsTag, String productId,
String limitPay) { String limitPay) {
@ -111,6 +214,9 @@ public class MchPayPackage extends PayPackage {
this.appId = appId; this.appId = appId;
this.mchId = mchId; this.mchId = mchId;
this.deviceInfo = deviceInfo; this.deviceInfo = deviceInfo;
this.subId = subId;
this.subMchId = subMchId;
this.subOpenId = subOpenId;
this.nonceStr = RandomUtil.generateString(16); this.nonceStr = RandomUtil.generateString(16);
this.tradeType = tradeType.name(); this.tradeType = tradeType.name();
this.openId = openId; this.openId = openId;
@ -169,9 +275,10 @@ public class MchPayPackage extends PayPackage {
@Override @Override
public String toString() { public String toString() {
return "MchPayPackage [appId=" + appId + ", mchId=" + mchId return "MchPayPackage [appId=" + appId + ", mchId=" + mchId
+ ", deviceInfo=" + deviceInfo + ", nonceStr=" + nonceStr + ", deviceInfo=" + deviceInfo + ", subId=" + subId
+ ", sign=" + sign + ", tradeType=" + tradeType + ", openId=" + ", subMchId=" + subMchId + ", subOpenId=" + subOpenId
+ openId + ", productId=" + productId + ", " + super.toString() + ", nonceStr=" + nonceStr + ", sign=" + sign + ", tradeType="
+ "]"; + tradeType + ", openId=" + openId + ", productId=" + productId
+ ", limitPay=" + limitPay + ", " + super.toString() + "]";
} }
} }

View File

@ -18,7 +18,7 @@ import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.xml.ListsuffixResult; import com.foxinmy.weixin4j.xml.ListsuffixResult;
/** /**
* V3订单信息 * 订单信息
* *
* @className Order * @className Order
* @author jy * @author jy
@ -131,6 +131,19 @@ public class Order extends ApiResult {
@JSONField(name = "trade_state_desc") @JSONField(name = "trade_state_desc")
private String tradeStateDesc; private String tradeStateDesc;
/**
* 用户在子商户下的openid
*/
@XmlElement(name = "sub_openid")
@JSONField(name = "sub_openid")
private String subOpenId;
/**
* 是否关注子公众账号,Y- 关注,N-未关注,仅在公众 账号类型支付有效
*/
@XmlElement(name = "sub_is_subscribe")
@JSONField(name = "sub_is_subscribe")
private String subIsSubscribe;
protected Order() { protected Order() {
// jaxb required // jaxb required
} }
@ -267,6 +280,19 @@ public class Order extends ApiResult {
this.couponList = couponList; this.couponList = couponList;
} }
public String getSubOpenId() {
return subOpenId;
}
public String getSubIsSubscribe() {
return subIsSubscribe;
}
@JSONField(serialize = false)
public boolean getFormatSubIsSubscribe() {
return subIsSubscribe != null && subIsSubscribe.equalsIgnoreCase("y");
}
@Override @Override
public String toString() { public String toString() {
return "Order [tradeState=" + tradeState + ", openId=" + openId return "Order [tradeState=" + tradeState + ", openId=" + openId
@ -278,7 +304,8 @@ public class Order extends ApiResult {
+ getFormatCouponFee() + ", couponCount=" + couponCount + getFormatCouponFee() + ", couponCount=" + couponCount
+ ", couponList=" + couponList + ", cashFee=" + ", couponList=" + couponList + ", cashFee="
+ getFormatCashFee() + ", timeEnd=" + getFormatTimeEnd() + getFormatCashFee() + ", timeEnd=" + getFormatTimeEnd()
+ ", tradeStateDesc=" + tradeStateDesc + ", " + ", tradeStateDesc=" + tradeStateDesc + ", subOpenId="
+ subOpenId + ", subIsSubscribe=" + subIsSubscribe
+ super.toString() + "]"; + super.toString() + "]";
} }
} }

View File

@ -8,7 +8,9 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.model.WeixinPayAccount;
import com.foxinmy.weixin4j.util.DateUtil; import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.RandomUtil;
/** /**
* 红包 * 红包
@ -27,12 +29,53 @@ import com.foxinmy.weixin4j.util.DateUtil;
public class Redpacket implements Serializable { public class Redpacket implements Serializable {
private static final long serialVersionUID = -7021352305575714281L; private static final long serialVersionUID = -7021352305575714281L;
/**
* 微信分配的公众账号 ID商户号 非空
*/
@XmlElement(name = "wxappid")
@JSONField(name = "wxappid")
private String appId;
/**
* 微信支付分配的商户号 非空
*/
@XmlElement(name = "mch_id")
@JSONField(name = "mch_id")
private String mchId;
/**
* 微信支付分配的子商户号 非必须
*/
@XmlElement(name = "sub_mch_id")
@JSONField(name = "sub_mch_id")
private String subMchId;
/**
* 服务商模式下触达用户时的appid(可填服务商自己的appid或子商户的appid)服务商模式下必填
* 服务商模式下填入的子商户appid必须在微信支付商户平台中先录入否则会校验不过 非必须
*/
@XmlElement(name = "msgappid")
@JSONField(name = "msgappid")
private String subMsgId;
/**
* 扣钱方mchid,常规模式下无效服务商模式下选填服务商模式下不填默认扣子商户的钱.非必须
*/
@XmlElement(name = "consume_mch_id")
@JSONField(name = "consume_mch_id")
private String consumeMchId;
/** /**
* 商户订单号每个订单号必须唯一 组成 mch_id+yyyymmdd+10位一天内不能重复的数字 * 商户订单号每个订单号必须唯一 组成 mch_id+yyyymmdd+10位一天内不能重复的数字
*/ */
@XmlElement(name = "mch_billno") @XmlElement(name = "mch_billno")
@JSONField(name = "mch_billno") @JSONField(name = "mch_billno")
private String outTradeNo; private String outTradeNo;
/**
* 随机字符串,不长于 32 必须
*/
@XmlElement(name = "nonce_str")
@JSONField(name = "nonce_str")
private String nonceStr;
/**
* 签名 <font color="red">调用者无需关心</font>
*/
private String sign;
/** /**
* 红包发送者名称 必填 * 红包发送者名称 必填
*/ */
@ -92,23 +135,83 @@ public class Redpacket implements Serializable {
* 红包 * 红包
* *
* @param outTradeNo * @param outTradeNo
* 商户侧一天内不可重复的订单号 接口根据商户订单号支持重入 如出现超时可再调用 * 商户侧一天内不可重复的订单号 接口根据商户订单号支持重入 如出现超时可再调用 必填
* @param sendName * @param sendName
* 红包发送者名称 * 红包发送者名称 必填
* @param openid * @param openid
* 接受收红包的用户的openid * 接受收红包的用户的openid 必填
* @param totalAmount * @param totalAmount
* 付款金额 <font color="red">单位为元,自动格式化为分</font> * 付款金额 <font color="red">单位为元,自动格式化为分</font> 必填
* @param totalNum * @param totalNum
* 红包发放总人数 大于1视为裂变红包 * 红包发放总人数 大于1视为裂变红包 必填
* @param wishing
* 红包祝福语 必填
* @param clientIp
* Ip地址 必填
* @param actName
* 活动名称 必填
* @param remark
* 备注 必填
*/ */
public Redpacket(String outTradeNo, String sendName, String openid, public Redpacket(WeixinPayAccount payAccount, String outTradeNo,
double totalAmount, int totalNum) { String sendName, String openid, double totalAmount, int totalNum,
String wishing, String clientIp, String actName, String remark) {
this(payAccount.getId(), payAccount.getMchId(), payAccount
.getSubMchId(), null, null, outTradeNo, sendName, openid,
totalAmount, totalNum, wishing, clientIp, actName, remark);
}
/**
* 红包 完整参数
*
* @param appId
* 公众号唯一标识 必填
* @param mchId
* 微信支付商户号 必填
* @param subMchId
* 子商户商户号 非必填
* @param subMsgId
* 触达用户appid 非必填
* @param consumeMchId
* 扣钱方mchid 非必填
* @param outTradeNo
* 商户侧一天内不可重复的订单号 接口根据商户订单号支持重入 如出现超时可再调用 必填
* @param sendName
* 红包发送者名称 必填
* @param openid
* 接受收红包的用户的openid 必填
* @param totalAmount
* 付款金额 <font color="red">单位为元,自动格式化为分</font> 必填
* @param totalNum
* 红包发放总人数 大于1视为裂变红包 必填
* @param wishing
* 红包祝福语 必填
* @param clientIp
* Ip地址 必填
* @param actName
* 活动名称 必填
* @param remark
* 备注 必填
*/
public Redpacket(String appId, String mchId, String subMchId,
String subMsgId, String consumeMchId, String outTradeNo,
String sendName, String openid, double totalAmount, int totalNum,
String wishing, String clientIp, String actName, String remark) {
this.appId = appId;
this.mchId = mchId;
this.subMchId = subMchId;
this.subMsgId = subMsgId;
this.consumeMchId = consumeMchId;
this.outTradeNo = outTradeNo; this.outTradeNo = outTradeNo;
this.sendName = sendName; this.sendName = sendName;
this.openid = openid; this.openid = openid;
this.totalAmount = DateUtil.formaFee2Fen(totalAmount);
this.totalNum = totalNum; this.totalNum = totalNum;
this.wishing = wishing;
this.clientIp = clientIp;
this.actName = actName;
this.remark = remark;
this.nonceStr = RandomUtil.generateString(16);
this.totalAmount = DateUtil.formaFee2Fen(totalAmount);
this.amtType = totalNum > 1 ? "ALL_RAND" : null; this.amtType = totalNum > 1 ? "ALL_RAND" : null;
} }
@ -136,10 +239,6 @@ public class Redpacket implements Serializable {
return wishing; return wishing;
} }
public void setWishing(String wishing) {
this.wishing = wishing;
}
public String getAmtType() { public String getAmtType() {
return amtType; return amtType;
} }
@ -148,32 +247,31 @@ public class Redpacket implements Serializable {
return clientIp; return clientIp;
} }
public void setClientIp(String clientIp) {
this.clientIp = clientIp;
}
public String getActName() { public String getActName() {
return actName; return actName;
} }
public void setActName(String actName) {
this.actName = actName;
}
public String getRemark() { public String getRemark() {
return remark; return remark;
} }
public void setRemark(String remark) { public String getSign() {
this.remark = remark; return sign;
}
public void setSign(String sign) {
this.sign = sign;
} }
@Override @Override
public String toString() { public String toString() {
return "Redpacket [ sendName=" + sendName + ", openid=" + openid return "Redpacket [appId=" + appId + ", mchId=" + mchId + ", subMchId="
+ ", amtType=" + amtType + ", totalAmount=" + totalAmount + subMchId + ", subMsgId=" + subMsgId + ", consumeMchId="
+ ", totalNum=" + totalNum + ", wishing=" + wishing + consumeMchId + ", outTradeNo=" + outTradeNo + ", nonceStr="
+ nonceStr + ", sendName=" + sendName + ", openid=" + openid
+ ", totalAmount=" + totalAmount + ", totalNum=" + totalNum
+ ", amtType=" + amtType + ", wishing=" + wishing
+ ", clientIp=" + clientIp + ", actName=" + actName + ", clientIp=" + clientIp + ", actName=" + actName
+ ", remark=" + remark + "]"; + ", remark=" + remark + ", sign=" + sign + "]";
} }
} }

View File

@ -26,21 +26,18 @@ public class CashTest extends PayTest {
@Test @Test
public void sendRedpacket() throws WeixinException, IOException { public void sendRedpacket() throws WeixinException, IOException {
Redpacket redpacket = new Redpacket("HB001", "无忧钱庄", Redpacket redpacket = new Redpacket(ACCOUNT, "HB001", "无忧钱庄",
"oyFLst1bqtuTcxK-ojF8hOGtLQao", 1d, 1); "oyFLst1bqtuTcxK-ojF8hOGtLQao", 1d, 1, "红包测试", "127.0.0.1",
redpacket.setActName("红包测试"); "快来领取红包吧!", "来就送钱");
redpacket.setClientIp("127.0.0.1"); RedpacketSendResult result = PAY.sendRedpack(
redpacket.setRemark("快来领取红包吧!"); new FileInputStream(caFile), redpacket);
redpacket.setWishing("来就送钱");
RedpacketSendResult result = PAY3.sendRedpack(new FileInputStream(
caFile), redpacket);
System.err.println(result); System.err.println(result);
} }
@Test @Test
public void queryRedpacket() throws WeixinException, IOException { public void queryRedpacket() throws WeixinException, IOException {
String outTradeNo = "HB001"; String outTradeNo = "HB001";
RedpacketRecord record = PAY3.queryRedpack(new FileInputStream(caFile), RedpacketRecord record = PAY.queryRedpack(new FileInputStream(caFile),
outTradeNo); outTradeNo);
System.err.println(record); System.err.println(record);
} }
@ -50,14 +47,14 @@ public class CashTest extends PayTest {
CorpPayment payment = new CorpPayment("MP001", CorpPayment payment = new CorpPayment("MP001",
"ofW1gwok9vZIyle0YbA-eQe83Uk8", "ofW1gwok9vZIyle0YbA-eQe83Uk8",
MPPaymentCheckNameType.NO_CHECK, "企业付款测试", 1d, "127.0.0.1"); MPPaymentCheckNameType.NO_CHECK, "企业付款测试", 1d, "127.0.0.1");
CorpPaymentResult result = PAY3.corpPayment( CorpPaymentResult result = PAY.corpPayment(new FileInputStream(caFile),
new FileInputStream(caFile), payment); payment);
System.err.println(result); System.err.println(result);
} }
@Test @Test
public void mchPaymentQuery() throws WeixinException, IOException { public void mchPaymentQuery() throws WeixinException, IOException {
System.err.println(PAY3.queryCorpPayment(new FileInputStream(caFile), System.err.println(PAY.queryCorpPayment(new FileInputStream(caFile),
"MP001")); "MP001"));
} }
} }

View File

@ -27,22 +27,22 @@ public class CouponTest extends PayTest {
@Test @Test
public void sendCoupon() throws WeixinException, IOException { public void sendCoupon() throws WeixinException, IOException {
String partnerTradeNo = String.format("%s%s%s", ACCOUNT3.getMchId(), String partnerTradeNo = String.format("%s%s%s", ACCOUNT.getMchId(),
DateUtil.fortmat2yyyyMMdd(new Date()), "1"); DateUtil.fortmat2yyyyMMdd(new Date()), "1");
CouponResult result = PAY3.sendCoupon(new FileInputStream(caFile), CouponResult result = PAY.sendCoupon(new FileInputStream(caFile),
"123", partnerTradeNo, "oyFLst1bqtuTcxK-ojF8hOGtLQao", null); "123", partnerTradeNo, "oyFLst1bqtuTcxK-ojF8hOGtLQao", null);
Assert.assertTrue(result.getRetCode().equalsIgnoreCase(Consts.SUCCESS)); Assert.assertTrue(result.getRetCode().equalsIgnoreCase(Consts.SUCCESS));
} }
@Test @Test
public void queryCouponStock() throws WeixinException { public void queryCouponStock() throws WeixinException {
CouponStock couponStock = PAY3.queryCouponStock("couponStockId"); CouponStock couponStock = PAY.queryCouponStock("couponStockId");
System.err.println(couponStock); System.err.println(couponStock);
} }
@Test @Test
public void queryCouponDetail() throws WeixinException { public void queryCouponDetail() throws WeixinException {
CouponDetail couponDetail = PAY3.queryCouponDetail("couponId"); CouponDetail couponDetail = PAY.queryCouponDetail("couponId");
System.err.println(couponDetail); System.err.println(couponDetail);
} }
} }

View File

@ -34,12 +34,11 @@ import com.foxinmy.weixin4j.util.Weixin4jSettings;
* @see * @see
*/ */
public class PayTest { public class PayTest {
protected final static WeixinPayProxy PAY3; protected final static WeixinPayProxy PAY;
protected final static WeixinPayAccount ACCOUNT3; protected final static WeixinPayAccount ACCOUNT;
static { static {
ACCOUNT3 = new WeixinPayAccount("appid", "appsecret", "paySignKey", ACCOUNT = new WeixinPayAccount("appid", "paySignKey", "mchid");
"mchid"); PAY = new WeixinPayProxy(new Weixin4jSettings(ACCOUNT));
PAY3 = new WeixinPayProxy(new Weixin4jSettings(ACCOUNT3));
} }
/** /**
* 商户证书文件 * 商户证书文件
@ -48,13 +47,12 @@ public class PayTest {
@Test @Test
public void orderQueryV3() throws WeixinException { public void orderQueryV3() throws WeixinException {
Order order = PAY3.orderQuery(new IdQuery("BY2016010800025", Order order = PAY.orderQuery(new IdQuery("BY2016010800025",
IdType.TRADENO)); IdType.TRADENO));
System.err.println(order); System.err.println(order);
String sign = order.getSign(); String sign = order.getSign();
order.setSign(null); order.setSign(null);
String valiSign = DigestUtil String valiSign = DigestUtil.paysignMd5(order, ACCOUNT.getPaySignKey());
.paysignMd5(order, ACCOUNT3.getPaySignKey());
System.err System.err
.println(String.format("sign=%s,valiSign=%s", sign, valiSign)); .println(String.format("sign=%s,valiSign=%s", sign, valiSign));
Assert.assertEquals(valiSign, sign); Assert.assertEquals(valiSign, sign);
@ -62,14 +60,14 @@ public class PayTest {
@Test @Test
public void refundQueryV3() throws WeixinException { public void refundQueryV3() throws WeixinException {
com.foxinmy.weixin4j.payment.mch.RefundRecord record = PAY3 com.foxinmy.weixin4j.payment.mch.RefundRecord record = PAY
.refundQuery(new IdQuery("TT_1427183696238", IdType.TRADENO)); .refundQuery(new IdQuery("TT_1427183696238", IdType.TRADENO));
System.err.println(record); System.err.println(record);
// 这里的验证签名需要把details循环拼接 // 这里的验证签名需要把details循环拼接
String sign = record.getSign(); String sign = record.getSign();
record.setSign(null); record.setSign(null);
String valiSign = DigestUtil.paysignMd5(record, String valiSign = DigestUtil
ACCOUNT3.getPaySignKey()); .paysignMd5(record, ACCOUNT.getPaySignKey());
System.err System.err
.println(String.format("sign=%s,valiSign=%s", sign, valiSign)); .println(String.format("sign=%s,valiSign=%s", sign, valiSign));
Assert.assertEquals(valiSign, sign); Assert.assertEquals(valiSign, sign);
@ -83,22 +81,22 @@ public class PayTest {
c.set(Calendar.MONTH, 2); c.set(Calendar.MONTH, 2);
c.set(Calendar.DAY_OF_MONTH, 24); c.set(Calendar.DAY_OF_MONTH, 24);
System.err.println(c.getTime()); System.err.println(c.getTime());
File file = PAY3.downloadBill(c.getTime(), null); File file = PAY.downloadBill(c.getTime(), null);
System.err.println(file); System.err.println(file);
} }
@Test @Test
public void refundV3() throws WeixinException, IOException { public void refundV3() throws WeixinException, IOException {
IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO); IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO);
com.foxinmy.weixin4j.payment.mch.RefundResult result = PAY3 com.foxinmy.weixin4j.payment.mch.RefundResult result = PAY.refundApply(
.refundApply(new FileInputStream(caFile), idQuery, "TT_R" new FileInputStream(caFile), idQuery,
+ System.currentTimeMillis(), 0.01d, 0.01d, null, "TT_R" + System.currentTimeMillis(), 0.01d, 0.01d, null,
"10020674"); "10020674");
System.err.println(result); System.err.println(result);
String sign = result.getSign(); String sign = result.getSign();
result.setSign(null); result.setSign(null);
String valiSign = DigestUtil.paysignMd5(result, String valiSign = DigestUtil
ACCOUNT3.getPaySignKey()); .paysignMd5(result, ACCOUNT.getPaySignKey());
System.err System.err
.println(String.format("sign=%s,valiSign=%s", sign, valiSign)); .println(String.format("sign=%s,valiSign=%s", sign, valiSign));
Assert.assertEquals(valiSign, sign); Assert.assertEquals(valiSign, sign);
@ -106,13 +104,13 @@ public class PayTest {
@Test @Test
public void nativeV3() throws WeixinException { public void nativeV3() throws WeixinException {
MchPayPackage payPackageV3 = new MchPayPackage(ACCOUNT3, MchPayPackage payPackageV3 = new MchPayPackage(ACCOUNT,
"oyFLst1bqtuTcxK-ojF8hOGtLQao", "native测试", "T0001", 0.1d, "oyFLst1bqtuTcxK-ojF8hOGtLQao", "native测试", "T0001", 0.1d,
"notify_url", "127.0.0.1", TradeType.NATIVE); "notify_url", "127.0.0.1", TradeType.NATIVE);
payPackageV3.setProductId("0001"); payPackageV3.setProductId("0001");
PrePay prePay = null; PrePay prePay = null;
try { try {
prePay = PAY3.createPrePay(payPackageV3); prePay = PAY.createPrePay(payPackageV3);
} catch (WeixinPayException e) { } catch (WeixinPayException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -121,12 +119,12 @@ public class PayTest {
@Test @Test
public void closeOrder() throws WeixinException { public void closeOrder() throws WeixinException {
ApiResult result = PAY3.closeOrder("D111"); ApiResult result = PAY.closeOrder("D111");
System.err.println(result); System.err.println(result);
String sign = result.getSign(); String sign = result.getSign();
result.setSign(null); result.setSign(null);
String valiSign = DigestUtil.paysignMd5(result, String valiSign = DigestUtil
ACCOUNT3.getPaySignKey()); .paysignMd5(result, ACCOUNT.getPaySignKey());
System.err System.err
.println(String.format("sign=%s,valiSign=%s", sign, valiSign)); .println(String.format("sign=%s,valiSign=%s", sign, valiSign));
Assert.assertEquals(valiSign, sign); Assert.assertEquals(valiSign, sign);
@ -135,7 +133,7 @@ public class PayTest {
@Test @Test
public void shortUrl() throws WeixinException { public void shortUrl() throws WeixinException {
String url = "weixin://wxpay/bizpayurl?xxxxxx"; String url = "weixin://wxpay/bizpayurl?xxxxxx";
String shortUrl = PAY3.getPayShorturl(url); String shortUrl = PAY.getPayShorturl(url);
System.err.println(shortUrl); System.err.println(shortUrl);
} }
@ -148,7 +146,7 @@ public class PayTest {
Date time = new Date(); Date time = new Date();
XmlResult returnXml = new XmlResult("SUCCESS", ""); XmlResult returnXml = new XmlResult("SUCCESS", "");
returnXml.setResultCode("SUCCESS"); returnXml.setResultCode("SUCCESS");
returnXml = PAY3.interfaceReport(interfaceUrl, executeTime, outTradeNo, returnXml = PAY.interfaceReport(interfaceUrl, executeTime, outTradeNo,
ip, time, returnXml); ip, time, returnXml);
System.err.println(returnXml); System.err.println(returnXml);
} }

View File

@ -33,14 +33,16 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor; import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor;
import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.model.WeixinPayOldAccount;
import com.foxinmy.weixin4j.mp.payment.v2.OrderV2; import com.foxinmy.weixin4j.mp.payment.v2.OrderV2;
import com.foxinmy.weixin4j.mp.payment.v2.PayPackageV2; import com.foxinmy.weixin4j.mp.payment.v2.PayPackageV2;
import com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2; import com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2;
import com.foxinmy.weixin4j.mp.payment.v2.RefundResultV2; import com.foxinmy.weixin4j.mp.payment.v2.RefundResultV2;
import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator; import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator;
import com.foxinmy.weixin4j.payment.PayRequest; import com.foxinmy.weixin4j.payment.PayRequest;
import com.foxinmy.weixin4j.token.FileTokenStorager;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.token.TokenStorager;
import com.foxinmy.weixin4j.type.BillType; import com.foxinmy.weixin4j.type.BillType;
import com.foxinmy.weixin4j.type.IdQuery; import com.foxinmy.weixin4j.type.IdQuery;
import com.foxinmy.weixin4j.type.RefundType; import com.foxinmy.weixin4j.type.RefundType;
@ -50,11 +52,11 @@ import com.foxinmy.weixin4j.util.DigestUtil;
import com.foxinmy.weixin4j.util.MapUtil; import com.foxinmy.weixin4j.util.MapUtil;
import com.foxinmy.weixin4j.util.RandomUtil; import com.foxinmy.weixin4j.util.RandomUtil;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jSettings; import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer; import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
/** /**
* V2支付API * V2支付API
* *
* @className Pay2Api * @className Pay2Api
* @author jy * @author jy
@ -62,24 +64,40 @@ import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
* @since JDK 1.6 * @since JDK 1.6
* @see * @see
*/ */
public class Pay2Api extends MpApi { public class PayOldApi extends MpApi {
private final Weixin4jSettings settings; private final WeixinPayOldAccount payAccount;
private final TokenHolder tokenHolder; private final TokenHolder tokenHolder;
public Pay2Api() { /**
this(new Weixin4jSettings()); * 默认使用weixin4j.properties配置信息
*/
public PayOldApi() {
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
WeixinPayOldAccount.class), new FileTokenStorager(
Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir",
System.getProperty("java.io.tmpdir"))));
} }
public Pay2Api(Weixin4jSettings settings) { public PayOldApi(WeixinPayOldAccount payAccount) {
this.tokenHolder = new TokenHolder(new WeixinTokenCreator(settings this(payAccount, new FileTokenStorager(
.getWeixinAccount().getId(), settings.getWeixinAccount() Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir",
.getSecret()), settings.getTokenStorager0()); System.getProperty("java.io.tmpdir"))));
this.settings = settings;
} }
public WeixinPayAccount getPayAccount() { public PayOldApi(TokenStorager tokenStorager) {
return this.settings.getWeixinPayAccount(); this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
WeixinPayOldAccount.class), tokenStorager);
}
public PayOldApi(WeixinPayOldAccount payAccount, TokenStorager tokenStorager) {
this.payAccount = payAccount;
this.tokenHolder = new TokenHolder(new WeixinTokenCreator(
payAccount.getId(), payAccount.getSecret()), tokenStorager);
}
public WeixinPayOldAccount getPayAccount() {
return this.payAccount;
} }
/** /**
@ -294,7 +312,7 @@ public class Pay2Api extends MpApi {
CertificateFactory cf = CertificateFactory CertificateFactory cf = CertificateFactory
.getInstance(com.foxinmy.weixin4j.model.Consts.X509); .getInstance(com.foxinmy.weixin4j.model.Consts.X509);
java.security.cert.Certificate cert = cf java.security.cert.Certificate cert = cf
.generateCertificate(Pay2Api.class .generateCertificate(PayOldApi.class
.getResourceAsStream("cacert.pem")); .getResourceAsStream("cacert.pem"));
ks = KeyStore ks = KeyStore
.getInstance(com.foxinmy.weixin4j.model.Consts.JKS); .getInstance(com.foxinmy.weixin4j.model.Consts.JKS);
@ -433,11 +451,13 @@ public class Pay2Api extends MpApi {
* @param billType * @param billType
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单 * 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
* REFUND,返回当日退款订单 * REFUND,返回当日退款订单
* @param billPath
* 对账单保存路径
* @return excel表格 * @return excel表格
* @since V2 * @since V2
* @throws WeixinException * @throws WeixinException
*/ */
public File downloadBill(Date billDate, BillType billType) public File downloadBill(Date billDate, BillType billType, String billPath)
throws WeixinException { throws WeixinException {
if (billDate == null) { if (billDate == null) {
Calendar now = Calendar.getInstance(); Calendar now = Calendar.getInstance();
@ -450,8 +470,7 @@ public class Pay2Api extends MpApi {
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate); String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
String fileName = String.format("%s_%s_%s.txt", formatBillDate, String fileName = String.format("%s_%s_%s.txt", formatBillDate,
billType.name().toLowerCase(), getPayAccount().getId()); billType.name().toLowerCase(), getPayAccount().getId());
File file = new File(String.format("%s/weixin4j_bill_%s", File file = new File(String.format("%s/%s", billPath, fileName));
settings.getTmpdir0(), fileName));
if (file.exists()) { if (file.exists()) {
return file; return file;
} }

View File

@ -9,7 +9,7 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.model.WeixinPayOldAccount;
import com.foxinmy.weixin4j.payment.PayRequest; import com.foxinmy.weixin4j.payment.PayRequest;
import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.DigestUtil;
@ -62,7 +62,7 @@ public class NativePayResponseV2 extends PayRequest {
* @param payPackage * @param payPackage
* 订单信息 * 订单信息
*/ */
public NativePayResponseV2(WeixinPayAccount weixinAccount, public NativePayResponseV2(WeixinPayOldAccount weixinAccount,
PayPackageV2 payPackage) { PayPackageV2 payPackage) {
super(weixinAccount.getId(), DigestUtil.packageSign(payPackage, super(weixinAccount.getId(), DigestUtil.packageSign(payPackage,
weixinAccount.getPartnerKey())); weixinAccount.getPartnerKey()));

View File

@ -6,11 +6,10 @@ import java.util.Calendar;
import org.junit.Test; import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.model.WeixinPayOldAccount;
import com.foxinmy.weixin4j.mp.api.Pay2Api; import com.foxinmy.weixin4j.mp.api.PayOldApi;
import com.foxinmy.weixin4j.type.IdQuery; import com.foxinmy.weixin4j.type.IdQuery;
import com.foxinmy.weixin4j.type.IdType; import com.foxinmy.weixin4j.type.IdType;
import com.foxinmy.weixin4j.util.Weixin4jSettings;
/** /**
* 支付测试V2版本 2014年9月之前申请微信支付的公众号 * 支付测试V2版本 2014年9月之前申请微信支付的公众号
@ -22,13 +21,13 @@ import com.foxinmy.weixin4j.util.Weixin4jSettings;
* @see * @see
*/ */
public class PayTest { public class PayTest {
protected final static Pay2Api PAY2; protected final static PayOldApi PAY2;
protected final static WeixinPayAccount ACCOUNT2; protected final static WeixinPayOldAccount ACCOUNT2;
static { static {
ACCOUNT2 = new WeixinPayAccount("请填入v2版本的appid", "请填入v2版本的appSecret", ACCOUNT2 = new WeixinPayOldAccount("请填入v2版本的appid",
"请填入v2版本的paysignkey", null, null, null, null, "请填入v2版本的appSecret", "请填入v2版本的paysignkey", "请填入v2版本的partnerId",
"请填入v2版本的partnerId", "请填入v2版本的partnerKey"); "请填入v2版本的partnerKey");
PAY2 = new Pay2Api(new Weixin4jSettings(ACCOUNT2)); PAY2 = new PayOldApi(ACCOUNT2);
} }
/** /**
* 商户证书文件 * 商户证书文件
@ -60,7 +59,7 @@ public class PayTest {
c.set(Calendar.YEAR, 2014); c.set(Calendar.YEAR, 2014);
c.set(Calendar.MONTH, 11); c.set(Calendar.MONTH, 11);
c.set(Calendar.DAY_OF_MONTH, 22); c.set(Calendar.DAY_OF_MONTH, 22);
File file = PAY2.downloadBill(c.getTime(), null); File file = PAY2.downloadBill(c.getTime(), null, "/tmp/bill");
System.err.println(file); System.err.println(file);
} }
} }