实现企业付款的接口,暂时未调通,因缺少证书 for issue #50

This commit is contained in:
Binary Wang
2016-10-06 20:53:39 +08:00
parent a4b0fdce93
commit dabafc2a9e
5 changed files with 553 additions and 14 deletions

View File

@@ -1,8 +1,11 @@
package me.chanjar.weixin.mp.api;
import java.io.File;
import java.util.Map;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.pay.WxEntPayRequest;
import me.chanjar.weixin.mp.bean.pay.WxEntPayResult;
import me.chanjar.weixin.mp.bean.pay.WxMpPayCallback;
import me.chanjar.weixin.mp.bean.pay.WxMpPayRefundResult;
import me.chanjar.weixin.mp.bean.pay.WxMpPayResult;
@@ -85,4 +88,17 @@ public interface WxMpPayService {
*/
WxRedpackResult sendRedpack(WxSendRedpackRequest request) throws WxErrorException;
/**
* <pre>
* 企业付款业务是基于微信支付商户平台的资金管理能力为了协助商户方便地实现企业向个人付款针对部分有开发能力的商户提供通过API完成企业付款的功能。
* 比如目前的保险行业向客户退保、给付、理赔。
* 企业付款将使用商户的可用余额需确保可用余额充足。查看可用余额、充值、提现请登录商户平台“资金管理”https://pay.weixin.qq.com/进行操作。
* 注意:与商户微信支付收款资金并非同一账户,需要单独充值。
* 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
* 接口链接https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers
* @param keyFile 证书文件对象
* </pre>
*/
WxEntPayResult entPay(WxEntPayRequest request, File keyFile) throws WxErrorException;
}

View File

@@ -1,6 +1,9 @@
package me.chanjar.weixin.mp.api.impl;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -8,8 +11,19 @@ import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.net.ssl.SSLContext;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.joor.Reflect;
import com.google.common.collect.Lists;
@@ -23,6 +37,8 @@ import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.api.WxMpPayService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.pay.WxEntPayRequest;
import me.chanjar.weixin.mp.bean.pay.WxEntPayResult;
import me.chanjar.weixin.mp.bean.pay.WxMpPayCallback;
import me.chanjar.weixin.mp.bean.pay.WxMpPayRefundResult;
import me.chanjar.weixin.mp.bean.pay.WxMpPayResult;
@@ -263,6 +279,23 @@ public class WxMpPayServiceImpl implements WxMpPayService {
private void checkParameters(WxUnifiedOrderRequest request) {
checkNotNullParams(request);
if (!TRADE_TYPES.contains(request.getTradeType())) {
throw new IllegalArgumentException("trade_type目前必须为" + TRADE_TYPES + "其中之一");
}
if ("JSAPI".equals(request.getTradeType()) && request.getOpenid() == null) {
throw new IllegalArgumentException("当 trade_type是'JSAPI'时未指定openid");
}
if ("NATIVE".equals(request.getTradeType()) && request.getProductId() == null) {
throw new IllegalArgumentException("当 trade_type是'NATIVE'时未指定product_id");
}
}
private void checkNotNullParams(Object request) {
List<String> nullFields = Lists.newArrayList();
for (Entry<String, Reflect> entry : Reflect.on(request).fields()
.entrySet()) {
@@ -281,20 +314,6 @@ public class WxMpPayServiceImpl implements WxMpPayService {
if (!nullFields.isEmpty()) {
throw new IllegalArgumentException("必填字段[" + nullFields + "]必须提供值");
}
if (!TRADE_TYPES.contains(request.getTradeType())) {
throw new IllegalArgumentException("trade_type目前必须为" + TRADE_TYPES + "其中之一");
}
if ("JSAPI".equals(request.getTradeType()) && request.getOpenid() == null) {
throw new IllegalArgumentException("当 trade_type是'JSAPI'时未指定openid");
}
if ("NATIVE".equals(request.getTradeType())
&& request.getProductId() == null) {
throw new IllegalArgumentException("当 trade_type是'NATIVE'时未指定product_id");
}
}
@Override
@@ -332,4 +351,50 @@ public class WxMpPayServiceImpl implements WxMpPayService {
return payInfo;
}
@Override
public WxEntPayResult entPay(WxEntPayRequest request, File keyFile) throws WxErrorException {
checkNotNullParams(request);
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxEntPayRequest.class);
xstream.processAnnotations(WxEntPayResult.class);
request.setMchAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId());
request.setNonceStr(System.currentTimeMillis() + "");
String sign = this.createSign(xmlBean2Map(request), this.wxMpService.getWxMpConfigStorage().getPartnerKey());
request.setSign(sign);
String url = PAY_BASE_URL + "/mmpaymkttransfers/promotion/transfers";
try (FileInputStream instream = new FileInputStream(keyFile)) {
String mchId = request.getMchId();
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(instream, mchId.toCharArray());
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
new DefaultHostnameVerifier());
try (CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build()) {
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(new String(xstream.toXML(request).getBytes("UTF-8"), "ISO-8859-1")));
try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
String responseContent = EntityUtils.toString(response.getEntity());
WxEntPayResult result = (WxEntPayResult) xstream.fromXML(responseContent);
if ("FAIL".equals(result.getResultCode())) {
throw new WxErrorException(
WxError.newBuilder().setErrorMsg(result.getErrCode() + ":" + result.getErrCodeDes()).build());
}
return result;
}
}
} catch (Exception e) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build(), e);
}
}
}