| @@ -4,14 +4,13 @@ import me.chanjar.weixin.common.bean.WxAccessToken; | |||||
| import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | ||||
| import javax.net.ssl.SSLContext; | import javax.net.ssl.SSLContext; | ||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.concurrent.locks.Lock; | import java.util.concurrent.locks.Lock; | ||||
| /** | /** | ||||
| * 微信客户端配置存储 | * 微信客户端配置存储 | ||||
| * @author chanjarster | |||||
| * | * | ||||
| * @author chanjarster | |||||
| */ | */ | ||||
| public interface WxMpConfigStorage { | public interface WxMpConfigStorage { | ||||
| @@ -28,13 +27,15 @@ public interface WxMpConfigStorage { | |||||
| /** | /** | ||||
| * 应该是线程安全的 | * 应该是线程安全的 | ||||
| * | |||||
| * @param accessToken 要更新的WxAccessToken对象 | * @param accessToken 要更新的WxAccessToken对象 | ||||
| */ | */ | ||||
| void updateAccessToken(WxAccessToken accessToken); | void updateAccessToken(WxAccessToken accessToken); | ||||
| /** | /** | ||||
| * 应该是线程安全的 | * 应该是线程安全的 | ||||
| * @param accessToken 新的accessToken值 | |||||
| * | |||||
| * @param accessToken 新的accessToken值 | |||||
| * @param expiresInSeconds 过期时间,以秒为单位 | * @param expiresInSeconds 过期时间,以秒为单位 | ||||
| */ | */ | ||||
| void updateAccessToken(String accessToken, int expiresInSeconds); | void updateAccessToken(String accessToken, int expiresInSeconds); | ||||
| @@ -52,7 +53,8 @@ public interface WxMpConfigStorage { | |||||
| /** | /** | ||||
| * 应该是线程安全的 | * 应该是线程安全的 | ||||
| * @param jsapiTicket 新的jsapi ticket值 | |||||
| * | |||||
| * @param jsapiTicket 新的jsapi ticket值 | |||||
| * @param expiresInSeconds 过期时间,以秒为单位 | * @param expiresInSeconds 过期时间,以秒为单位 | ||||
| */ | */ | ||||
| void updateJsapiTicket(String jsapiTicket, int expiresInSeconds); | void updateJsapiTicket(String jsapiTicket, int expiresInSeconds); | ||||
| @@ -70,7 +72,8 @@ public interface WxMpConfigStorage { | |||||
| /** | /** | ||||
| * 应该是线程安全的 | * 应该是线程安全的 | ||||
| * @param cardApiTicket 新的cardApi ticket值 | |||||
| * | |||||
| * @param cardApiTicket 新的cardApi ticket值 | |||||
| * @param expiresInSeconds 过期时间,以秒为单位 | * @param expiresInSeconds 过期时间,以秒为单位 | ||||
| */ | */ | ||||
| void updateCardApiTicket(String cardApiTicket, int expiresInSeconds); | void updateCardApiTicket(String cardApiTicket, int expiresInSeconds); | ||||
| @@ -82,21 +85,23 @@ public interface WxMpConfigStorage { | |||||
| String getPartnerId(); | String getPartnerId(); | ||||
| String getPartnerKey(); | String getPartnerKey(); | ||||
| /** | /** | ||||
| * 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数。 | * 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数。 | ||||
| * @since 2.5.0 | |||||
| * | |||||
| * @return | * @return | ||||
| * @since 2.5.0 | |||||
| */ | */ | ||||
| String getNotifyURL(); | String getNotifyURL(); | ||||
| /** | /** | ||||
| * 交易类型 | * 交易类型 | ||||
| * <pre> | * <pre> | ||||
| * JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 | * JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 | ||||
| * </pre> | * </pre> | ||||
| * @since 2.5.0 | |||||
| * | |||||
| * @return | * @return | ||||
| * @since 2.5.0 | |||||
| */ | */ | ||||
| String getTradeType(); | String getTradeType(); | ||||
| @@ -118,23 +123,20 @@ public interface WxMpConfigStorage { | |||||
| File getTmpDirFile(); | File getTmpDirFile(); | ||||
| @Deprecated | |||||
| SSLContext getSSLContext(); | |||||
| SSLContext getSslContext(); | SSLContext getSslContext(); | ||||
| void setSslContext(SSLContext sslContext); | void setSslContext(SSLContext sslContext); | ||||
| /** | |||||
| * 在此之前,必须将partnerId进行赋值 | |||||
| * | |||||
| * @param filePath | |||||
| * apiclient_cert.p12的文件的绝对路径 | |||||
| */ | |||||
| void setSslContextFilePath(String filePath) throws Exception; | |||||
| /** | |||||
| * 在此之前,必须将partnerId进行赋值 | |||||
| * | |||||
| * @param filePath apiclient_cert.p12的文件的绝对路径 | |||||
| */ | |||||
| void setSslContextFilePath(String filePath) throws Exception; | |||||
| /** | /** | ||||
| * http client builder | * http client builder | ||||
| * | |||||
| * @return ApacheHttpClientBuilder | * @return ApacheHttpClientBuilder | ||||
| */ | */ | ||||
| ApacheHttpClientBuilder getApacheHttpClientBuilder(); | ApacheHttpClientBuilder getApacheHttpClientBuilder(); | ||||
| @@ -143,5 +145,5 @@ public interface WxMpConfigStorage { | |||||
| * 是否自动刷新token | * 是否自动刷新token | ||||
| */ | */ | ||||
| boolean autoRefreshToken(); | boolean autoRefreshToken(); | ||||
| } | } | ||||
| @@ -1,23 +1,21 @@ | |||||
| package me.chanjar.weixin.mp.api; | 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 org.apache.http.ssl.SSLContexts; | |||||
| import javax.net.ssl.SSLContext; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.FileInputStream; | import java.io.FileInputStream; | ||||
| import java.security.KeyStore; | import java.security.KeyStore; | ||||
| import java.util.concurrent.locks.Lock; | import java.util.concurrent.locks.Lock; | ||||
| import java.util.concurrent.locks.ReentrantLock; | 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,在实际生产环境中应该将这些配置持久化 | * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | ||||
| * @author chanjarster | |||||
| * | * | ||||
| * @author chanjarster | |||||
| */ | */ | ||||
| public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | ||||
| @@ -63,6 +61,10 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
| return this.accessToken; | return this.accessToken; | ||||
| } | } | ||||
| public void setAccessToken(String accessToken) { | |||||
| this.accessToken = accessToken; | |||||
| } | |||||
| @Override | @Override | ||||
| public Lock getAccessTokenLock() { | public Lock getAccessTokenLock() { | ||||
| return this.accessTokenLock; | return this.accessTokenLock; | ||||
| @@ -94,15 +96,15 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
| return this.jsapiTicket; | return this.jsapiTicket; | ||||
| } | } | ||||
| public void setJsapiTicket(String jsapiTicket) { | |||||
| this.jsapiTicket = jsapiTicket; | |||||
| } | |||||
| @Override | @Override | ||||
| public Lock getJsapiTicketLock() { | public Lock getJsapiTicketLock() { | ||||
| return this.jsapiTicketLock; | return this.jsapiTicketLock; | ||||
| } | } | ||||
| public void setJsapiTicket(String jsapiTicket) { | |||||
| this.jsapiTicket = jsapiTicket; | |||||
| } | |||||
| public long getJsapiTicketExpiresTime() { | public long getJsapiTicketExpiresTime() { | ||||
| return this.jsapiTicketExpiresTime; | return this.jsapiTicketExpiresTime; | ||||
| } | } | ||||
| @@ -163,31 +165,35 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
| return this.appId; | return this.appId; | ||||
| } | } | ||||
| public void setAppId(String appId) { | |||||
| this.appId = appId; | |||||
| } | |||||
| @Override | @Override | ||||
| public String getSecret() { | public String getSecret() { | ||||
| return this.secret; | return this.secret; | ||||
| } | } | ||||
| public void setSecret(String secret) { | |||||
| this.secret = secret; | |||||
| } | |||||
| @Override | @Override | ||||
| public String getToken() { | public String getToken() { | ||||
| return this.token; | return this.token; | ||||
| } | } | ||||
| public void setToken(String token) { | |||||
| this.token = token; | |||||
| } | |||||
| @Override | @Override | ||||
| public long getExpiresTime() { | public long getExpiresTime() { | ||||
| return this.expiresTime; | return this.expiresTime; | ||||
| } | } | ||||
| public void setAppId(String appId) { | |||||
| this.appId = appId; | |||||
| } | |||||
| public void setSecret(String secret) { | |||||
| this.secret = secret; | |||||
| } | |||||
| public void setToken(String token) { | |||||
| this.token = token; | |||||
| public void setExpiresTime(long expiresTime) { | |||||
| this.expiresTime = expiresTime; | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -199,14 +205,6 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
| this.aesKey = aesKey; | this.aesKey = aesKey; | ||||
| } | } | ||||
| public void setAccessToken(String accessToken) { | |||||
| this.accessToken = accessToken; | |||||
| } | |||||
| public void setExpiresTime(long expiresTime) { | |||||
| this.expiresTime = expiresTime; | |||||
| } | |||||
| @Override | @Override | ||||
| public String getOauth2redirectUri() { | public String getOauth2redirectUri() { | ||||
| return this.oauth2redirectUri; | return this.oauth2redirectUri; | ||||
| @@ -259,40 +257,40 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
| @Override | @Override | ||||
| public String getPartnerId() { | public String getPartnerId() { | ||||
| return this.partnerId; | |||||
| return this.partnerId; | |||||
| } | } | ||||
| public void setPartnerId(String partnerId) { | public void setPartnerId(String partnerId) { | ||||
| this.partnerId = partnerId; | |||||
| this.partnerId = partnerId; | |||||
| } | } | ||||
| @Override | @Override | ||||
| public String getPartnerKey() { | public String getPartnerKey() { | ||||
| return this.partnerKey; | |||||
| return this.partnerKey; | |||||
| } | } | ||||
| public void setPartnerKey(String partnerKey) { | public void setPartnerKey(String partnerKey) { | ||||
| this.partnerKey = partnerKey; | |||||
| this.partnerKey = partnerKey; | |||||
| } | |||||
| public String getNotifyURL() { | |||||
| return notifyURL; | |||||
| } | } | ||||
| public String getNotifyURL() { | |||||
| return notifyURL; | |||||
| } | |||||
| public void setNotifyURL(String notifyURL) { | |||||
| this.notifyURL = notifyURL; | |||||
| } | |||||
| public void setNotifyURL(String notifyURL) { | |||||
| this.notifyURL = notifyURL; | |||||
| } | |||||
| public String getTradeType() { | |||||
| return tradeType; | |||||
| } | |||||
| public String getTradeType() { | |||||
| return tradeType; | |||||
| } | |||||
| public void setTradeType(String tradeType) { | |||||
| this.tradeType = tradeType; | |||||
| } | |||||
| public void setTradeType(String tradeType) { | |||||
| this.tradeType = tradeType; | |||||
| } | |||||
| @Override | |||||
| @Override | |||||
| public File getTmpDirFile() { | public File getTmpDirFile() { | ||||
| return this.tmpDirFile; | return this.tmpDirFile; | ||||
| } | } | ||||
| @@ -302,47 +300,43 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
| } | } | ||||
| @Override | @Override | ||||
| public SSLContext getSSLContext() { | |||||
| public SSLContext getSslContext() { | |||||
| return this.sslContext; | return this.sslContext; | ||||
| } | } | ||||
| @Override | @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; | |||||
| } | |||||
| public void setSslContext(SSLContext context) { | |||||
| this.sslContext = context; | |||||
| } | |||||
| @Override | @Override | ||||
| public ApacheHttpClientBuilder getApacheHttpClientBuilder() { | |||||
| return this.apacheHttpClientBuilder; | |||||
| 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 | @Override | ||||
| public boolean autoRefreshToken() { | |||||
| return true; | |||||
| public ApacheHttpClientBuilder getApacheHttpClientBuilder() { | |||||
| return this.apacheHttpClientBuilder; | |||||
| } | } | ||||
| public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { | public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { | ||||
| this.apacheHttpClientBuilder = apacheHttpClientBuilder; | this.apacheHttpClientBuilder = apacheHttpClientBuilder; | ||||
| } | } | ||||
| @Override | |||||
| public boolean autoRefreshToken() { | |||||
| return true; | |||||
| } | |||||
| } | } | ||||
| @@ -7,7 +7,6 @@ import me.chanjar.weixin.mp.bean.pay.request.WxPaySendRedpackRequest; | |||||
| import me.chanjar.weixin.mp.bean.pay.request.WxPayUnifiedOrderRequest; | import me.chanjar.weixin.mp.bean.pay.request.WxPayUnifiedOrderRequest; | ||||
| import me.chanjar.weixin.mp.bean.pay.result.*; | import me.chanjar.weixin.mp.bean.pay.result.*; | ||||
| import java.io.File; | |||||
| import java.util.Map; | import java.util.Map; | ||||
| /** | /** | ||||
| @@ -76,10 +75,9 @@ public interface WxMpPayService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param request 请求对象 | * @param request 请求对象 | ||||
| * @param keyFile 证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3) | |||||
| * @return 退款操作结果 | * @return 退款操作结果 | ||||
| */ | */ | ||||
| WxPayRefundResult refund(WxPayRefundRequest request, File keyFile) throws WxErrorException; | |||||
| WxPayRefundResult refund(WxPayRefundRequest request) throws WxErrorException; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -128,7 +126,7 @@ public interface WxMpPayService { | |||||
| /** | /** | ||||
| * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) | * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) | ||||
| * | * | ||||
| * @param prams 参数信息,默认使用配置中的PartnerKey进行签名 | |||||
| * @param prams 参数信息,默认使用配置中的PartnerKey进行签名 | |||||
| * @return 签名字符串 | * @return 签名字符串 | ||||
| * @see #createSign(Map, String) | * @see #createSign(Map, String) | ||||
| */ | */ | ||||
| @@ -176,7 +174,7 @@ public interface WxMpPayService { | |||||
| /** | /** | ||||
| * 校验签名是否正确 | * 校验签名是否正确 | ||||
| * | * | ||||
| * @param params 需要校验的参数Map | |||||
| * @param params 需要校验的参数Map | |||||
| * @param signKey 校验的签名Key | * @param signKey 校验的签名Key | ||||
| * @return true - 签名校验成功,false - 签名校验失败 | * @return true - 签名校验成功,false - 签名校验失败 | ||||
| * @see #checkSign(Map, String) | * @see #checkSign(Map, String) | ||||
| @@ -195,41 +193,9 @@ public interface WxMpPayService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param request 请求对象 | * @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; | WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) 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) | |||||
| */ | |||||
| @Deprecated | |||||
| WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 查询红包记录 | * 查询红包记录 | ||||
| @@ -240,7 +206,6 @@ public interface WxMpPayService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890 | * @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; | WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxErrorException; | ||||
| @@ -255,9 +220,8 @@ public interface WxMpPayService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param request 请求对象 | * @param request 请求对象 | ||||
| * @param keyFile 证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3) | |||||
| */ | */ | ||||
| WxEntPayResult entPay(WxEntPayRequest request, File keyFile) throws WxErrorException; | |||||
| WxEntPayResult entPay(WxEntPayRequest request) throws WxErrorException; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -268,8 +232,7 @@ public interface WxMpPayService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param partnerTradeNo 商户订单号 | * @param partnerTradeNo 商户订单号 | ||||
| * @param keyFile 证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3) | |||||
| */ | */ | ||||
| WxEntPayQueryResult queryEntPay(String partnerTradeNo, File keyFile) throws WxErrorException; | |||||
| WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxErrorException; | |||||
| } | } | ||||
| @@ -23,16 +23,12 @@ import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||||
| import org.apache.http.entity.StringEntity; | import org.apache.http.entity.StringEntity; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
| import org.apache.http.impl.client.HttpClients; | import org.apache.http.impl.client.HttpClients; | ||||
| import org.apache.http.ssl.SSLContexts; | |||||
| import org.apache.http.util.EntityUtils; | import org.apache.http.util.EntityUtils; | ||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
| import javax.net.ssl.SSLContext; | import javax.net.ssl.SSLContext; | ||||
| import java.io.File; | |||||
| import java.io.FileInputStream; | |||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.security.KeyStore; | |||||
| import java.util.*; | import java.util.*; | ||||
| /** | /** | ||||
| @@ -44,7 +40,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| private static final String PAY_BASE_URL = "https://api.mch.weixin.qq.com"; | private static final String PAY_BASE_URL = "https://api.mch.weixin.qq.com"; | ||||
| private static final String[] TRADE_TYPES = new String[]{"JSAPI", "NATIVE", "APP"}; | private static final String[] TRADE_TYPES = new String[]{"JSAPI", "NATIVE", "APP"}; | ||||
| private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS","REFUND_SOURCE_UNSETTLED_FUNDS"}; | |||||
| private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS", "REFUND_SOURCE_UNSETTLED_FUNDS"}; | |||||
| private final Logger log = LoggerFactory.getLogger(this.getClass()); | private final Logger log = LoggerFactory.getLogger(this.getClass()); | ||||
| private WxMpService wxMpService; | private WxMpService wxMpService; | ||||
| @@ -57,20 +53,20 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| } | } | ||||
| @Override | @Override | ||||
| public WxPayRefundResult refund(WxPayRefundRequest request, File keyFile) throws WxErrorException { | |||||
| public WxPayRefundResult refund(WxPayRefundRequest request) throws WxErrorException { | |||||
| XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
| xstream.processAnnotations(WxPayRefundRequest.class); | xstream.processAnnotations(WxPayRefundRequest.class); | ||||
| xstream.processAnnotations(WxPayRefundResult.class); | xstream.processAnnotations(WxPayRefundResult.class); | ||||
| initRequest(request); | initRequest(request); | ||||
| if(StringUtils.isBlank(request.getOpUserId())){ | |||||
| if (StringUtils.isBlank(request.getOpUserId())) { | |||||
| request.setOpUserId(getConfig().getPartnerId()); | request.setOpUserId(getConfig().getPartnerId()); | ||||
| } | } | ||||
| checkParameters(request); | checkParameters(request); | ||||
| request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
| String url = PAY_BASE_URL + "/secapi/pay/refund"; | String url = PAY_BASE_URL + "/secapi/pay/refund"; | ||||
| String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), request.getMchId()); | |||||
| String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
| WxPayRefundResult result = (WxPayRefundResult) xstream.fromXML(responseContent); | WxPayRefundResult result = (WxPayRefundResult) xstream.fromXML(responseContent); | ||||
| this.checkResult(result); | this.checkResult(result); | ||||
| return result; | return result; | ||||
| @@ -158,10 +154,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| } | } | ||||
| } | } | ||||
| @Override | @Override | ||||
| @Deprecated | |||||
| public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile) | |||||
| public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) | |||||
| throws WxErrorException { | throws WxErrorException { | ||||
| XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
| xstream.processAnnotations(WxPaySendRedpackRequest.class); | xstream.processAnnotations(WxPaySendRedpackRequest.class); | ||||
| @@ -175,36 +169,14 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| //裂变红包 | //裂变红包 | ||||
| url = PAY_BASE_URL + "/mmpaymkttransfers/sendgroupredpack"; | url = PAY_BASE_URL + "/mmpaymkttransfers/sendgroupredpack"; | ||||
| } | } | ||||
| String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), request.getMchId()); | |||||
| String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
| WxPaySendRedpackResult result = (WxPaySendRedpackResult) xstream.fromXML(responseContent); | WxPaySendRedpackResult result = (WxPaySendRedpackResult) xstream.fromXML(responseContent); | ||||
| this.checkResult(result); | this.checkResult(result); | ||||
| return 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 | @Override | ||||
| @Deprecated | |||||
| public WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException { | |||||
| public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxErrorException { | |||||
| XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
| xstream.processAnnotations(WxPayRedpackQueryRequest.class); | xstream.processAnnotations(WxPayRedpackQueryRequest.class); | ||||
| xstream.processAnnotations(WxPayRedpackQueryResult.class); | xstream.processAnnotations(WxPayRedpackQueryResult.class); | ||||
| @@ -216,30 +188,11 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
| String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo"; | String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo"; | ||||
| String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), request.getMchId()); | |||||
| String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
| WxPayRedpackQueryResult result = (WxPayRedpackQueryResult) xstream.fromXML(responseContent); | WxPayRedpackQueryResult result = (WxPayRedpackQueryResult) xstream.fromXML(responseContent); | ||||
| this.checkResult(result); | this.checkResult(result); | ||||
| return 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 | @Override | ||||
| public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException { | public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException { | ||||
| @@ -296,17 +249,17 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
| xstream.processAnnotations(WxPayUnifiedOrderRequest.class); | xstream.processAnnotations(WxPayUnifiedOrderRequest.class); | ||||
| xstream.processAnnotations(WxPayUnifiedOrderResult.class); | xstream.processAnnotations(WxPayUnifiedOrderResult.class); | ||||
| initRequest(request); | initRequest(request); | ||||
| if(StringUtils.isBlank(request.getNotifyURL())){ | |||||
| if (StringUtils.isBlank(request.getNotifyURL())) { | |||||
| request.setNotifyURL(getConfig().getNotifyURL()); | request.setNotifyURL(getConfig().getNotifyURL()); | ||||
| } | } | ||||
| if(StringUtils.isBlank(request.getTradeType())){ | |||||
| if (StringUtils.isBlank(request.getTradeType())) { | |||||
| request.setTradeType(getConfig().getTradeType()); | request.setTradeType(getConfig().getTradeType()); | ||||
| } | } | ||||
| checkParameters(request);//校验参数 | checkParameters(request);//校验参数 | ||||
| request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
| String url = PAY_BASE_URL + "/pay/unifiedorder"; | String url = PAY_BASE_URL + "/pay/unifiedorder"; | ||||
| String xmlParam = xstream.toXML(request); | String xmlParam = xstream.toXML(request); | ||||
| log.debug("微信统一下单接口,URL:{},参数:{}", url, xmlParam); | log.debug("微信统一下单接口,URL:{},参数:{}", url, xmlParam); | ||||
| @@ -317,15 +270,15 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| this.checkResult(result); | this.checkResult(result); | ||||
| return result; | return result; | ||||
| } | } | ||||
| private void initRequest(WxPayBaseRequest request){ | |||||
| if(StringUtils.isBlank(request.getAppid())){ | |||||
| private void initRequest(WxPayBaseRequest request) { | |||||
| if (StringUtils.isBlank(request.getAppid())) { | |||||
| request.setAppid(getConfig().getAppId()); | request.setAppid(getConfig().getAppId()); | ||||
| } | } | ||||
| if(StringUtils.isBlank(request.getMchId())){ | |||||
| if (StringUtils.isBlank(request.getMchId())) { | |||||
| request.setMchId(getConfig().getPartnerId()); | request.setMchId(getConfig().getPartnerId()); | ||||
| } | } | ||||
| if(StringUtils.isBlank(request.getNonceStr())){ | |||||
| if (StringUtils.isBlank(request.getNonceStr())) { | |||||
| request.setNonceStr(String.valueOf(System.currentTimeMillis())); | request.setNonceStr(String.valueOf(System.currentTimeMillis())); | ||||
| } | } | ||||
| } | } | ||||
| @@ -370,25 +323,25 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| } | } | ||||
| @Override | @Override | ||||
| public WxEntPayResult entPay(WxEntPayRequest request, File keyFile) throws WxErrorException { | |||||
| public WxEntPayResult entPay(WxEntPayRequest request) throws WxErrorException { | |||||
| XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
| xstream.processAnnotations(WxEntPayRequest.class); | xstream.processAnnotations(WxEntPayRequest.class); | ||||
| xstream.processAnnotations(WxEntPayResult.class); | xstream.processAnnotations(WxEntPayResult.class); | ||||
| initRequest(request); | initRequest(request); | ||||
| BeanUtils.checkRequiredFields(request); | BeanUtils.checkRequiredFields(request); | ||||
| request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
| String url = PAY_BASE_URL + "/mmpaymkttransfers/promotion/transfers"; | String url = PAY_BASE_URL + "/mmpaymkttransfers/promotion/transfers"; | ||||
| String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), request.getMchId()); | |||||
| String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
| WxEntPayResult result = (WxEntPayResult) xstream.fromXML(responseContent); | WxEntPayResult result = (WxEntPayResult) xstream.fromXML(responseContent); | ||||
| this.checkResult(result); | this.checkResult(result); | ||||
| return result; | return result; | ||||
| } | } | ||||
| @Override | @Override | ||||
| public WxEntPayQueryResult queryEntPay(String partnerTradeNo, File keyFile) throws WxErrorException { | |||||
| public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxErrorException { | |||||
| XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
| xstream.processAnnotations(WxEntPayQueryRequest.class); | xstream.processAnnotations(WxEntPayQueryRequest.class); | ||||
| xstream.processAnnotations(WxEntPayQueryResult.class); | xstream.processAnnotations(WxEntPayQueryResult.class); | ||||
| @@ -398,7 +351,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| request.setSign(this.createSign(request)); | request.setSign(this.createSign(request)); | ||||
| String url = PAY_BASE_URL + "/mmpaymkttransfers/gettransferinfo"; | String url = PAY_BASE_URL + "/mmpaymkttransfers/gettransferinfo"; | ||||
| String responseContent = this.executeRequestWithKeyFile(url, keyFile, xstream.toXML(request), request.getMchId()); | |||||
| String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | |||||
| WxEntPayQueryResult result = (WxEntPayQueryResult) xstream.fromXML(responseContent); | WxEntPayQueryResult result = (WxEntPayQueryResult) xstream.fromXML(responseContent); | ||||
| this.checkResult(result); | this.checkResult(result); | ||||
| return result; | return result; | ||||
| @@ -425,15 +378,15 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| httpPost.releaseConnection(); | 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"); | |||||
| keyStore.load(inputStream, mchId.toCharArray()); | |||||
| SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build(); | |||||
| SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, | |||||
| private String executeRequestWithKeyFile(String url, String requestStr) throws WxErrorException { | |||||
| try { | |||||
| SSLContext sslContext = getConfig().getSslContext(); | |||||
| if (null == sslContext) { | |||||
| throw new Exception("请将配置类(即WxMpConfigStorage的实现类)中的SSLContext初始化"); | |||||
| } | |||||
| SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1"}, null, | |||||
| new DefaultHostnameVerifier()); | new DefaultHostnameVerifier()); | ||||
| HttpPost httpPost = new HttpPost(url); | HttpPost httpPost = new HttpPost(url); | ||||
| @@ -456,38 +409,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg(e.getMessage()).build(), e); | throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg(e.getMessage()).build(), e); | ||||
| } | } | ||||
| } | } | ||||
| 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 | @Override | ||||
| public String createSign(Object xmlBean) { | public String createSign(Object xmlBean) { | ||||
| return createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); | return createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); | ||||
| @@ -20,8 +20,6 @@ import org.apache.http.HttpHost; | |||||
| import org.apache.http.client.config.RequestConfig; | import org.apache.http.client.config.RequestConfig; | ||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpGet; | 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.impl.client.BasicResponseHandler; | import org.apache.http.impl.client.BasicResponseHandler; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| @@ -30,55 +28,39 @@ import org.slf4j.LoggerFactory; | |||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.util.concurrent.locks.Lock; | import java.util.concurrent.locks.Lock; | ||||
| //import org.apache.http.conn.ssl.DefaultHostnameVerifier; | |||||
| //import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||||
| public class WxMpServiceImpl implements WxMpService { | public class WxMpServiceImpl implements WxMpService { | ||||
| private static final JsonParser JSON_PARSER = new JsonParser(); | private static final JsonParser JSON_PARSER = new JsonParser(); | ||||
| protected final Logger log = LoggerFactory.getLogger(this.getClass()); | |||||
| protected final Logger log = LoggerFactory.getLogger(this.getClass()); | |||||
| protected WxSessionManager sessionManager = new StandardSessionManager(); | |||||
| private WxMpConfigStorage configStorage; | private WxMpConfigStorage configStorage; | ||||
| private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); | private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); | ||||
| private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); | private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); | ||||
| private WxMpMenuService menuService = new WxMpMenuServiceImpl(this); | private WxMpMenuService menuService = new WxMpMenuServiceImpl(this); | ||||
| private WxMpUserService userService = new WxMpUserServiceImpl(this); | private WxMpUserService userService = new WxMpUserServiceImpl(this); | ||||
| private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this); | private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this); | ||||
| private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this); | private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this); | ||||
| private WxMpCardService cardService = new WxMpCardServiceImpl(this); | private WxMpCardService cardService = new WxMpCardServiceImpl(this); | ||||
| private WxMpPayService payService = new WxMpPayServiceImpl(this); | private WxMpPayService payService = new WxMpPayServiceImpl(this); | ||||
| private WxMpStoreService storeService = new WxMpStoreServiceImpl(this); | private WxMpStoreService storeService = new WxMpStoreServiceImpl(this); | ||||
| private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this); | private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this); | ||||
| private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); | private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); | ||||
| private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); | private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); | ||||
| private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); | private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); | ||||
| private CloseableHttpClient httpClient; | private CloseableHttpClient httpClient; | ||||
| private HttpHost httpProxy; | private HttpHost httpProxy; | ||||
| private int retrySleepMillis = 1000; | private int retrySleepMillis = 1000; | ||||
| private int maxRetryTimes = 5; | private int maxRetryTimes = 5; | ||||
| protected WxSessionManager sessionManager = new StandardSessionManager(); | |||||
| @Override | @Override | ||||
| public boolean checkSignature(String timestamp, String nonce, String signature) { | public boolean checkSignature(String timestamp, String nonce, String signature) { | ||||
| try { | try { | ||||
| return SHA1.gen(this.configStorage.getToken(), timestamp, nonce) | return SHA1.gen(this.configStorage.getToken(), timestamp, nonce) | ||||
| .equals(signature); | |||||
| .equals(signature); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -101,8 +83,8 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| if (this.configStorage.isAccessTokenExpired()) { | if (this.configStorage.isAccessTokenExpired()) { | ||||
| String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" + | String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" + | ||||
| "&appid=" + this.configStorage.getAppId() + "&secret=" | |||||
| + this.configStorage.getSecret(); | |||||
| "&appid=" + this.configStorage.getAppId() + "&secret=" | |||||
| + this.configStorage.getSecret(); | |||||
| try { | try { | ||||
| HttpGet httpGet = new HttpGet(url); | HttpGet httpGet = new HttpGet(url); | ||||
| if (this.httpProxy != null) { | if (this.httpProxy != null) { | ||||
| @@ -117,8 +99,8 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| } | } | ||||
| WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | ||||
| this.configStorage.updateAccessToken(accessToken.getAccessToken(), | this.configStorage.updateAccessToken(accessToken.getAccessToken(), | ||||
| accessToken.getExpiresIn()); | |||||
| }finally { | |||||
| accessToken.getExpiresIn()); | |||||
| } finally { | |||||
| httpGet.releaseConnection(); | httpGet.releaseConnection(); | ||||
| } | } | ||||
| } catch (IOException e) { | } catch (IOException e) { | ||||
| @@ -167,7 +149,7 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| String noncestr = RandomUtils.getRandomStr(); | String noncestr = RandomUtils.getRandomStr(); | ||||
| String jsapiTicket = getJsapiTicket(false); | String jsapiTicket = getJsapiTicket(false); | ||||
| String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, | String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, | ||||
| "noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url); | |||||
| "noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url); | |||||
| WxJsapiSignature jsapiSignature = new WxJsapiSignature(); | WxJsapiSignature jsapiSignature = new WxJsapiSignature(); | ||||
| jsapiSignature.setAppid(this.configStorage.getAppId()); | jsapiSignature.setAppid(this.configStorage.getAppId()); | ||||
| jsapiSignature.setTimestamp(timestamp); | jsapiSignature.setTimestamp(timestamp); | ||||
| @@ -247,7 +229,7 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| @Override | @Override | ||||
| public String buildQrConnectUrl(String redirectURI, String scope, | public String buildQrConnectUrl(String redirectURI, String scope, | ||||
| String state) { | |||||
| String state) { | |||||
| StringBuilder url = new StringBuilder(); | StringBuilder url = new StringBuilder(); | ||||
| url.append("https://open.weixin.qq.com/connect/qrconnect?"); | url.append("https://open.weixin.qq.com/connect/qrconnect?"); | ||||
| url.append("appid=").append(this.configStorage.getAppId()); | url.append("appid=").append(this.configStorage.getAppId()); | ||||
| @@ -366,7 +348,7 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| do { | do { | ||||
| try { | try { | ||||
| T result = executeInternal(executor, uri, data); | T result = executeInternal(executor, uri, data); | ||||
| this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}",uri, data, result); | |||||
| this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", uri, data, result); | |||||
| return result; | return result; | ||||
| } catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
| if (retryTimes + 1 > this.maxRetryTimes) { | if (retryTimes + 1 > this.maxRetryTimes) { | ||||
| @@ -416,7 +398,7 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { | if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { | ||||
| // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | ||||
| this.configStorage.expireAccessToken(); | this.configStorage.expireAccessToken(); | ||||
| if(this.configStorage.autoRefreshToken()){ | |||||
| if (this.configStorage.autoRefreshToken()) { | |||||
| return this.execute(executor, uri, data); | return this.execute(executor, uri, data); | ||||
| } | } | ||||
| } | } | ||||
| @@ -441,30 +423,24 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| return this.httpClient; | return this.httpClient; | ||||
| } | } | ||||
| @Override | |||||
| public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { | |||||
| this.configStorage = wxConfigProvider; | |||||
| this.initHttpClient(); | |||||
| } | |||||
| private void initHttpClient() { | private void initHttpClient() { | ||||
| ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage | ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage | ||||
| .getApacheHttpClientBuilder(); | |||||
| .getApacheHttpClientBuilder(); | |||||
| if (null == apacheHttpClientBuilder) { | if (null == apacheHttpClientBuilder) { | ||||
| apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); | apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); | ||||
| } | } | ||||
| apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) | apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) | ||||
| .httpProxyPort(this.configStorage.getHttpProxyPort()) | |||||
| .httpProxyUsername(this.configStorage.getHttpProxyUsername()) | |||||
| .httpProxyPassword(this.configStorage.getHttpProxyPassword()); | |||||
| .httpProxyPort(this.configStorage.getHttpProxyPort()) | |||||
| .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) { | if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { | ||||
| this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); | this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); | ||||
| @@ -478,6 +454,12 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| return this.configStorage; | return this.configStorage; | ||||
| } | } | ||||
| @Override | |||||
| public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { | |||||
| this.configStorage = wxConfigProvider; | |||||
| this.initHttpClient(); | |||||
| } | |||||
| @Override | @Override | ||||
| public void setRetrySleepMillis(int retrySleepMillis) { | public void setRetrySleepMillis(int retrySleepMillis) { | ||||
| this.retrySleepMillis = retrySleepMillis; | this.retrySleepMillis = retrySleepMillis; | ||||
| @@ -34,7 +34,7 @@ public class WxMpPayServiceImplTest { | |||||
| } | } | ||||
| /** | /** | ||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#refund(WxPayRefundRequest, File)} . | |||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#refund(WxPayRefundRequest)} . | |||||
| */ | */ | ||||
| @Test | @Test | ||||
| public void testRefund() throws Exception { | public void testRefund() throws Exception { | ||||
| @@ -43,8 +43,7 @@ public class WxMpPayServiceImplTest { | |||||
| request.setOutTradeNo("1111"); | request.setOutTradeNo("1111"); | ||||
| request.setTotalFee(1222); | request.setTotalFee(1222); | ||||
| request.setRefundFee(111); | request.setRefundFee(111); | ||||
| File keyFile = new File("E:\\dlt.p12"); | |||||
| WxPayRefundResult result = this.wxService.getPayService().refund(request, keyFile); | |||||
| WxPayRefundResult result = this.wxService.getPayService().refund(request); | |||||
| System.err.println(result); | System.err.println(result); | ||||
| } | } | ||||
| @@ -72,7 +71,7 @@ public class WxMpPayServiceImplTest { | |||||
| } | } | ||||
| /** | /** | ||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#sendRedpack(WxPaySendRedpackRequest, File)} . | |||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#sendRedpack(WxPaySendRedpackRequest)} . | |||||
| */ | */ | ||||
| @Test | @Test | ||||
| public void testSendRedpack() throws Exception { | public void testSendRedpack() throws Exception { | ||||
| @@ -82,18 +81,17 @@ public class WxMpPayServiceImplTest { | |||||
| request.setMchBillNo("aaaa"); | request.setMchBillNo("aaaa"); | ||||
| request | request | ||||
| .setReOpenid(((WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage()).getOpenid()); | .setReOpenid(((WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage()).getOpenid()); | ||||
| File keyFile = new File("E:\\dlt.p12"); | |||||
| WxPaySendRedpackResult redpackResult = this.wxService.getPayService().sendRedpack(request, keyFile); | |||||
| WxPaySendRedpackResult redpackResult = this.wxService.getPayService().sendRedpack(request); | |||||
| System.err.println(redpackResult); | System.err.println(redpackResult); | ||||
| } | } | ||||
| /** | /** | ||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#queryRedpack(String, File)}. | |||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#queryRedpack(String)}. | |||||
| */ | */ | ||||
| @Test | @Test | ||||
| public void testQueryRedpack() throws Exception { | public void testQueryRedpack() throws Exception { | ||||
| File keyFile = new File("E:\\dlt.p12"); | File keyFile = new File("E:\\dlt.p12"); | ||||
| WxPayRedpackQueryResult redpackResult = this.wxService.getPayService().queryRedpack("aaaa", keyFile); | |||||
| WxPayRedpackQueryResult redpackResult = this.wxService.getPayService().queryRedpack("aaaa"); | |||||
| System.err.println(redpackResult); | System.err.println(redpackResult); | ||||
| } | } | ||||
| @@ -128,21 +126,19 @@ public class WxMpPayServiceImplTest { | |||||
| } | } | ||||
| /** | /** | ||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#entPay(WxEntPayRequest, File)}. | |||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#entPay(WxEntPayRequest)}. | |||||
| */ | */ | ||||
| @Test | @Test | ||||
| public final void testEntPay() throws WxErrorException { | public final void testEntPay() throws WxErrorException { | ||||
| File keyFile = new File("E:\\dlt.p12"); | |||||
| WxEntPayRequest request = new WxEntPayRequest(); | WxEntPayRequest request = new WxEntPayRequest(); | ||||
| System.err.println(this.wxService.getPayService().entPay(request, keyFile)); | |||||
| System.err.println(this.wxService.getPayService().entPay(request)); | |||||
| } | } | ||||
| /** | /** | ||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#queryEntPay(String, File)}. | |||||
| * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpPayServiceImpl#queryEntPay(String)}. | |||||
| */ | */ | ||||
| @Test | @Test | ||||
| public final void testQueryEntPay() throws WxErrorException { | public final void testQueryEntPay() throws WxErrorException { | ||||
| File keyFile = new File("E:\\dlt.p12"); | |||||
| System.err.println(this.wxService.getPayService().queryEntPay("11212121", keyFile)); | |||||
| System.err.println(this.wxService.getPayService().queryEntPay("11212121")); | |||||
| } | } | ||||
| } | } | ||||