|
@@ -1,18 +1,23 @@
|
|
package com.miaxis.app.controller.film;
|
|
package com.miaxis.app.controller.film;
|
|
|
|
|
|
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.miaxis.common.config.WxpayConfig;
|
|
import com.miaxis.common.config.WxpayConfig;
|
|
import com.miaxis.common.constant.Constants;
|
|
import com.miaxis.common.constant.Constants;
|
|
import com.miaxis.common.core.domain.Response;
|
|
import com.miaxis.common.core.domain.Response;
|
|
import com.miaxis.common.exception.CustomException;
|
|
import com.miaxis.common.exception.CustomException;
|
|
import com.miaxis.common.utils.AesUtil;
|
|
import com.miaxis.common.utils.AesUtil;
|
|
|
|
+import com.miaxis.common.utils.uuid.CommonUtils;
|
|
import com.miaxis.feign.dto.FilmDTO;
|
|
import com.miaxis.feign.dto.FilmDTO;
|
|
|
|
+import com.miaxis.feign.dto.FilmMcpData;
|
|
|
|
+import com.miaxis.feign.dto.FilmXdResult;
|
|
import com.miaxis.film.domain.FilmOrder;
|
|
import com.miaxis.film.domain.FilmOrder;
|
|
import com.miaxis.film.domain.RefundRecord;
|
|
import com.miaxis.film.domain.RefundRecord;
|
|
import com.miaxis.film.dto.*;
|
|
import com.miaxis.film.dto.*;
|
|
import com.miaxis.film.service.IFilmOrderService;
|
|
import com.miaxis.film.service.IFilmOrderService;
|
|
import com.miaxis.film.service.IRefundRecordService;
|
|
import com.miaxis.film.service.IRefundRecordService;
|
|
|
|
+import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
|
|
import io.swagger.annotations.Api;
|
|
import io.swagger.annotations.Api;
|
|
import io.swagger.annotations.ApiOperation;
|
|
import io.swagger.annotations.ApiOperation;
|
|
import lombok.Data;
|
|
import lombok.Data;
|
|
@@ -21,8 +26,10 @@ import lombok.extern.slf4j.Slf4j;
|
|
import org.joda.time.DateTime;
|
|
import org.joda.time.DateTime;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
+import org.springframework.core.io.ClassPathResource;
|
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
+import org.springframework.util.Base64Utils;
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
@@ -30,8 +37,12 @@ import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import java.io.BufferedReader;
|
|
import java.io.BufferedReader;
|
|
|
|
+import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
-import java.security.GeneralSecurityException;
|
|
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
+import java.security.*;
|
|
|
|
+import java.security.cert.X509Certificate;
|
|
|
|
+import java.util.Base64;
|
|
|
|
|
|
import static com.miaxis.common.utils.OrderCodeFactory.getOrderCode;
|
|
import static com.miaxis.common.utils.OrderCodeFactory.getOrderCode;
|
|
|
|
|
|
@@ -56,6 +67,9 @@ public class NotifyController {
|
|
@Autowired
|
|
@Autowired
|
|
private IRefundRecordService refundRecordService;
|
|
private IRefundRecordService refundRecordService;
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private AutoUpdateCertificatesVerifier verifier;
|
|
|
|
+
|
|
|
|
|
|
@Value("${film.notifyUrl}")
|
|
@Value("${film.notifyUrl}")
|
|
private String notifyUrl ;
|
|
private String notifyUrl ;
|
|
@@ -65,11 +79,14 @@ public class NotifyController {
|
|
*/
|
|
*/
|
|
@PostMapping(value = "/wxpay")
|
|
@PostMapping(value = "/wxpay")
|
|
@ApiOperation("微信支付回调")
|
|
@ApiOperation("微信支付回调")
|
|
- public WxNotifyReturnDTO wxpayNotify(@RequestBody FilmWxpayDTO filmWxpayDTO, HttpServletRequest request, BufferedReader br) throws GeneralSecurityException, IOException {
|
|
|
|
- String bodyString = getBodyString(br);
|
|
|
|
- System.out.println(bodyString);
|
|
|
|
- Boolean pass = validate(request);
|
|
|
|
|
|
+ public WxNotifyReturnDTO wxpayNotify(@RequestBody FilmWxpayDTO filmWxpayDTO, HttpServletRequest request) throws GeneralSecurityException, IOException {
|
|
|
|
|
|
|
|
+ String bodyString = getBodyString(request);
|
|
|
|
+ System.out.println(bodyString);
|
|
|
|
+ Boolean pass = validate(request,bodyString);
|
|
|
|
+ if (!pass){
|
|
|
|
+ throw new CustomException("签名失败");
|
|
|
|
+ }
|
|
String resourceString = getSourString(filmWxpayDTO);
|
|
String resourceString = getSourString(filmWxpayDTO);
|
|
log.info(resourceString);
|
|
log.info(resourceString);
|
|
JSONObject jsonObject = JSONObject.parseObject(resourceString);
|
|
JSONObject jsonObject = JSONObject.parseObject(resourceString);
|
|
@@ -82,48 +99,60 @@ public class NotifyController {
|
|
return wxNotifyReturnDTO;
|
|
return wxNotifyReturnDTO;
|
|
}
|
|
}
|
|
|
|
|
|
- private String getBodyString(BufferedReader br) {
|
|
|
|
- String inputLine;
|
|
|
|
-
|
|
|
|
- String str = "";
|
|
|
|
-
|
|
|
|
- try {
|
|
|
|
- while ((inputLine = br.readLine()) != null) {
|
|
|
|
- str += inputLine;
|
|
|
|
-
|
|
|
|
|
|
+ private String getBodyString(HttpServletRequest request) {
|
|
|
|
+ BufferedReader br = null;
|
|
|
|
+ StringBuilder sb = new StringBuilder("");
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ br = request.getReader();
|
|
|
|
+ String str;
|
|
|
|
+ while ((str = br.readLine()) != null)
|
|
|
|
+ {
|
|
|
|
+ sb.append(str);
|
|
|
|
+ }
|
|
|
|
+ br.close();
|
|
}
|
|
}
|
|
|
|
+ catch (IOException e)
|
|
|
|
+ {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ finally
|
|
|
|
+ {
|
|
|
|
+ if (null != br)
|
|
|
|
+ {
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ br.close();
|
|
|
|
+ }
|
|
|
|
+ catch (IOException e)
|
|
|
|
+ {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return sb.toString();
|
|
|
|
|
|
- br.close();
|
|
|
|
-
|
|
|
|
- } catch (IOException e) {
|
|
|
|
- System.out.println("IOException: " + e);
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- return str;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- private Boolean validate(HttpServletRequest request) {
|
|
|
|
|
|
+ private Boolean validate(HttpServletRequest request, String bodyString) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
|
|
String sign = request.getHeader("Wechatpay-Signature");
|
|
String sign = request.getHeader("Wechatpay-Signature");
|
|
String timestamp = request.getHeader("Wechatpay-Timestamp");
|
|
String timestamp = request.getHeader("Wechatpay-Timestamp");
|
|
String nonce = request.getHeader("Wechatpay-Nonce");
|
|
String nonce = request.getHeader("Wechatpay-Nonce");
|
|
|
|
|
|
-
|
|
|
|
StringBuffer sb = new StringBuffer();
|
|
StringBuffer sb = new StringBuffer();
|
|
sb.append(timestamp + "\n");
|
|
sb.append(timestamp + "\n");
|
|
sb.append(nonce + "\n");
|
|
sb.append(nonce + "\n");
|
|
- System.out.println(sb);
|
|
|
|
- return true;
|
|
|
|
-
|
|
|
|
-// File file = new ClassPathResource("wechatpay/apiclient_key.pem").getFile();
|
|
|
|
-// String realPath =file.getAbsolutePath();
|
|
|
|
-// PrivateKey privateKey = CommonUtils.getPrivateKey(realPath);
|
|
|
|
-// // 进行签名服务
|
|
|
|
-// Signature signature = Signature.getInstance("SHA256withRSA");
|
|
|
|
-// signature.initSign(privateKey);
|
|
|
|
-// signature.update(sb.toString().getBytes("UTF-8"));
|
|
|
|
-// byte[] signedData = signature.sign();
|
|
|
|
-// String base64Str = Base64.getEncoder().encodeToString(signedData);
|
|
|
|
-
|
|
|
|
|
|
+ sb.append(bodyString + "\n");
|
|
|
|
+ X509Certificate validCertificate = verifier.getValidCertificate();
|
|
|
|
+ // 进行签名服务
|
|
|
|
+ Signature signature = Signature.getInstance("SHA256withRSA");
|
|
|
|
+ // 用微信平台公钥对签名器进行初始化
|
|
|
|
+ signature.initVerify(validCertificate);
|
|
|
|
+ // 把我们构造的验签名串更新到签名器中
|
|
|
|
+ signature.update(sb.toString().getBytes(StandardCharsets.UTF_8));
|
|
|
|
+ Boolean result = signature.verify(Base64Utils.decodeFromString(sign));
|
|
|
|
+ log.info("微信支付回调验签:"+result.toString());
|
|
|
|
+ return result;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -285,34 +314,60 @@ public class NotifyController {
|
|
threadPoolTaskExecutor.execute(new Runnable() {
|
|
threadPoolTaskExecutor.execute(new Runnable() {
|
|
@Override
|
|
@Override
|
|
public void run() {
|
|
public void run() {
|
|
|
|
+ FilmOrderCreateDTO filmOrderCreateDTO = filmOrderJsonData.getFilmOrderCreateDTO();
|
|
FilmDTO filmDTO = new FilmDTO();
|
|
FilmDTO filmDTO = new FilmDTO();
|
|
- filmDTO.setUrl("api/order/create");
|
|
|
|
|
|
+ if (filmOrderCreateDTO.getTicketType() ==1){
|
|
|
|
+ filmDTO.setUrl("api/order/create");
|
|
|
|
+ }else if (filmOrderCreateDTO.getTicketType() ==2){
|
|
|
|
+ filmDTO.setUrl("api/order/create-soon-order");
|
|
|
|
+ }
|
|
|
|
+
|
|
StringBuffer paramData = new StringBuffer();
|
|
StringBuffer paramData = new StringBuffer();
|
|
- FilmOrderCreateDTO filmOrder = filmOrderJsonData.getFilmOrderCreateDTO();
|
|
|
|
- paramData.append("showId="+filmOrder.getShowId()+"&");
|
|
|
|
- paramData.append("seat="+filmOrder.getSeat()+"&");
|
|
|
|
- if (filmOrder.getReservedPhone() != null){
|
|
|
|
- paramData.append("reservedPhone="+filmOrder.getReservedPhone()+"&");
|
|
|
|
|
|
+ paramData.append("showId="+filmOrderCreateDTO.getShowId()+"&");
|
|
|
|
+ paramData.append("seat="+filmOrderCreateDTO.getSeat()+"&");
|
|
|
|
+ if (filmOrderCreateDTO.getReservedPhone() != null){
|
|
|
|
+ paramData.append("reservedPhone="+filmOrderCreateDTO.getReservedPhone()+"&");
|
|
}
|
|
}
|
|
- paramData.append("thirdOrderId="+filmOrder.getThirdOrderId()+"&");
|
|
|
|
|
|
+ paramData.append("thirdOrderId="+filmOrderCreateDTO.getThirdOrderId()+"&");
|
|
paramData.append("notifyUrl="+notifyUrl+"&");
|
|
paramData.append("notifyUrl="+notifyUrl+"&");
|
|
- if (filmOrder.getSeatId() != null){
|
|
|
|
- paramData.append("seatId="+filmOrder.getSeatId()+"&");
|
|
|
|
|
|
+ if (filmOrderCreateDTO.getSeatId() != null){
|
|
|
|
+ paramData.append("seatId="+filmOrderCreateDTO.getSeatId()+"&");
|
|
}
|
|
}
|
|
- if (filmOrder.getSeatNo() != null){
|
|
|
|
- paramData.append("seatNo="+filmOrder.getSeatNo()+"&");
|
|
|
|
|
|
+ if (filmOrderCreateDTO.getSeatNo() != null){
|
|
|
|
+ paramData.append("seatNo="+filmOrderCreateDTO.getSeatNo()+"&");
|
|
}
|
|
}
|
|
- paramData.append("acceptChangeSeat="+filmOrder.getAcceptChangeSeat());
|
|
|
|
|
|
+ paramData.append("acceptChangeSeat="+filmOrderCreateDTO.getAcceptChangeSeat());
|
|
filmDTO.setParamData(paramData.toString());
|
|
filmDTO.setParamData(paramData.toString());
|
|
|
|
|
|
String s = filmOrderService.excuteFilmApi(filmDTO);
|
|
String s = filmOrderService.excuteFilmApi(filmDTO);
|
|
log.info("电影下单返回值:"+s);
|
|
log.info("电影下单返回值:"+s);
|
|
|
|
+ FilmXdResult filmXdResult = JSONObject.parseObject(s, FilmXdResult.class);
|
|
|
|
+ //如果返回值不是200 ,则调用退款流程
|
|
|
|
+ if (filmXdResult.getCode()!=200){
|
|
|
|
+ String refundCode = getOrderCode(null);
|
|
|
|
+ filmOrder.setOutRefundNo(refundCode);
|
|
|
|
+ try {
|
|
|
|
+ refundRecordService.refund(filmOrder,refundCode);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ if (filmXdResult.getData()!= null){
|
|
|
|
+ FilmMcpData filmMcpData = filmXdResult.getData();
|
|
|
|
+ filmOrderJsonData.setFilmMcpData(filmMcpData);
|
|
|
|
+ filmOrder.setOrderDataJson(JSONObject.toJSONString(filmOrderJsonData));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ filmOrderService.updateById(filmOrder);
|
|
|
|
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- filmOrderService.updateById(filmOrder);
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
private String getSourString(FilmWxpayDTO filmWxpayDTO) throws GeneralSecurityException, IOException {
|
|
private String getSourString(FilmWxpayDTO filmWxpayDTO) throws GeneralSecurityException, IOException {
|