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 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.Map;
|
import java.util.Objects;
|
|
/**
|
* @program: ruoyi
|
* @author: linqingsong
|
* @create: 2023-07-22 17:20
|
* @description: 成都软思同创科技有限公司
|
**/
|
@Api(value = "微信通知控制", tags = "微信通知控制", description = "微信通知控制")
|
@RestController
|
@RequestMapping("/app/notify")
|
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(response);
|
|
NotifyResponse responseData = GSON.fromJson(notifyData, NotifyResponse.class);
|
String eventType = responseData.getEventType();
|
|
int resultType = 1;
|
String resultMessage = "";
|
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);
|
}
|
// 保存支付/退款回调信息
|
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
|
|
// 获取请求头
|
SignatureHeader signatureHeader = getSignatureHeader(response);
|
|
|
ProfitSharingNotifyNewResult notifyResult = getProfitSharingNotifyData(notifyData, signatureHeader);
|
ProfitSharingNotifyResult result = notifyResult.getResult();
|
|
String eventType = notifyResult.getRawData().getEventType();
|
if(WxPayNotifyEventTypeEnum.PROFIT_SHARING_SUCCESS.getCode().equals(eventType)){
|
// 分账通知回调
|
orderService.profitSharingBack(result);
|
}
|
|
String resultMessage = GSON.toJson(notifyResult);
|
// 保存记录分账回调信息
|
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(HttpServletResponse response){
|
SignatureHeader signatureHeader = new SignatureHeader();
|
signatureHeader.setSerialNo(response.getHeader(WECHAT_PAY_SERIAL));
|
signatureHeader.setSigned(response.getHeader(WECHAT_PAY_SIGNATURE));
|
signatureHeader.setNonce(response.getHeader(WECHAT_PAY_NONCE));
|
signatureHeader.setTimeStamp(response.getHeader(WECHAT_PAY_TIMESTAMP));
|
return signatureHeader;
|
}
|
}
|