package com.ruoyi.order.controller.miniapp;
|
|
import com.github.binarywang.wxpay.bean.ecommerce.*;
|
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Response;
|
import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingNotifyData;
|
import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingNotifyResult;
|
import com.github.binarywang.wxpay.exception.WxPayException;
|
import com.github.binarywang.wxpay.service.ProfitSharingV3Service;
|
import com.github.binarywang.wxpay.service.WxPayService;
|
import com.github.binarywang.wxpay.v3.auth.Verifier;
|
import com.github.binarywang.wxpay.v3.util.AesUtils;
|
import com.google.gson.Gson;
|
import com.google.gson.GsonBuilder;
|
import com.ruoyi.common.core.web.controller.BaseController;
|
import com.ruoyi.order.domain.vo.ProfitSharingNotifyNewResult;
|
import com.ruoyi.order.enums.WxPayNotifyEventTypeEnum;
|
import com.ruoyi.order.service.account.BackMessageService;
|
import com.ruoyi.order.service.order.OrderService;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import lombok.extern.log4j.Log4j2;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.bind.annotation.*;
|
|
import javax.annotation.Resource;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.IOException;
|
import java.nio.charset.StandardCharsets;
|
import java.security.GeneralSecurityException;
|
import java.util.Collection;
|
import java.util.Enumeration;
|
import java.util.Map;
|
import java.util.Objects;
|
|
/**
|
* @program: ruoyi
|
* @author: linqingsong
|
* @create: 2023-07-22 17:20
|
* @description: 成都软思同创科技有限公司
|
**/
|
@Api(value = "微信通知控制", tags = "微信通知控制", description = "微信通知控制")
|
@RestController
|
@RequestMapping("/app/notify")
|
@Log4j2
|
public class NotifyController extends BaseController {
|
|
public static final String WECHAT_PAY_SERIAL = "Wechatpay-Serial";
|
public static final String WECHAT_PAY_SIGNATURE = "Wechatpay-Signature";
|
public static final String WECHAT_PAY_TIMESTAMP = "Wechatpay-Timestamp";
|
public static final String WECHAT_PAY_NONCE = "Wechatpay-Nonce";
|
|
private static final Gson GSON = new GsonBuilder().create();
|
|
@Resource
|
private OrderService orderService;
|
|
@Resource
|
private WxPayService wxService;
|
@Resource
|
private BackMessageService backMessageService;
|
|
@PostMapping(value = "/payNotify")
|
@ApiOperation(value = "微信支付/退款通知")
|
public String payNotify(@RequestBody String notifyData, HttpServletRequest request, HttpServletResponse response) throws WxPayException {
|
|
// 获取请求头
|
SignatureHeader signatureHeader = getSignatureHeader(request);
|
|
log.info("微信支付/退款通知: {}", notifyData);
|
|
NotifyResponse responseData = GSON.fromJson(notifyData, NotifyResponse.class);
|
String eventType = responseData.getEventType();
|
|
int resultType = 1;
|
String resultMessage = notifyData;
|
|
try {
|
if (WxPayNotifyEventTypeEnum.TRANSACTION_SUCCESS.getCode().equals(eventType)) {
|
PartnerTransactionsNotifyResult notifyResult = wxService.getEcommerceService().parsePartnerNotifyResult(notifyData, signatureHeader);
|
PartnerTransactionsResult result = notifyResult.getResult();
|
// 支付通知回调
|
if ("SUCCESS".equals(result.getTradeState())) {
|
orderService.payBack(result);
|
}
|
resultMessage = GSON.toJson(notifyResult);
|
} else if (WxPayNotifyEventTypeEnum.REFUND_SUCCESS.getCode().equals(eventType)
|
|| WxPayNotifyEventTypeEnum.REFUND_ABNORMAL.getCode().equals(eventType)
|
|| WxPayNotifyEventTypeEnum.REFUND_CLOSED.getCode().equals(eventType)) {
|
|
RefundNotifyResult result = wxService.getEcommerceService().parseRefundNotifyResult(notifyData, signatureHeader);
|
orderService.orderRefundBack(result);
|
resultType = 2;
|
resultMessage = GSON.toJson(result);
|
}
|
|
}catch (Exception e){
|
log.info("微信支付/退款通知异常: {}", e.getMessage());
|
}
|
// 保存支付/退款回调信息
|
backMessageService.saveBackMessage(resultType, resultMessage);
|
return WxPayNotifyV3Response.success("成功");
|
}
|
|
@PostMapping(value = "/profitSharingNotify")
|
@ApiOperation(value = "微信分账通知")
|
public String profitSharingNotify(@RequestBody String notifyData, HttpServletRequest request, HttpServletResponse response) throws WxPayException {
|
ProfitSharingV3Service sharingV3Service = wxService.getProfitSharingV3Service();
|
// ProfitSharingNotifyResult
|
log.info("微信分账通知: {}", notifyData);
|
|
// 获取请求头
|
SignatureHeader signatureHeader = getSignatureHeader(request);
|
|
ProfitSharingNotifyNewResult notifyResult = getProfitSharingNotifyData(notifyData, signatureHeader);
|
ProfitSharingNotifyResult result = notifyResult.getResult();
|
String eventType = "-1";
|
String resultMessage = notifyData;
|
try {
|
eventType = notifyResult.getRawData().getEventType();
|
if (WxPayNotifyEventTypeEnum.PROFIT_SHARING_SUCCESS.getCode().equals(eventType)) {
|
// 分账通知回调
|
orderService.profitSharingBack(result);
|
}
|
|
resultMessage = GSON.toJson(notifyResult);
|
}catch (Exception e){
|
log.info("微信分账通知通知异常: {}", e.getMessage());
|
}
|
// 保存记录分账回调信息
|
backMessageService.saveBackMessage(3, resultMessage);
|
|
return WxPayNotifyV3Response.success("成功");
|
}
|
|
@RequestMapping(value = "/shareNotify", method = RequestMethod.POST)
|
@ApiOperation(value = "微信支付通知")
|
public Map shareNotify(HttpServletRequest request, HttpServletResponse response) {
|
|
return null;
|
}
|
|
public ProfitSharingNotifyNewResult getProfitSharingNotifyData(String notifyData, SignatureHeader header) throws WxPayException {
|
if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) {
|
throw new WxPayException("非法请求,头部信息验证失败");
|
}
|
ProfitSharingNotifyData response = GSON.fromJson(notifyData, ProfitSharingNotifyData.class);
|
|
ProfitSharingNotifyData.Resource resource = response.getResource();
|
String cipherText = resource.getCipherText();
|
String associatedData = resource.getAssociatedData();
|
String nonce = resource.getNonce();
|
String apiV3Key = this.wxService.getConfig().getApiV3Key();
|
try {
|
String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key);
|
ProfitSharingNotifyResult profitSharingResult = GSON.fromJson(result, ProfitSharingNotifyResult.class);
|
|
ProfitSharingNotifyNewResult notifyResult = new ProfitSharingNotifyNewResult();
|
notifyResult.setRawData(response);
|
notifyResult.setResult(profitSharingResult);
|
return notifyResult;
|
} catch (GeneralSecurityException | IOException e) {
|
throw new WxPayException("解析报文异常!", e);
|
}
|
}
|
|
private boolean verifyNotifySign(SignatureHeader header, String data) throws WxPayException {
|
String beforeSign = String.format("%s\n%s\n%s\n",
|
header.getTimeStamp(),
|
header.getNonce(),
|
data);
|
Verifier verifier = this.wxService.getConfig().getVerifier();
|
if (verifier == null) {
|
throw new WxPayException("证书检验对象为空");
|
}
|
return verifier.verify(header.getSerialNo(),
|
beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned());
|
}
|
|
private SignatureHeader getSignatureHeader(HttpServletRequest request){
|
SignatureHeader signatureHeader = new SignatureHeader();
|
signatureHeader.setSerialNo(request.getHeader(WECHAT_PAY_SERIAL));
|
signatureHeader.setSigned(request.getHeader(WECHAT_PAY_SIGNATURE));
|
signatureHeader.setNonce(request.getHeader(WECHAT_PAY_NONCE));
|
signatureHeader.setTimeStamp(request.getHeader(WECHAT_PAY_TIMESTAMP));
|
|
log.info("timeStamp:{} nonce : {} signed:{} serialNo:{}",
|
signatureHeader.getTimeStamp(),
|
signatureHeader.getNonce(),
|
signatureHeader.getSigned(),
|
signatureHeader.getSerialNo());
|
|
return signatureHeader;
|
}
|
}
|