新增企业付款查询接口 & 对多个公众号的接入支持

This commit is contained in:
jinyu
2015-06-23 22:20:24 +08:00
parent 37503acac6
commit bb79042d4e
27 changed files with 667 additions and 136 deletions
+5 -1
View File
@@ -112,4 +112,8 @@
* 2015-06-04
+ 新增查询红包接口
+ 新增查询红包接口
* 2015-06-23
+ 新增企业付款查询接口
@@ -18,6 +18,7 @@ import com.foxinmy.weixin4j.mp.payment.coupon.CouponResult;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponStock;
import com.foxinmy.weixin4j.mp.payment.v3.ApiResult;
import com.foxinmy.weixin4j.mp.payment.v3.MPPayment;
import com.foxinmy.weixin4j.mp.payment.v3.MPPaymentRecord;
import com.foxinmy.weixin4j.mp.payment.v3.MPPaymentResult;
import com.foxinmy.weixin4j.mp.payment.v3.Redpacket;
import com.foxinmy.weixin4j.mp.payment.v3.RedpacketRecord;
@@ -30,7 +31,6 @@ import com.foxinmy.weixin4j.mp.type.IdType;
import com.foxinmy.weixin4j.mp.type.RefundType;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.token.TokenStorager;
import com.foxinmy.weixin4j.util.ConfigUtil;
/**
* 微信支付接口实现
@@ -239,9 +239,8 @@ public class WeixinPayProxy {
IdQuery idQuery, String outRefundNo, double totalFee,
double refundFee, String opUserId, String opUserPasswd)
throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return refundV2(caFile, idQuery, outRefundNo, totalFee, refundFee,
opUserId, opUserPasswd);
return refundV2(PayApi.DEFAULT_CA_FILE, idQuery, outRefundNo, totalFee,
refundFee, opUserId, opUserPasswd);
}
/**
@@ -358,9 +357,8 @@ public class WeixinPayProxy {
public com.foxinmy.weixin4j.mp.payment.v3.RefundResult refundV3(
IdQuery idQuery, String outRefundNo, double totalFee,
double refundFee, String opUserId) throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return pay3Api.refund(caFile, idQuery, outRefundNo, totalFee,
refundFee, CurrencyType.CNY, opUserId);
return pay3Api.refund(PayApi.DEFAULT_CA_FILE, idQuery, outRefundNo,
totalFee, refundFee, CurrencyType.CNY, opUserId);
}
/**
@@ -444,8 +442,7 @@ public class WeixinPayProxy {
* @throws WeixinException
*/
public ApiResult reverse(IdQuery idQuery) throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return payApi.reverse(caFile, idQuery);
return payApi.reverse(PayApi.DEFAULT_CA_FILE, idQuery);
}
/**
@@ -552,9 +549,8 @@ public class WeixinPayProxy {
*/
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
String openId) throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return couponApi.sendCoupon(caFile, couponStockId, partnerTradeNo,
openId, null);
return couponApi.sendCoupon(PayApi.DEFAULT_CA_FILE, couponStockId,
partnerTradeNo, openId, null);
}
/**
@@ -618,8 +614,7 @@ public class WeixinPayProxy {
*/
public RedpacketSendResult sendRedpack(Redpacket redpacket)
throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return cashApi.sendRedpack(caFile, redpacket);
return cashApi.sendRedpack(PayApi.DEFAULT_CA_FILE, redpacket);
}
/**
@@ -648,8 +643,7 @@ public class WeixinPayProxy {
*/
public RedpacketRecord queryRedpack(String outTradeNo)
throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return cashApi.queryRedpack(caFile, outTradeNo);
return cashApi.queryRedpack(PayApi.DEFAULT_CA_FILE, outTradeNo);
}
/**
@@ -679,7 +673,35 @@ public class WeixinPayProxy {
*/
public MPPaymentResult mpPayment(MPPayment mpPayment)
throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return cashApi.mpPayment(caFile, mpPayment);
return cashApi.mpPayment(PayApi.DEFAULT_CA_FILE, mpPayment);
}
/**
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
*
* @param caFile
* 证书文件(V3版本后缀为*.p12)
* @param outTradeNo
* 商户调用企业付款API时使用的商户订单号
* @return 付款记录
* @see com.foxinmy.weixin4j.mp.api.CashApi
* @see com.foxinmy.weixin4j.mp.payment.v3.MPPaymentRecord
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_3">企业付款查询</a>
* @throws WeixinException
*/
public MPPaymentRecord mpPaymentQuery(File caFile, String outTradeNo)
throws WeixinException {
return cashApi.mpPaymentQuery(caFile, outTradeNo);
}
/**
* 企业付款查询采用properties中配置的ca文件
*
* @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#mpPaymentQuery(File, String)}
*/
public MPPaymentRecord mpPaymentQuery(String outTradeNo)
throws WeixinException {
return cashApi.mpPaymentQuery(PayApi.DEFAULT_CA_FILE, outTradeNo);
}
}
@@ -16,6 +16,7 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.payment.PayUtil;
import com.foxinmy.weixin4j.mp.payment.v3.MPPayment;
import com.foxinmy.weixin4j.mp.payment.v3.MPPaymentRecord;
import com.foxinmy.weixin4j.mp.payment.v3.MPPaymentResult;
import com.foxinmy.weixin4j.mp.payment.v3.Redpacket;
import com.foxinmy.weixin4j.mp.payment.v3.RedpacketRecord;
@@ -194,4 +195,52 @@ public class CashApi extends MpApi {
.replaceFirst("</mchid>", "</mch_id>");
return XmlStream.fromXML(text, MPPaymentResult.class);
}
/**
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
*
* @param caFile
* 证书文件(V3版本后缀为*.p12)
* @param outTradeNo
* 商户调用企业付款API时使用的商户订单号
* @return 付款记录
* @see com.foxinmy.weixin4j.mp.payment.v3.MPPaymentRecord
* @see <a
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_3">企业付款查询</a>
* @throws WeixinException
*/
public MPPaymentRecord mpPaymentQuery(File caFile, String outTradeNo)
throws WeixinException {
JSONObject obj = new JSONObject();
obj.put("nonce_str", RandomUtil.generateString(16));
obj.put("mch_id", weixinAccount.getMchId());
obj.put("appid", weixinAccount.getId());
obj.put("partner_trade_no", outTradeNo);
String sign = PayUtil.paysignMd5(obj, weixinAccount.getPaySignKey());
obj.put("sign", sign);
String param = XmlStream.map2xml(obj);
String mp_payquery_uri = getRequestUri("mp_payquery_uri");
WeixinResponse response = null;
InputStream ca = null;
try {
ca = new FileInputStream(caFile);
SSLHttpClinet request = new SSLHttpClinet(weixinAccount.getMchId(),
ca);
response = request.post(mp_payquery_uri, param);
} catch (WeixinException e) {
throw e;
} catch (IOException e) {
throw new WeixinException(e.getMessage());
} finally {
if (ca != null) {
try {
ca.close();
} catch (IOException e) {
;
}
}
}
return response.getAsObject(new TypeReference<MPPaymentRecord>() {
});
}
}
@@ -18,13 +18,13 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
* @see <a href="http://mp.weixin.qq.com/wiki/index.php">api文档</a>
*/
public class MpApi extends BaseApi {
private final static ResourceBundle WEIXIN_BUNDLE;
/**
* 默认使用weixin4j.properties文件中的公众号信息
*/
public final static WeixinMpAccount DEFAULT_WEIXIN_ACCOUNT;
static {
WEIXIN_BUNDLE = ResourceBundle
.getBundle("com/foxinmy/weixin4j/mp/api/weixin");
@@ -17,6 +17,7 @@ import com.foxinmy.weixin4j.mp.type.BillType;
import com.foxinmy.weixin4j.mp.type.IdQuery;
import com.foxinmy.weixin4j.mp.type.SignType;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.util.DateUtil;
/**
@@ -31,6 +32,12 @@ import com.foxinmy.weixin4j.util.DateUtil;
*/
public abstract class PayApi extends MpApi {
/**
* 默认的证书文件
*/
public final static File DEFAULT_CA_FILE = new File(
ConfigUtil.getClassPathValue("ca_file"));
protected final WeixinMpAccount weixinAccount;
protected final TokenHolder tokenHolder;
@@ -93,8 +100,9 @@ public abstract class PayApi extends MpApi {
throws WeixinException {
String payfeedback_update_uri = getRequestUri("payfeedback_update_uri");
Token token = tokenHolder.getToken();
WeixinResponse response = weixinClient.get(String.format(payfeedback_update_uri,
token.getAccessToken(), openId, feedbackId));
WeixinResponse response = weixinClient.get(String.format(
payfeedback_update_uri, token.getAccessToken(), openId,
feedbackId));
return response.getAsJsonResult();
}
@@ -180,4 +180,6 @@ redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack
# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305
redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo
# \u4f01\u4e1a\u5411\u4e2a\u4eba\u4ed8\u6b3e
mp_payment_uri={mch_base_url}/mmpaymkttransfers/promotion/transfers
mp_payment_uri={mch_base_url}/mmpaymkttransfers/promotion/transfers
# \u4f01\u4e1a\u4ed8\u6b3e\u67e5\u8be2
mp_payquery_uri={mch_base_url}/mmpaymkttransfers/gettransferinfo
@@ -0,0 +1,193 @@
package com.foxinmy.weixin4j.mp.payment.v3;
import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.type.MPPaymentCheckNameType;
import com.foxinmy.weixin4j.util.DateUtil;
/**
* 企业付款记录
*
* @className MPPaymentRecord
* @author jy
* @date 2015年6月23日
* @since JDK 1.7
* @see
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class MPPaymentRecord extends ApiResult {
private static final long serialVersionUID = -1926873539419750498L;
/**
* 微信订单订单号
*/
@JSONField(name = "detail_id")
@XmlElement(name = "detail_id")
private String transactionId;
/**
* 商户订单号
*/
@JSONField(name = "partner_trade_no")
@XmlElement(name = "partner_trade_no")
private String outTradeNo;
/**
* 交易状态 SUCCESS:转账成功 FAILED:转账失败
*/
@JSONField(name = "status")
@XmlElement(name = "status")
private String transactionStatus;
/**
* 如果失败则应该有原因
*/
@JSONField(name = "reason")
@XmlElement(name = "reason")
private String failureReason;
/**
* 收款用户openid
*/
private String openid;
/**
* 收款用户姓名
*/
@JSONField(name = "transfer_name")
@XmlElement(name = "transfer_name")
private String transferName;
/**
* 付款金额(单位为分)
*/
@JSONField(name = "payment_amount")
@XmlElement(name = "payment_amount")
private int paymentAmount;
/**
* 转账时间
*/
@JSONField(name = "transfer_time")
@XmlElement(name = "transfer_time")
private String transferTime;
/**
* 校验用户姓名选项
*
* @see com.foxinmy.weixin4j.mp.type.MPPaymentCheckNameType
*/
@XmlElement(name = "check_name")
@JSONField(name = "check_name")
private MPPaymentCheckNameType checkNameType;
/**
* 企业付款描述信息
*/
private String desc;
/**
* 实名验证结果 PASS:通过 FAILED:不通过
*/
@JSONField(name = "check_name_result")
@XmlElement(name = "check_name_result")
private String checkNameResult;
protected MPPaymentRecord() {
// jaxb required
}
public String getTransactionId() {
return transactionId;
}
public String getOutTradeNo() {
return outTradeNo;
}
public String getTransactionStatus() {
return transactionStatus;
}
/**
* 格式化交易状态
*
* @return
*/
@JSONField(serialize = false)
public boolean getFormatTransactionStatus() {
return "success".equalsIgnoreCase(transactionStatus);
}
public String getFailureReason() {
return failureReason;
}
public String getOpenid() {
return openid;
}
public String getTransferName() {
return transferName;
}
public int getPaymentAmount() {
return paymentAmount;
}
/**
* <font color="red">调用接口获取单位为分,get方法转换为元方便使用</font>
*
* @return 元单位
*/
@JSONField(serialize = false)
public double getFormatPaymentAmount() {
return paymentAmount / 100d;
}
public String getTransferTime() {
return transferTime;
}
/**
* 格式化转账时间
*
* @return
*/
@JSONField(serialize = false)
public Date getFormatTransferTime() {
return DateUtil.parse2yyyyMMddHHmmss(transferTime);
}
public MPPaymentCheckNameType getCheckNameType() {
return checkNameType;
}
public String getDesc() {
return desc;
}
public String getCheckNameResult() {
return checkNameResult;
}
/**
* 格式化交易状态
*
* @return
*/
@JSONField(serialize = false)
public boolean getFormatCheckNameResult() {
return "pass".equalsIgnoreCase(checkNameResult);
}
@Override
public String toString() {
return "MPPaymentRecord [transactionId=" + transactionId
+ ", outTradeNo=" + outTradeNo + ", transactionStatus="
+ getFormatTransactionStatus() + ", failureReason="
+ failureReason + ", openid=" + openid + ", transferName="
+ transferName + ", paymentAmount=" + getFormatPaymentAmount()
+ ", transferTime=" + transferTime + ", checkNameType="
+ checkNameType + ", desc=" + desc + ", checkNameResult="
+ getFormatCheckNameResult() + ", " + super.toString() + "]";
}
}