|
@@ -8,14 +8,14 @@ import com.github.binarywang.wxpay.bean.request.*;
|
|
|
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryV3Result;
|
|
|
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
|
|
|
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
|
|
|
+import com.github.binarywang.wxpay.constant.WxPayConstants;
|
|
|
import com.github.binarywang.wxpay.exception.WxPayException;
|
|
|
import com.github.binarywang.wxpay.service.WxPayService;
|
|
|
+import com.github.binarywang.wxpay.util.SignUtils;
|
|
|
+import com.yonge.toolset.base.exception.BizException;
|
|
|
import com.yonge.toolset.base.result.BaseResult;
|
|
|
import com.yonge.toolset.payment.base.PaymentTemplate;
|
|
|
-import com.yonge.toolset.payment.base.enums.MethodNameEnum;
|
|
|
-import com.yonge.toolset.payment.base.enums.OpenEnum;
|
|
|
-import com.yonge.toolset.payment.base.enums.PayChannelEnum;
|
|
|
-import com.yonge.toolset.payment.base.enums.TradeStatusEnum;
|
|
|
+import com.yonge.toolset.payment.base.enums.*;
|
|
|
import com.yonge.toolset.payment.base.model.ClosePayment;
|
|
|
import com.yonge.toolset.payment.base.model.OpenAuth;
|
|
|
import com.yonge.toolset.payment.base.model.Payment;
|
|
@@ -47,13 +47,14 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
+import javax.annotation.Resource;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.TimeZone;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.security.PrivateKey;
|
|
|
+import java.security.Signature;
|
|
|
+import java.util.*;
|
|
|
|
|
|
@Component
|
|
|
public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
@@ -66,8 +67,10 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
@Autowired
|
|
|
private SysConfigPaymentService configPaymentService;
|
|
|
|
|
|
- @Autowired
|
|
|
- private WxPayService wxPayService;
|
|
|
+ @Resource(name = "studentWxService")
|
|
|
+ private WxPayService studentWxService;
|
|
|
+ @Resource(name = "teacherWxService")
|
|
|
+ private WxPayService teacherWxService;
|
|
|
|
|
|
@Override
|
|
|
public BaseResult<Map<String, Object>> getOpenAuthMsg(OpenAuth openAuth) {
|
|
@@ -86,6 +89,7 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
request.setOutTradeNo(payment.getPaymentNo());
|
|
|
request.setNotifyUrl(paymentProperties.getNotifyUrl()
|
|
|
+ "/" + payment.getOpenType().getCode()
|
|
|
+ + "/" + payment.getPaymentClient().getCode()
|
|
|
+ "/" + payment.getPayChannel().getCode()
|
|
|
+ "/executePayment");
|
|
|
|
|
@@ -100,8 +104,20 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
request.setAmount(amount);
|
|
|
|
|
|
try {
|
|
|
- Object orderV3 = wxPayService.createOrderV3(TradeTypeEnum.APP, request);
|
|
|
- payment.setPayInfo(JSONObject.toJSONString(orderV3));
|
|
|
+ Object orderV3 = getWxPayService(payment.getPaymentClient())
|
|
|
+ .createOrderV3(TradeTypeEnum.APP, request);
|
|
|
+ Map<String, String> stringStringMap = SignUtils.xmlBean2Map(orderV3);
|
|
|
+ String msg = buildMessage(
|
|
|
+ APP_ID,
|
|
|
+ Long.parseLong(stringStringMap.get("timestamp")),
|
|
|
+ stringStringMap.get("noncestr"),
|
|
|
+ stringStringMap.get("prepayid")
|
|
|
+ );
|
|
|
+
|
|
|
+ String sign = sign(msg.getBytes(StandardCharsets.UTF_8), payment.getPaymentClient());
|
|
|
+ stringStringMap.put("sign", sign);
|
|
|
+
|
|
|
+ payment.setPayInfo(JSONObject.toJSONString(stringStringMap));
|
|
|
|
|
|
BaseResult<Payment> paymentBaseResult = queryPayment(payment);
|
|
|
if (paymentBaseResult.getStatus()) {
|
|
@@ -129,7 +145,8 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
param.setOutTradeNo(payment.getPaymentNo());
|
|
|
|
|
|
try {
|
|
|
- WxPayOrderQueryV3Result res = wxPayService.queryOrderV3(param);
|
|
|
+ WxPayOrderQueryV3Result res = getWxPayService(payment.getPaymentClient())
|
|
|
+ .queryOrderV3(param);
|
|
|
|
|
|
payment.setId(res.getTransactionId());
|
|
|
String tradeState = res.getTradeState();
|
|
@@ -154,7 +171,7 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
|
|
|
@Override
|
|
|
public BaseResult<ClosePayment> closePayment(ClosePayment closePayment) {
|
|
|
- if(StringUtil.isEmpty(closePayment.getPaymentNo())){
|
|
|
+ if (StringUtil.isEmpty(closePayment.getPaymentNo())) {
|
|
|
return BaseResult.failed("缺失渠道关单必要参数");
|
|
|
}
|
|
|
|
|
@@ -165,7 +182,8 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
param.setOutTradeNo(closePayment.getPaymentNo());
|
|
|
|
|
|
try {
|
|
|
- wxPayService.closeOrderV3(param);
|
|
|
+ getWxPayService(closePayment.getPaymentClient())
|
|
|
+ .closeOrderV3(param);
|
|
|
closePayment.setStatus(TradeStatusEnum.succeeded);
|
|
|
return BaseResult.succeed(closePayment);
|
|
|
} catch (WxPayException e) {
|
|
@@ -187,6 +205,7 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
|
|
|
param.setNotifyUrl(paymentProperties.getNotifyUrl()
|
|
|
+ "/" + refundBill.getOpenType().getCode()
|
|
|
+ + "/" + refundBill.getPaymentClient().getCode()
|
|
|
+ "/" + refundBill.getPayChannel().getCode()
|
|
|
+ "/refundPayment");
|
|
|
|
|
@@ -201,7 +220,8 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
param.setAmount(amount);
|
|
|
|
|
|
try {
|
|
|
- WxPayRefundV3Result res = wxPayService.refundV3(param);
|
|
|
+ WxPayRefundV3Result res = getWxPayService(refundBill.getPaymentClient())
|
|
|
+ .refundV3(param);
|
|
|
|
|
|
String refund_id = res.getRefundId();
|
|
|
refundBill.setId(refund_id);
|
|
@@ -216,7 +236,7 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public BaseResult<PaymentCallBack> analysisNotice(OpenEnum openType, PayChannelEnum payChannel, MethodNameEnum methodName, HttpServletRequest request) {
|
|
|
+ public BaseResult<PaymentCallBack> analysisNotice(OpenEnum openType, PaymentClientEnum paymentClient, PayChannelEnum payChannel, MethodNameEnum methodName, HttpServletRequest request) {
|
|
|
//支付回调
|
|
|
SignatureHeader header = new SignatureHeader();
|
|
|
header.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
|
|
@@ -234,7 +254,7 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
Map<String, Object> resMsg = new HashMap<>();
|
|
|
try {
|
|
|
if (MethodNameEnum.executePayment.equals(methodName)) {
|
|
|
- WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = wxPayService.parseOrderNotifyV3Result(params, header);
|
|
|
+ WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = getWxPayService(paymentClient).parseOrderNotifyV3Result(params, header);
|
|
|
log.info("微信APP回调-支付请求:{}", JSONObject.toJSONString(wxPayOrderNotifyV3Result));
|
|
|
|
|
|
//封装支付回调对象
|
|
@@ -254,16 +274,16 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
}
|
|
|
|
|
|
ExecutePaymentCallBack executePayment = new ExecutePaymentCallBack();
|
|
|
- if(!StringUtil.isEmpty(result.getAmount().getTotal())){
|
|
|
+ if (!StringUtil.isEmpty(result.getAmount().getTotal())) {
|
|
|
executePayment.setPayAmt(new BigDecimal(result.getAmount().getTotal()).divide(new BigDecimal("100")).toString());
|
|
|
}
|
|
|
- if(!StringUtil.isEmpty(result.getSuccessTime())){
|
|
|
+ if (!StringUtil.isEmpty(result.getSuccessTime())) {
|
|
|
Date date = new DateTime(result.getSuccessTime()).toDate();
|
|
|
executePayment.setTradeTime(date);
|
|
|
}
|
|
|
paymentCallBack.setExecutePaymentCallBack(executePayment);
|
|
|
} else if (MethodNameEnum.refundPayment.equals(methodName)) {
|
|
|
- WxPayRefundNotifyV3Result wxPayRefundNotifyV3Result = wxPayService.parseRefundNotifyV3Result(params, header);
|
|
|
+ WxPayRefundNotifyV3Result wxPayRefundNotifyV3Result = getWxPayService(paymentClient).parseRefundNotifyV3Result(params, header);
|
|
|
log.info("微信APP回调-退款请求:{}", JSONObject.toJSONString(wxPayRefundNotifyV3Result));
|
|
|
//封装退款回调对象
|
|
|
WxPayRefundNotifyV3Result.DecryptNotifyResult result = wxPayRefundNotifyV3Result.getResult();
|
|
@@ -286,7 +306,7 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
refundPayment.setTransNo(result.getRefundId());
|
|
|
refundPayment.setRefundAmt(result.getAmount().getRefund());
|
|
|
|
|
|
- if(!StringUtil.isEmpty(result.getSuccessTime())){
|
|
|
+ if (!StringUtil.isEmpty(result.getSuccessTime())) {
|
|
|
Date date = new DateTime(result.getSuccessTime()).toDate();
|
|
|
refundPayment.setTradeTime(date);
|
|
|
}
|
|
@@ -309,4 +329,29 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
|
|
|
return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "解析异常");
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ String sign(byte[] message, PaymentClientEnum paymentClient) throws Exception {
|
|
|
+ Signature sign = Signature.getInstance("SHA256withRSA");
|
|
|
+ PrivateKey privateKey = getWxPayService(paymentClient).getConfig().getPrivateKey();
|
|
|
+ sign.initSign(privateKey);
|
|
|
+ sign.update(message);
|
|
|
+ return Base64.getEncoder().encodeToString(sign.sign());
|
|
|
+ }
|
|
|
+
|
|
|
+ String buildMessage(String appid, long timestamp, String nonceStr, String prepay_id) {
|
|
|
+ return appid + "\n"
|
|
|
+ + timestamp + "\n"
|
|
|
+ + nonceStr + "\n"
|
|
|
+ + prepay_id + "\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ private WxPayService getWxPayService(PaymentClientEnum paymentClient) {
|
|
|
+ if (PaymentClientEnum.STUDENT.equals(paymentClient)) {
|
|
|
+ return this.studentWxService;
|
|
|
+ }
|
|
|
+ if (PaymentClientEnum.TEACHER.equals(paymentClient)) {
|
|
|
+ return this.teacherWxService;
|
|
|
+ }
|
|
|
+ throw new BizException("未知的客户端类型");
|
|
|
+ }
|
|
|
}
|