提交 7e119aa2 编写于 作者: terrfly's avatar terrfly

完善退款申请api;

上级 36f9aa52
......@@ -282,6 +282,7 @@ CREATE TABLE `t_pay_order` (
`channel_extra` VARCHAR(512) DEFAULT NULL COMMENT '特定渠道发起额外参数',
`channel_user` VARCHAR(64) DEFAULT NULL COMMENT '渠道用户标识,如微信openId,支付宝账号',
`channel_order_no` VARCHAR(64) DEFAULT NULL COMMENT '渠道订单号',
`refund_state` TINYINT(6) NOT NULL DEFAULT '0' COMMENT '退款状态: 0-未发生实际退款, 1-部分退款, 2-全额退款',
`refund_times` INT NOT NULL DEFAULT 0 COMMENT '退款次数',
`refund_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '退款总金额,单位分',
`division_flag` TINYINT(6) DEFAULT 0 COMMENT '订单分账标志:0-否 1-是',
......
......@@ -55,6 +55,9 @@ public class PayOrder extends BaseModel implements Serializable {
public static final byte STATE_REFUND = 5; //已退款
public static final byte STATE_CLOSED = 6; //订单关闭
public static final byte REFUND_STATE_NONE = 0; //未发生实际退款
public static final byte REFUND_STATE_SUB = 1; //部分退款
public static final byte REFUND_STATE_ALL = 2; //全额退款
/**
* 支付订单号
......@@ -152,6 +155,11 @@ public class PayOrder extends BaseModel implements Serializable {
*/
private String channelOrderNo;
/**
* 退款状态: 0-未发生实际退款, 1-部分退款, 2-全额退款
*/
private Byte refundState;
/**
* 退款次数
*/
......
/*
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jeequan.jeepay.pay.channel;
import com.jeequan.jeepay.pay.util.ChannelCertConfigKitBean;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
/*
* 退款接口抽象类
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/17 9:37
*/
public abstract class AbstractRefundService implements IRefundService{
@Autowired protected SysConfigService sysConfigService;
@Autowired protected ChannelCertConfigKitBean channelCertConfigKitBean;
protected String getNotifyUrl(){
return sysConfigService.getDBApplicationConfig().getPaySiteUrl() + "/api/refund/notify/" + getIfCode();
}
protected String getNotifyUrl(String payOrderId){
return sysConfigService.getDBApplicationConfig().getPaySiteUrl() + "/api/refund/notify/" + getIfCode() + "/" + payOrderId;
}
}
/*
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jeequan.jeepay.pay.channel;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.entity.RefundOrder;
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.pay.rqrs.refund.RefundOrderRQ;
/*
* 调起上游渠道侧退款接口
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/17 9:35
*/
public interface IRefundService {
/* 获取到接口code **/
String getIfCode();
/** 前置检查如参数等信息是否符合要求, 返回错误信息或直接抛出异常即可 */
String preCheck(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder);
/** 调起退款接口,并响应数据; 内部处理普通商户和服务商模式 **/
ChannelRetMsg refund(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception;
}
......@@ -55,7 +55,7 @@ public class AlipayKit {
else if(req instanceof AlipayTradePrecreateRequest) ((AlipayTradePrecreateRequest)req).putOtherTextParam("app_auth_token", isvsubMchParams.getAppAuthToken());
else if(req instanceof AlipayTradeWapPayRequest) ((AlipayTradeWapPayRequest)req).putOtherTextParam("app_auth_token", isvsubMchParams.getAppAuthToken());
else if(req instanceof AlipayTradeQueryRequest) ((AlipayTradeQueryRequest)req).putOtherTextParam("app_auth_token", isvsubMchParams.getAppAuthToken());
else if(req instanceof AlipayTradeRefundRequest) ((AlipayTradeRefundRequest)req).putOtherTextParam("app_auth_token", isvsubMchParams.getAppAuthToken());
// 服务商信息
ExtendParams extendParams = new ExtendParams();
......
/*
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jeequan.jeepay.pay.channel.alipay;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.entity.RefundOrder;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.pay.channel.AbstractRefundService;
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.pay.rqrs.refund.RefundOrderRQ;
import org.springframework.stereotype.Service;
/*
* 退款接口: 支付宝官方
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/17 9:38
*/
@Service
public class AlipayRefundService extends AbstractRefundService {
@Override
public String getIfCode() {
return CS.IF_CODE.ALIPAY;
}
@Override
public String preCheck(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder) {
return null;
}
@Override
public ChannelRetMsg refund(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
model.setOutTradeNo(refundOrder.getPayOrderId());
model.setTradeNo(refundOrder.getChannelPayOrderNo());
model.setOutRequestNo(refundOrder.getRefundOrderId());
model.setRefundAmount(AmountUtil.convertCent2Dollar(refundOrder.getRefundAmount().toString()));
model.setRefundReason(refundOrder.getRefundReason());
request.setBizModel(model);
//统一放置 isv接口必传信息
AlipayKit.putApiIsvInfo(mchAppConfigContext, request, model);
AlipayTradeRefundResponse response = mchAppConfigContext.getAlipayClientWrapper().execute(request);
ChannelRetMsg channelRetMsg = new ChannelRetMsg();
channelRetMsg.setChannelAttach(response.getBody());
channelRetMsg.setChannelOrderId(response.getTradeNo());
// 调用成功
if(response.isSuccess()){
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);
}else{
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
channelRetMsg.setChannelErrCode(response.getSubCode());
channelRetMsg.setChannelErrMsg(response.getSubMsg());
}
return channelRetMsg;
}
}
......@@ -15,14 +15,18 @@
*/
package com.jeequan.jeepay.pay.ctrl.refund;
import com.jeequan.jeepay.core.entity.*;
import com.jeequan.jeepay.core.entity.MchApp;
import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.entity.RefundOrder;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.pay.channel.IPaymentService;
import com.jeequan.jeepay.pay.channel.IRefundService;
import com.jeequan.jeepay.pay.ctrl.ApiController;
import com.jeequan.jeepay.pay.exception.ChannelException;
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.pay.rqrs.refund.RefundOrderRQ;
......@@ -57,10 +61,14 @@ public class RefundOrderController extends ApiController {
@PostMapping("/api/refund/refundOrder")
public ApiRes refundOrder(){
RefundOrder refundOrder = null;
//获取参数 & 验签
RefundOrderRQ rq = getRQByWithMchSign(RefundOrderRQ.class);
try {
//获取参数 & 验签
RefundOrderRQ rq = getRQByWithMchSign(RefundOrderRQ.class);
if(StringUtils.isAllEmpty(rq.getMchOrderNo(), rq.getPayOrderId())){
throw new BizException("mchOrderNo 和 payOrderId不能同时为空");
......@@ -68,13 +76,39 @@ public class RefundOrderController extends ApiController {
PayOrder payOrder = payOrderService.queryMchOrder(rq.getMchNo(), rq.getPayOrderId(), rq.getMchOrderNo());
if(payOrder == null){
throw new BizException("订单不存在");
throw new BizException("退款订单不存在");
}
if(payOrder.getState() != PayOrder.STATE_SUCCESS){
throw new BizException("订单状态不正确, 无法完成退款");
}
if(payOrder.getRefundState() == PayOrder.REFUND_STATE_ALL || payOrder.getRefundAmount() >= payOrder.getAmount()){
throw new BizException("订单已全额退款,本次申请失败");
}
if(payOrder.getRefundAmount() + rq.getRefundAmount() > payOrder.getAmount()){
throw new BizException("申请金额超出订单可退款余额,请检查退款金额");
}
if(refundOrderService.count(RefundOrder.gw().eq(RefundOrder::getPayOrderId, payOrder.getPayOrderId()).eq(RefundOrder::getState, RefundOrder.STATE_ING)) > 0){
throw new BizException("支付订单具有在途退款申请,请稍后再试");
}
//全部退款金额 (退款订单表)
Long sumSuccessRefundAmount = refundOrderService.getBaseMapper().sumSuccessRefundAmount(payOrder.getPayOrderId());
if(sumSuccessRefundAmount >= payOrder.getAmount()){
throw new BizException("退款单已完成全部订单退款,本次申请失败");
}
if(sumSuccessRefundAmount + rq.getRefundAmount() > payOrder.getAmount()){
throw new BizException("申请金额超出订单可退款余额,请检查退款金额");
}
String mchNo = rq.getMchNo();
String appId = rq.getAppId();
// 只有新订单模式,进行校验
// 校验退款单号是否重复
if(refundOrderService.count(RefundOrder.gw().eq(RefundOrder::getMchNo, mchNo).eq(RefundOrder::getMchRefundNo, rq.getMchRefundNo())) > 0){
throw new BizException("商户退款订单号["+rq.getMchRefundNo()+"]已存在");
}
......@@ -93,33 +127,44 @@ public class RefundOrderController extends ApiController {
MchApp mchApp = mchAppConfigContext.getMchApp();
//获取支付接口
// 接口代码 TODO
IPaymentService paymentService = SpringBeansUtil.getBean(payOrder.getIfCode() + "PaymentService", IPaymentService.class);
if(paymentService == null){
//获取退款接口
IRefundService refundService = SpringBeansUtil.getBean(payOrder.getIfCode() + "RefundService", IRefundService.class);
if(refundService == null){
throw new BizException("当前通道不支持退款!");
}
refundOrder = genRefundOrder(rq, payOrder, mchInfo, mchApp);
RefundOrder refundOrder = genRefundOrder(rq, payOrder, mchInfo, mchApp);
//订单入库 订单状态: 生成状态 此时没有和任何上游渠道产生交互。
//退款单入库 退款单状态:生成状态 此时没有和任何上游渠道产生交互。
refundOrderService.save(refundOrder);
//调起上游支付接口
// bizRS = (UnifiedOrderRS) paymentService.pay(bizRQ, payOrder, mchAppConfigContext);
// 调起退款接口
ChannelRetMsg channelRetMsg = null;
ChannelRetMsg channelRetMsg = refundService.refund(rq, refundOrder, payOrder, mchAppConfigContext);
//处理退款单状态
this.processChannelMsg(channelRetMsg, refundOrder);
RefundOrderRS bizRes = RefundOrderRS.buildByRefundOrder(refundOrder);
return ApiRes.okWithSign(bizRes, configContextService.getMchAppConfigContext(rq.getMchNo(), rq.getAppId()).getMchApp().getAppSecret());
} catch (BizException e) {
return ApiRes.customFail(e.getMessage());
} catch (ChannelException e) {
//处理上游返回数据
this.processChannelMsg(e.getChannelRetMsg(), refundOrder);
if(e.getChannelRetMsg().getChannelState() == ChannelRetMsg.ChannelState.SYS_ERROR ){
return ApiRes.customFail(e.getMessage());
}
RefundOrderRS bizRes = RefundOrderRS.buildByRefundOrder(refundOrder);
return ApiRes.okWithSign(bizRes, configContextService.getMchAppConfigContext(rq.getMchNo(), rq.getAppId()).getMchApp().getAppSecret());
} catch (Exception e) {
log.error("系统异常:{}", e);
return ApiRes.customFail("系统异常");
......@@ -160,38 +205,36 @@ public class RefundOrderController extends ApiController {
}
/** 处理返回的渠道信息,并更新单状态
/** 处理返回的渠道信息,并更新退款单状态
* payOrder将对部分信息进行 赋值操作。
* **/
private void processChannelMsg(ChannelRetMsg channelRetMsg, PayOrder payOrder){
private void processChannelMsg(ChannelRetMsg channelRetMsg, RefundOrder refundOrder){
//对象为空 || 上游返回状态为空, 则无需操作
if(channelRetMsg == null || channelRetMsg.getChannelState() == null){
return ;
}
String payOrderId = payOrder.getPayOrderId();
//明确成功
if(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS == channelRetMsg.getChannelState()) {
this.updateInitOrderStateThrowException(PayOrder.STATE_SUCCESS, payOrder, channelRetMsg);
this.updateInitOrderStateThrowException(RefundOrder.STATE_SUCCESS, refundOrder, channelRetMsg);
// payMchNotifyService.payOrderNotify(payOrder);
//明确失败
}else if(ChannelRetMsg.ChannelState.CONFIRM_FAIL == channelRetMsg.getChannelState()) {
this.updateInitOrderStateThrowException(PayOrder.STATE_FAIL, payOrder, channelRetMsg);
this.updateInitOrderStateThrowException(RefundOrder.STATE_FAIL, refundOrder, channelRetMsg);
// 上游处理中 || 未知 || 上游接口返回异常 订单为支付中状态
// 上游处理中 || 未知 || 上游接口返回异常 退款单为退款中状态
}else if( ChannelRetMsg.ChannelState.WAITING == channelRetMsg.getChannelState() ||
ChannelRetMsg.ChannelState.UNKNOWN == channelRetMsg.getChannelState() ||
ChannelRetMsg.ChannelState.API_RET_ERROR == channelRetMsg.getChannelState()
){
this.updateInitOrderStateThrowException(PayOrder.STATE_ING, payOrder, channelRetMsg);
this.updateInitOrderStateThrowException(RefundOrder.STATE_ING, refundOrder, channelRetMsg);
// 系统异常: 单不再处理。 为: 生成状态
// 系统异常: 退款单不再处理。 为: 生成状态
}else if( ChannelRetMsg.ChannelState.SYS_ERROR == channelRetMsg.getChannelState()){
}else{
......@@ -199,34 +242,28 @@ public class RefundOrderController extends ApiController {
throw new BizException("ChannelState 返回异常!");
}
//判断是否需要轮询查单
if(channelRetMsg.isNeedQuery()){
// mqChannelOrderQueryQueue.send(MqQueue4ChannelOrderQuery.buildMsg(payOrderId, 1), 5 * 1000);
}
}
/** 更新订单状态 --》 订单生成--》 其他状态 (向外抛出异常) **/
private void updateInitOrderStateThrowException(byte orderState, PayOrder payOrder, ChannelRetMsg channelRetMsg){
/** 更新退款单状态 --》 退款单生成--》 其他状态 (向外抛出异常) **/
private void updateInitOrderStateThrowException(byte orderState, RefundOrder refundOrder, ChannelRetMsg channelRetMsg){
payOrder.setState(orderState);
payOrder.setChannelOrderNo(channelRetMsg.getChannelOrderId());
payOrder.setErrCode(channelRetMsg.getChannelErrCode());
payOrder.setErrMsg(channelRetMsg.getChannelErrMsg());
refundOrder.setState(orderState);
refundOrder.setChannelOrderNo(channelRetMsg.getChannelOrderId());
refundOrder.setChannelErrCode(channelRetMsg.getChannelErrCode());
refundOrder.setChannelErrMsg(channelRetMsg.getChannelErrMsg());
boolean isSuccess = payOrderService.updateInit2Ing(payOrder.getPayOrderId(), payOrder.getIfCode(), payOrder.getWayCode());
boolean isSuccess = refundOrderService.updateInit2Ing(refundOrder.getRefundOrderId());
if(!isSuccess){
throw new BizException("更新单异常!");
throw new BizException("更新退款单异常!");
}
isSuccess = payOrderService.updateIng2SuccessOrFail(payOrder.getPayOrderId(), payOrder.getState(),
isSuccess = refundOrderService.updateIng2SuccessOrFail(refundOrder.getRefundOrderId(), refundOrder.getState(),
channelRetMsg.getChannelOrderId(), channelRetMsg.getChannelErrCode(), channelRetMsg.getChannelErrMsg());
if(!isSuccess){
throw new BizException("更新单异常!");
throw new BizException("更新退款单异常!");
}
}
}
......@@ -41,7 +41,7 @@ public class ChannelException extends RuntimeException{
/** 未知状态 **/
public static ChannelException unknown(String channelErrMsg){
return new ChannelException(ChannelRetMsg.sysError(channelErrMsg));
return new ChannelException(ChannelRetMsg.unknown(channelErrMsg));
}
/** 系统内异常 **/
......
......@@ -113,6 +113,11 @@ public class ChannelRetMsg implements Serializable {
return new ChannelRetMsg(ChannelState.UNKNOWN, null, null, null);
}
/** 状态未知的情况 **/
public static ChannelRetMsg unknown(String channelErrMsg){
return new ChannelRetMsg(ChannelState.UNKNOWN, null, null, channelErrMsg);
}
}
......
......@@ -15,10 +15,17 @@
*/
package com.jeequan.jeepay.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.core.entity.RefundOrder;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.service.mapper.PayOrderMapper;
import com.jeequan.jeepay.service.mapper.RefundOrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
/**
* <p>
......@@ -31,4 +38,74 @@ import org.springframework.stereotype.Service;
@Service
public class RefundOrderService extends ServiceImpl<RefundOrderMapper, RefundOrder> {
@Autowired private PayOrderMapper payOrderMapper;
/** 更新退款单状态 【退款单生成】 --》 【退款中】 **/
public boolean updateInit2Ing(String refundOrderId){
RefundOrder updateRecord = new RefundOrder();
updateRecord.setState(RefundOrder.STATE_ING);
return update(updateRecord, new LambdaUpdateWrapper<RefundOrder>()
.eq(RefundOrder::getRefundOrderId, refundOrderId).eq(RefundOrder::getState, RefundOrder.STATE_INIT));
}
/** 更新退款单状态 【退款中】 --》 【退款成功】 **/
@Transactional
public boolean updateIng2Success(String refundOrderId, String channelOrderNo){
RefundOrder updateRecord = new RefundOrder();
updateRecord.setState(RefundOrder.STATE_SUCCESS);
updateRecord.setChannelOrderNo(channelOrderNo);
updateRecord.setSuccessTime(new Date());
//1. 更新退款订单表数据
if(! update(updateRecord, new LambdaUpdateWrapper<RefundOrder>()
.eq(RefundOrder::getRefundOrderId, refundOrderId).eq(RefundOrder::getState, RefundOrder.STATE_ING))
){
return false;
}
//2. 更新订单表数据
RefundOrder refundOrder = getOne(RefundOrder.gw().select(RefundOrder::getPayOrderId, RefundOrder::getRefundAmount).eq(RefundOrder::getRefundOrderId, refundOrderId));
int updateCount = payOrderMapper.updateRefundAmountAndCount(refundOrder.getPayOrderId(), refundOrder.getRefundAmount());
if(updateCount <= 0){
throw new BizException("更新订单数据异常");
}
return true;
}
/** 更新退款单状态 【退款中】 --》 【退款失败】 **/
@Transactional
public boolean updateIng2Fail(String refundOrderId, String channelOrderNo, String channelErrCode, String channelErrMsg){
RefundOrder updateRecord = new RefundOrder();
updateRecord.setState(RefundOrder.STATE_FAIL);
updateRecord.setChannelErrCode(channelErrCode);
updateRecord.setChannelErrMsg(channelErrMsg);
updateRecord.setChannelOrderNo(channelOrderNo);
return update(updateRecord, new LambdaUpdateWrapper<RefundOrder>()
.eq(RefundOrder::getRefundOrderId, refundOrderId).eq(RefundOrder::getState, RefundOrder.STATE_ING));
}
/** 更新退款单状态 【退款中】 --》 【退款成功/退款失败】 **/
@Transactional
public boolean updateIng2SuccessOrFail(String refundOrderId, Byte updateState, String channelOrderNo, String channelErrCode, String channelErrMsg){
if(updateState == RefundOrder.STATE_ING){
return true;
}else if(updateState == RefundOrder.STATE_SUCCESS){
return updateIng2Success(refundOrderId, channelOrderNo);
}else if(updateState == RefundOrder.STATE_FAIL){
return updateIng2Fail(refundOrderId, channelOrderNo, channelErrCode, channelErrMsg);
}
return false;
}
}
......@@ -17,6 +17,7 @@ package com.jeequan.jeepay.service.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jeequan.jeepay.core.entity.PayOrder;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
......@@ -38,4 +39,7 @@ public interface PayOrderMapper extends BaseMapper<PayOrder> {
Map selectTotalCount(Map param);
List<Map> selectOrderCount(Map param);
/** 更新订单退款金额和次数 **/
int updateRefundAmountAndCount(@Param("payOrderId") String payOrderId, @Param("currentRefundAmount") Long currentRefundAmount);
}
......@@ -23,6 +23,7 @@
<result column="channel_extra" property="channelExtra" />
<result column="channel_user" property="channelUser" />
<result column="channel_order_no" property="channelOrderNo" />
<result column="refund_state" property="refundState" />
<result column="refund_times" property="refundTimes" />
<result column="refund_amount" property="refundAmount" />
<result column="division_flag" property="divisionFlag" />
......@@ -86,4 +87,19 @@
GROUP BY groupDate
ORDER BY groupDate desc
</select>
<!-- 更新订单退款金额和次数 -->
<update id="updateRefundAmountAndCount">
update t_pay_order
set refund_times = refund_times + 1, <!-- 退款次数 +1 -->
refund_state = CASE WHEN refund_amount + #{currentRefundAmount} >= amount THEN 2 ELSE 1 END, <!-- 更新是否已全额退款。 此更新需在refund_amount更新之前,否则需要去掉累加逻辑 -->
refund_amount = refund_amount + #{currentRefundAmount} <!-- 退款金额累加 -->
where
pay_order_id = #{payOrderId} and `state` = 2 <!-- 订单号 & 成功状态的可退款 -->
and refund_amount + #{currentRefundAmount} &lt;= amount <!-- 已退款金额 + 本次退款金额 小于等于订单金额 -->
and refund_state in (0, 1) <!-- 只有未发生退款和部分退款可退 -->
</update>
</mapper>
......@@ -28,4 +28,7 @@ import com.jeequan.jeepay.core.entity.RefundOrder;
*/
public interface RefundOrderMapper extends BaseMapper<RefundOrder> {
/** 查询全部退成功金额 **/
Long sumSuccessRefundAmount(String payOrderId);
}
......@@ -32,4 +32,9 @@
<result column="updated_at" property="updatedAt" />
</resultMap>
<select id="sumSuccessRefundAmount" resultType="Long">
select ifnull(sum(refund_amount), 0) from t_refund_order
where pay_order_id = #{payOrderId} and state = 2
</select>
</mapper>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册