...
|
...
|
@@ -2,6 +2,8 @@ package com.yohoufo.order.service.pay.weixin; |
|
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.yoho.core.common.utils.YHMath;
|
|
|
import com.yoho.core.security.WechatException;
|
|
|
import com.yoho.core.security.WechatHelper;
|
|
|
import com.yoho.error.ServiceError;
|
|
|
import com.yoho.error.exception.ServiceException;
|
|
|
import com.yohoufo.common.utils.DateUtil;
|
...
|
...
|
@@ -27,10 +29,12 @@ import java.util.HashMap; |
|
|
import java.util.LinkedHashMap;
|
|
|
import java.util.Map;
|
|
|
|
|
|
import static com.yohoufo.order.utils.ServiceExceptions.throwServiceException;
|
|
|
|
|
|
public abstract class AbstractWeixinPayService extends AbstractPayService {
|
|
|
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger("wechatLogger");
|
|
|
private static final Logger log = LoggerFactory.getLogger("wechatLogger");
|
|
|
|
|
|
|
|
|
@Value("${wechat.notifyurl}")
|
...
|
...
|
@@ -43,14 +47,13 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
@Autowired
|
|
|
PaymentSupportService paymentSupportService;
|
|
|
|
|
|
protected abstract String getMchId();
|
|
|
@Autowired
|
|
|
private WechatHelper wechatHelper;
|
|
|
|
|
|
protected abstract String getMchKey();
|
|
|
protected abstract String getMchId();
|
|
|
|
|
|
protected abstract String getAppId();
|
|
|
|
|
|
protected abstract String getMchCertPath();
|
|
|
|
|
|
protected abstract String getTradeType();
|
|
|
|
|
|
protected abstract HttpClient getSslHttpClient();
|
...
|
...
|
@@ -60,12 +63,12 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
//验证业务结果
|
|
|
String resultCode = paramsMap.get(WeixinPayConfig.ApiConstants.RETURN_RESULT_CODE);
|
|
|
if(!WeixinPayConfig.ApiConstants.PREPAY_RESULT_SUCCESS.equals(resultCode)){
|
|
|
logger.error("[{}] trade failed, resultCode: {}", paramsMap.get("out_trade_no"), resultCode);
|
|
|
log.error("[{}] trade failed, resultCode: {}", paramsMap.get("out_trade_no"), resultCode);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if(!md5SignVerify(paramsMap)) {
|
|
|
logger.error("[{}] sign verify failed", paramsMap.get("out_trade_no"));
|
|
|
log.error("[{}] sign verify failed", paramsMap.get("out_trade_no"));
|
|
|
return false;
|
|
|
}
|
|
|
|
...
|
...
|
@@ -135,17 +138,17 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
* @return
|
|
|
*/
|
|
|
private String sendQueryRequest(String tradeNo, String requestXml) {
|
|
|
logger.info("WeixinQuerier request tradeNo: {}, request: {}", tradeNo, requestXml);
|
|
|
log.info("WeixinQuerier request tradeNo: {}, request: {}", tradeNo, requestXml);
|
|
|
|
|
|
String respXml = "";
|
|
|
try {
|
|
|
respXml = httpClient.post(WeixinPayConfig.WEIXIN_PAY_QUERY_URL, requestXml);
|
|
|
} catch (Exception e) {
|
|
|
logger.error("WeixinQuerier request failed, orderCode:{}, ex: {}", tradeNo, e.getMessage());
|
|
|
log.error("WeixinQuerier request failed, orderCode:{}, ex: {}", tradeNo, e.getMessage());
|
|
|
return respXml;
|
|
|
}
|
|
|
|
|
|
logger.info("WeixinQuerier response: {}", respXml);
|
|
|
log.info("WeixinQuerier response: {}", respXml);
|
|
|
return respXml;
|
|
|
}
|
|
|
|
...
|
...
|
@@ -164,15 +167,29 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
paramMap.put("nonce_str", WXUtils.getNonceStr());
|
|
|
|
|
|
//md5签名
|
|
|
String sign = WXUtils.signMd5(paramMap, getMchKey());
|
|
|
String sign = signByMD5(paramMap);
|
|
|
paramMap.put(WeixinPayConfig.ApiConstants.SIGN, sign);
|
|
|
return paramMap;
|
|
|
}
|
|
|
|
|
|
protected String signByMD5(Map<String, String> signParams) {
|
|
|
String sign;
|
|
|
try {
|
|
|
|
|
|
sign = wechatHelper.signByMD5(getMchId(), WXUtils.buildPreSignContent(signParams).toString());
|
|
|
|
|
|
} catch (WechatException e) {
|
|
|
log.info("wechat sign fail", e);
|
|
|
throwServiceException("微信签名失败");
|
|
|
sign = StringUtils.EMPTY;
|
|
|
}
|
|
|
return sign;
|
|
|
}
|
|
|
|
|
|
|
|
|
public PaymentData getPaymentData(Map<String, String> paramsMap) {
|
|
|
PaymentData paymentData = new PaymentData();
|
|
|
logger.info("paramsMap is: {}", paramsMap);
|
|
|
log.info("paramsMap is: {}", paramsMap);
|
|
|
try {
|
|
|
/**
|
|
|
* 普通支付 out_trade_no就是订单号
|
...
|
...
|
@@ -197,7 +214,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
paymentData.setAppId(paramsMap.get("appid"));
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
logger.error("[{}] get payment data error: {}", paramsMap.get("out_trade_no"), e.getMessage());
|
|
|
log.error("[{}] get payment data error: {}", paramsMap.get("out_trade_no"), e.getMessage());
|
|
|
throw new ServiceException(ServiceError.ORDER_PAYMENT_IS_EMPTY);
|
|
|
}
|
|
|
return paymentData;
|
...
|
...
|
@@ -242,49 +259,48 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
|
|
|
/**
|
|
|
* 退款请求
|
|
|
* @param orderCode
|
|
|
* @param requestXml
|
|
|
* @return
|
|
|
*/
|
|
|
private String sendRefundRequest(String tradeNo, String requestXml) {
|
|
|
logger.info("WeixinRefunder request tradeNo: {}, request: {}", tradeNo, requestXml);
|
|
|
log.info("WeixinRefunder request tradeNo: {}, request: {}", tradeNo, requestXml);
|
|
|
|
|
|
String respXml = "";
|
|
|
HttpClient httpClient = getSslHttpClient();
|
|
|
if(httpClient == null) {
|
|
|
logger.error("init weixin ssl httpclient faild, unable refund weixinpay");
|
|
|
log.error("init weixin ssl httpclient faild, unable refund weixinpay");
|
|
|
return respXml;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
respXml = httpClient.post(WeixinPayConfig.WEIXIN_PAY_REFUND_URL, requestXml);
|
|
|
} catch (Exception e) {
|
|
|
logger.error("WeixinRefunder request failed, orderCode:{}, ex: {}", tradeNo, e.getMessage());
|
|
|
log.error("WeixinRefunder request failed, orderCode:{}, ex: {}", tradeNo, e.getMessage());
|
|
|
}
|
|
|
|
|
|
logger.info("WeixinRefunder response: {}", respXml);
|
|
|
log.info("WeixinRefunder response: {}", respXml);
|
|
|
return respXml;
|
|
|
}
|
|
|
|
|
|
|
|
|
public JSONObject prepayRequest(OrderInfo orderInfo) {
|
|
|
logger.info("[{}] prepayRequest begin", orderInfo.getOrderCode());
|
|
|
log.info("[{}] prepayRequest begin", orderInfo.getOrderCode());
|
|
|
Map<String, String> requestParams = buildPrepayParams( orderInfo);
|
|
|
String requestXml = WXUtils.createWXPayXml(requestParams);
|
|
|
String respXml = sendPrepayRequest(orderInfo.getOrderCode(), requestXml);
|
|
|
if(StringUtils.isEmpty(respXml)) {
|
|
|
logger.error("[{}] prepayRequest failed", orderInfo.getOrderCode());
|
|
|
log.error("[{}] prepayRequest failed", orderInfo.getOrderCode());
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
Map<String, String> reponseMap = WXUtils.parseWXPayXml(respXml);
|
|
|
if(!checkPrepayResponse(orderInfo.getOrderCode(), reponseMap)) {
|
|
|
logger.error("[{}] valid prepay response failed", orderInfo.getOrderCode());
|
|
|
log.error("[{}] valid prepay response failed", orderInfo.getOrderCode());
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
JSONObject prepayJson = getPrepayData(requestParams, reponseMap);
|
|
|
logger.info("[{}] response prepayData: {}", orderInfo.getOrderCode(), prepayJson);
|
|
|
log.info("[{}] response prepayData: {}", orderInfo.getOrderCode(), prepayJson);
|
|
|
return prepayJson;
|
|
|
}
|
|
|
|
...
|
...
|
@@ -304,7 +320,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
|
|
|
//签名
|
|
|
//md5签名
|
|
|
String sign = WXUtils.signMd5(paramMap, getMchKey());
|
|
|
String sign = signByMD5(paramMap);
|
|
|
paramMap.put(WeixinPayConfig.ApiConstants.SIGN, sign);
|
|
|
|
|
|
return paramMap;
|
...
|
...
|
@@ -342,7 +358,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
private JSONObject getNativePrepayData(Map<String, String> requestParams, Map<String, String> responseParams) {
|
|
|
String codeUrl = responseParams.get(WeixinPayConfig.ApiConstants.RETURN_CODE_URL);
|
|
|
if(StringUtils.isEmpty(codeUrl)) {
|
|
|
logger.error("[{}] obtain codeUrl failed", requestParams.get(WeixinPayConfig.ApiConstants.OUT_TRADE_NO));
|
|
|
log.error("[{}] obtain codeUrl failed", requestParams.get(WeixinPayConfig.ApiConstants.OUT_TRADE_NO));
|
|
|
return null;
|
|
|
}
|
|
|
JSONObject sendData = new JSONObject();
|
...
|
...
|
@@ -358,7 +374,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
private JSONObject getJSAPIPrepayData(Map<String, String> requestParams, Map<String, String> responseParams) {
|
|
|
String prepayId = responseParams.get(WeixinPayConfig.ApiConstants.RETURN_PREPAY_ID);
|
|
|
if(StringUtils.isEmpty(prepayId)) {
|
|
|
logger.error("[{}] obtain prepayId failed", requestParams.get(WeixinPayConfig.ApiConstants.OUT_TRADE_NO));
|
|
|
log.error("[{}] obtain prepayId failed", requestParams.get(WeixinPayConfig.ApiConstants.OUT_TRADE_NO));
|
|
|
return null;
|
|
|
}
|
|
|
|
...
|
...
|
@@ -371,7 +387,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
signParams.put("timeStamp", timeStamp);
|
|
|
signParams.put("signType", "MD5");
|
|
|
|
|
|
String sign = WXUtils.signMd5(signParams, getMchKey());
|
|
|
String sign = signByMD5(signParams);
|
|
|
|
|
|
JSONObject prepayJson = new JSONObject();
|
|
|
prepayJson.put("timeStamp", signParams.get("timeStamp"));
|
...
|
...
|
@@ -391,7 +407,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
private JSONObject getAppPrepayData(Map<String, String> requestParams, Map<String, String> responseParams) {
|
|
|
String prepayId = responseParams.get(WeixinPayConfig.ApiConstants.RETURN_PREPAY_ID);
|
|
|
if(StringUtils.isEmpty(prepayId)) {
|
|
|
logger.error("[{}] obtain prepayId failed", requestParams.get(WeixinPayConfig.ApiConstants.OUT_TRADE_NO));
|
|
|
log.error("[{}] obtain prepayId failed", requestParams.get(WeixinPayConfig.ApiConstants.OUT_TRADE_NO));
|
|
|
return null;
|
|
|
}
|
|
|
|
...
|
...
|
@@ -405,7 +421,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
prePayData.put("noncestr", requestParams.get(WeixinPayConfig.ApiConstants.NONCE_STR));
|
|
|
prePayData.put("timestamp", timeStamp);
|
|
|
|
|
|
String sign = WXUtils.signMd5(prePayData, getMchKey());
|
|
|
String sign = signByMD5(prePayData);
|
|
|
prePayData.put("sign", sign);
|
|
|
|
|
|
JSONObject sendData = new JSONObject();
|
...
|
...
|
@@ -413,7 +429,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
sendData.put("token", "xxxxx"); //实际上没用,为兼容APP,暂且保留
|
|
|
sendData.put("prePayData", prePayData);
|
|
|
|
|
|
//logger.info("[] weixin prepay data: {}", requestParams.get(WeixinPayConfig.ApiConstants.OUT_TRADE_NO), prePayData);
|
|
|
//log.info("[] weixin prepay data: {}", requestParams.get(WeixinPayConfig.ApiConstants.OUT_TRADE_NO), prePayData);
|
|
|
return sendData;
|
|
|
}
|
|
|
|
...
|
...
|
@@ -426,25 +442,25 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
*/
|
|
|
private boolean checkPrepayResponse(long orderCode, Map<String, String> reponseMap) {
|
|
|
if(reponseMap == null || reponseMap.size() == 0) {
|
|
|
logger.error("[{}] Prepay response parse failed", orderCode);
|
|
|
log.error("[{}] Prepay response parse failed", orderCode);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
String returnCode = reponseMap.get(WeixinPayConfig.ApiConstants.RETURN_CODE);
|
|
|
String resultCode = reponseMap.get(WeixinPayConfig.ApiConstants.RETURN_RESULT_CODE);
|
|
|
if(!WeixinPayConfig.ApiConstants.PREPAY_RESULT_SUCCESS.equals(returnCode)) {
|
|
|
logger.error("[{}] prepay returnCode error: {}", orderCode, returnCode);
|
|
|
log.error("[{}] prepay returnCode error: {}", orderCode, returnCode);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//验证签名
|
|
|
if(!md5SignVerify(reponseMap)){
|
|
|
logger.error("[{}] sign verify failed", orderCode);
|
|
|
log.error("[{}] sign verify failed", orderCode);
|
|
|
return false;
|
|
|
}
|
|
|
//return_code和result_code都为SUCCESS时,返回prepayId
|
|
|
if(!WeixinPayConfig.ApiConstants.PREPAY_RESULT_SUCCESS.equals(resultCode)){
|
|
|
logger.error("[{}] prepay resultCode error: {}", orderCode, resultCode);
|
|
|
log.error("[{}] prepay resultCode error: {}", orderCode, resultCode);
|
|
|
return false;
|
|
|
}
|
|
|
|
...
|
...
|
@@ -461,8 +477,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
if(paramsMap == null)
|
|
|
return false;
|
|
|
|
|
|
return WXUtils.signMd5(paramsMap, getMchKey())
|
|
|
.equals(paramsMap.get(WeixinPayConfig.ApiConstants.SIGN));
|
|
|
return signByMD5(paramsMap).equals(paramsMap.get(WeixinPayConfig.ApiConstants.SIGN));
|
|
|
}
|
|
|
|
|
|
/**
|
...
|
...
|
@@ -472,17 +487,17 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
* @return
|
|
|
*/
|
|
|
private String sendPrepayRequest(long orderCode, String requestXml) {
|
|
|
logger.info("[{}] prepay request: {}", orderCode, requestXml);
|
|
|
log.info("[{}] prepay request: {}", orderCode, requestXml);
|
|
|
|
|
|
String respXml = "";
|
|
|
try {
|
|
|
respXml = httpClient.post(WeixinPayConfig.WEIXIN_PREPAY_URL, requestXml);
|
|
|
} catch (Exception e) {
|
|
|
logger.error("[{}] prepay request failed: {}", orderCode, e.getMessage());
|
|
|
log.error("[{}] prepay request failed: {}", orderCode, e.getMessage());
|
|
|
return respXml;
|
|
|
}
|
|
|
|
|
|
logger.info("[{}] prepay response: {}", orderCode, respXml);
|
|
|
log.info("[{}] prepay response: {}", orderCode, respXml);
|
|
|
return respXml;
|
|
|
}
|
|
|
|
...
|
...
|
@@ -519,7 +534,7 @@ public abstract class AbstractWeixinPayService extends AbstractPayService { |
|
|
}
|
|
|
|
|
|
//md5签名
|
|
|
String sign = WXUtils.signMd5(parameters, getMchKey());
|
|
|
String sign = signByMD5(parameters);
|
|
|
parameters.put(WeixinPayConfig.ApiConstants.SIGN, sign);
|
|
|
|
|
|
return parameters;
|
...
|
...
|
|