调整退款(未完成,暂不合并到master)

This commit is contained in:
HH 2023-03-29 00:09:09 +08:00
parent ab0183910a
commit b0476acce0
28 changed files with 528 additions and 279 deletions

View File

@ -1,4 +1,4 @@
package com.ghy.payment.service.impl;
package com.ghy.callback;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.Event;

View File

@ -1,4 +1,4 @@
package com.ghy.payment.service.impl;
package com.ghy.callback;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
@ -22,8 +22,6 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;
/**
* 支付回调
@ -70,11 +68,11 @@ public class PayCallbackService implements CallBackService {
Long financialMasterId = null;
for (String financialChangeRecordId: financialChangeRecordArr) {
FinancialChangeRecord financialChangeRecord = new FinancialChangeRecord();
financialChangeRecord.setId(financialChangeRecordId);
financialChangeRecord.setId(Long.valueOf(financialChangeRecordId));
financialChangeRecord.setPayStatus(1);
// 加价的支付paymentId回填到remark
financialChangeRecord.setRemark(payment.getId());
financialChangeRecordService.updateFinancialChangeRecord(financialChangeRecord);
financialChangeRecordService.update(financialChangeRecord);
// 修改子订单的payMoney
FinancialChangeRecord fc = financialChangeRecordService.selectFinancialChangeRecordById(financialChangeRecord.getId());

View File

@ -0,0 +1,75 @@
package com.ghy.callback;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.adapay.model.Event;
import com.ghy.common.adapay.model.PayReverseCallback;
import com.ghy.order.service.OrderDetailService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.service.CallBackService;
import com.ghy.payment.service.FinancialChangeRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 撤销支付回调
*
* @author HH 2022/5/31
*/
@Slf4j
@Service("payReverseCallbackService")
public class PayReverseCallbackService implements CallBackService {
private OrderMasterService orderMasterService;
private OrderDetailService orderDetailService;
private FinancialChangeRecordService financialChangeRecordService;
@Override
public void onCallback(Event event) {
log.debug("撤销支付 callback: {}", event);
PayReverseCallback callback = JSON.parseObject(event.getData(), PayReverseCallback.class);
String reverseId = callback.getId();
if (AdapayStatusEnum.succeeded.code.equals(callback.getStatus())) {
String orderNo = callback.getOrderNo();
String type = orderNo.substring(0, 3);
switch (type) {
case "ROM":
orderMasterService.refundSucceeded(reverseId);
break;
case "ROD":
orderDetailService.refundSucceeded(reverseId);
break;
case "RCG":
financialChangeRecordService.refundSucceeded(reverseId);
break;
case "RAS": // TODO
break;
default:
throw new IllegalArgumentException(String.format("未知的退款类型[%s]", type));
}
}
}
@Override
public void onResponse(JSONObject response) {
log.debug("撤销支付 Response: {}", response.toString());
}
@Autowired
public void setOrderMasterService(OrderMasterService orderMasterService) {
this.orderMasterService = orderMasterService;
}
@Autowired
public void setOrderDetailService(OrderDetailService orderDetailService) {
this.orderDetailService = orderDetailService;
}
@Autowired
public void setFinancialChangeRecordService(FinancialChangeRecordService financialChangeRecordService) {
this.financialChangeRecordService = financialChangeRecordService;
}
}

View File

@ -1,4 +1,4 @@
package com.ghy.payment.service.impl;
package com.ghy.callback;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.Event;

View File

@ -26,10 +26,7 @@ import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.domain.OrderTimeoutRecord;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import com.ghy.payment.service.OrderFineRecordService;
import com.ghy.payment.service.*;
import com.ghy.system.domain.SysArea;
import com.ghy.system.domain.SysDeptConfig;
import com.ghy.system.service.ISysAreaService;
@ -45,11 +42,10 @@ import com.ghy.worker.service.WorkerService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -108,8 +104,10 @@ public class OrderDetailController extends BaseController {
private ISysDeptConfigService sysDeptConfigService;
@Resource
private OrderBehaviorService orderBehaviorService;
@Autowired
@Resource
private IWxMsgService wxMsgService;
@Resource
private AdapayService adapayService;
@RequiresPermissions("order:detail:view")
@GetMapping()

View File

@ -1,5 +1,7 @@
package com.ghy.web.controller.order;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.annotation.Log;
import com.ghy.common.constant.UserConstants;
import com.ghy.common.core.controller.BaseController;
@ -9,6 +11,8 @@ import com.ghy.common.core.page.TableDataInfo;
import com.ghy.common.core.page.TableSupport;
import com.ghy.common.enums.BusinessType;
import com.ghy.common.enums.ImgType;
import com.ghy.common.enums.PayStatus;
import com.ghy.common.enums.RefundType;
import com.ghy.common.utils.ExceptionUtil;
import com.ghy.common.utils.StringUtils;
import com.ghy.common.utils.poi.ExcelUtil;
@ -34,10 +38,7 @@ import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.domain.OrderTimeoutRecord;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import com.ghy.payment.service.OrderFineRecordService;
import com.ghy.payment.service.*;
import com.ghy.system.domain.SysArea;
import com.ghy.system.service.ISysAreaService;
import com.ghy.web.pojo.vo.OrderListResponse;
@ -51,14 +52,16 @@ import com.ghy.worker.service.WorkerService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -77,10 +80,10 @@ public class OrderMasterController extends BaseController {
@Resource
private OrderMasterService orderMasterService;
@Autowired
@Resource
private GoodsAreaService goodsAreaService;
@Resource
private AdapayService adapayService;
@Resource
private WorkerService workerService;
@Resource
@ -832,4 +835,68 @@ public class OrderMasterController extends BaseController {
}
return true;
}
/**
* 撤销支付适用于延迟分账的订单
*
* @param orderMasterId 主订单ID
*/
@PostMapping("reverse")
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public AjaxResult reverse(Long orderMasterId) throws BaseAdaPayException {
OrderMaster orderMaster = orderMasterService.selectById(orderMasterId);
Assert.notNull(orderMaster, "找不到对应的订单");
FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMasterId);
Assert.notNull(financialMaster, "找不到订单");
Assert.isTrue(!PayStatus.WAIT_PAY.getCode().equals(financialMaster.getPayStatus()), "订单未支付");
Assert.isTrue(!PayStatus.CANCEL.getCode().equals(financialMaster.getPayStatus()), "订单已取消");
Assert.isTrue(!PayStatus.REFUND.getCode().equals(financialMaster.getPayStatus()), "订单已退款");
boolean paid = PayStatus.PAID.getCode().equals(financialMaster.getPayStatus()) ||
PayStatus.PAYED_ADD.getCode().equals(financialMaster.getPayStatus());
Assert.isTrue(paid, "订单未支付");
Assert.hasText(financialMaster.getPaymentId(), "找不到订单的支付记录,请联系管理员");
// 先改状态 后面出错就回滚
orderMasterService.updatePayStatus(orderMasterId, PayStatus.REVERSING.getCode());
OrderDetail odUpdate = new OrderDetail();
odUpdate.setOrderMasterId(orderMasterId);
odUpdate.setPayStatus(PayStatus.REVERSING.getCode());
orderDetailService.updateByOrderMasterId(odUpdate);
// 主订单金额=订单原价+加价
BigDecimal payMoney = financialMaster.getPayMoney();
List<FinancialChangeRecord> fcrList = financialChangeRecordService.selectByMasterId(orderMasterId);
for (FinancialChangeRecord fcr : fcrList) {
// 把已支付的加价单退了 并从主单金额里减去
if (PayStatus.PAID.getCode().equals(fcr.getPayStatus())) {
financialChangeRecordService.refund(orderMaster.getDeptId(), fcr);
payMoney = payMoney.subtract(fcr.getChangeMoney());
}
}
List<FinancialDetail> fdList = financialDetailService.selectByFinancialMasterId(financialMaster.getId());
for (FinancialDetail fd : fdList) {
// 如果有已退款或正在退款的子财务单 从主单金额里减去
if (PayStatus.REFUND.getCode().equals(fd.getPayStatus()) ||
PayStatus.REFUNDING.getCode().equals(fd.getPayStatus()) ||
PayStatus.REVERSING.getCode().equals(fd.getPayStatus())) {
payMoney = payMoney.subtract(fd.getPayMoney());
}
}
if (payMoney.compareTo(BigDecimal.ZERO) < 1) {
logger.info("无需退款 reverseAmt={}", payMoney);
}
String reverseAmt = payMoney.setScale(2, RoundingMode.DOWN).toString();
JSONObject response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), reverseAmt, RefundType.ROM);
if (AdapayStatusEnum.succeeded.code.equals(response.getString("status")) ||
AdapayStatusEnum.pending.code.equals(response.getString("status"))) {
// TODO 保存reverseId
return AjaxResult.success();
} else {
// TODO 重试
return AjaxResult.error(response.getString("error_msg"));
}
}
}

View File

@ -36,51 +36,51 @@ public class PayController {
@Resource
private FinancialMasterService financialMasterService;
/**
* 发起退款
*
* @param orderMasterId 主订单ID
* @param refundAmt 退款金额 保留两位小数
*/
@PostMapping("refund")
@ResponseBody
public AjaxResult refund(Long orderMasterId, String refundAmt) throws BaseAdaPayException {
OrderMaster orderMaster = orderMasterService.selectById(orderMasterId);
Assert.notNull(orderMaster, "找不到对应的订单");
FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMasterId);
Assert.notNull(financialMaster, "找不到订单");
PaymentDTO payment = financialMasterService.selectPaymentById(financialMaster.getPaymentId());
Assert.notNull(payment, "找不到支付记录");
Assert.isTrue(financialMaster.getPayStatus() == 1, "订单未支付");
Assert.hasText(financialMaster.getPaymentId(), "找不到订单的支付记录,请联系管理员");
JSONObject response = adapayService.refund(orderMaster.getDeptId(), financialMaster.getPaymentId(), payment.getOrderNo(), refundAmt);
if (AdapayStatusEnum.succeeded.code.equals(response.getString("status"))) {
return AjaxResult.success();
} else {
return AjaxResult.error(response.getString("error_msg"));
}
}
// /**
// * 发起退款
// *
// * @param orderMasterId 主订单ID
// * @param refundAmt 退款金额 保留两位小数
// */
// @PostMapping("refund")
// @ResponseBody
// public AjaxResult refund(Long orderMasterId, String refundAmt) throws BaseAdaPayException {
// OrderMaster orderMaster = orderMasterService.selectById(orderMasterId);
// Assert.notNull(orderMaster, "找不到对应的订单");
// FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMasterId);
// Assert.notNull(financialMaster, "找不到订单");
// PaymentDTO payment = financialMasterService.selectPaymentById(financialMaster.getPaymentId());
// Assert.notNull(payment, "找不到支付记录");
// Assert.isTrue(financialMaster.getPayStatus() == 1, "订单未支付");
// Assert.hasText(financialMaster.getPaymentId(), "找不到订单的支付记录,请联系管理员");
// JSONObject response = adapayService.refund(orderMaster.getDeptId(), financialMaster.getPaymentId(), payment.getOrderNo(), refundAmt);
// if (AdapayStatusEnum.succeeded.code.equals(response.getString("status"))) {
// return AjaxResult.success();
// } else {
// return AjaxResult.error(response.getString("error_msg"));
// }
// }
/**
* 撤销支付
*
* @param orderMasterId 主订单ID
* @param reverseAmt 撤销金额 保留两位小数
*/
@PostMapping("reverse")
@ResponseBody
public AjaxResult reverse(Long orderMasterId, String reverseAmt) throws BaseAdaPayException {
OrderMaster orderMaster = orderMasterService.selectById(orderMasterId);
Assert.notNull(orderMaster, "找不到对应的订单");
FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMasterId);
Assert.notNull(financialMaster, "找不到订单");
Assert.isTrue(financialMaster.getPayStatus() == 1, "订单未支付");
Assert.hasText(financialMaster.getPaymentId(), "找不到订单的支付记录,请联系管理员");
JSONObject response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), reverseAmt);
if (AdapayStatusEnum.succeeded.code.equals(response.getString("status"))) {
return AjaxResult.success();
} else {
return AjaxResult.error(response.getString("error_msg"));
}
}
// /**
// * 撤销支付
// *
// * @param orderMasterId 主订单ID
// * @param reverseAmt 撤销金额 保留两位小数
// */
// @PostMapping("reverse")
// @ResponseBody
// public AjaxResult reverse(Long orderMasterId, String reverseAmt) throws BaseAdaPayException {
// OrderMaster orderMaster = orderMasterService.selectById(orderMasterId);
// Assert.notNull(orderMaster, "找不到对应的订单");
// FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMasterId);
// Assert.notNull(financialMaster, "找不到订单");
// Assert.isTrue(financialMaster.getPayStatus() == 1, "订单未支付");
// Assert.hasText(financialMaster.getPaymentId(), "找不到订单的支付记录,请联系管理员");
// JSONObject response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), reverseAmt);
// if (AdapayStatusEnum.succeeded.code.equals(response.getString("status"))) {
// return AjaxResult.success();
// } else {
// return AjaxResult.error(response.getString("error_msg"));
// }
// }
}

View File

@ -10,7 +10,12 @@ public enum PayStatus {
PAID(1, "已支付"),
CANCEL(2, "已取消"),
REFUND(3, "已退款"),
PAYED_ADD(4, "加价原单已付款");
PAYED_ADD(4, "加价原单已付款"),
REFUNDING(5, "退款中"),
/**
* 支付模式为"延迟分账"时的退款
*/
REVERSING(6, "撤销支付中");
private final Integer code;
private final String desc;

View File

@ -0,0 +1,30 @@
package com.ghy.common.enums;
/**
* 退款类型
*/
public enum RefundType {
/**
* 主订单退款
*/
ROM("ROM"),
/**
* 子订单退款
*/
ROD("ROD"),
/**
* 加价单退款
*/
RCG("RCG"),
/**
* 售后退款
*/
RAS("RAS");
public final String code;
RefundType(String code) {
this.code = code;
}
}

View File

@ -6,6 +6,7 @@ import com.ghy.common.core.domain.BaseEntity;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.worker.domain.Worker;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import java.util.List;
@ -15,6 +16,7 @@ import java.util.List;
* 主单表(对应付款订单)
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class OrderMaster extends BaseEntity {
private static final long serialVersionUID = 1L;

View File

@ -87,4 +87,6 @@ public interface OrderMasterMapper {
List<OrderMaster> selectUnfinished();
List<OrderMaster> selectByIds(@Param("orderMasterId") Collection<Long> orderMasterIds);
int updatePayStatus(@Param("orderMasterId") Long orderMasterId, @Param("payStatus") Integer payStatus);
}

View File

@ -146,4 +146,11 @@ public interface OrderDetailService {
* @return 1
*/
int updateDrawCashStatus(String drawCashId, int drawCashStatus, Date arrivalTime);
/**
* 退款成功时 退款回调接口里会调用这个方法
*
* @param reverseId 退款ID
*/
void refundSucceeded(String reverseId);
}

View File

@ -119,4 +119,13 @@ public interface OrderMasterService {
List<OrderMaster> selectUnfinished();
List<OrderMaster> selectByIds(Collection<Long> masterIds);
int updatePayStatus(Long orderMasterId, Integer payStatus);
/**
* 退款成功时 退款回调接口里会调用这个方法
*
* @param reverseId 退款ID
*/
void refundSucceeded(String reverseId);
}

View File

@ -1,21 +1,17 @@
package com.ghy.order.service.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.adapay.model.PaymentDTO;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.core.text.Convert;
import com.ghy.common.enums.OrderStatus;
import com.ghy.common.enums.PayStatus;
import com.ghy.common.enums.PayTypeEnum;
import com.ghy.common.enums.RefundType;
import com.ghy.common.exception.base.BaseException;
import com.ghy.common.utils.DateUtils;
import com.ghy.common.utils.ObjectUtils;
import com.ghy.order.domain.*;
import com.ghy.order.mapper.AfterServiceRecordMapper;
import com.ghy.order.service.*;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
@ -25,11 +21,14 @@ import com.ghy.payment.service.FinancialMasterService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ghy.order.mapper.AfterServiceRecordMapper;
import com.ghy.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* 售后记录Service业务层处理
*
@ -135,7 +134,7 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
Assert.notNull(orderMaster, "找不到对应的订单");
FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderDetail.getOrderMasterId());
Assert.notNull(financialMaster, "找不到订单");
BigDecimal refundMoney = BigDecimal.ZERO;
BigDecimal refundMoney;
if(ObjectUtils.isNotEmpty(afterServiceRecord.getAgreedRefund())){
refundMoney = afterServiceRecord.getAgreedRefund();
}else {
@ -171,7 +170,7 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
Assert.hasText(financialMaster.getPaymentId(), "找不到订单的支付记录,请联系管理员");
JSONObject response = null;
try {
response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), String.valueOf(refundMoney));
response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), String.valueOf(refundMoney), RefundType.RAS);
if (AdapayStatusEnum.pending.code.equals(response.getString("status"))) {
financialMaster.setPayMoney(financialMaster.getPayMoney().subtract(refundMoney));
financialMasterService.updateFinancialMaster(financialMaster);

View File

@ -7,10 +7,7 @@ import com.ghy.common.adapay.model.DivMember;
import com.ghy.common.adapay.model.PaymentDTO;
import com.ghy.common.constant.UserConstants;
import com.ghy.common.core.text.Convert;
import com.ghy.common.enums.AdapayOrderType;
import com.ghy.common.enums.FinancialDetailType;
import com.ghy.common.enums.OrderStatus;
import com.ghy.common.enums.PayStatus;
import com.ghy.common.enums.*;
import com.ghy.common.exception.base.BaseException;
import com.ghy.common.utils.AdapayUtils;
import com.ghy.common.utils.ObjectUtils;
@ -278,7 +275,7 @@ public class OrderDetailServiceImpl implements OrderDetailService {
OrderMaster orderMaster = orderMasterMapper.selectById(orderDetail.getOrderMasterId());
FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMaster.getId());
String refundAmt = AdapayUtils.bigDecimalToString(payMoney);
JSONObject response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), refundAmt);
JSONObject response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), refundAmt, RefundType.ROD);
logger.debug("子订单退款结果: " + response.toJSONString());
boolean status = AdapayStatusEnum.pending.code.equals(response.getString("status")) ||
AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
@ -554,7 +551,7 @@ public class OrderDetailServiceImpl implements OrderDetailService {
financialChangeRecord.setChangeMoney(changeMoney);
financialChangeRecord.setType(type);
financialChangeRecord.setRemark(remark);
affectedRows = financialChangeRecordService.updateFinancialChangeRecord(financialChangeRecord);
affectedRows = financialChangeRecordService.update(financialChangeRecord);
} else {
// 创建改单记录
financialChangeRecord = new FinancialChangeRecord();
@ -598,4 +595,9 @@ public class OrderDetailServiceImpl implements OrderDetailService {
public int updateDrawCashStatus(String drawCashId, int drawCashStatus, Date arrivalTime) {
return orderDetailMapper.updateDrawCashStatus(drawCashId, drawCashStatus, arrivalTime);
}
@Override
public void refundSucceeded(String reverseId) {
// TODO
}
}

View File

@ -6,10 +6,7 @@ import com.ghy.common.adapay.model.DivMember;
import com.ghy.common.adapay.model.PaymentDTO;
import com.ghy.common.constant.UserConstants;
import com.ghy.common.core.text.Convert;
import com.ghy.common.enums.AdapayOrderType;
import com.ghy.common.enums.FinancialDetailType;
import com.ghy.common.enums.OrderStatus;
import com.ghy.common.enums.PayStatus;
import com.ghy.common.enums.*;
import com.ghy.common.utils.AdapayUtils;
import com.ghy.order.domain.OrderDetail;
import com.ghy.order.domain.OrderMaster;
@ -385,7 +382,7 @@ public class OrderMasterServiceImpl implements OrderMasterService {
financialDetailService.updateByFinancialMasterId(fdUpdate);
String refundAmt = AdapayUtils.bigDecimalToString(payMoney);
JSONObject response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), refundAmt);
JSONObject response = adapayService.payReverse(orderMaster.getDeptId(), financialMaster.getPaymentId(), refundAmt, RefundType.ROM);
logger.debug("退款结果: " + response.toJSONString());
boolean status = AdapayStatusEnum.pending.code.equals(response.getString("status")) ||
AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
@ -406,4 +403,14 @@ public class OrderMasterServiceImpl implements OrderMasterService {
}
return orderMasterMapper.selectByIds(masterIds);
}
@Override
public int updatePayStatus(Long orderMasterId, Integer payStatus) {
return orderMasterMapper.updatePayStatus(orderMasterId, payStatus);
}
@Override
public void refundSucceeded(String reverseId) {
// TODO
}
}

View File

@ -268,6 +268,13 @@
WHERE id = #{orderMasterId}
</update>
<update id="updatePayStatus">
UPDATE order_master
SET pay_status = #{payStatus},
update_time = SYSDATE()
WHERE id = #{orderMasterId}
</update>
<insert id="insertOrderMaster" parameterType="com.ghy.order.domain.OrderMaster" useGeneratedKeys="true" keyProperty="id">
INSERT INTO order_master(
<if test="deptId != null and deptId != 0">dept_id,</if>

View File

@ -1,10 +1,13 @@
package com.ghy.payment.domain;
import java.math.BigDecimal;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ghy.common.annotation.Excel;
import com.ghy.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal;
/**
* 改价记录对象 financial_change_record
@ -12,98 +15,61 @@ import com.ghy.common.core.domain.BaseEntity;
* @author clunt
* @date 2022-09-15
*/
public class FinancialChangeRecord extends BaseEntity
{
@Data
@EqualsAndHashCode(callSuper = true)
public class FinancialChangeRecord extends BaseEntity {
private static final long serialVersionUID = 1L;
/** $column.columnComment */
private String id;
private Long id;
/** 改价子单 */
/**
* 改价子单
*/
@Excel(name = "改价子单")
private Long orderDetailId;
/** 改价金额 */
/**
* 子单所属主单ID
*/
private Long orderMasterId;
/**
* 支付ID
*/
private String paymentId;
/**
* Adapay撤销支付或退款ID
*/
private String reverseId;
/**
* 改价金额
*/
@Excel(name = "改价金额")
private BigDecimal changeMoney;
/** 状态0.待审核 1.审核通过 2.审核拒绝 */
/**
* 状态0.待审核 1.审核通过 2.审核拒绝
*/
@Excel(name = "状态0.待审核 1.审核通过 2.审核拒绝")
private Integer status;
/** 0 待支付 1.已支付 */
/**
* {@link com.ghy.common.enums.PayStatus}
*/
@Excel(name = "0 待支付 1.已支付")
private Integer payStatus;
/** 1.本单报价 2.加单报价 **/
/**
* 1.本单报价 2.加单报价
**/
@Excel(name = "1.本单报价 2.加单报价")
private Integer type;
@Excel(name = "剩余分账金额")
private BigDecimal leftMoney;
public BigDecimal getLeftMoney() {
return leftMoney;
}
public void setLeftMoney(BigDecimal leftMoney) {
this.leftMoney = leftMoney;
}
public void setId(String id)
{
this.id = id;
}
public String getId()
{
return id;
}
public void setOrderDetailId(Long orderDetailId)
{
this.orderDetailId = orderDetailId;
}
public Long getOrderDetailId()
{
return orderDetailId;
}
public void setChangeMoney(BigDecimal changeMoney)
{
this.changeMoney = changeMoney;
}
public BigDecimal getChangeMoney()
{
return changeMoney;
}
public void setStatus(Integer status)
{
this.status = status;
}
public Integer getStatus()
{
return status;
}
public void setPayStatus(Integer payStatus)
{
this.payStatus = payStatus;
}
public Integer getPayStatus()
{
return payStatus;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)

View File

@ -10,7 +10,7 @@ import java.util.List;
*/
public interface FinancialChangeRecordMapper {
public FinancialChangeRecord selectNotPayRecordByDetailId(Long orderDetailId);
FinancialChangeRecord selectNotPayRecordByDetailId(Long orderDetailId);
/**
* 查询改价记录
@ -18,7 +18,7 @@ public interface FinancialChangeRecordMapper {
* @param id 改价记录主键
* @return 改价记录
*/
public FinancialChangeRecord selectFinancialChangeRecordById(String id);
FinancialChangeRecord selectFinancialChangeRecordById(Long id);
/**
* 查询改价记录列表
@ -26,16 +26,17 @@ public interface FinancialChangeRecordMapper {
* @param financialChangeRecord 改价记录
* @return 改价记录集合
*/
public List<FinancialChangeRecord> selectFinancialChangeRecordList(FinancialChangeRecord financialChangeRecord);
List<FinancialChangeRecord> selectFinancialChangeRecordList(FinancialChangeRecord financialChangeRecord);
List<FinancialChangeRecord> selectByDetailIds(@Param("ids") String ids);
public List<FinancialChangeRecord> selectByDetailIds(@Param("ids") String ids);
/**
* 新增改价记录
*
* @param financialChangeRecord 改价记录
* @return 结果
*/
public int insertFinancialChangeRecord(FinancialChangeRecord financialChangeRecord);
int insertFinancialChangeRecord(FinancialChangeRecord financialChangeRecord);
/**
* 修改改价记录
@ -43,7 +44,7 @@ public interface FinancialChangeRecordMapper {
* @param financialChangeRecord 改价记录
* @return 结果
*/
public int updateFinancialChangeRecord(FinancialChangeRecord financialChangeRecord);
int updateFinancialChangeRecord(FinancialChangeRecord financialChangeRecord);
/**
* 删除改价记录
@ -51,7 +52,7 @@ public interface FinancialChangeRecordMapper {
* @param id 改价记录主键
* @return 结果
*/
public int deleteFinancialChangeRecordById(String id);
int deleteFinancialChangeRecordById(Long id);
/**
* 批量删除改价记录
@ -59,6 +60,9 @@ public interface FinancialChangeRecordMapper {
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteFinancialChangeRecordByIds(String[] ids);
int deleteFinancialChangeRecordByIds(String[] ids);
List<FinancialChangeRecord> selectByMasterId(@Param("orderMasterId") Long orderMasterId);
int updatePayStatus(@Param("id") Long id, @Param("payStatus") Integer payStatus);
}

View File

@ -94,4 +94,6 @@ public interface FinancialDetailMapper {
* @param financialDetail 子财务单
*/
void updateByFinancialMasterId(FinancialDetail financialDetail);
int updatePayStatus(@Param("id") Long id, @Param("payStatus") Integer payStatus);
}

View File

@ -1,23 +1,21 @@
package com.ghy.payment.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.AdapayConfig;
import com.ghy.common.adapay.AdapayProperties;
import com.ghy.common.adapay.model.*;
import com.ghy.payment.service.impl.DrawCashCallbackService;
import com.ghy.payment.service.impl.PayCallbackService;
import com.ghy.payment.service.impl.PayReverseCallbackService;
import com.ghy.payment.service.impl.RefundCallbackService;
import com.ghy.common.enums.RefundType;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.Collection;
import java.util.List;
@ -29,18 +27,47 @@ import java.util.List;
@Service
public class AdapayService {
@Resource
private ThreadPoolTaskExecutor executor;
@Resource
private PayCallbackService payCallbackService;
@Resource
private RefundCallbackService refundCallbackService;
@Resource
private DrawCashCallbackService drawCashCallbackService;
@Resource
private PayReverseCallbackService payReverseCallbackService;
@Resource
private AdapayProperties adapayProperties;
private CallBackService payCallbackService;
private CallBackService refundCallbackService;
private CallBackService drawCashCallbackService;
private CallBackService payReverseCallbackService;
@Autowired
public void setExecutor(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
this.executor = threadPoolTaskExecutor;
}
@Autowired
public void setAdapayProperties(AdapayProperties adapayProperties) {
log.info("Adapay load properties: {}", JSON.toJSONString(adapayProperties));
this.adapayProperties = adapayProperties;
}
@Autowired
public void setPayCallbackService(CallBackService payCallbackService) {
log.info("Adapay load callback: {}", payCallbackService.getClass().toString());
this.payCallbackService = payCallbackService;
}
@Autowired
public void setRefundCallbackService(CallBackService refundCallbackService) {
log.info("Adapay load callback: {}", refundCallbackService.getClass().toString());
this.refundCallbackService = refundCallbackService;
}
@Autowired
public void setDrawCashCallbackService(CallBackService drawCashCallbackService) {
log.info("Adapay load callback: {}", drawCashCallbackService.getClass().toString());
this.drawCashCallbackService = drawCashCallbackService;
}
@Autowired
public void setPayReverseCallbackService(CallBackService payReverseCallbackService) {
log.info("Adapay load callback: {}", payReverseCallbackService.getClass().toString());
this.payReverseCallbackService = payReverseCallbackService;
}
/**
* 查询支付对象
@ -479,19 +506,32 @@ public class AdapayService {
*
* @param deptId [必填]商户ID
* @param paymentId [必填]Adapay生成的支付对象id
* @param reverseAmt [必填]撤销金额必须大于0保留两位小数点如0.10100.05等撤销金额必须小于等于支付金额 - 已确认金额 - 已撤销撤销成功+撤销中金额
* @param reverseAmt [必填]撤销金额必须大于0保留两位小数点如0.10100.05等
* 撤销金额必须小于等于支付金额 - 已确认金额 - 已撤销撤销成功+撤销中金额
* @param type 退款类型 回调时根据它找到对应的财务单
* @return 创建支付撤销对象同步返回成功表示 Adapay 受理成功撤销结果以异步通知为准
*/
public JSONObject payReverse(@NotNull Long deptId, @NotNull String paymentId, @NotNull String reverseAmt) throws BaseAdaPayException {
public JSONObject payReverse(@NotNull Long deptId, @NotNull String paymentId, @NotNull String reverseAmt, @NotNull RefundType type) throws BaseAdaPayException {
JSONObject reverseParams = new JSONObject();
reverseParams.put("app_id", AdapayConfig.getAppId(deptId));
reverseParams.put("payment_id", paymentId);
reverseParams.put("reverse_amt", reverseAmt);
reverseParams.put("notify_url", adapayProperties.getNotifyUrl());
reverseParams.put("order_no", "PAYMENT_REVERSE" + System.currentTimeMillis());
reverseParams.put("order_no", type.code + System.currentTimeMillis());
JSONObject response = (JSONObject) PaymentReverse.create(reverseParams, deptId.toString());
executor.execute(() -> payReverseCallbackService.onResponse(response));
return response;
}
/**
* 通过 Payment对象 id 查询一个已创建的 Payment对象
* 仅支持查询支付交易发起之后3天内的交易状态3天之后的交易状态请使用 对账单下载 对账或登陆 控制台 查询
*
* @param deptId [必填]商户ID
* @param paymentId [必填]Adapay生成的支付对象id
* @return https://docs.adapay.tech/api/trade.html#id17
*/
public JSONObject queryPayment(@NotNull Long deptId, @NotNull String paymentId) throws BaseAdaPayException {
return (JSONObject) Payment.query(paymentId, deptId.toString());
}
}

View File

@ -1,6 +1,8 @@
package com.ghy.payment.service;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Set;
@ -18,7 +20,7 @@ public interface FinancialChangeRecordService {
* @param id 改价记录主键
* @return 改价记录
*/
FinancialChangeRecord selectFinancialChangeRecordById(String id);
FinancialChangeRecord selectFinancialChangeRecordById(Long id);
/**
* 查询改价记录列表
@ -46,7 +48,7 @@ public interface FinancialChangeRecordService {
* @param financialChangeRecord 改价记录
* @return 结果
*/
int updateFinancialChangeRecord(FinancialChangeRecord financialChangeRecord);
int update(FinancialChangeRecord financialChangeRecord);
/**
* 批量删除改价记录
@ -62,6 +64,24 @@ public interface FinancialChangeRecordService {
* @param id 改价记录主键
* @return 结果
*/
int deleteFinancialChangeRecordById(String id);
int deleteFinancialChangeRecordById(Long id);
List<FinancialChangeRecord> selectByMasterId(@Param("orderMasterId") Long orderMasterId);
int updatePayStatus(Long id, Integer payStatus);
/**
* 加价单发起全额退款
*
* @param deptId 公司ID
* @param fcr 加价单
*/
void refund(Long deptId, FinancialChangeRecord fcr) throws BaseAdaPayException;
/**
* 退款成功时 退款回调接口里会调用这个方法
*
* @param reverseId 退款ID
*/
void refundSucceeded(String reverseId);
}

View File

@ -114,4 +114,6 @@ public interface FinancialDetailService {
* @param type 子财务单类型 FinancialDetail.financialDetailType
*/
List<FinancialDetail> selectByFinancialMasterIdAndType(Long financialMasterId, int type);
int updatePayStatus(Long id, Integer payStatus);
}

View File

@ -1,14 +1,20 @@
package com.ghy.payment.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.core.text.Convert;
import com.ghy.common.enums.RefundType;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.mapper.FinancialChangeRecordMapper;
import com.ghy.payment.service.AdapayService;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@ -20,6 +26,8 @@ import java.util.StringJoiner;
@Service
public class FinancialChangeRecordServiceImpl implements FinancialChangeRecordService {
@Resource
private AdapayService adapayService;
@Resource
private FinancialChangeRecordMapper financialChangeRecordMapper;
@ -35,7 +43,7 @@ public class FinancialChangeRecordServiceImpl implements FinancialChangeRecordSe
* @return 改价记录
*/
@Override
public FinancialChangeRecord selectFinancialChangeRecordById(String id) {
public FinancialChangeRecord selectFinancialChangeRecordById(Long id) {
return financialChangeRecordMapper.selectFinancialChangeRecordById(id);
}
@ -87,7 +95,7 @@ public class FinancialChangeRecordServiceImpl implements FinancialChangeRecordSe
* @return 结果
*/
@Override
public int updateFinancialChangeRecord(FinancialChangeRecord financialChangeRecord) {
public int update(FinancialChangeRecord financialChangeRecord) {
return financialChangeRecordMapper.updateFinancialChangeRecord(financialChangeRecord);
}
@ -109,8 +117,36 @@ public class FinancialChangeRecordServiceImpl implements FinancialChangeRecordSe
* @return 结果
*/
@Override
public int deleteFinancialChangeRecordById(String id) {
public int deleteFinancialChangeRecordById(Long id) {
return financialChangeRecordMapper.deleteFinancialChangeRecordById(id);
}
@Override
public List<FinancialChangeRecord> selectByMasterId(Long orderMasterId) {
return financialChangeRecordMapper.selectByMasterId(orderMasterId);
}
@Override
public int updatePayStatus(Long id, Integer payStatus) {
return financialChangeRecordMapper.updatePayStatus(id, payStatus);
}
@Override
public void refund(Long deptId, FinancialChangeRecord fcr) throws BaseAdaPayException {
String changeMoney = fcr.getChangeMoney().setScale(2, RoundingMode.DOWN).toString();
JSONObject response = adapayService.payReverse(deptId, fcr.getPaymentId(), changeMoney, RefundType.RCG);
if (AdapayStatusEnum.succeeded.code.equals(response.getString("status")) ||
AdapayStatusEnum.pending.code.equals(response.getString("status"))) {
// 发起撤销支付成功
FinancialChangeRecord update = new FinancialChangeRecord();
update.setId(fcr.getId());
update.setReverseId(response.getString("id"));
update(update);
}
}
@Override
public void refundSucceeded(String reverseId) {
// TODO
}
}

View File

@ -170,4 +170,9 @@ public class FinancialDetailServiceImpl implements FinancialDetailService {
}
return financialDetailMapper.selectByOrderDetailIds(orderDetailIds);
}
@Override
public int updatePayStatus(Long id, Integer payStatus) {
return financialDetailMapper.updatePayStatus(id, payStatus);
}
}

View File

@ -1,63 +0,0 @@
package com.ghy.payment.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.adapay.model.Event;
import com.ghy.common.adapay.model.PayReverseCallback;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.service.CallBackService;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
/**
* 撤销支付回调
*
* @author HH 2022/5/31
*/
@Service("payReverseCallbackService")
public class PayReverseCallbackService implements CallBackService {
private static final Logger logger = LoggerFactory.getLogger(PayReverseCallbackService.class);
@Resource
private FinancialMasterService financialMasterService;
@Resource
private FinancialDetailService financialDetailService;
@Override
public void onCallback(Event event) {
logger.debug("撤销支付 callback: {}", event);
PayReverseCallback callback = JSON.parseObject(event.getData(), PayReverseCallback.class);
if (AdapayStatusEnum.succeeded.code.equals(callback.getStatus())) {
// 将子财务单支付状态设置为3 表示退款成功
financialDetailService.payReverseSucceeded(callback.getId());
}
}
@Override
public void onResponse(JSONObject response) {
logger.debug("撤销支付 Response: {}", response.toString());
if (AdapayStatusEnum.pending.code.equals(response.getString("status"))) {
String reverseId = response.getString("id");
String paymentId = response.getString("payment_id");
String reverseAmt = response.getString("reverse_amt");
FinancialMaster fm = financialMasterService.selectByPaymentId(paymentId);
// 创建并保存一条子财务单(type=撤销支付)
FinancialDetail fd = new FinancialDetail(fm.getDeptId(), financialDetailService.createCode(), fm.getId(),
fm.getCode(), new BigDecimal(reverseAmt), 4, null);
// 子财务单关联撤销支付ID
fd.setReverseId(reverseId);
financialDetailService.insertFinancialDetail(fd);
} else {
logger.warn("撤销失败: {}", response.toJSONString());
}
}
}

View File

@ -4,9 +4,12 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ghy.payment.mapper.FinancialChangeRecordMapper">
<resultMap type="FinancialChangeRecord" id="FinancialChangeRecordResult">
<result property="id" column="id" />
<resultMap id="FinancialChangeRecordResult" type="FinancialChangeRecord">
<id property="id" column="id"/>
<result property="orderDetailId" column="order_detail_id"/>
<result property="orderMasterId" column="order_master_id"/>
<result property="paymentId" column="payment_id"/>
<result property="reverseId" column="reverse_id"/>
<result property="changeMoney" column="change_money"/>
<result property="status" column="status"/>
<result property="payStatus" column="pay_status"/>
@ -14,7 +17,8 @@
</resultMap>
<sql id="selectFinancialChangeRecordVo">
select id, order_detail_id, change_money, status, pay_status, type, left_money, remark from financial_change_record
SELECT id, order_detail_id, order_master_id, payment_id, reverse_id,
change_money, status, pay_status, type, left_money, remark FROM financial_change_record
</sql>
<select id="selectNotPayRecordByDetailId" parameterType="Long" resultMap="FinancialChangeRecordResult">
@ -38,6 +42,11 @@
where order_detail_id in ( ${ids} )
</select>
<select id="selectByMasterId" parameterType="String" resultMap="FinancialChangeRecordResult">
<include refid="selectFinancialChangeRecordVo"/>
where order_master_id = #{orderMasterId}
</select>
<select id="selectFinancialChangeRecordById" parameterType="String" resultMap="FinancialChangeRecordResult">
<include refid="selectFinancialChangeRecordVo"/>
where id = #{id}
@ -47,6 +56,9 @@
insert into financial_change_record
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="orderDetailId != null">order_detail_id,</if>
<if test="orderMasterId != null">order_master_id,</if>
<if test="paymentId != null">payment_id,</if>
<if test="reverseId != null">reverse_id,</if>
<if test="changeMoney != null">change_money,</if>
<if test="status != null">status,</if>
<if test="payStatus != null">pay_status,</if>
@ -55,6 +67,9 @@
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="orderDetailId != null">#{orderDetailId},</if>
<if test="orderMasterId != null">#{orderMasterId},</if>
<if test="paymentId != null">#{paymentId},</if>
<if test="reverseId != null">#{reverseId},</if>
<if test="changeMoney != null">#{changeMoney},</if>
<if test="status != null">#{status},</if>
<if test="payStatus != null">#{payStatus},</if>
@ -67,6 +82,9 @@
update financial_change_record
<trim prefix="SET" suffixOverrides=",">
<if test="orderDetailId != null">order_detail_id = #{orderDetailId},</if>
<if test="orderMasterId != null">order_master_id = #{orderMasterId},</if>
<if test="paymentId != null">payment_id = #{paymentId},</if>
<if test="reverseId != null">reverse_id = #{reverseId},</if>
<if test="changeMoney != null">change_money = #{changeMoney},</if>
<if test="status != null">status = #{status},</if>
<if test="payStatus != null">pay_status = #{payStatus},</if>
@ -88,4 +106,9 @@
</foreach>
</delete>
<update id="updatePayStatus">
UPDATE financial_change_record
SET pay_status = #{payStatus}
WHERE id = #{id}
</update>
</mapper>

View File

@ -149,6 +149,12 @@
WHERE financial_master_id = #{financialMasterId}
</update>
<update id="updatePayStatus">
UPDATE financial_detail
SET pay_status = #{payStatus}
WHERE id = #{id}
</update>
<select id="selectByOrderDetailId" resultMap="FinancialDetailResult">
<include refid="selectFinancialDetail" />
WHERE