xiaoyong931011
2022-08-05 1825949df8995ed189e733a4882f13343041912f
20220805
2 files added
8 files modified
259 ■■■■ changed files
src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/ApiMallOrderController.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallRefundMapper.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java 103 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/util/WeixinServiceUtil.java 97 ●●●● patch | view | raw | blame | history
src/main/resources/application-dev.yml 3 ●●●●● patch | view | raw | blame | history
src/main/resources/application-prod.yml 5 ●●●● patch | view | raw | blame | history
src/main/resources/application-test.yml 3 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java
@@ -18,5 +18,11 @@
    private String wecharPaynotifyUrl;
    //测试支付的开关,true:支付0.01元
    private Boolean debug;
    //支付证书地址
    private String certLocalPath;
    //微信商户号
    private String wecharpayMchid;
    //支付秘钥
    private String wecharpaySecret;
}
src/main/java/cc/mrbird/febs/mall/controller/ApiMallOrderController.java
@@ -89,6 +89,12 @@
        return new FebsResponse().success().message("删除成功");
    }
    @ApiOperation(value = "用户退款", notes = "用户退款")
    @PostMapping(value = "/refundOrder/{id}")
    public FebsResponse refundOrder(@PathVariable("id") Long id) {
        return mallOrderInfoService.refundOrder(id);
    }
    @ApiOperation(value = "提交退款申请", notes = "提交退款申请")
    @PostMapping(value = "/applyRefund")
    public FebsResponse applyRefund(@RequestBody AddRefundDto addRefundDto) {
src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java
New file
@@ -0,0 +1,26 @@
package cc.mrbird.febs.mall.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
@Data
@TableName("mall_refund")
public class MallRefundEntity extends BaseEntity {
    //退款编号
    private String refundNo;
    //退款人ID
    private Long memberId;
    //退款订单ID
    private Long orderId;
    //退款方式 1:微信 2:支付宝 3:其他
    private Integer type;
    //退款状态 1:成功 2:失败 3:退款中
    private Integer state;
    //退款金额
    private BigDecimal amount;
}
src/main/java/cc/mrbird/febs/mall/mapper/MallRefundMapper.java
New file
@@ -0,0 +1,7 @@
package cc.mrbird.febs.mall.mapper;
import cc.mrbird.febs.mall.entity.MallRefundEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface MallRefundMapper extends BaseMapper<MallRefundEntity> {
}
src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java
@@ -1,5 +1,6 @@
package cc.mrbird.febs.mall.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.mall.dto.*;
import cc.mrbird.febs.mall.entity.MallOrderInfo;
import cc.mrbird.febs.mall.vo.OrderDetailVo;
@@ -32,4 +33,6 @@
    void autoCancelOrder(Long id);
    void goodsComment(ApiAddCommentDtos addCommentDtos);
    FebsResponse refundOrder(Long id);
}
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
@@ -1,7 +1,9 @@
package cc.mrbird.febs.mall.service.impl;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.enumerates.*;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.properties.XcxProperties;
import cc.mrbird.febs.common.utils.*;
import cc.mrbird.febs.mall.conversion.MallGoodsCommentConversion;
import cc.mrbird.febs.mall.conversion.MallOrderInfoConversion;
@@ -16,18 +18,22 @@
import cc.mrbird.febs.pay.model.BrandWCPayRequestData;
import cc.mrbird.febs.pay.service.IPayService;
import cc.mrbird.febs.pay.service.IXcxPayService;
import cc.mrbird.febs.pay.util.WeixinServiceUtil;
import cc.mrbird.febs.rabbit.producter.AgentProducer;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -62,6 +68,7 @@
    private final IPayService payService;
    private final IXcxPayService iXcxPayService;
    private final IMallAchieveService mallAchieveService;
    private final MallRefundMapper mallRefundMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -560,4 +567,100 @@
        }
    }
    @Autowired
    private WeixinServiceUtil weixinServiceUtil;
    private final XcxProperties xcxProperties = SpringContextHolder.getBean(XcxProperties.class);
    @Override
    @Transactional
    public FebsResponse refundOrder(Long id) {
        MallMember member = LoginUserUtil.getLoginUser();
        MallOrderInfo mallOrderInfo = this.baseMapper.selectById(id);
        if(ObjectUtil.isEmpty(mallOrderInfo)){
            return new FebsResponse().fail().message("订单不存在");
        }
        Integer status = mallOrderInfo.getStatus();
        if(OrderStatusEnum.WAIT_SHIPPING.getValue() != status){
            return new FebsResponse().fail().message("订单不是待发货状态");
        }
        Integer deliveryState = mallOrderInfo.getDeliveryState();
        if(1 != deliveryState){
            return new FebsResponse().fail().message("订单不是待配送状态");
        }
        QueryWrapper<MallRefundEntity> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("member_id",member.getId());
        objectQueryWrapper.eq("order_id",mallOrderInfo.getId());
        MallRefundEntity mallRefund = mallRefundMapper.selectOne(objectQueryWrapper);
        MallRefundEntity mallRefundEntity = new MallRefundEntity();
        if(ObjectUtil.isEmpty(mallRefund)){
            mallRefundEntity.setRefundNo(mallOrderInfo.getOrderNo()+"_r");
            mallRefundEntity.setMemberId(member.getId());
            mallRefundEntity.setOrderId(mallOrderInfo.getId());
            mallRefundEntity.setType(1);
            mallRefundEntity.setState(3);
            mallRefundEntity.setAmount(mallOrderInfo.getAmount());
            mallRefundMapper.insert(mallRefundEntity);
        }
        if(mallRefund.getState() == 1){
            return new FebsResponse().fail().message("订单已退款");
        }
        if(mallRefund.getState() == 3){
            return new FebsResponse().fail().message("订单退款中");
        }
        if(mallRefund.getState() == 2){
            mallRefundEntity.setId(mallRefund.getId());
            mallRefundEntity.setRefundNo(mallRefund.getRefundNo());
            mallRefundEntity.setMemberId(mallRefund.getMemberId());
            mallRefundEntity.setOrderId(mallRefund.getOrderId());
            mallRefundEntity.setType(mallRefund.getType());
            mallRefundEntity.setState(3);
            mallRefundEntity.setAmount(mallRefund.getAmount());
            mallRefundMapper.updateById(mallRefundEntity);
        }
        //退款订单编号
        String orderNo = mallOrderInfo.getOrderNo();
        //退款退款编号
        String refundNo = mallRefundEntity.getRefundNo();
        //退款订单金额
        BigDecimal orderAmount = mallOrderInfo.getAmount();
        BigDecimal aa = new BigDecimal(100);
        int orderMoney = orderAmount.multiply(aa).intValue();
        //退款退款金额
        BigDecimal refundAmount = mallRefundEntity.getAmount();
        BigDecimal bb = new BigDecimal(100);
        int refundMoney = refundAmount.multiply(bb).intValue();
        Boolean flag = false;
        Boolean debug = xcxProperties.getDebug();
        if (debug) {
            boolean b = weixinServiceUtil.comRefund(orderNo, refundNo, 1, 1, null);
            flag = b;
        } else {
            log.info("开始调用退款接口。。。退款编号为{}", refundNo);
            boolean b = weixinServiceUtil.comRefund(orderNo, refundNo, orderMoney, refundMoney, null);
            flag = b;
        }
        /**
         * 更新退款表
         * 更新订单表
         */
        Long refundId = mallRefundEntity.getId();
        MallRefundEntity mallRefundOld = mallRefundMapper.selectById(refundId);
        MallOrderInfo mallOrderInfoOld = this.baseMapper.selectByOrderNo(orderNo);
        if(flag){
            mallRefundOld.setState(1);
            mallRefundMapper.updateById(mallRefundOld);
            mallOrderInfoOld.setStatus(OrderStatusEnum.REFUNDED.getValue());
            this.baseMapper.updateById(mallOrderInfoOld);
        }else{
            mallRefundOld.setState(2);
            mallRefundMapper.updateById(mallRefundOld);
            return new FebsResponse().fail().message("退款失败,请联系客服人员");
        }
        return new FebsResponse().success().message("退款成功");
    }
}
src/main/java/cc/mrbird/febs/pay/util/WeixinServiceUtil.java
@@ -3,10 +3,9 @@
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.properties.XcxProperties;
import cc.mrbird.febs.common.utils.SpringContextHolder;
import cc.mrbird.febs.pay.model.BrandWCPayRequestData;
import cc.mrbird.febs.pay.model.JsApiPayBusiness;
import cc.mrbird.febs.pay.model.JsApiPayReqData;
import cc.mrbird.febs.pay.model.JsApiPayResData;
import cc.mrbird.febs.pay.model.*;
import cc.mrbird.febs.pay.service.impl.RefundService;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -46,9 +45,9 @@
        JsApiPayBusiness jsApiPayBusiness = new JsApiPayBusiness();
        String idAddr = getIpAddr(WebUtil.getRequest());
        String mchID = WechatConfigure.WECHARPAY_MCHID;
        String paySecret = WechatConfigure.WECHARPAY_SECRET;
        String appId = WechatConfigure.MINIPROGRAM_APPID;
        String mchID = xcxProperties.getWecharpayMchid();
        String paySecret = xcxProperties.getWecharpaySecret();
        String appId = xcxProperties.getXcxAppid();
        JsApiPayReqData jsApiPayReqData = new JsApiPayReqData(
                appId, mchID, paySecret, notifyUrl, desc,
@@ -81,48 +80,48 @@
     * @param opUserID 操作员id,默认为商户号
     * @return
     */
//    public boolean comRefund(String outTradeNo, String outRefundNo,int totalFee,
//            int refundFee, String opUserID){
//        LogUtil.info("#---outTradeNo:{}#---outRefundNo:{}#---totalFee:{}#---refundFee:{}",
//                outTradeNo,outRefundNo,totalFee,refundFee);
//        BusParameterSettings mchID = busParameterSettingsDao.selectCompanyParamByCode(AppConstance.WECHARPAY_MCHID, HostInterceptor.getCompanyId());
//        if(opUserID==null){
//            opUserID=mchID.getParamValue();
//        }
//        RefundResData result=null;
//        boolean flag=false;
//        try {
//            JsApiPayBusiness jsApiPayBusiness = new JsApiPayBusiness();
//            Long companyId=HostInterceptor.getCompanyId();
//            BusParameterSettings paySecret = busParameterSettingsDao.selectCompanyParamByCode(AppConstance.WECHARPAY_SECRET, companyId);
//            BusParameterSettings appId = busParameterSettingsDao.selectCompanyParamByCode(AppConstance.MINIPROGRAM_APPID, companyId);
//            BusParameterSettings certLocalPath = busParameterSettingsDao.selectCompanyParamByCode(AppConstance.WECHARPAY_CERTLOCAL_PATH, companyId);
//
//            RefundReqData refundReqData=new RefundReqData(mchID.getParamValue(),appId.getParamValue(),paySecret.getParamValue(), outTradeNo, outRefundNo, totalFee, refundFee,opUserID);
//            RefundService refundService=new RefundService();
//            HttpsRequest2 request2= (HttpsRequest2) refundService.getServiceRequest();
//            request2.setCertLocalPath(certLocalPath.getParamValue());
//            request2.setMchId(mchID.getParamValue());
//
//            result = jsApiPayBusiness.refundComOrder(refundService, refundReqData);
//            LogUtil.info("#退款,企业付款到个人---result:{}",result);
//            //如果返回余额不足时
//            if (StringUtils.equals(AppConstance.REFUND_FAIL_NOTENOUGH, result.getErr_code())) {
//                LogUtil.info("#退款失败,{}!", "商户余额不足");
//                throw new GlobleException("退款失败,请联系管理员!");
//            }
//        } catch (Exception e) {
//            LogUtil.error("#企业付款到个人异常#退款#outTradeNo:{}#opUserID:{}", e, outTradeNo,opUserID);
//        }
//
//        if (result.getResult_code().equals(WechatConfigure.SUCCESS)) {
//             flag=true;
//        }else{
//             flag=false;
//             throw new GlobleException(result.getErr_code_des());
//        }
//        return flag;
//    }
    public boolean comRefund(String outTradeNo, String outRefundNo,int totalFee,
            int refundFee, String opUserID){
        log.info("#---outTradeNo:{}#---outRefundNo:{}#---totalFee:{}#---refundFee:{}",
                outTradeNo,outRefundNo,totalFee,refundFee);
        String mchID = xcxProperties.getWecharpayMchid();
        if(opUserID==null){
            opUserID=mchID;
        }
        RefundResData result=null;
        boolean flag=false;
        try {
            JsApiPayBusiness jsApiPayBusiness = new JsApiPayBusiness();
            String paySecret = xcxProperties.getWecharpaySecret();
            String appId = xcxProperties.getXcxAppid();
            String certLocalPath = xcxProperties.getCertLocalPath();
            RefundReqData refundReqData=new RefundReqData(mchID,appId,paySecret, outTradeNo, outRefundNo, totalFee, refundFee,opUserID);
            RefundService refundService=new RefundService();
            HttpsRequest2 request2= (HttpsRequest2) refundService.getServiceRequest();
            request2.setCertLocalPath(certLocalPath);
            request2.setMchId(mchID);
            result = jsApiPayBusiness.refundComOrder(refundService, refundReqData);
            log.info("#退款,企业付款到个人---result:{}",result);
            //如果返回余额不足时,商户余额不足时微信返回状态码(退款失败时)
            if (StrUtil.equals("NOTENOUGH", result.getErr_code())) {
                log.info("#退款失败,{}!", "商户余额不足");
                flag=false;
            }
        } catch (Exception e) {
            log.error("#企业付款到个人异常#退款#outTradeNo:{}#opUserID:{}", e, outTradeNo,opUserID);
            flag=false;
        }
        if (result.getResult_code().equals("SUCCESS")) {
             flag=true;
        }else{
             flag=false;
        }
        return flag;
    }
    
    /**@Description 支付获取远程设备的ip
       @date 2017年6月27日
src/main/resources/application-dev.yml
@@ -69,3 +69,6 @@
  xcx_secret: 71403646f666f9b9dca308d4f357765c
  debug: true
  wecharPaynotifyUrl: http://groupbuy.csxuncong.com/api/xcxPay/wxpayCallback
  certLocalPath: /home/xuncongCert/apiclient_cert.p12
  wecharpayMchid: 1605533690
  wecharpaySecret: CSxc168888CSxc168888CSxc168888xc
src/main/resources/application-prod.yml
@@ -63,5 +63,8 @@
  wechar_login_url: https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code
  xcx_appid: wx5cc58f796224af61
  xcx_secret: 71403646f666f9b9dca308d4f357765c
  debug: false
  debug: true
  wecharPaynotifyUrl: http://groupbuy.csxuncong.com/api/xcxPay/wxpayCallback
  certLocalPath: /home/xuncongCert/apiclient_cert.p12
  wecharpayMchid: 1605533690
  wecharpaySecret: CSxc168888CSxc168888CSxc168888xc
src/main/resources/application-test.yml
@@ -65,3 +65,6 @@
  xcx_secret: 71403646f666f9b9dca308d4f357765c
  debug: true
  wecharPaynotifyUrl: http://groupbuy.csxuncong.com/api/xcxPay/wxpayCallback
  certLocalPath: /home/xuncongCert/apiclient_cert.p12
  wecharpayMchid: 1605533690
  wecharpaySecret: CSxc168888CSxc168888CSxc168888xc