#355 修复为支持拉取订单评价数据接口而引入的签名bug

This commit is contained in:
Binary Wang 2017-10-17 17:40:33 +08:00
parent 447c73e43a
commit 64f0e7cf6b
11 changed files with 168 additions and 108 deletions

View File

@ -38,7 +38,7 @@ public class WxMpSelfMenuInfo implements Serializable {
public static class WxMpSelfMenuButton implements Serializable { public static class WxMpSelfMenuButton implements Serializable {
private static final long serialVersionUID = -4426602953309048341L; private static final long serialVersionUID = -4426602953309048341L;
/** /**
* <pre> * <pre>
* 菜单的类型公众平台官网上能够设置的菜单类型有view跳转网页text返回文本下同imgphotovideovoice * 菜单的类型公众平台官网上能够设置的菜单类型有view跳转网页text返回文本下同imgphotovideovoice

View File

@ -14,6 +14,8 @@ import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal; import java.math.BigDecimal;
import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.ALL_SIGN_TYPES;
/** /**
* <pre> * <pre>
* Created by Binary Wang on 2016-10-24. * Created by Binary Wang on 2016-10-24.
@ -189,8 +191,9 @@ public abstract class WxPayBaseRequest {
* </pre> * </pre>
* *
* @param config 支付配置对象用于读取相应系统配置信息 * @param config 支付配置对象用于读取相应系统配置信息
* @param isIgnoreSignType 签名时是否忽略signType
*/ */
public void checkAndSign(WxPayConfig config) throws WxPayException { public void checkAndSign(WxPayConfig config, boolean isIgnoreSignType) throws WxPayException {
this.checkFields(); this.checkFields();
if (StringUtils.isBlank(getAppid())) { if (StringUtils.isBlank(getAppid())) {
@ -209,11 +212,24 @@ public abstract class WxPayBaseRequest {
this.setSubMchId(config.getSubMchId()); this.setSubMchId(config.getSubMchId());
} }
if (StringUtils.isBlank(getSignType())) {
if (config.getSignType() != null && !ALL_SIGN_TYPES.contains(config.getSignType())) {
throw new WxPayException("非法的signType配置" + config.getSignType() + ",请检查配置!");
}
this.setSignType(StringUtils.trimToNull(config.getSignType()));
} else {
if (!ALL_SIGN_TYPES.contains(this.getSignType())) {
throw new WxPayException("非法的sign_type参数" + this.getSignType());
}
}
if (StringUtils.isBlank(getNonceStr())) { if (StringUtils.isBlank(getNonceStr())) {
this.setNonceStr(String.valueOf(System.currentTimeMillis())); this.setNonceStr(String.valueOf(System.currentTimeMillis()));
} }
//设置签名字段的值 //设置签名字段的值
this.setSign(SignUtils.createSign(this, config.getMchKey(), this.signType)); this.setSign(SignUtils.createSign(this, this.getSignType(), config.getMchKey(),
isIgnoreSignType));
} }
} }

View File

@ -165,12 +165,12 @@ public class WxPayRefundRequest extends WxPayBaseRequest {
private String refundDesc; private String refundDesc;
@Override @Override
public void checkAndSign(WxPayConfig config) throws WxPayException { public void checkAndSign(WxPayConfig config, boolean isIgnoreSignType) throws WxPayException {
if (StringUtils.isBlank(this.getOpUserId())) { if (StringUtils.isBlank(this.getOpUserId())) {
this.setOpUserId(config.getMchId()); this.setOpUserId(config.getMchId());
} }
super.checkAndSign(config); super.checkAndSign(config, isIgnoreSignType);
} }
@Override @Override

View File

@ -349,7 +349,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
} }
@Override @Override
public void checkAndSign(WxPayConfig config) throws WxPayException { public void checkAndSign(WxPayConfig config, boolean isIgnoreSignType) throws WxPayException {
if (StringUtils.isBlank(this.getNotifyURL())) { if (StringUtils.isBlank(this.getNotifyURL())) {
this.setNotifyURL(config.getNotifyUrl()); this.setNotifyURL(config.getNotifyUrl());
} }
@ -358,7 +358,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
this.setTradeType(config.getTradeType()); this.setTradeType(config.getTradeType());
} }
super.checkAndSign(config); super.checkAndSign(config, isIgnoreSignType);
} }
} }

View File

@ -216,12 +216,13 @@ public abstract class WxPayBaseResult {
/** /**
* 校验返回结果签名 * 校验返回结果签名
* *
* @param signType 签名类型
* @param checkSuccess 是否同时检查结果是否成功 * @param checkSuccess 是否同时检查结果是否成功
*/ */
public void checkResult(WxPayServiceAbstractImpl wxPayService, boolean checkSuccess) throws WxPayException { public void checkResult(WxPayServiceAbstractImpl wxPayService, String signType, boolean checkSuccess) throws WxPayException {
//校验返回结果签名 //校验返回结果签名
Map<String, String> map = toMap(); Map<String, String> map = toMap();
if (getSign() != null && !SignUtils.checkSign(map, wxPayService.getConfig().getMchKey())) { if (getSign() != null && !SignUtils.checkSign(map, signType, wxPayService.getConfig().getMchKey())) {
this.getLogger().debug("校验结果签名失败,参数:{}", map); this.getLogger().debug("校验结果签名失败,参数:{}", map);
throw new WxPayException("参数格式校验错误!"); throw new WxPayException("参数格式校验错误!");
} }

View File

@ -36,6 +36,7 @@ public class WxPayConfig {
private String subMchId; private String subMchId;
private String notifyUrl; private String notifyUrl;
private String tradeType; private String tradeType;
private String signType;
private SSLContext sslContext; private SSLContext sslContext;
private String keyPath; private String keyPath;
private boolean useSandboxEnv = false; private boolean useSandboxEnv = false;
@ -139,6 +140,19 @@ public class WxPayConfig {
this.tradeType = tradeType; this.tradeType = tradeType;
} }
/**
* 签名方式
* 有两种HMAC_SHA256 和MD5
* @see com.github.binarywang.wxpay.constant.WxPayConstants.SignType
*/
public String getSignType() {
return this.signType;
}
public void setSignType(String signType) {
this.signType = signType;
}
public SSLContext getSslContext() { public SSLContext getSslContext() {
return this.sslContext; return this.sslContext;
} }

View File

@ -1,6 +1,9 @@
package com.github.binarywang.wxpay.constant; package com.github.binarywang.wxpay.constant;
import com.google.common.collect.Lists;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.List;
/** /**
* <pre> * <pre>
@ -96,6 +99,7 @@ public class WxPayConstants {
public static class SignType { public static class SignType {
public static final String HMAC_SHA256 = "HMAC-SHA256"; public static final String HMAC_SHA256 = "HMAC-SHA256";
public static final String MD5 = "MD5"; public static final String MD5 = "MD5";
public static final List<String> ALL_SIGN_TYPES = Lists.newArrayList(HMAC_SHA256, MD5);
} }
/** /**

View File

@ -72,12 +72,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
@Override @Override
public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException { public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/secapi/pay/refund"; String url = this.getPayBaseUrl() + "/secapi/pay/refund";
String responseContent = this.post(url, request.toXML(), true); String responseContent = this.post(url, request.toXML(), true);
WxPayRefundResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundResult.class); WxPayRefundResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@ -90,13 +90,13 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
request.setOutRefundNo(StringUtils.trimToNull(outRefundNo)); request.setOutRefundNo(StringUtils.trimToNull(outRefundNo));
request.setRefundId(StringUtils.trimToNull(refundId)); request.setRefundId(StringUtils.trimToNull(refundId));
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/pay/refundquery"; String url = this.getPayBaseUrl() + "/pay/refundquery";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPayRefundQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundQueryResult.class); WxPayRefundQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundQueryResult.class);
result.composeRefundRecords(); result.composeRefundRecords();
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@ -112,7 +112,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
log.debug("微信支付异步通知请求参数:{}", xmlData); log.debug("微信支付异步通知请求参数:{}", xmlData);
WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlData); WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlData);
log.debug("微信支付异步通知请求解析后的对象:{}", result); log.debug("微信支付异步通知请求解析后的对象:{}", result);
result.checkResult(this, false); result.checkResult(this, null, false);
return result; return result;
} catch (WxPayException e) { } catch (WxPayException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
@ -138,7 +138,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
@Override @Override
public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxPayException { public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendredpack"; String url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendredpack";
if (request.getAmtType() != null) { if (request.getAmtType() != null) {
@ -156,12 +156,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest();
request.setMchBillNo(mchBillNo); request.setMchBillNo(mchBillNo);
request.setBillType(BillType.MCHT); request.setBillType(BillType.MCHT);
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gethbinfo"; String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gethbinfo";
String responseContent = this.post(url, request.toXML(), true); String responseContent = this.post(url, request.toXML(), true);
WxPayRedpackQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRedpackQueryResult.class); WxPayRedpackQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRedpackQueryResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@ -170,7 +170,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
WxPayOrderQueryRequest request = new WxPayOrderQueryRequest(); WxPayOrderQueryRequest request = new WxPayOrderQueryRequest();
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
request.setTransactionId(StringUtils.trimToNull(transactionId)); request.setTransactionId(StringUtils.trimToNull(transactionId));
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/pay/orderquery"; String url = this.getPayBaseUrl() + "/pay/orderquery";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
@ -180,7 +180,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
WxPayOrderQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderQueryResult.class); WxPayOrderQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderQueryResult.class);
result.composeCoupons(); result.composeCoupons();
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@ -192,12 +192,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
WxPayOrderCloseRequest request = new WxPayOrderCloseRequest(); WxPayOrderCloseRequest request = new WxPayOrderCloseRequest();
request.setOutTradeNo(StringUtils.trimToNull(outTradeNo)); request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/pay/closeorder"; String url = this.getPayBaseUrl() + "/pay/closeorder";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPayOrderCloseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderCloseResult.class); WxPayOrderCloseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderCloseResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@ -236,7 +236,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
configMap.put("appid", appId); configMap.put("appid", appId);
payResult = WxPayAppOrderResult.builder() payResult = WxPayAppOrderResult.builder()
.sign(SignUtils.createSign(configMap, this.getConfig().getMchKey(), null)) .sign(SignUtils.createSign(configMap, null, this.getConfig().getMchKey(), false))
.prepayId(prepayId) .prepayId(prepayId)
.partnerId(partnerId) .partnerId(partnerId)
.appId(appId) .appId(appId)
@ -255,9 +255,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
.signType(SignType.MD5) .signType(SignType.MD5)
.build(); .build();
((WxPayMpOrderResult) payResult) ((WxPayMpOrderResult) payResult)
.setPaySign(SignUtils.createSign(payResult, this.getConfig().getMchKey(), null)); .setPaySign(SignUtils.createSign(payResult, null, this.getConfig().getMchKey(), false));
break; break;
} }
default: {
throw new WxPayException("该交易类型暂不支持");
}
} }
return (T) payResult; return (T) payResult;
@ -265,12 +268,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
@Override @Override
public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxPayException { public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/pay/unifiedorder"; String url = this.getPayBaseUrl() + "/pay/unifiedorder";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPayUnifiedOrderResult result = WxPayBaseResult.fromXML(responseContent, WxPayUnifiedOrderResult.class); WxPayUnifiedOrderResult result = WxPayBaseResult.fromXML(responseContent, WxPayUnifiedOrderResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@ -303,7 +306,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
configMap.put("noncestr", nonceStr); configMap.put("noncestr", nonceStr);
configMap.put("appid", appId); configMap.put("appid", appId);
// 此map用于客户端与微信服务器交互 // 此map用于客户端与微信服务器交互
payInfo.put("sign", SignUtils.createSign(configMap, this.getConfig().getMchKey(), null)); payInfo.put("sign", SignUtils.createSign(configMap, null, this.getConfig().getMchKey(), false));
payInfo.put("prepayId", prepayId); payInfo.put("prepayId", prepayId);
payInfo.put("partnerId", partnerId); payInfo.put("partnerId", partnerId);
payInfo.put("appId", appId); payInfo.put("appId", appId);
@ -317,7 +320,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
payInfo.put("nonceStr", nonceStr); payInfo.put("nonceStr", nonceStr);
payInfo.put("package", "prepay_id=" + prepayId); payInfo.put("package", "prepay_id=" + prepayId);
payInfo.put("signType", SignType.MD5); payInfo.put("signType", SignType.MD5);
payInfo.put("paySign", SignUtils.createSign(payInfo, this.getConfig().getMchKey(), null)); payInfo.put("paySign", SignUtils.createSign(payInfo, null, this.getConfig().getMchKey(), false));
} }
return payInfo; return payInfo;
@ -325,12 +328,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
@Override @Override
public WxEntPayResult entPay(WxEntPayRequest request) throws WxPayException { public WxEntPayResult entPay(WxEntPayRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/mmpaymkttransfers/promotion/transfers"; String url = this.getPayBaseUrl() + "/mmpaymkttransfers/promotion/transfers";
String responseContent = this.post(url, request.toXML(), true); String responseContent = this.post(url, request.toXML(), true);
WxEntPayResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayResult.class); WxEntPayResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@ -338,12 +341,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException { public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException {
WxEntPayQueryRequest request = new WxEntPayQueryRequest(); WxEntPayQueryRequest request = new WxEntPayQueryRequest();
request.setPartnerTradeNo(partnerTradeNo); request.setPartnerTradeNo(partnerTradeNo);
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo"; String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo";
String responseContent = this.post(url, request.toXML(), true); String responseContent = this.post(url, request.toXML(), true);
WxEntPayQueryResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayQueryResult.class); WxEntPayQueryResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayQueryResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@ -364,7 +367,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
params.put("time_stamp", String.valueOf(System.currentTimeMillis() / 1000));//这里需要秒10位数字 params.put("time_stamp", String.valueOf(System.currentTimeMillis() / 1000));//这里需要秒10位数字
params.put("nonce_str", String.valueOf(System.currentTimeMillis())); params.put("nonce_str", String.valueOf(System.currentTimeMillis()));
String sign = SignUtils.createSign(params, this.getConfig().getMchKey(), null); String sign = SignUtils.createSign(params, null, this.getConfig().getMchKey(), false);
params.put("sign", sign); params.put("sign", sign);
for (String key : params.keySet()) { for (String key : params.keySet()) {
@ -389,13 +392,14 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
return QrcodeUtils.createQrcode(content, sideLength, logoFile); return QrcodeUtils.createQrcode(content, sideLength, logoFile);
} }
@Override
public void report(WxPayReportRequest request) throws WxPayException { public void report(WxPayReportRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/payitil/report"; String url = this.getPayBaseUrl() + "/payitil/report";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPayCommonResult result = WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class); WxPayCommonResult result = WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
} }
@Override @Override
@ -406,7 +410,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
request.setTarType(tarType); request.setTarType(tarType);
request.setDeviceInfo(deviceInfo); request.setDeviceInfo(deviceInfo);
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/pay/downloadbill"; String url = this.getPayBaseUrl() + "/pay/downloadbill";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
@ -488,34 +492,34 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
@Override @Override
public WxPayMicropayResult micropay(WxPayMicropayRequest request) throws WxPayException { public WxPayMicropayResult micropay(WxPayMicropayRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/pay/micropay"; String url = this.getPayBaseUrl() + "/pay/micropay";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPayMicropayResult result = WxPayBaseResult.fromXML(responseContent, WxPayMicropayResult.class); WxPayMicropayResult result = WxPayBaseResult.fromXML(responseContent, WxPayMicropayResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@Override @Override
public WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) throws WxPayException { public WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/secapi/pay/reverse"; String url = this.getPayBaseUrl() + "/secapi/pay/reverse";
String responseContent = this.post(url, request.toXML(), true); String responseContent = this.post(url, request.toXML(), true);
WxPayOrderReverseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderReverseResult.class); WxPayOrderReverseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderReverseResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@Override @Override
public String shorturl(WxPayShorturlRequest request) throws WxPayException { public String shorturl(WxPayShorturlRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/tools/shorturl"; String url = this.getPayBaseUrl() + "/tools/shorturl";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPayShorturlResult result = WxPayBaseResult.fromXML(responseContent, WxPayShorturlResult.class); WxPayShorturlResult result = WxPayBaseResult.fromXML(responseContent, WxPayShorturlResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result.getShortUrl(); return result.getShortUrl();
} }
@ -526,12 +530,12 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
@Override @Override
public String authcode2Openid(WxPayAuthcode2OpenidRequest request) throws WxPayException { public String authcode2Openid(WxPayAuthcode2OpenidRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/tools/authcodetoopenid"; String url = this.getPayBaseUrl() + "/tools/authcodetoopenid";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPayAuthcode2OpenidResult result = WxPayBaseResult.fromXML(responseContent, WxPayAuthcode2OpenidResult.class); WxPayAuthcode2OpenidResult result = WxPayBaseResult.fromXML(responseContent, WxPayAuthcode2OpenidResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result.getOpenid(); return result.getOpenid();
} }
@ -543,45 +547,45 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
@Override @Override
public String getSandboxSignKey() throws WxPayException { public String getSandboxSignKey() throws WxPayException {
WxPayDefaultRequest request = new WxPayDefaultRequest(); WxPayDefaultRequest request = new WxPayDefaultRequest();
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey"; String url = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPaySandboxSignKeyResult result = WxPayBaseResult.fromXML(responseContent, WxPaySandboxSignKeyResult.class); WxPaySandboxSignKeyResult result = WxPayBaseResult.fromXML(responseContent, WxPaySandboxSignKeyResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result.getSandboxSignKey(); return result.getSandboxSignKey();
} }
@Override @Override
public WxPayCouponSendResult sendCoupon(WxPayCouponSendRequest request) throws WxPayException { public WxPayCouponSendResult sendCoupon(WxPayCouponSendRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/mmpaymkttransfers/send_coupon"; String url = this.getPayBaseUrl() + "/mmpaymkttransfers/send_coupon";
String responseContent = this.post(url, request.toXML(), true); String responseContent = this.post(url, request.toXML(), true);
WxPayCouponSendResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponSendResult.class); WxPayCouponSendResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponSendResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@Override @Override
public WxPayCouponStockQueryResult queryCouponStock(WxPayCouponStockQueryRequest request) throws WxPayException { public WxPayCouponStockQueryResult queryCouponStock(WxPayCouponStockQueryRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/mmpaymkttransfers/query_coupon_stock"; String url = this.getPayBaseUrl() + "/mmpaymkttransfers/query_coupon_stock";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPayCouponStockQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponStockQueryResult.class); WxPayCouponStockQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponStockQueryResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@Override @Override
public WxPayCouponInfoQueryResult queryCouponInfo(WxPayCouponInfoQueryRequest request) throws WxPayException { public WxPayCouponInfoQueryResult queryCouponInfo(WxPayCouponInfoQueryRequest request) throws WxPayException {
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), false);
String url = this.getPayBaseUrl() + "/mmpaymkttransfers/querycouponsinfo"; String url = this.getPayBaseUrl() + "/mmpaymkttransfers/querycouponsinfo";
String responseContent = this.post(url, request.toXML(), false); String responseContent = this.post(url, request.toXML(), false);
WxPayCouponInfoQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponInfoQueryResult.class); WxPayCouponInfoQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponInfoQueryResult.class);
result.checkResult(this, true); result.checkResult(this, request.getSignType(), true);
return result; return result;
} }
@ -605,7 +609,7 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService {
request.setLimit(limit); request.setLimit(limit);
request.setSignType(SignType.HMAC_SHA256); request.setSignType(SignType.HMAC_SHA256);
request.checkAndSign(this.getConfig()); request.checkAndSign(this.getConfig(), true);
String url = this.getPayBaseUrl() + "/billcommentsp/batchquerycomment"; String url = this.getPayBaseUrl() + "/billcommentsp/batchquerycomment";

View File

@ -27,31 +27,40 @@ public class SignUtils {
/** /**
* 微信公众号支付签名算法(详见: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 xmlBean Bean需要标记有XML注解 * @param xmlBean Bean需要标记有XML注解
* @param signKey 签名Key * @param signType 签名类型如果为空则默认为MD5
* @param signType 签名类型如果为空则默认为MD5 * @param signKey 签名Key
* @param isIgnoreSignType 签名时是否忽略signType
* @return 签名字符串 * @return 签名字符串
*/ */
public static String createSign(Object xmlBean, String signKey, String signType) { public static String createSign(Object xmlBean, String signType, String signKey, boolean isIgnoreSignType) {
return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey, signType); return createSign(BeanUtils.xmlBean2Map(xmlBean), signType, signKey, isIgnoreSignType);
} }
/** /**
* 微信公众号支付签名算法(详见: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 params 参数信息 * @param params 参数信息
* @param signKey 签名Key * @param signType 签名类型如果为空则默认为MD5
* @param signType 签名类型如果为空则默认为md5 * @param signKey 签名Key
* @param isIgnoreSignType 签名时是否忽略signType
* @return 签名字符串 * @return 签名字符串
*/ */
public static String createSign(Map<String, String> params, String signKey, String signType) { public static String createSign(Map<String, String> params, String signType, String signKey, boolean isIgnoreSignType) {
SortedMap<String, String> sortedMap = new TreeMap<>(params); SortedMap<String, String> sortedMap = new TreeMap<>(params);
StringBuilder toSign = new StringBuilder(); StringBuilder toSign = new StringBuilder();
for (String key : sortedMap.keySet()) { for (String key : sortedMap.keySet()) {
String value = params.get(key); String value = params.get(key);
if (StringUtils.isNotEmpty(value) && boolean shouldSign = false;
!Lists.newArrayList("sign", "key", "sign_type").contains(key)) { if (isIgnoreSignType && "sign_type".equals(key)) {
shouldSign = false;
} else if (StringUtils.isNotEmpty(value)
&& !Lists.newArrayList("sign", "key").contains(key)) {
shouldSign = true;
}
if (shouldSign) {
toSign.append(key).append("=").append(value).append("&"); toSign.append(key).append("=").append(value).append("&");
} }
} }
@ -81,25 +90,27 @@ public class SignUtils {
/** /**
* 校验签名是否正确 * 校验签名是否正确
* *
* @param xmlBean Bean需要标记有XML注解 * @param xmlBean Bean需要标记有XML注解
* @param signKey 校验的签名Key * @param signType 签名类型如果为空则默认为MD5
* @param signKey 校验的签名Key
* @return true - 签名校验成功false - 签名校验失败 * @return true - 签名校验成功false - 签名校验失败
* @see #checkSign(Map, String) * @see #checkSign(Map, String, String)
*/ */
public static boolean checkSign(Object xmlBean, String signKey) { public static boolean checkSign(Object xmlBean, String signType, String signKey) {
return checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey); return checkSign(BeanUtils.xmlBean2Map(xmlBean), signType, signKey);
} }
/** /**
* 校验签名是否正确 * 校验签名是否正确
* *
* @param params 需要校验的参数Map * @param params 需要校验的参数Map
* @param signKey 校验的签名Key * @param signType 签名类型如果为空则默认为MD5
* @param signKey 校验的签名Key
* @return true - 签名校验成功false - 签名校验失败 * @return true - 签名校验成功false - 签名校验失败
* @see #checkSign(Map, String) * @see #checkSign(Map, String, String)
*/ */
public static boolean checkSign(Map<String, String> params, String signKey) { public static boolean checkSign(Map<String, String> params, String signType, String signKey) {
String sign = createSign(params, signKey, null); String sign = createSign(params, signType, signKey, false);
return sign.equals(params.get("sign")); return sign.equals(params.get("sign"));
} }
} }

View File

@ -46,16 +46,17 @@ public class WxPayServiceAbstractImplTest {
*/ */
@Test @Test
public void testUnifiedOrder() throws WxPayException { public void testUnifiedOrder() throws WxPayException {
WxPayUnifiedOrderResult result = this.payService WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
.unifiedOrder(WxPayUnifiedOrderRequest.newBuilder() .body("我去")
.body("我去") .totalFee(1)
.totalFee(1) .spbillCreateIp("11.1.11.1")
.spbillCreateIp("11.1.11.1") .notifyURL("111111")
.notifyURL("111111") .tradeType(TradeType.JSAPI)
.tradeType(TradeType.JSAPI) .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid())
.openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()) .outTradeNo("1111112")
.outTradeNo("1111112") .build();
.build()); request.setSignType(SignType.HMAC_SHA256);
WxPayUnifiedOrderResult result = this.payService.unifiedOrder(request);
this.logger.info(result.toString()); this.logger.info(result.toString());
this.logger.warn(this.payService.getWxApiData().toString()); this.logger.warn(this.payService.getWxApiData().toString());
} }
@ -284,13 +285,15 @@ public class WxPayServiceAbstractImplTest {
@Test @Test
public void testMicropay() throws Exception { public void testMicropay() throws Exception {
WxPayMicropayResult result = this.payService.micropay(WxPayMicropayRequest.newBuilder() WxPayMicropayResult result = this.payService.micropay(
.body("body") WxPayMicropayRequest
.outTradeNo("aaaaa") .newBuilder()
.totalFee(123) .body("body")
.spbillCreateIp("127.0.0.1") .outTradeNo("aaaaa")
.authCode("aaa") .totalFee(123)
.build()); .spbillCreateIp("127.0.0.1")
.authCode("aaa")
.build());
this.logger.info(result.toString()); this.logger.info(result.toString());
} }
@ -306,9 +309,11 @@ public class WxPayServiceAbstractImplTest {
@Test @Test
public void testReverseOrder() throws Exception { public void testReverseOrder() throws Exception {
WxPayOrderReverseResult result = this.payService.reverseOrder(WxPayOrderReverseRequest.newBuilder() WxPayOrderReverseResult result = this.payService.reverseOrder(
.outTradeNo("1111") WxPayOrderReverseRequest
.build()); .newBuilder()
.outTradeNo("1111")
.build());
assertNotNull(result); assertNotNull(result);
this.logger.info(result.toString()); this.logger.info(result.toString());
} }
@ -359,33 +364,38 @@ public class WxPayServiceAbstractImplTest {
@Test @Test
public void testQueryCouponStock() throws Exception { public void testQueryCouponStock() throws Exception {
WxPayCouponStockQueryResult result = this.payService.queryCouponStock(WxPayCouponStockQueryRequest.newBuilder() WxPayCouponStockQueryResult result = this.payService.queryCouponStock(
.couponStockId("123") WxPayCouponStockQueryRequest
.build()); .newBuilder()
.couponStockId("123")
.build());
this.logger.info(result.toString()); this.logger.info(result.toString());
} }
@Test @Test
public void testQueryCouponInfo() throws Exception { public void testQueryCouponInfo() throws Exception {
WxPayCouponInfoQueryResult result = this.payService.queryCouponInfo(WxPayCouponInfoQueryRequest.newBuilder() WxPayCouponInfoQueryResult result = this.payService.queryCouponInfo(
.openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") WxPayCouponInfoQueryRequest
.couponId("11") .newBuilder()
.stockId("1121") .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4")
.build()); .couponId("11")
.stockId("1121")
.build());
this.logger.info(result.toString()); this.logger.info(result.toString());
} }
/** /**
* 目前调用接口总报系统繁忙清稍后再试怀疑根本没法使用 * 只支持拉取90天内的评论数据
*/ */
@Test @Test
public void testQueryComment() throws Exception { public void testQueryComment() throws Exception {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -2); calendar.add(Calendar.DAY_OF_MONTH, -1);
Date beginDate = calendar.getTime();
calendar.add(Calendar.MONTH, -1);
Date endDate = calendar.getTime(); Date endDate = calendar.getTime();
this.payService.queryComment(beginDate, endDate, 0, null); calendar.add(Calendar.DAY_OF_MONTH, -88);
Date beginDate = calendar.getTime();
String result = this.payService.queryComment(beginDate, endDate, 0, null);
this.logger.info(result);
} }
@Test @Test

View File

@ -20,7 +20,7 @@ public class SignUtilsTest {
public void testCreateSign() throws Exception { public void testCreateSign() throws Exception {
String signKey = "192006250b4c09247ec02edce69f6a2d"; String signKey = "192006250b4c09247ec02edce69f6a2d";
String message = "appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA"; String message = "appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
assertEquals(SignUtils.createSign((Splitter.on("&").withKeyValueSeparator("=").split(message)), signKey, null), assertEquals(SignUtils.createSign((Splitter.on("&").withKeyValueSeparator("=").split(message)), null, signKey, false),
"9A0A8659F005D6984697E2CA0A9CF3B7"); "9A0A8659F005D6984697E2CA0A9CF3B7");
} }
@ -29,7 +29,7 @@ public class SignUtilsTest {
String signKey = "192006250b4c09247ec02edce69f6a2d"; String signKey = "192006250b4c09247ec02edce69f6a2d";
final String message = "appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA"; final String message = "appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
String sign = SignUtils.createSign(Splitter.on("&").withKeyValueSeparator("=").split(message), String sign = SignUtils.createSign(Splitter.on("&").withKeyValueSeparator("=").split(message),
signKey, HMAC_SHA256); HMAC_SHA256, signKey, false);
assertEquals(sign, "6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6"); assertEquals(sign, "6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6");
} }