diff --git a/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java b/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java index 9ba590979..1539b3649 100644 --- a/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java +++ b/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java @@ -979,6 +979,9 @@ public class OrderService { } else if (AdapayEventEnum.refund_succeeded.getValue().equals(type)) { // 退款成功 refundSucceeded(data); + } else if (AdapayEventEnum.refund_failed.getValue().equals(type)) { + // 退款失败 + refundFailed(data); } else if (AdapayEventEnum.corp_member_failed.getValue().equals(type)) { // 开户失败 删除 corpMemberFailed(data); @@ -1121,13 +1124,47 @@ public class OrderService { * 汇付退款成功 */ private void refundSucceeded(String data) { + log.info("退款成功 data:{}", JSON.toJSONString(data)); // 保存退款回调记录 adapayRefundRecordService.saveAdapayRefundRecord(data); + + JSONObject jsonObject = JSON.parseObject(data); + JSONObject reason = jsonObject.getJSONObject("reason"); + if (ScenarioEnum.BALANCE.getValue().equals(reason.getString("scenarioType"))) { + // 这笔支付订单原来是充值余额的,退款成功了,需要扣掉会员的本金金额 + UpdateMemberBalanceDTO dto = new UpdateMemberBalanceDTO(); + String memberId = reason.getString("memberId"); + dto.setMemberId(memberId); + dto.setUpdatePrincipalBalance(new BigDecimal(jsonObject.getString("refund_amt"))); // 更新会员本金金额,单位元 + dto.setType(MemberWalletEnum.TYPE_OUT.getValue()); + dto.setSubType(MemberWalletEnum.SUBTYPE_USER_REFUND.getValue()); + memberBasicInfoService.updateMemberBalance(dto); + + // 收到回调,删除缓存 + String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + memberId; + redisCache.deleteObject(redisKey); + } + } + + /** + * 退款失败 + * @param data + */ + private void refundFailed(String data) { + log.info("退款失败 data:{}", JSON.toJSONString(data)); + JSONObject jsonObject = JSON.parseObject(data); + JSONObject reason = jsonObject.getJSONObject("reason"); + if (ScenarioEnum.BALANCE.getValue().equals(reason.getString("scenarioType"))) { + String memberId = reason.getString("memberId"); + + // 收到回调,删除缓存 + String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + memberId; + redisCache.deleteObject(redisKey); + } } /** * 对公账户创建失败 - * @param data */ private void corpMemberFailed(String data) { // 删除表中的记录 @@ -1147,7 +1184,6 @@ public class OrderService { /** * 对公账户创建成功 - * @param data */ private void corpMemberSucceeded(String data) { JSONObject jsonObject = JSON.parseObject(data); diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/operation/PaymentRefundOperation.java b/jsowell-pile/src/main/java/com/jsowell/adapay/operation/PaymentRefundOperation.java new file mode 100644 index 000000000..d7cc4fc5b --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/operation/PaymentRefundOperation.java @@ -0,0 +1,19 @@ +package com.jsowell.adapay.operation; + +import lombok.*; + +import java.math.BigDecimal; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class PaymentRefundOperation extends AdapayOperationInfo{ + private String paymentId; + private BigDecimal refundAmt; + private String wechatAppId; + private String memberId; + private String scenarioType; + private String orderCode; +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/orderlogic/DelayMerchantOrderLogic.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/orderlogic/DelayMerchantOrderLogic.java index 024dba769..c8c712b2d 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/orderlogic/DelayMerchantOrderLogic.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/orderlogic/DelayMerchantOrderLogic.java @@ -14,6 +14,7 @@ import com.jsowell.adapay.config.AbstractAdapayConfig; import com.jsowell.adapay.factory.AdapayConfigFactory; import com.jsowell.adapay.operation.PaymentReverseOperation; import com.jsowell.adapay.response.PaymentReverseResponse; +import com.jsowell.common.constant.CacheConstants; import com.jsowell.common.constant.Constants; import com.jsowell.common.core.domain.ykc.TransactionRecordsData; import com.jsowell.common.enums.AcquirerEnum; @@ -493,7 +494,51 @@ public class DelayMerchantOrderLogic extends AbstractOrderLogic { */ @Override public void refundBalance(ApplyRefundDTO dto) { + // 做个拦截,如果前一笔退款没有完成,就抛异常 + String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + dto.getMemberId(); + PaymentReverseResponse redisResult = redisCache.getCacheObject(redisKey); + if (Objects.nonNull(redisResult)) { + throw new BusinessException(ReturnCodeEnum.CODE_BALANCE_REFUNDS_ARE_IN_PROGRESS_ERROR); + } + // 查会员余额 + MemberVO memberVO = memberBasicInfoService.queryMemberInfoByMemberId(dto.getMemberId()); + if (memberVO == null) { + throw new BusinessException(ReturnCodeEnum.CODE_MEMBER_NOT_FOUND_ERROR); + } + + // 校验退款金额 + BigDecimal principalBalance = memberVO.getPrincipalBalance(); + BigDecimal refundAmount = dto.getRefundAmount(); + if (refundAmount.compareTo(principalBalance) > 0) { + throw new BusinessException(ReturnCodeEnum.CODE_REFUND_MEMBER_BALANCE_ERROR); + } + + // 查询用户充值余额订单 过滤掉已经退款的充值订单 + List list = calculateTheBalanceDeductionAmount(dto.getMemberId(), refundAmount); + for (BalanceDeductionAmountVO vo : list) { + String paymentId = vo.getPaymentId(); + BigDecimal deductionAmount = vo.getDeductionAmount(); + + // 调汇付的交易撤销接口 + // PaymentReverseResponse paymentReverseRequest = adapayService.createPaymentReverseRequest(paymentId, deductionAmount, dto.getWechatAppId(), + // dto.getMemberId(), ScenarioEnum.BALANCE.getValue(), null); + + PaymentReverseOperation operation = new PaymentReverseOperation(); + operation.setPaymentId(paymentId); + operation.setReverseAmt(deductionAmount); + operation.setMerchantKey(dto.getWechatAppId()); + operation.setMemberId(dto.getMemberId()); + operation.setScenarioType(ScenarioEnum.BALANCE.getValue()); + PaymentReverseResponse paymentReverseRequest = adapayService.createPaymentReverseRequest(operation); + + if (paymentReverseRequest != null && paymentReverseRequest.isNotFailed()) { + memberAdapayRecordService.updateRefundAmount(paymentId, deductionAmount); + + // 放缓存 + redisCache.setCacheObject(redisKey, paymentReverseRequest, CacheConstants.cache_expire_time_30m); + } + } } /** diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/orderlogic/NotDelayMerchantOrderLogic.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/orderlogic/NotDelayMerchantOrderLogic.java index 0e0c41dbb..9006aa077 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/orderlogic/NotDelayMerchantOrderLogic.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/orderlogic/NotDelayMerchantOrderLogic.java @@ -12,6 +12,7 @@ import com.jsowell.adapay.common.CreateAdaPaymentParam; import com.jsowell.adapay.config.AbstractAdapayConfig; import com.jsowell.adapay.factory.AdapayConfigFactory; import com.jsowell.adapay.response.RefundResponse; +import com.jsowell.common.constant.CacheConstants; import com.jsowell.common.constant.Constants; import com.jsowell.common.core.domain.ykc.TransactionRecordsData; import com.jsowell.common.enums.AcquirerEnum; @@ -465,7 +466,43 @@ public class NotDelayMerchantOrderLogic extends AbstractOrderLogic{ */ @Override public void refundBalance(ApplyRefundDTO dto) { + // 做个拦截,如果前一笔退款没有完成,就抛异常 + String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + dto.getMemberId(); + RefundResponse redisResult = redisCache.getCacheObject(redisKey); + if (Objects.nonNull(redisResult)) { + throw new BusinessException(ReturnCodeEnum.CODE_BALANCE_REFUNDS_ARE_IN_PROGRESS_ERROR); + } + // 查会员余额 + MemberVO memberVO = memberBasicInfoService.queryMemberInfoByMemberId(dto.getMemberId()); + if (memberVO == null) { + throw new BusinessException(ReturnCodeEnum.CODE_MEMBER_NOT_FOUND_ERROR); + } + + // 校验退款金额 + BigDecimal principalBalance = memberVO.getPrincipalBalance(); + BigDecimal refundAmount = dto.getRefundAmount(); + if (refundAmount.compareTo(principalBalance) > 0) { + throw new BusinessException(ReturnCodeEnum.CODE_REFUND_MEMBER_BALANCE_ERROR); + } + + // 查询用户充值余额订单 过滤掉已经退款的充值订单 + List list = calculateTheBalanceDeductionAmount(dto.getMemberId(), refundAmount); + for (BalanceDeductionAmountVO vo : list) { + String paymentId = vo.getPaymentId(); + BigDecimal deductionAmount = vo.getDeductionAmount(); + + // 调汇付的交易退款接口 + RefundResponse refundRequest = adapayService.createRefundRequest(paymentId, refundAmount, + dto.getWechatAppId(), dto.getMemberId(), ScenarioEnum.ORDER.getValue(), dto.getOrderCode()); + + if (refundRequest != null && refundRequest.isNotFailed()) { + memberAdapayRecordService.updateRefundAmount(paymentId, deductionAmount); + + // 放缓存 + redisCache.setCacheObject(redisKey, refundRequest, CacheConstants.cache_expire_time_30m); + } + } } // uniApp 发送停止充电订阅消息