From 1825949df8995ed189e733a4882f13343041912f Mon Sep 17 00:00:00 2001
From: xiaoyong931011 <15274802129@163.com>
Date: Fri, 05 Aug 2022 14:26:41 +0800
Subject: [PATCH] 20220805

---
 src/main/java/cc/mrbird/febs/mall/controller/ApiMallOrderController.java        |    6 +
 src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java               |    6 +
 src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java         |    3 
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java |  103 ++++++++++++++++++++
 src/main/java/cc/mrbird/febs/mall/mapper/MallRefundMapper.java                  |    7 +
 src/main/resources/application-dev.yml                                          |    3 
 src/main/resources/application-prod.yml                                         |    5 
 src/main/java/cc/mrbird/febs/pay/util/WeixinServiceUtil.java                    |   97 +++++++++---------
 src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java                  |   26 +++++
 src/main/resources/application-test.yml                                         |    3 
 10 files changed, 209 insertions(+), 50 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java b/src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java
index a737ad7..1077d2d 100644
--- a/src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java
+++ b/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;
 
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ApiMallOrderController.java b/src/main/java/cc/mrbird/febs/mall/controller/ApiMallOrderController.java
index 0260de6..92f5254 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/ApiMallOrderController.java
+++ b/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) {
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java b/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java
new file mode 100644
index 0000000..884b517
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java
@@ -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;
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallRefundMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallRefundMapper.java
new file mode 100644
index 0000000..4ccf42f
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallRefundMapper.java
@@ -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> {
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java b/src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java
index 8b63908..8064576 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java
+++ b/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);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
index 9ac608f..dd09c75 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
+++ b/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("退款成功");
+    }
+
 }
diff --git a/src/main/java/cc/mrbird/febs/pay/util/WeixinServiceUtil.java b/src/main/java/cc/mrbird/febs/pay/util/WeixinServiceUtil.java
index 1125bb7..3c6d58d 100644
--- a/src/main/java/cc/mrbird/febs/pay/util/WeixinServiceUtil.java
+++ b/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日
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index 09edaa3..8cba712 100644
--- a/src/main/resources/application-dev.yml
+++ b/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
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
index 561c2b7..ca0815b 100644
--- a/src/main/resources/application-prod.yml
+++ b/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
diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml
index dfdbd49..17463e2 100644
--- a/src/main/resources/application-test.yml
+++ b/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

--
Gitblit v1.9.1