From 588403fc6c0d83caf96e0152f9c523d1fd4325e6 Mon Sep 17 00:00:00 2001 From: gongbiao Date: Thu, 21 Feb 2019 18:18:15 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=8B=BC=E5=9B=A2][=E6=B7=BB=E5=8A=A0][?= =?UTF-8?q?=E9=80=80=E6=AC=BE]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/WxRefundOrderService.java | 13 +- .../service/impl/WxOrderGroupServiceImpl.java | 23 +- .../impl/WxRefundOrderServiceImpl.java | 245 ++++++++++++++++++ 3 files changed, 272 insertions(+), 9 deletions(-) diff --git a/mallinkService/src/main/java/com/iformall/service/WxRefundOrderService.java b/mallinkService/src/main/java/com/iformall/service/WxRefundOrderService.java index e24d3f5ff..118dfc43b 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxRefundOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxRefundOrderService.java @@ -1,6 +1,5 @@ package com.iformall.service; -import java.util.*; import com.github.pagehelper.PageInfo; import com.iformall.common.ResultData; import com.iformall.domain.po.WxAppinfo; @@ -8,6 +7,8 @@ import com.iformall.domain.po.WxRefundOrder; import com.iformall.enums.EnumPayType; import com.iformall.enums.EnumPayWay; +import java.util.Map; + public interface WxRefundOrderService { @@ -94,12 +95,8 @@ public interface WxRefundOrderService { * @param id */ void deleteById(Long id); - - - - - - - + + ResultData returnMoney(WxAppinfo appInfo, Long orderId); + } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java index b1503630b..345eb5d01 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderGroupServiceImpl.java @@ -7,12 +7,14 @@ import com.iformall.common.IdWorker; import com.iformall.common.Result; import com.iformall.common.ResultData; import com.iformall.domain.po.*; +import com.iformall.enums.EnumAppType; import com.iformall.enums.EnumCouponStatus; import com.iformall.enums.EnumOrderStatus; import com.iformall.exception.MallinkException; import com.iformall.mapper.*; import com.iformall.service.WxOrderGroupService; import com.iformall.service.WxOrderService; +import com.iformall.service.WxRefundOrderService; import com.iformall.utils.DateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,6 +54,12 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { @Autowired WxMallMapper wxMallMapper; + @Autowired + WxAppinfoMapper wxAppinfoMapper; + + @Autowired + WxRefundOrderService WxRefundOrderService; + @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) public void createOrderGroup(WxOrder order, WxCoupon wxCoupon) { @@ -154,6 +162,7 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { } @Override + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) public ResultData toOrderGroup(WxOrderGroup wxOrderGroup) { WxOrder wxOrder = new WxOrder(); wxOrder.setId(wxOrderGroup.getOrderId()); @@ -217,6 +226,18 @@ public class WxOrderGroupServiceImpl implements WxOrderGroupService { order.setOrderGroupId(group.getId()); order.setOrderStatus(group.getStatus()); wxOrderMapper.updateStatusByOrderGroupId(order); - //退款流程 TODO gongbiao + //获取APP信息 + WxAppinfo appinfo = new WxAppinfo(); + appinfo.setTenantId(order.getTenantId()); + appinfo.setType(EnumAppType.C.getCode()); + appinfo = wxAppinfoMapper.findList(appinfo).get(0); + //退款流程 + WxOrder wxOrder = new WxOrder(); + wxOrder.setTenantId(group.getTenantId()); + wxOrder.setOrderGroupId(group.getId()); + List list = wxOrderMapper.findList(wxOrder); + for (WxOrder temp : list) { + WxRefundOrderService.returnMoney(appinfo, temp.getId()); + } } } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java index b36725355..0f453ee53 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java @@ -1326,4 +1326,249 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { wxRefundOrderMapper.deleteByPrimaryKey(id); } + @Override + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + public ResultData returnMoney(WxAppinfo appInfo, Long orderId) { + WxOrder wxOrder = wxOrderMapper.selectByPrimaryKey(orderId); + final IdWorker idWorker = IdWorker.get(); + Long refundOrderId = idWorker.nextId(); + Date currentDate = new Date(); + // 创建 refund Order + WxOrder rOrder = new WxOrder(); + rOrder.setId(refundOrderId); + rOrder.setTenantId(appInfo.getTenantId()); + // 退款订单填写支付订单orderNumber + rOrder.setOrderNumber(wxOrder.getOrderNumber()); + rOrder.setProductId(wxOrder.getProductId()); + rOrder.setType(EnumOrderType.COUPON.getCode()); + rOrder.setcUserId(wxOrder.getcUserId()); + rOrder.setPaymentType(EnumPayType.PAY_AUTO_REFUND.getCode()); + rOrder.setPayment(wxOrder.getPayment()); + rOrder.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PENDING_REFUND.getCode()); + rOrder.setCreateDate(currentDate); + rOrder.setUpdateDate(currentDate); + try { + wxOrderMapper.insertSelective(rOrder); + } catch (Exception e) { + logger.error("退款订单保存出错: " + e.getMessage()); + throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "退款订单保存出错"); + } + + // 查找支付订单 + WxPayOrder payOrderQ = new WxPayOrder(); + payOrderQ.setTenantId(appInfo.getTenantId()); + payOrderQ.setcUserId(wxOrder.getcUserId()); + payOrderQ.setOrderId(wxOrder.getId()); + payOrderQ.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); + + WxPayOrder payOrder = null; + List list = wxPayOrderMapper.findList(payOrderQ); + if (list.size() > 0) { + if (list.size() > 1) { + logger.error("TODO: payOrder成功记录应该只有一条????!!!"); + } + logger.warn(""); + payOrder = list.get(0); + } + if (payOrder == null) { + logger.error("支付订单不存在(payOrder不存在)"); + return new ResultData(ErrorCode.PAY_ORDER_NOT_FOUND); + } + + WxRefundOrder record = new WxRefundOrder(); + record.setPayOrderNo(String.valueOf(payOrder.getId())); + record.setOrderId(rOrder.getId()); + // 创建退款订单 + Long refundId = idWorker.nextId(); + String out_refund_id = String.valueOf(refundId); + + record.setId(refundId); + record.setTenantId(appInfo.getTenantId()); + record.setCreateTime(currentDate); + record.setUpdateTime(currentDate); + // 微信内部订单号 + record.setTransactionId(payOrder.getTransactionId()); + record.setCUserId(payOrder.getcUserId()); + record.setTotalFee(payOrder.getPayAmount()); + record.setRefundFee(payOrder.getPayAmount()); + record.setRefundTimeStart(currentDate); + record.setRefundOrderStatus(EnumRefundStatus.REFUND_WAIT.getCode()); + + // 退款订单 + try { + int sqlRow = wxRefundOrderMapper.insertSelective(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); + } + WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appInfo.getPayId()); + if (StringUtils.isBlank(payAccount.getApiKey())) { + logger.error("支付密钥为空"); + throw new MallinkException(ErrorCode.API_KEY_NOT_FOUND.getCode(), "支付密钥为空,请联系商城管理员"); + } + if (StringUtils.isBlank(payAccount.getCertPath())) { + logger.error("证书路径为空"); + throw new MallinkException(ErrorCode.CERT_PATH_NOT_FOUND.getCode(), "证书路径为空,请联系商城管理员"); + } + if (!Utility.isFileExist(payAccount.getCertPath())) { + logger.error("证书文件不存在"); + throw new MallinkException(ErrorCode.CERT_PATH_NOT_FOUND.getCode(), "证书文件不存在,请联系商城管理员"); + } + // check 是否有退款订单 + List refundList = wxRefundOrderMapper.findList(record); + if (refundList.size() > 0) { + logger.error("退款订单已存在, 无法再提交退款申请"); + throw new MallinkException(ErrorCode.REFUND_ORDER_EXIST.getCode(), "退款订单已存在, 无法再提交退款申请"); + } + + // 实际支付 + // 向微信提交退款申请 + if (payAccount.getType().equals(EnumPayMode.MCH.getCode())) { + // 普通商户模式 + String noncestr = Utility.generate32UUID(); + WxRefundOrderP wxRefundOrderP = new WxRefundOrderP(); + wxRefundOrderP.setAppid(appInfo.getAppId()); + wxRefundOrderP.setMch_id(payAccount.getMchId()); + wxRefundOrderP.setNonce_str(noncestr); + // 微信内部订单号 + if (record.getTransactionId() != null) { + wxRefundOrderP.setTransaction_id(record.getTransactionId()); + } + // 支付订单号 + wxRefundOrderP.setOut_trade_no(payOrder.getPayOrderNo()); + // 退款支付订单号 + wxRefundOrderP.setOut_refund_no(out_refund_id); + wxRefundOrderP.setTotal_fee(record.getTotalFee()); + wxRefundOrderP.setRefund_fee(record.getRefundFee()); + wxRefundOrderP.setRefund_desc("拼团失败退款"); + wxRefundOrderP.setNotify_url(payAccount.getRefundNotifyUrl()); + + Map signMap = null; + try { + signMap = BeanUtils.toStringMap(wxRefundOrderP); + } catch (Exception e) { + logger.error("退款命令生辰: " + e.getMessage()); + throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常"); + } + + String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey()); + signMap.put("sign", signAgent); + String response = null; + try { + response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getMchId()); + } catch (Exception e) { + logger.error("退款异常: " + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); + } + logger.info("微信退款订单:" + wxRefundOrderP.toString() + ", response: " + response.toString()); + Map returnMap = WxPayment.xmlToMap(response); + String result_no = returnMap.get("result_code"); + String refund_id = returnMap.get("refund_id"); + // 设置 微信退款订单号 + record.setRefundId(refund_id); + record.setRefundVendor(EnumPayWay.PAY_WAY_WEAPP.getCode()); + if ("SUCCESS".equals(result_no)) { + logger.info("微信退款订单申请成功: " + returnMap.toString()); + try { + record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); + wxRefundOrderMapper.updateByPrimaryKey(record); + return new ResultData(Result.SUCCESS, "退款订单申请成功", returnMap); + } catch (Exception e) { + logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); + } + } else { + logger.error("微信退款订单申请失败: " + response); + String errMsg = ""; + JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); + if (errObj != null) { + errMsg = errObj.toJSONString(); + record.setFailReason(errMsg); + } else { + errMsg = returnMap.get("return_msg"); + record.setFailReason(errMsg); + } + record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_FAIL.getCode()); + wxRefundOrderMapper.updateByPrimaryKey(record); + return new ResultData(ErrorCode.REFUND_ORDER_ERROR.getCode(), errMsg, returnMap); + } + } else { + // 服务商模式 + String noncestr = Utility.generate32UUID(); + WxRefundOrderSP wxRefundOrderSP = new WxRefundOrderSP(); + wxRefundOrderSP.setAppid(appInfo.getParentAppId()); + wxRefundOrderSP.setSub_appid(appInfo.getAppId()); + wxRefundOrderSP.setMch_id(payAccount.getMchId()); + wxRefundOrderSP.setSub_mch_id(payAccount.getSubMchId()); + wxRefundOrderSP.setNonce_str(noncestr); + // 微信内部订单号 + if (record.getTransactionId() != null) { + wxRefundOrderSP.setTransaction_id(record.getTransactionId()); + } + // 支付订单号 + wxRefundOrderSP.setOut_trade_no(payOrder.getPayOrderNo()); + // 退款支付订单号 + wxRefundOrderSP.setOut_refund_no(out_refund_id); + wxRefundOrderSP.setTotal_fee(record.getTotalFee()); + wxRefundOrderSP.setRefund_fee(record.getRefundFee()); + wxRefundOrderSP.setRefund_desc("拼团失败退款"); + wxRefundOrderSP.setNotify_url(payAccount.getRefundNotifyUrl()); + wxRefundOrderSP.setSign_type("HMAC-SHA256"); + + Map signMap = null; + try { + signMap = BeanUtils.toStringMap(wxRefundOrderSP); + } catch (Exception e) { + logger.error("退款命令生辰: " + e.getMessage()); + throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常"); + } + + String signAgent = WxPayment.createSignHMAC(signMap, payAccount.getApiKey()); + signMap.put("sign", signAgent); + String response = null; + try { + response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getMchId()); + } catch (Exception e) { + logger.error("退款异常: " + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); + } + logger.info("微信退款订单:" + wxRefundOrderSP.toString() + ", response: " + response.toString()); + Map returnMap = WxPayment.xmlToMap(response); + String result_no = returnMap.get("result_code"); + String refund_id = returnMap.get("refund_id"); + // 设置 微信退款订单号 + record.setRefundId(refund_id); + record.setRefundVendor(EnumPayWay.PAY_WAY_WEAPP.getCode()); + if ("SUCCESS".equals(result_no)) { + logger.info("微信退款订单申请成功: " + returnMap.toString()); + try { + record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); + wxRefundOrderMapper.updateByPrimaryKey(record); + return new ResultData(Result.SUCCESS, "退款订单申请成功", returnMap); + } catch (Exception e) { + logger.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "订单状态更新失败"); + } + } else { + logger.error("微信退款订单申请失败: " + response); + String errMsg = ""; + JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); + if (errObj != null) { + errMsg = errObj.toJSONString(); + record.setFailReason(errMsg); + } else { + errMsg = returnMap.get("return_msg"); + record.setFailReason(errMsg); + } + record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_FAIL.getCode()); + wxRefundOrderMapper.updateByPrimaryKey(record); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), errMsg); + } + } + } + }