package com.doumee.api.web;
|
|
import com.doumee.config.wx.WxMiniConfig;
|
import com.doumee.config.wx.WxPayV3Service;
|
import com.doumee.core.constants.Constants;
|
import com.doumee.core.utils.ID;
|
import com.doumee.dao.business.OrdersRefundMapper;
|
import com.doumee.dao.business.OrdersMapper;
|
import com.doumee.dao.business.model.Notice;
|
import com.doumee.dao.business.model.Orders;
|
import com.doumee.dao.business.model.OrdersRefund;
|
import com.doumee.service.business.NoticeService;
|
import com.doumee.service.business.OrdersService;
|
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
|
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
|
import com.wechat.pay.java.service.payments.model.Transaction;
|
import com.wechat.pay.java.service.refund.model.RefundNotification;
|
import com.wechat.pay.java.service.refund.model.Status;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.bind.annotation.*;
|
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* 支付回调
|
*
|
* @Author : Rk
|
* @create 2023/3/24 16:57
|
*/
|
@Slf4j
|
@RestController
|
@CrossOrigin
|
public class PaymentCallback extends ApiController {
|
|
@Autowired
|
private OrdersService ordersService;
|
|
@Autowired
|
private WxPayV3Service wxPayV3Service;
|
|
@Autowired
|
private OrdersRefundMapper ordersRefundMapper;
|
|
@Autowired
|
private OrdersMapper ordersMapper;
|
|
@Autowired
|
private NoticeService noticeService;
|
|
|
// ==================== V2 回调 ====================
|
|
@PostMapping("/web/api/wxPayNotify")
|
public String wxPay_notify(@RequestBody String xmlResult) {
|
String wxId = ID.nextGUID();
|
log.info("V2支付回调信息(" + wxId + ") => " + xmlResult);
|
if (StringUtils.isEmpty(xmlResult)) {
|
return null;
|
}
|
try {
|
WxPayOrderNotifyResult result = WxMiniConfig.wxPayService.parseOrderNotifyResult(xmlResult);
|
String outTradeNo = result.getOutTradeNo();
|
String paymentNo = result.getTransactionId();
|
|
if (Constants.SUCCESS.equals(result.getReturnCode())) {
|
switch (result.getAttach()) {
|
case "storageOrder": {
|
ordersService.handleStorageOrderPayNotify(outTradeNo, paymentNo);
|
break;
|
}
|
case "shopDeposit": {
|
ordersService.handleShopDepositPayNotify(outTradeNo, paymentNo);
|
break;
|
}
|
case "overdueFee": {
|
ordersService.handleOverdueFeePayNotify(outTradeNo, paymentNo);
|
break;
|
}
|
}
|
return WxPayNotifyResponse.success("处理成功!");
|
}
|
return WxPayNotifyResponse.fail(result.getReturnMsg());
|
} catch (Exception e) {
|
e.printStackTrace();
|
log.error("V2微信回调结果异常,异常原因{}", e.getLocalizedMessage());
|
return WxPayNotifyResponse.fail(e.getMessage());
|
}
|
}
|
|
// ==================== V3 回调 ====================
|
|
/**
|
* V3支付回调
|
*/
|
@PostMapping("/web/api/wxPayV3Notify")
|
public Map<String, String> wxPayV3Notify(
|
@RequestHeader("Wechatpay-Serial") String serialNumber,
|
@RequestHeader("Wechatpay-Timestamp") String timestamp,
|
@RequestHeader("Wechatpay-Nonce") String nonce,
|
@RequestHeader("Wechatpay-Signature") String signature,
|
@RequestBody String body) {
|
String wxId = ID.nextGUID();
|
log.info("V3支付回调信息({}) => {}", wxId, body);
|
try {
|
Transaction transaction = wxPayV3Service.parsePayNotify(
|
serialNumber, timestamp, nonce, signature, body);
|
|
String outTradeNo = transaction.getOutTradeNo();
|
String paymentNo = transaction.getTransactionId();
|
|
if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
|
String attach = transaction.getAttach();
|
if (StringUtils.isNotBlank(attach)) {
|
switch (attach) {
|
case "storageOrder":
|
ordersService.handleStorageOrderPayNotify(outTradeNo, paymentNo);
|
break;
|
case "shopDeposit":
|
ordersService.handleShopDepositPayNotify(outTradeNo, paymentNo);
|
break;
|
case "overdueFee":
|
ordersService.handleOverdueFeePayNotify(outTradeNo, paymentNo);
|
break;
|
}
|
}
|
}
|
|
Map<String, String> response = new HashMap<>();
|
response.put("code", "SUCCESS");
|
response.put("message", "处理成功");
|
return response;
|
} catch (Exception e) {
|
log.error("V3支付回调异常,异常原因{}", e.getLocalizedMessage());
|
Map<String, String> response = new HashMap<>();
|
response.put("code", "FAIL");
|
response.put("message", e.getMessage());
|
return response;
|
}
|
}
|
|
/**
|
* V3退款回调
|
*/
|
@PostMapping("/web/api/wxRefundV3Notify")
|
public Map<String, String> wxRefundV3Notify(
|
@RequestHeader("Wechatpay-Serial") String serialNumber,
|
@RequestHeader("Wechatpay-Timestamp") String timestamp,
|
@RequestHeader("Wechatpay-Nonce") String nonce,
|
@RequestHeader("Wechatpay-Signature") String signature,
|
@RequestBody String body) {
|
String wxId = ID.nextGUID();
|
log.info("V3退款回调信息({}) => {}", wxId, body);
|
try {
|
RefundNotification refundNotification = wxPayV3Service.parseRefundNotify(
|
serialNumber, timestamp, nonce, signature, body);
|
|
log.info("V3退款回调结果, outTradeNo={}, outRefundNo={}, refundStatus={}",
|
refundNotification.getOutTradeNo(),
|
refundNotification.getOutRefundNo(),
|
refundNotification.getRefundStatus());
|
|
// 根据退款单号更新退款记录状态
|
String outRefundNo = refundNotification.getOutRefundNo();
|
OrdersRefund refundRecord = ordersRefundMapper.selectOne(
|
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<OrdersRefund>().lambda()
|
.eq(OrdersRefund::getRefundCode, outRefundNo)
|
.eq(OrdersRefund::getDeleted, Constants.ZERO)
|
.last("limit 1"));
|
if (refundRecord != null) {
|
Status refundStatus = refundNotification.getRefundStatus();
|
if (Status.SUCCESS.equals(refundStatus)) {
|
refundRecord.setStatus(Constants.ONE); // 退款成功
|
refundRecord.setRefundTime(new java.util.Date());
|
} else if (Status.CLOSED.equals(refundStatus) || Status.ABNORMAL.equals(refundStatus)) {
|
refundRecord.setStatus(Constants.TWO); // 退款失败
|
}
|
ordersRefundMapper.updateById(refundRecord);
|
log.info("退款记录状态已更新, refundRecordId={}, status={}", refundRecord.getId(), refundRecord.getStatus());
|
|
// 退款成功 → 通知会员
|
if (Status.SUCCESS.equals(refundStatus) && refundRecord.getOrderId() != null) {
|
Orders refundOrder = ordersMapper.selectById(refundRecord.getOrderId());
|
if (refundOrder != null) {
|
Notice notice = new Notice();
|
notice.setUserType(0);
|
notice.setUserId(refundOrder.getMemberId());
|
notice.setTitle(Constants.MemberOrderNotify.REFUNDED.getTitle());
|
notice.setContent(Constants.MemberOrderNotify.REFUNDED.format(
|
"orderNo", refundOrder.getCode(),
|
"amount", String.valueOf(Constants.getFormatMoney(refundOrder.getRefundAmount() != null ? refundOrder.getRefundAmount() : 0L))));
|
notice.setObjId(refundOrder.getId());
|
notice.setObjType(0);
|
notice.setStatus(0);
|
notice.setIsdeleted(Constants.ZERO);
|
notice.setCreateDate(new java.util.Date());
|
noticeService.create(notice);
|
}
|
}
|
}
|
|
Map<String, String> response = new HashMap<>();
|
response.put("code", "SUCCESS");
|
response.put("message", "处理成功");
|
return response;
|
} catch (Exception e) {
|
log.error("V3退款回调异常,异常原因{}", e.getLocalizedMessage());
|
Map<String, String> response = new HashMap<>();
|
response.put("code", "FAIL");
|
response.put("message", e.getMessage());
|
return response;
|
}
|
}
|
|
}
|