Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,20 @@ public interface WxMpConfigStorage {

File getTmpDirFile();

@Deprecated
SSLContext getSSLContext();

SSLContext getSslContext();

void setSslContext(SSLContext sslContext);

/**
* 在此之前,必须将partnerId进行赋值
*
* @param filePath
* apiclient_cert.p12的文件的绝对路径
*/
void setSslContextFilePath(String filePath) throws Exception;

/**
* http client builder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package me.chanjar.weixin.mp.api;

import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.net.ssl.SSLContext;

import org.apache.http.ssl.SSLContexts;

import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;

/**
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化
* @author chanjarster
Expand Down Expand Up @@ -300,11 +305,33 @@ public void setTmpDirFile(File tmpDirFile) {
public SSLContext getSSLContext() {
return this.sslContext;
}

public void setSSLContext(SSLContext context) {
this.sslContext = context;

@Override
public SSLContext getSslContext() {
return this.sslContext;
}

@Override
public void setSslContextFilePath(String filePath) throws Exception {
if (null == partnerId) {
throw new Exception("请先将partnerId进行赋值");
}
File file = new File(filePath);
if (!file.exists()) {
throw new RuntimeException(file.getPath() + ":文件不存在!在设置SSLContext的时候");
}
FileInputStream inputStream = new FileInputStream(file);
KeyStore keystore = KeyStore.getInstance("PKCS12");
char[] partnerId2charArray = partnerId.toCharArray();
keystore.load(inputStream, partnerId2charArray);
this.sslContext = SSLContexts.custom().loadKeyMaterial(keystore, partnerId2charArray).build();
}

@Override
public void setSslContext(SSLContext context) {
this.sslContext = context;
}

@Override
public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
return this.apacheHttpClientBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,24 @@ public interface WxMpPayService {
* @param request 请求对象
* @param keyFile 证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3)
*/
@Deprecated
WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile) throws WxErrorException;

/**
* 发送微信红包给个人用户
* <pre>
* 文档详见:
* 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
* 接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
* 发送裂变红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4
* 接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack
* </pre>
*
* @param request 请求对象
* @param keyFile 证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3)
*/
WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxErrorException;

/**
* <pre>
* 查询红包记录
Expand All @@ -211,7 +227,22 @@ public interface WxMpPayService {
* @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890
* @param keyFile 证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3)
*/
@Deprecated
WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException;

/**
* <pre>
* 查询红包记录
* 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。
* 请求Url https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo
* 是否需要证书 是(证书及使用说明详见商户证书)
* 请求方式 POST
* </pre>
*
* @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890
* @param keyFile 证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3)
*/
WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxErrorException;

/**
* <pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxErro


@Override
@Deprecated
public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile)
throws WxErrorException {
XStream xstream = XStreamInitializer.getInstance();
Expand All @@ -179,8 +180,30 @@ public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File
this.checkResult(result);
return result;
}

@Override
public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request)
throws WxErrorException {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPaySendRedpackRequest.class);
xstream.processAnnotations(WxPaySendRedpackResult.class);

initRequest(request);
request.setSign(this.createSign(request));

String url = PAY_BASE_URL + "/mmpaymkttransfers/sendredpack";
if (request.getAmtType() != null) {
//裂变红包
url = PAY_BASE_URL + "/mmpaymkttransfers/sendgroupredpack";
}
String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request));
WxPaySendRedpackResult result = (WxPaySendRedpackResult) xstream.fromXML(responseContent);
this.checkResult(result);
return result;
}

@Override
@Deprecated
public WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPayRedpackQueryRequest.class);
Expand All @@ -198,6 +221,25 @@ public WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) thro
this.checkResult(result);
return result;
}

@Override
public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxErrorException {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(WxPayRedpackQueryRequest.class);
xstream.processAnnotations(WxPayRedpackQueryResult.class);

WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest();
request.setMchBillNo(mchBillNo);
request.setBillType("MCHT");
initRequest(request);
request.setSign(this.createSign(request));

String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo";
String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request));
WxPayRedpackQueryResult result = (WxPayRedpackQueryResult) xstream.fromXML(responseContent);
this.checkResult(result);
return result;
}

@Override
public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException {
Expand Down Expand Up @@ -383,7 +425,8 @@ private String executeRequest(String url, String requestStr) throws WxErrorExcep
httpPost.releaseConnection();
}
}


@Deprecated
private String executeRequestWithKeyFile(String url, File keyFile, String requestStr, String mchId) throws WxErrorException {
try (FileInputStream inputStream = new FileInputStream(keyFile)) {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
Expand Down Expand Up @@ -414,6 +457,37 @@ private String executeRequestWithKeyFile(String url, File keyFile, String reques
}
}

private String executeRequestWithKeyFile(String url, String requestStr) throws WxErrorException {
try {

SSLContext sslcontext = getConfig().getSSLContext();
if(null==sslcontext){
throw new Exception("请将配置类(WxMpInMemoryConfigStorage)中的SSLContext初始化");
}
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null,
new DefaultHostnameVerifier());

HttpPost httpPost = new HttpPost(url);
if (this.wxMpService.getHttpProxy() != null) {
httpPost.setConfig(RequestConfig.custom().setProxy(this.wxMpService.getHttpProxy()).build());
}

try (CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build()) {
httpPost.setEntity(new StringEntity(new String(requestStr.getBytes("UTF-8"), "ISO-8859-1")));
try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
String result = EntityUtils.toString(response.getEntity(), Consts.UTF_8);
this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", url, requestStr, result);
return result;
}
} finally {
httpPost.releaseConnection();
}
} catch (Exception e) {
this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[EXCEPTION]: {}", url, requestStr, e.getMessage());
throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg(e.getMessage()).build(), e);
}
}

@Override
public String createSign(Object xmlBean) {
return createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
//import org.apache.http.conn.ssl.DefaultHostnameVerifier;
//import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
Expand All @@ -33,7 +33,7 @@
public class WxMpServiceImpl implements WxMpService {

private static final JsonParser JSON_PARSER = new JsonParser();

protected final Logger log = LoggerFactory.getLogger(this.getClass());

private WxMpConfigStorage configStorage;
Expand Down Expand Up @@ -459,12 +459,12 @@ private void initHttpClient() {
.httpProxyUsername(this.configStorage.getHttpProxyUsername())
.httpProxyPassword(this.configStorage.getHttpProxyPassword());

if (this.configStorage.getSSLContext() != null) {
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
this.configStorage.getSSLContext(), new String[] { "TLSv1" }, null,
new DefaultHostnameVerifier());
apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf);
}
// if (this.configStorage.getSSLContext() != null) {
// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
// this.configStorage.getSSLContext(), new String[] { "TLSv1" }, null,
// new DefaultHostnameVerifier());
// apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf);
// }

if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) {
this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort());
Expand Down