| @@ -0,0 +1,2 @@ | |||||
| ALTER TABLE `mallink`.`wx_card_spend` | |||||
| ADD COLUMN `pay_type` smallint(2) NOT NULL DEFAULT 0 AFTER `owner_id`; | |||||
| @@ -10,23 +10,9 @@ import com.iformall.domain.po.*; | |||||
| import com.iformall.domain.po.base.BaseEntity; | import com.iformall.domain.po.base.BaseEntity; | ||||
| import com.iformall.domain.vo.WxCardSpendVo; | import com.iformall.domain.vo.WxCardSpendVo; | ||||
| import com.iformall.domain.vo.WxCouponOrderCVo; | import com.iformall.domain.vo.WxCouponOrderCVo; | ||||
| import com.iformall.enums.EnumCardInfoStatus; | |||||
| import com.iformall.enums.EnumCouponPasswordStatus; | |||||
| import com.iformall.enums.EnumCouponStatus; | |||||
| import com.iformall.enums.EnumCreditLockedStatus; | |||||
| import com.iformall.enums.EnumMerchantStatus; | |||||
| import com.iformall.enums.EnumMerchantSubsidySource; | |||||
| import com.iformall.enums.EnumPayWay; | |||||
| import com.iformall.enums.EnumYesOrNo; | |||||
| import com.iformall.enums.*; | |||||
| import com.iformall.exception.MallinkException; | import com.iformall.exception.MallinkException; | ||||
| import com.iformall.service.WxCUserBasicInfoService; | |||||
| import com.iformall.service.WxCardInfoService; | |||||
| import com.iformall.service.WxCardSpendService; | |||||
| import com.iformall.service.WxCouponOrderService; | |||||
| import com.iformall.service.WxCouponPasswordService; | |||||
| import com.iformall.service.WxCouponService; | |||||
| import com.iformall.service.WxMerchantService; | |||||
| import com.iformall.service.WxOrderService; | |||||
| import com.iformall.service.*; | |||||
| import com.iformall.utils.Constant; | import com.iformall.utils.Constant; | ||||
| import com.iformall.utils.DateUtils; | import com.iformall.utils.DateUtils; | ||||
| @@ -80,6 +66,9 @@ public class WxCardPayController extends BaseController { | |||||
| @Autowired | @Autowired | ||||
| WxCouponService wxCouponService; | WxCouponService wxCouponService; | ||||
| @Autowired | |||||
| WxRefundOrderService wxRefundOrderService; | |||||
| @ApiOperation("C端扫B端储值卡交易流水(消费记录 + 补贴)列表接口") | @ApiOperation("C端扫B端储值卡交易流水(消费记录 + 补贴)列表接口") | ||||
| @GetMapping("list") | @GetMapping("list") | ||||
| @ApiImplicitParams({ | @ApiImplicitParams({ | ||||
| @@ -117,6 +106,7 @@ public class WxCardPayController extends BaseController { | |||||
| String cardIdStr = paramMap.get("dynamicId"); | String cardIdStr = paramMap.get("dynamicId"); | ||||
| String totalFeeStr = paramMap.get("totalFee"); | String totalFeeStr = paramMap.get("totalFee"); | ||||
| String cardPayTypeStr = paramMap.get("cardPayType"); | |||||
| String password = paramMap.get("password"); | String password = paramMap.get("password"); | ||||
| if (StringUtils.isBlank(cardIdStr) || cardIdStr.equalsIgnoreCase(Constant.UNDEFINED)) { | if (StringUtils.isBlank(cardIdStr) || cardIdStr.equalsIgnoreCase(Constant.UNDEFINED)) { | ||||
| @@ -126,9 +116,24 @@ public class WxCardPayController extends BaseController { | |||||
| if (StringUtils.isBlank(totalFeeStr) || totalFeeStr.equalsIgnoreCase(Constant.UNDEFINED)) { | if (StringUtils.isBlank(totalFeeStr) || totalFeeStr.equalsIgnoreCase(Constant.UNDEFINED)) { | ||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "totalFee不能为空"); | return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "totalFee不能为空"); | ||||
| } | } | ||||
| EnumCardSpendFrom cardPayType = null; | |||||
| if(StringUtils.isNotBlank(cardPayTypeStr)){ | |||||
| try{ | |||||
| int payType = Integer.parseInt(cardPayTypeStr); | |||||
| cardPayType = EnumCardSpendFrom.getEnum(payType); | |||||
| }catch(Exception e){ | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(), "cardPayType格式不正确"); | |||||
| } | |||||
| } | |||||
| String _decodeCouponOrderId = WxCouponOrderCVo.getDecodeExpiredCouponOrderId(cardIdStr); | String _decodeCouponOrderId = WxCouponOrderCVo.getDecodeExpiredCouponOrderId(cardIdStr); | ||||
| if (_decodeCouponOrderId.contains(WxCouponOrderCVo.arg)) { | if (_decodeCouponOrderId.contains(WxCouponOrderCVo.arg)) { | ||||
| if(cardPayType == null){ | |||||
| cardPayType = EnumCardSpendFrom.C; | |||||
| } | |||||
| String[] decodeids = _decodeCouponOrderId.split(WxCouponOrderCVo.arg); | String[] decodeids = _decodeCouponOrderId.split(WxCouponOrderCVo.arg); | ||||
| cardIdStr = decodeids[0]; | cardIdStr = decodeids[0]; | ||||
| String expiredtimeStr = decodeids[1]; | String expiredtimeStr = decodeids[1]; | ||||
| @@ -140,20 +145,29 @@ public class WxCardPayController extends BaseController { | |||||
| if (StringUtils.isBlank(cUserIdStr) || cUserIdStr.equalsIgnoreCase(Constant.UNDEFINED)) { | if (StringUtils.isBlank(cUserIdStr) || cUserIdStr.equalsIgnoreCase(Constant.UNDEFINED)) { | ||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "cUserId不能为空"); | return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "cUserId不能为空"); | ||||
| } | } | ||||
| return saveECardCardPayOrder(cardIdStr,cUserIdStr,totalFeeStr); | |||||
| }else { | |||||
| return savePasswordCardPayOrder(cardIdStr,totalFeeStr,password); | |||||
| return saveECardCardPayOrder(cardIdStr,cUserIdStr,totalFeeStr,cardPayType); | |||||
| }else if(EnumCardSpendFrom.phone.equals(cardPayType)){ | |||||
| return saveECardCardPayOrder(cardIdStr,null,totalFeeStr,cardPayType); | |||||
| }else{ | |||||
| if(cardPayType == null){ | |||||
| cardPayType = EnumCardSpendFrom.card; | |||||
| } | |||||
| return savePasswordCardPayOrder(cardIdStr,totalFeeStr,password,cardPayType); | |||||
| } | } | ||||
| } | } | ||||
| private ResultData saveECardCardPayOrder(String cardIdStr,String cUserIdStr,String totalFeeStr) { | |||||
| Long cUserId = null; | |||||
| try { | |||||
| cUserId = Long.valueOf(cUserIdStr); | |||||
| } catch (Exception e) { | |||||
| logger.error("cardId convert failed:" + cardIdStr); | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "cardIdStr转换失败"); | |||||
| private ResultData saveECardCardPayOrder(String cardIdStr,String cUserIdStr,String totalFeeStr,EnumCardSpendFrom cardPayType) { | |||||
| Long cUserId = null; | |||||
| if(StringUtils.isNotBlank(cUserIdStr)){ | |||||
| try { | |||||
| cUserId = Long.valueOf(cUserIdStr); | |||||
| } catch (Exception e) { | |||||
| logger.error("cardId convert failed:" + cardIdStr); | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "cardIdStr转换失败"); | |||||
| } | |||||
| } | } | ||||
| WxMerchantBUser merchantBUser = getLoginBUser(); | WxMerchantBUser merchantBUser = getLoginBUser(); | ||||
| Long cardId = null; | Long cardId = null; | ||||
| try { | try { | ||||
| @@ -168,10 +182,13 @@ public class WxCardPayController extends BaseController { | |||||
| logger.error("卡不存在: " + cardIdStr); | logger.error("卡不存在: " + cardIdStr); | ||||
| return new ResultData(ErrorCode.CARD_IS_NOT_FOUND); | return new ResultData(ErrorCode.CARD_IS_NOT_FOUND); | ||||
| } | } | ||||
| return saveCardPayOrder(cUserId,cardInfo,merchantBUser,totalFeeStr,true); | |||||
| if (cUserId != null && !cardInfo.getOwnerUserId().equals(cUserId)) { | |||||
| return new ResultData(ErrorCode.CARD_TRANSFERED); | |||||
| } | |||||
| return saveCardPayOrder(cUserId,cardInfo,merchantBUser,totalFeeStr,cardPayType); | |||||
| } | } | ||||
| public ResultData savePasswordCardPayOrder(String cardIdStr,String totalFeeStr,String password) { | |||||
| public ResultData savePasswordCardPayOrder(String cardIdStr,String totalFeeStr,String password,EnumCardSpendFrom cardPayType) { | |||||
| Long cardId = null; | Long cardId = null; | ||||
| try { | try { | ||||
| cardId = Long.valueOf(cardIdStr); | cardId = Long.valueOf(cardIdStr); | ||||
| @@ -216,10 +233,10 @@ public class WxCardPayController extends BaseController { | |||||
| if (null == cardInfo) { | if (null == cardInfo) { | ||||
| cardInfo = wxCardInfoService.cardCreateByOffline(couponPassword, coupon); | cardInfo = wxCardInfoService.cardCreateByOffline(couponPassword, coupon); | ||||
| } | } | ||||
| return saveCardPayOrder(cardInfo.getOwnerUserId(),cardInfo,merchantBUser,totalFeeStr,false); | |||||
| return saveCardPayOrder(cardInfo.getOwnerUserId(),cardInfo,merchantBUser,totalFeeStr,cardPayType); | |||||
| } | } | ||||
| private ResultData saveCardPayOrder(Long cUserId,WxCardInfo cardInfo,WxMerchantBUser merchantBUser,String totalFeeStr,boolean isEcard) { | |||||
| private ResultData saveCardPayOrder(Long cUserId,WxCardInfo cardInfo,WxMerchantBUser merchantBUser,String totalFeeStr,EnumCardSpendFrom cardPayType) { | |||||
| if (EnumCardInfoStatus.STOP.getCode().intValue() == cardInfo.getStatus().intValue()) { | if (EnumCardInfoStatus.STOP.getCode().intValue() == cardInfo.getStatus().intValue()) { | ||||
| return new ResultData(ErrorCode.CARD_IS_NOT_FOUND.getCode(),"卡已被禁用."); | return new ResultData(ErrorCode.CARD_IS_NOT_FOUND.getCode(),"卡已被禁用."); | ||||
| @@ -247,16 +264,6 @@ public class WxCardPayController extends BaseController { | |||||
| return new ResultData(ErrorCode.CARD_REMAIN_AMOUNT_IS_NOT_ENOUGH); | return new ResultData(ErrorCode.CARD_REMAIN_AMOUNT_IS_NOT_ENOUGH); | ||||
| } | } | ||||
| //查看所有者与扫码者是否为一致 | |||||
| if (!cardInfo.getOwnerUserId().equals(cUserId)) { | |||||
| return new ResultData(ErrorCode.CARD_TRANSFERED); | |||||
| } | |||||
| // WxCouponOrder couponOrder = wxCouponOrderService.getById(cardInfo.getId(),cardInfo.getTenantId()); | |||||
| // if (!couponOrder.getOwnerId().equals(cUserId)) { | |||||
| // logger.error("卡已被领取: " + cardInfo.getId()); | |||||
| // return new ResultData(ErrorCode.CARD_TRANSFERED); | |||||
| // } | |||||
| WxCouponMerchant couponMerchant = wxCardSpendService.checkMerchantInCoupon(cardInfo, merchantId); | WxCouponMerchant couponMerchant = wxCardSpendService.checkMerchantInCoupon(cardInfo, merchantId); | ||||
| if(couponMerchant == null) { | if(couponMerchant == null) { | ||||
| logger.error("商户不支持此卡 " + cardInfo.getId()); | logger.error("商户不支持此卡 " + cardInfo.getId()); | ||||
| @@ -288,11 +295,8 @@ public class WxCardPayController extends BaseController { | |||||
| record.setOrderId(order.getId()); | record.setOrderId(order.getId()); | ||||
| record.setIp(ipStr); | record.setIp(ipStr); | ||||
| record.setDeductionAmount(payment); | record.setDeductionAmount(payment); | ||||
| if (isEcard) { | |||||
| record.setRemark("操作于[B扫C电子卡支付]"); | |||||
| }else { | |||||
| record.setRemark("操作于[B扫C实体卡支付]"); | |||||
| } | |||||
| record.setPayFrom(cardPayType.getCode()); | |||||
| record.setRemark(cardPayType.getMessage()); | |||||
| try { | try { | ||||
| return wxCardSpendService.createCardSpend(record, order, couponMerchant); | return wxCardSpendService.createCardSpend(record, order, couponMerchant); | ||||
| @@ -304,7 +308,71 @@ public class WxCardPayController extends BaseController { | |||||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, e.getMessage()); | return new ResultData(ErrorCode.PAY_ORDER_ERROR, e.getMessage()); | ||||
| } | } | ||||
| } | } | ||||
| @ApiOperation(value = "微信B端储值卡退款", notes = "params:{\"cardSpendId\":\"String\",\"refundFee\":\"String(元)\"}") | |||||
| @PostMapping("refundCardOrder") | |||||
| public ResultData refundCardOrder(@RequestBody Map<String, String> paramMap, HttpServletRequest request) { | |||||
| logger.info("refundCardOrder:"+JSON.toJSONString(paramMap)); | |||||
| String cardSpendIdStr = paramMap.get("cardSpendId"); | |||||
| String refundFeeStr = paramMap.get("refundFee"); | |||||
| if (StringUtils.isBlank(cardSpendIdStr) || cardSpendIdStr.equalsIgnoreCase(Constant.UNDEFINED)) { | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "cardSpendId不能为空"); | |||||
| } | |||||
| Long cardSpendId = null; | |||||
| try { | |||||
| cardSpendId = Long.valueOf(cardSpendIdStr); | |||||
| } catch (Exception e) { | |||||
| logger.error("cardSpendId convert failed:" + cardSpendIdStr); | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "cardSpendId格式不正确"); | |||||
| } | |||||
| if (StringUtils.isBlank(refundFeeStr) || refundFeeStr.equalsIgnoreCase(Constant.UNDEFINED)) { | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "refundFee不能为空"); | |||||
| } | |||||
| Integer refund = null; | |||||
| try{ | |||||
| BigDecimal refundFee = new BigDecimal(refundFeeStr); | |||||
| refundFee.setScale(2, BigDecimal.ROUND_HALF_UP); // 第一个变量是小数位数,第二个变量是取舍方法(四舍五入) | |||||
| refund = refundFee.multiply(new BigDecimal(100)).intValue(); | |||||
| }catch(Exception e){ | |||||
| logger.error("refundFee convert failed:" + refundFeeStr); | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "refundFee格式不正确"); | |||||
| } | |||||
| if(refund.intValue() <= 0){ | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "refundFee格式不正确"); | |||||
| } | |||||
| WxCardSpend cardSend = wxCardSpendService.getById(cardSpendId); | |||||
| if(cardSend == null || EnumPayType.PAY_PAYMENT.getCode().equals(cardSend.getPayType())){ | |||||
| return new ResultData(ErrorCode.ORDER_IS_NOT_FIND.getCode(), "未找到订单"); | |||||
| } | |||||
| if(!getLoginBUser().getMerchantId().equals(cardSend.getMerchantId())){ | |||||
| return new ResultData(ErrorCode.ORDER_IS_NOT_FIND.getCode(), "该门店与订单不匹配"); | |||||
| } | |||||
| if(refund > cardSend.getDeductionAmount()){ | |||||
| return new ResultData(ErrorCode.ORDER_PAY_REFUND_FAIL.getCode(), "退款金额大于订单金额"); | |||||
| } | |||||
| try { | |||||
| wxRefundOrderService.createRefundCardOrder(cardSend,refund,getLoginBUser()); | |||||
| return new ResultData(); | |||||
| } catch (MallinkException e) { | |||||
| logger.error(e.getMessage(),e); | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } catch (Exception e) { | |||||
| logger.error(e.getMessage(),e); | |||||
| return new ResultData(ErrorCode.REFUND_ORDER_ERROR); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -19,6 +19,9 @@ public class WxCardSpend extends TenantEntity { | |||||
| protected Long id; | protected Long id; | ||||
| @io.swagger.annotations.ApiModelProperty(value="EnumPayType",name="payType") | |||||
| private Integer payType; | |||||
| @io.swagger.annotations.ApiModelProperty(value="储值卡ID",name="cardId") | @io.swagger.annotations.ApiModelProperty(value="储值卡ID",name="cardId") | ||||
| private Long cardId; | private Long cardId; | ||||
| @TableField(exist = false) | @TableField(exist = false) | ||||
| @@ -7,8 +7,11 @@ public enum EnumCardSpendFrom { | |||||
| // 0:C端小程序扫一扫, 1:POS支付 | // 0:C端小程序扫一扫, 1:POS支付 | ||||
| C(0, "微信小程序支付"), | |||||
| POS(1, "POS支付") | |||||
| C(0, "B扫C电子卡收款"), | |||||
| POS(1, "pos扫码收款"), | |||||
| card(2,"B扫实体卡收款"), | |||||
| phone(3,"B手机号查询收款"), | |||||
| pay(4,"C扫B付款"), | |||||
| ; | ; | ||||
| public static EnumCardSpendFrom getEnum(Integer code) { | public static EnumCardSpendFrom getEnum(Integer code) { | ||||
| @@ -14,6 +14,7 @@ import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
| import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
| import java.util.Date; | |||||
| import java.util.List; | import java.util.List; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| @@ -82,6 +83,8 @@ public interface WxCardSpendService { | |||||
| */ | */ | ||||
| int finishCard(WxCardInfo cardInfo); | int finishCard(WxCardInfo cardInfo); | ||||
| boolean cardFinishedUsing(Date curDate, WxCardInfo cardInfo); | |||||
| /** | /** | ||||
| * 根据Id删除实体 | * 根据Id删除实体 | ||||
| * | * | ||||
| @@ -113,4 +113,9 @@ public interface WxRefundOrderService { | |||||
| ResultData ttCallBackCreateRefundOrder(TenantEntity tenantEntity, Long memberId, RefundOrderCallback refundOrderCallback); | ResultData ttCallBackCreateRefundOrder(TenantEntity tenantEntity, Long memberId, RefundOrderCallback refundOrderCallback); | ||||
| ResultData syncRefundOrder(WxAppinfo appinfo, WxPayAccount payAccount, WxRefundOrder order); | ResultData syncRefundOrder(WxAppinfo appinfo, WxPayAccount payAccount, WxRefundOrder order); | ||||
| ResultData createRefundCardOrder(WxCardSpend cardSend, Integer refundFeeStr, WxMerchantBUser bUser); | |||||
| ResultData refundCardOrderSuccess(WxRefundOrder refundOrder,WxOrder wxOrder); | |||||
| } | } | ||||
| @@ -182,7 +182,9 @@ public class WxCardSpendServiceImpl implements WxCardSpendService { | |||||
| // 5 insert card_spend | // 5 insert card_spend | ||||
| record.setId(idWorker.nextId()); | record.setId(idWorker.nextId()); | ||||
| record.updateTenantInfo(cardInfo); | record.updateTenantInfo(cardInfo); | ||||
| record.setPayFrom(EnumCardSpendFrom.C.getCode()); | |||||
| if(record.getPayFrom() == null){ | |||||
| record.setPayFrom(EnumCardSpendFrom.C.getCode()); | |||||
| } | |||||
| record.setPayment(payment); | record.setPayment(payment); | ||||
| record.setRealPayment(real_payment); | record.setRealPayment(real_payment); | ||||
| record.setCardBeforeAmount(cardInfo.getRemainingAmount()); | record.setCardBeforeAmount(cardInfo.getRemainingAmount()); | ||||
| @@ -442,6 +444,29 @@ public class WxCardSpendServiceImpl implements WxCardSpendService { | |||||
| return false; | return false; | ||||
| } | } | ||||
| /** | |||||
| * 卡重新启用 | |||||
| * | |||||
| * @param curDate | |||||
| * @param cardInfo | |||||
| * @return | |||||
| */ | |||||
| @Override | |||||
| public boolean cardFinishedUsing(Date curDate, WxCardInfo cardInfo) { | |||||
| WxCouponOrder couponOrder = new WxCouponOrder(); | |||||
| couponOrder.setId(cardInfo.getId()); | |||||
| couponOrder.setCouponId(cardInfo.getCouponId()); | |||||
| couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.CARD_USING.getCode()); | |||||
| couponOrder.setUpdateDate(curDate); | |||||
| try { | |||||
| wxCouponOrderMapper.updateById(couponOrder); | |||||
| } catch (Exception e) { | |||||
| logger.error("couponOrder status update error"); | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| private Map<Long,WxMerchant> getMerchantMap(List<Long> merchantIdList,TenantEntity tenantEntity) { | private Map<Long,WxMerchant> getMerchantMap(List<Long> merchantIdList,TenantEntity tenantEntity) { | ||||
| Map<Long,WxMerchant> merchantMap = new HashMap<Long,WxMerchant>(); | Map<Long,WxMerchant> merchantMap = new HashMap<Long,WxMerchant>(); | ||||
| if (merchantIdList.size() > 0 ){ | if (merchantIdList.size() > 0 ){ | ||||
| @@ -19,14 +19,13 @@ import com.iformall.enums.*; | |||||
| import com.iformall.exception.MallinkException; | import com.iformall.exception.MallinkException; | ||||
| import com.iformall.mapper.*; | import com.iformall.mapper.*; | ||||
| import com.iformall.mq.MqBaseProducer; | import com.iformall.mq.MqBaseProducer; | ||||
| import com.iformall.service.WxAppinfoService; | |||||
| import com.iformall.service.WxOrderService; | |||||
| import com.iformall.service.WxRefundOrderService; | |||||
| import com.iformall.service.*; | |||||
| import com.iformall.service.pay.PayServiceFactory; | import com.iformall.service.pay.PayServiceFactory; | ||||
| import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | ||||
| import com.iformall.service.pay.service.refund.entity.RefundAdapterResult; | import com.iformall.service.pay.service.refund.entity.RefundAdapterResult; | ||||
| import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult; | import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult; | ||||
| import com.iformall.utils.DateUtils; | import com.iformall.utils.DateUtils; | ||||
| import com.iformall.utils.PayUtils; | |||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| @@ -47,6 +46,9 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| @Autowired | @Autowired | ||||
| WxAppinfoService wxAppinfoService; | WxAppinfoService wxAppinfoService; | ||||
| @Autowired | |||||
| WxPayAccountService wxPayAccountService; | |||||
| @Autowired | @Autowired | ||||
| WxRefundOrderMapper wxRefundOrderMapper; | WxRefundOrderMapper wxRefundOrderMapper; | ||||
| @@ -63,6 +65,9 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| @Autowired | @Autowired | ||||
| WxOrderService wxOrderService; | WxOrderService wxOrderService; | ||||
| @Autowired | |||||
| WxCardSpendService wxCardSpendService; | |||||
| @Autowired | @Autowired | ||||
| WxCouponOrderMapper wxCouponOrderMapper; | WxCouponOrderMapper wxCouponOrderMapper; | ||||
| @@ -93,6 +98,15 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| @Autowired | @Autowired | ||||
| WxBatchOrderMapper wxBatchOrderMapper; | WxBatchOrderMapper wxBatchOrderMapper; | ||||
| @Autowired | |||||
| WxCardInfoMapper wxCardInfoMapper; | |||||
| @Autowired | |||||
| WxCardSpendMapper wxCardSpendMapper; | |||||
| @Autowired | |||||
| WxMerchantSubsidyMapper wxMerchantSubsidyMapper; | |||||
| @Autowired | @Autowired | ||||
| private MqBaseProducer mqBaseProducer; | private MqBaseProducer mqBaseProducer; | ||||
| @@ -1086,5 +1100,260 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| return new ResultData(); | return new ResultData(); | ||||
| } | } | ||||
| @Override | |||||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||||
| public ResultData createRefundCardOrder(WxCardSpend cardSend, Integer refundFee, WxMerchantBUser bUser) { | |||||
| WxOrder wxOrder = wxOrderMapper.selectById(cardSend.getOrderId(),cardSend.getTenantId()); | |||||
| if (wxOrder == null) { | |||||
| logger.error("交易订单不存在:" + cardSend.getOrderId()); | |||||
| throw new MallinkException(ErrorCode.ORDER_IS_NOT_FIND); | |||||
| } | |||||
| if(!EnumOrderStatus.ORDER_STATUS_PAYMENT_SUCCESS.getCode().equals(wxOrder.getOrderStatus())){ | |||||
| logger.error("交易订单状态不支持退款:" + EnumOrderStatus.getEnum(wxOrder.getOrderStatus()).getMessage()); | |||||
| throw new MallinkException(ErrorCode.ORDER_PAY_REFUND_FAIL); | |||||
| } | |||||
| if(refundFee > cardSend.getDeductionAmount()){ | |||||
| return new ResultData(ErrorCode.ORDER_PAY_REFUND_FAIL.getCode(), "退款金额大于订单金额"); | |||||
| } | |||||
| Date currentDate = new Date(); | |||||
| //这里wx_order不创建退款订单了, 直接修改原订单 | |||||
| WxOrder updWxOrder = new WxOrder(); | |||||
| updWxOrder.setId(wxOrder.getId()); | |||||
| updWxOrder.updateTenantInfo(wxOrder); | |||||
| updWxOrder.setRefDetail("B端管理员"+"["+bUser.getId()+"]"+"操作退款"); //B端发起退款后存B端用户ID在此 | |||||
| updWxOrder.setPaymentType(EnumPayType.PAY_B_REFUND.getCode()); | |||||
| updWxOrder.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PENDING_REFUND.getCode()); | |||||
| updWxOrder.setUpdateDate(currentDate); | |||||
| try { | |||||
| wxOrderMapper.updateById(updWxOrder); | |||||
| } catch (Exception e) { | |||||
| logger.error("db failed: wxOrder-" + wxOrder.getId() + ", e:" + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||||
| } | |||||
| WxRefundOrder record = new WxRefundOrder(); | |||||
| record.updateTenantInfo(wxOrder); | |||||
| record.setPayOrderNo(String.valueOf(cardSend.getId()));//卡没有支付订单 | |||||
| record.setOrderId(wxOrder.getId()); | |||||
| record.setNotStatus(EnumRefundStatus.REFUND_FAIL.getCode()); | |||||
| // check 是否有退款订单 | |||||
| List<WxRefundOrder> refundList = wxRefundOrderMapper.findList(record); | |||||
| if (refundList.size() > 0) { | |||||
| logger.error("退款订单已存在, 无法再提交退款申请"); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_EXIST.getCode(), "退款订单已存在, 无法再提交退款申请"); | |||||
| } | |||||
| final IdWorker idWorker = IdWorker.get(); | |||||
| // 创建退款订单 | |||||
| Long refundId = idWorker.nextId(); | |||||
| //String out_refund_id = String.valueOf(refundId); | |||||
| record.setId(refundId); | |||||
| record.setCreateTime(currentDate); | |||||
| record.setUpdateTime(currentDate); | |||||
| // 微信内部订单号 | |||||
| // record.setTransactionId(payOrder.getTransactionId()); | |||||
| record.setCUserId(wxOrder.getCUserId()); | |||||
| record.setTotalFee(wxOrder.getPayment()); | |||||
| record.setRefundFee(refundFee); | |||||
| record.setRefundTimeStart(currentDate); | |||||
| record.setRefundOrderStatus(EnumRefundStatus.REFUND_WAIT.getCode()); | |||||
| record.setRefundVendor(wxOrder.getPayVendor()); | |||||
| // 退款订单 | |||||
| try { | |||||
| int sqlRow = wxRefundOrderMapper.insert(record); | |||||
| if (sqlRow != 1) { | |||||
| logger.error("退款订单数据库插入出错: " + record.toString()); | |||||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||||
| } | |||||
| } catch (Exception e) { | |||||
| logger.error("退款订单数据库插入出错: " + record.toString()); | |||||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||||
| } | |||||
| refundCardOrderSuccess(record,wxOrder); | |||||
| return new ResultData(); | |||||
| } | |||||
| @Override | |||||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||||
| public ResultData refundCardOrderSuccess(WxRefundOrder refundOrder,WxOrder wxOrder) { | |||||
| Long cardSpendId = Long.parseLong(refundOrder.getPayOrderNo()); | |||||
| WxCardSpend cardSend = wxCardSpendMapper.selectById(cardSpendId); | |||||
| if(cardSend == null || EnumPayType.PAY_PAYMENT.getCode().equals(cardSend.getPayType())){ | |||||
| logger.error("付款订单未找到, e:"); | |||||
| throw new MallinkException(ErrorCode.ORDER_IS_NOT_FIND); | |||||
| } | |||||
| WxCardInfo cardInfo = wxCardInfoMapper.selectById(cardSend.getCardId()); | |||||
| if (cardInfo == null) { | |||||
| logger.error("card not found: " + cardSend.getCardId()); | |||||
| throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND); | |||||
| } | |||||
| WxAppinfo cAppInfo = wxAppinfoService.getCAppInfoFromRedis(cardInfo.getTenantId(), EnumAppPlat.WX); | |||||
| if(cAppInfo == null){ | |||||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); | |||||
| } | |||||
| WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(cAppInfo.getPayId()); | |||||
| if(payAccount == null){ | |||||
| throw new MallinkException(ErrorCode.API_KEY_NOT_FOUND); | |||||
| } | |||||
| Date currentDate = new Date(); | |||||
| WxCardSpend record = new WxCardSpend(); | |||||
| record.updateTenantInfo(cardSend); | |||||
| record.setPayType(EnumPayType.PAY_B_REFUND.getCode()); | |||||
| record.setCardId(cardSend.getCardId()); | |||||
| record.setOrderId(cardSend.getOrderId()); | |||||
| WxCardSpend wxCardSpend = wxCardSpendMapper.selectOne(new QueryWrapper<>(record)); | |||||
| if(wxCardSpend != null){ | |||||
| logger.error("已存在退款订单, "); | |||||
| throw new MallinkException(ErrorCode.ORDER_PAY_REFUND); | |||||
| } | |||||
| //计算 、 | |||||
| Integer refundFee = refundOrder.getRefundFee();//退款金额 | |||||
| Double refundD = 1.0 * cardSend.getPayment() * refundFee / cardSend.getDeductionAmount(); | |||||
| Integer refund = refundD.intValue();//实际退款金额 | |||||
| Double realRefundD = 1.0 * cardSend.getRealPayment() * refundFee / cardSend.getDeductionAmount(); | |||||
| Integer real_refund = realRefundD.intValue();//退分账金额 | |||||
| Integer remain_real_pament = cardInfo.getRemainingShareFeeAmount() + real_refund;//分账剩余金额 | |||||
| Integer remaingAmount = cardInfo.getRemainingAmount() + refundFee;//剩余面额 | |||||
| final IdWorker idWorker = IdWorker.get(); | |||||
| record.setId(idWorker.nextId()); | |||||
| record.setOwnerId(cardSend.getOwnerId()); | |||||
| record.setMerchantId(cardSend.getMerchantId()); | |||||
| record.setPayFrom(EnumCardSpendFrom.C.getCode()); | |||||
| record.setDeductionAmount(refundFee); | |||||
| record.setRemark("退款"); | |||||
| record.setPayment(refund); | |||||
| record.setRealPayment(real_refund); | |||||
| record.setCardBeforeAmount(cardInfo.getRemainingAmount()); | |||||
| record.setCardRemainAmount(remaingAmount); | |||||
| record.setCardBeforeRealAmount(cardInfo.getRemainingShareFeeAmount()); | |||||
| record.setCardRemainRealAmount(remain_real_pament); | |||||
| record.setPayStatus(EnumCardSpendStatus.PS_SHARED.getCode());//已退款 | |||||
| record.setCreateDate(currentDate); | |||||
| record.setUpdateDate(currentDate); | |||||
| WxRefundOrder updateOrder = new WxRefundOrder(); | |||||
| updateOrder.setId(refundOrder.getId()); | |||||
| updateOrder.setOrderId(refundOrder.getOrderId()); | |||||
| updateOrder.setUpdateTime(currentDate); | |||||
| updateOrder.setRefundOrderStatus(EnumRefundStatus.REFUND_SUCCESS.getCode()); | |||||
| // updateOrder.setTransactionId(transactionId); | |||||
| updateOrder.setRefundId(record.getId().toString()); | |||||
| // 修改退款订单状态 | |||||
| try { | |||||
| int i = wxRefundOrderMapper.updateById(updateOrder); | |||||
| } catch (Exception e) { | |||||
| logger.error(e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.ORDER_UPDATE_ERR); | |||||
| } | |||||
| WxOrder refOrder = new WxOrder(); | |||||
| refOrder.setId(updateOrder.getId()); | |||||
| refOrder.setOrderStatus(EnumOrderStatus.ORDER_STATUS_REFUND_SUCCESS.getCode()); | |||||
| refOrder.setUpdateDate(currentDate); | |||||
| refOrder.updateTenantInfo(updateOrder); | |||||
| try { | |||||
| int i = wxOrderMapper.updateById(refOrder); | |||||
| } catch (Exception e) { | |||||
| logger.error("订单状态更新失败, e:" + e.getMessage(),e); | |||||
| throw new MallinkException(ErrorCode.ORDER_UPDATE_ERR); | |||||
| } | |||||
| WxCardInfo updateCardInfo = new WxCardInfo(); | |||||
| updateCardInfo.setId(cardInfo.getId()); | |||||
| updateCardInfo.setRemainingAmount(remaingAmount); | |||||
| updateCardInfo.setRemainingShareFeeAmount(remain_real_pament); | |||||
| updateCardInfo.setUpdateDate(currentDate); | |||||
| cardInfo.setRemainingAmount(remaingAmount); | |||||
| cardInfo.setRemainingShareFeeAmount(remain_real_pament); | |||||
| cardInfo.setUpdateDate(currentDate); | |||||
| try { | |||||
| wxCardInfoMapper.updateById(updateCardInfo); | |||||
| } catch (Exception e) { | |||||
| logger.error("card info update error"); | |||||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "card info 更新出错!"); | |||||
| } | |||||
| if(record.getCardBeforeAmount().equals(0)){ | |||||
| if (wxCardSpendService.cardFinishedUsing(currentDate, cardInfo)) { | |||||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "couponOrder status 更新出错!"); | |||||
| } | |||||
| } | |||||
| Integer subsidyFee = 0; | |||||
| if(cardSend.getSubsidy() > 0){ | |||||
| //退补贴 | |||||
| Double subsidyD = 1.0 * cardSend.getSubsidy() * refundFee / cardSend.getDeductionAmount(); | |||||
| subsidyFee = subsidyD.intValue(); | |||||
| if(subsidyFee > 0){ | |||||
| int iSubChargeFee = PayUtils.getPayRate(subsidyFee, payAccount.getRealRate(), false); | |||||
| Integer realSubsidyFee = subsidyFee - iSubChargeFee; | |||||
| WxMerchantSubsidy merchantSubsidy = new WxMerchantSubsidy(); | |||||
| merchantSubsidy.setId(idWorker.nextId()); | |||||
| merchantSubsidy.updateTenantInfo(record); | |||||
| merchantSubsidy.setOrderId(wxOrder.getId()); | |||||
| merchantSubsidy.setOrderType(EnumOrderType.PREPAIDCARD.getCode()); | |||||
| merchantSubsidy.setMerchantId(record.getMerchantId()); | |||||
| merchantSubsidy.setBTenantId(record.getTenantId()); | |||||
| merchantSubsidy.setCouponOrderId(cardInfo.getId()); | |||||
| merchantSubsidy.setCouponType(EnumCouponType.CARD_MULTIMCH.getCode()); | |||||
| merchantSubsidy.setOrderPayment(0-record.getDeductionAmount()); | |||||
| merchantSubsidy.setReceiverPayment(0-refund); | |||||
| merchantSubsidy.setRealPayment(0-real_refund); | |||||
| merchantSubsidy.setSubsidy(0-subsidyFee); | |||||
| merchantSubsidy.setRealSubsidy(0-realSubsidyFee); | |||||
| merchantSubsidy.setStatus(EnumMerchantSubsidyStatus.NOT_SUBSIDY.getCode()); | |||||
| merchantSubsidy.setType(EnumMerchantSubsidyType.MANUAL.getCode()); | |||||
| merchantSubsidy.setSource(EnumMerchantSubsidySource.CARD.getCode()); | |||||
| //如果是有价卡,并且有补贴,则该记录不能显示在卡消费列表里面 | |||||
| if (cardInfo.getSaleAmount()>0 && subsidyFee > 0) { | |||||
| merchantSubsidy.setCardSpendListShow(0); | |||||
| } | |||||
| merchantSubsidy.setCreateDate(currentDate); | |||||
| merchantSubsidy.setUpdateDate(currentDate); | |||||
| try { | |||||
| wxMerchantSubsidyMapper.insert(merchantSubsidy); | |||||
| } catch (Exception e) { | |||||
| logger.error("merchantSubsidy info insert error"); | |||||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "merchantSubsidy info 插入出错!"); | |||||
| } | |||||
| } | |||||
| } | |||||
| try { | |||||
| record.setSubsidy(subsidyFee); | |||||
| wxCardSpendMapper.insert(record); | |||||
| } catch (Exception e) { | |||||
| logger.error("card spend insert error"); | |||||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "card spend 插入出错!"); | |||||
| } | |||||
| return new ResultData(); | |||||
| } | |||||
| } | } | ||||
| @@ -7,6 +7,7 @@ | |||||
| <result column="parent_tenant_id" jdbcType="VARCHAR" property="parentTenantId" /> | <result column="parent_tenant_id" jdbcType="VARCHAR" property="parentTenantId" /> | ||||
| <result column="card_id" jdbcType="BIGINT" property="cardId"/> | <result column="card_id" jdbcType="BIGINT" property="cardId"/> | ||||
| <result column="owner_id" jdbcType="BIGINT" property="ownerId"/> | <result column="owner_id" jdbcType="BIGINT" property="ownerId"/> | ||||
| <result column="pay_type" jdbcType="INTEGER" property="payType"/> | |||||
| <result column="merchant_id" jdbcType="BIGINT" property="merchantId"/> | <result column="merchant_id" jdbcType="BIGINT" property="merchantId"/> | ||||
| <result column="order_id" jdbcType="BIGINT" property="orderId"/> | <result column="order_id" jdbcType="BIGINT" property="orderId"/> | ||||
| <result column="pos_order_id" jdbcType="BIGINT" property="posOrderId"/> | <result column="pos_order_id" jdbcType="BIGINT" property="posOrderId"/> | ||||
| @@ -25,7 +26,7 @@ | |||||
| </resultMap> | </resultMap> | ||||
| <sql id="allColumns"> | <sql id="allColumns"> | ||||
| `id`,`tenant_id`,`parent_tenant_id`,`card_id`,`owner_id`,`merchant_id`,`order_id`,`pos_order_id`, | |||||
| `id`,`tenant_id`,`parent_tenant_id`,`card_id`,`owner_id`,`pay_type`,`merchant_id`,`order_id`,`pos_order_id`, | |||||
| `deduction_amount`,`payment`,`real_payment`,`subsidy`, `card_remain_amount`, | `deduction_amount`,`payment`,`real_payment`,`subsidy`, `card_remain_amount`, | ||||
| `card_before_amount`,`card_remain_real_amount`,`card_before_real_amount`, | `card_before_amount`,`card_remain_real_amount`,`card_before_real_amount`, | ||||
| `create_date`, `update_date`, `pay_status`, `pay_from` | `create_date`, `update_date`, `pay_status`, `pay_from` | ||||
| @@ -48,6 +49,9 @@ | |||||
| <if test=" null != ownerId "> | <if test=" null != ownerId "> | ||||
| and `owner_id` = #{ownerId} | and `owner_id` = #{ownerId} | ||||
| </if> | </if> | ||||
| <if test=" null != payType "> | |||||
| and `pay_type` = #{payType} | |||||
| </if> | |||||
| <if test=" null != merchantId "> | <if test=" null != merchantId "> | ||||
| and `merchant_id` = #{merchantId} | and `merchant_id` = #{merchantId} | ||||
| </if> | </if> | ||||