From b217f0ac3ed4ed69ff94ca482916437be2653074 Mon Sep 17 00:00:00 2001 From: Stormeye Wu Date: Fri, 9 Nov 2018 10:06:04 +0800 Subject: [PATCH] =?UTF-8?q?[=E5=88=B7=E5=8D=A1=E6=94=AF=E4=BB=98][?= =?UTF-8?q?=E6=94=B6=E9=93=B6=E5=8F=B0]:=E9=80=80=E6=AC=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/WxMicroPayController.java | 38 ++ .../controller/WxOrderController.java | 1 + .../service/WxRefundOrderService.java | 11 + .../service/impl/WxOrderServiceImpl.java | 4 + .../service/impl/WxPayOrderServiceImpl.java | 1 + .../impl/WxRefundOrderServiceImpl.java | 343 ++++++++++++++++++ 6 files changed, 398 insertions(+) diff --git a/mallinkBApi/src/main/java/com/iformall/controller/WxMicroPayController.java b/mallinkBApi/src/main/java/com/iformall/controller/WxMicroPayController.java index c136687ed..22a1932d4 100644 --- a/mallinkBApi/src/main/java/com/iformall/controller/WxMicroPayController.java +++ b/mallinkBApi/src/main/java/com/iformall/controller/WxMicroPayController.java @@ -7,6 +7,7 @@ import com.iformall.config.PayProperty; import com.iformall.domain.po.*; import com.iformall.enums.EnumOrderType; import com.iformall.enums.EnumPayWay; +import com.iformall.enums.EnumRefundWay; import com.iformall.exception.MallinkException; import com.iformall.service.*; import com.iformall.utils.IPUtil; @@ -47,6 +48,9 @@ public class WxMicroPayController extends BaseController { @Autowired WxPayOrderService wxPayOrderService; + @Autowired + WxRefundOrderService wxRefundOrderService; + @ApiOperation(value = "刷卡支付订单", notes = "params:{\"authCode\":\"String\",\"totalFee\":\"String\"},\n" + "注意:\n" + "提醒1:提交支付请求后微信会同步返回支付结果。当返回结果为“系统错误”时,商户系统等待5秒后调用【查询订单API】,查询支付实际交易结果;当返回结果为“USERPAYING”时,商户系统可设置间隔时间(建议10秒)重新查询支付结果,直到支付成功或超时(建议30秒);\n" + @@ -209,4 +213,38 @@ public class WxMicroPayController extends BaseController { public ResultData listUnverified(String date, Integer pageNum, Integer pageSize) { return wxOrderService.microPayListOnDateAsPage(getUser().getId(), EnumOrderType.MICROPAY.getCode(), date, pageNum, pageSize); } + + + @ApiOperation(value = "刷卡支付退款", notes = "{\"orderId\":\"string\"}") + @PostMapping("/microPayRefund") + public ResultData create(@RequestBody Map paramMap) { + //Assert.notNull(wxRefundOrder.getName(), "角色名不能为空"); + //Assert.isTrue(!checkUnique(sysRole.getName(), null), "重复的角色名"); + logger.info(paramMap.toString()); + String orderIdStr = paramMap.get("orderId"); + if (StringUtils.isBlank(orderIdStr)) { + logger.error("orderId不能为空: " + paramMap.toString()); + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); + } + Long orderId = 0L; + try { + orderId = Long.valueOf(orderIdStr); + } catch (NumberFormatException e) { + logger.error("orderId参数不正确: " + paramMap.toString()); + return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); + } + + WxMerchantBUser bUser = getUser(); + WxAppinfo appinfo = getAppInfo(bUser.getAppId()); + try { + ResultData rd = wxRefundOrderService.createRefundOrderFromMicroPay(payProperty.isReal(), appinfo, orderId, EnumRefundWay.B, bUser.getId()); + return rd; + } catch (MallinkException e) { + logger.error(e.getMessage()); + return new ResultData(e.getErrorCode(), e.getMessage()); + } catch (Exception e) { + logger.error(e.getMessage()); + return new ResultData(ErrorCode.REFUND_ORDER_ERROR); + } + } } diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java index 79d42ece6..ceaaad575 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxOrderController.java @@ -10,6 +10,7 @@ import com.iformall.domain.po.WxOrder; import com.iformall.domain.vo.WxOrderCVo; import com.iformall.enums.EnumCouponChannelStatus; import com.iformall.enums.EnumOrderStatus; +import com.iformall.enums.EnumOrderType; import com.iformall.exception.MallinkException; import com.iformall.service.WxCouponChannelService; import com.iformall.service.WxOrderService; diff --git a/mallinkService/src/main/java/com/iformall/service/WxRefundOrderService.java b/mallinkService/src/main/java/com/iformall/service/WxRefundOrderService.java index 63dfb7839..5cbc50b96 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxRefundOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxRefundOrderService.java @@ -21,6 +21,17 @@ public interface WxRefundOrderService { */ ResultData createRefundOrder(boolean isReal, WxAppinfo appInfo, Long couponOrderId, EnumRefundWay refundWay, Long bUserId); + /** + * 创建退款订单 + * @param isReal + * @param appInfo + * @param orderId 订单Id + * @param refundWay 退款来源 + * @param bUserId b端退款Id,auto,admin,self可为null + * @return + */ + ResultData createRefundOrderFromMicroPay(boolean isReal, WxAppinfo appInfo, Long orderId, EnumRefundWay refundWay, Long bUserId); + /** * 退款订单查询 * @param appInfo diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java index 7de575ed5..29ab13599 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java @@ -155,6 +155,7 @@ public class WxOrderServiceImpl implements WxOrderService { orderQ.setTenantId(user.getTenantId()); orderQ.setCouponId(counpon.getId()); orderQ.setType(EnumOrderType.COUPON.getCode()); + orderQ.setType(EnumOrderType.COUPON.getCode()); orderQ.setCUserId(user.getId()); orderQ.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PENDING_PAYMENT.getCode()); try { @@ -337,6 +338,7 @@ public class WxOrderServiceImpl implements WxOrderService { record.setOrderNumber(orderNumber); record.setCouponId(couponId); record.setType(EnumOrderType.COUPON.getCode()); + record.setType(EnumOrderType.COUPON.getCode()); record.setCUserId(user.getId()); record.setMerchantId(coupon.getMerchantId()); record.setPaymentType(EnumPayType.PAY_PAYMENT.getCode()); @@ -525,6 +527,7 @@ public class WxOrderServiceImpl implements WxOrderService { record.setTenantId(user.getTenantId()); record.setOrderNumber(orderNumber); record.setCouponId(couponId); + record.setType(EnumOrderType.COUPON.getCode()); record.setCUserId(user.getId()); record.setMerchantId(coupon.getMerchantId()); record.setPaymentType(EnumPayType.PAY_PAYMENT.getCode()); @@ -604,6 +607,7 @@ public class WxOrderServiceImpl implements WxOrderService { record.setTenantId(user.getTenantId()); record.setOrderNumber(orderNumber); record.setCouponId(couponId); + record.setType(EnumOrderType.COUPON.getCode()); record.setCUserId(user.getId()); record.setMerchantId(coupon.getMerchantId()); record.setPaymentType(EnumPayType.PAY_PAYMENT.getCode()); diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java index 3a5b62ee6..3c5c1bcac 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java @@ -930,6 +930,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { } WxOrder order = new WxOrder(); order.setId(record.getOrderId()); + order.setType(EnumOrderType.MICROPAY.getCode()); order.setOrderStatus(EnumOrderStatus.ORDER_STATUS_OVERTIME_CANCEL.getCode()); order.setUpdateDate(new Date()); try { 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 7965ef266..d9a1453fb 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java @@ -291,6 +291,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { rOrder.setTenantId(appInfo.getTenantId()); rOrder.setOrderNumber(wxOrder.getOrderNumber()); // 退款订单填写支付订单orderNumber rOrder.setCouponId(wxOrder.getCouponId()); + rOrder.setType(EnumOrderType.COUPON.getCode()); rOrder.setCUserId(wxOrder.getCUserId()); if (refundWay == EnumRefundWay.B) { rOrder.setBUserId(bUserId); @@ -609,6 +610,348 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { } } + @Override + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + public ResultData createRefundOrderFromMicroPay(boolean isReal, WxAppinfo appInfo, Long orderId, EnumRefundWay refundWay, Long bUserId) { + WxOrder wxOrder = wxOrderMapper.selectByPrimaryKey(orderId); + + if (refundWay == EnumRefundWay.B) { + logger.info("B端发起退款: bUserId-" + bUserId); + if (bUserId == null || bUserId == 0) { + logger.error("B端用户不存在:" + bUserId); + throw new MallinkException(ErrorCode.USER_IS_EMPTY); + } + // B端用户退款检查一下商户 + WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectByPrimaryKey(bUserId); + if (wxMerchantBUser == null) { + logger.error("操作员ID不存在:" + bUserId); + throw new MallinkException(ErrorCode.COUPON_ORDER_BUSER_IS_NULL); + } + if (!wxOrder.getMerchantId().equals(wxMerchantBUser.getMerchantId())) { + logger.error("券: couponMerchantId-" + wxOrder.getMerchantId() + "核销: couponMerchantId-" + wxMerchantBUser.getMerchantId()); + throw new MallinkException(ErrorCode.COUPON_ORDER_BUSER_IS_NULL); + } + } else if (refundWay == EnumRefundWay.ADMIN) { + logger.info("ADMIN端发起退款: bUserId-" + bUserId); + } else if (refundWay == EnumRefundWay.AUTO) { + logger.info("auto端发起退款"); + } else { + logger.info("自己发起退款: cUserId-" + bUserId); + } + if (wxOrder.getPayment() <= 0) { + logger.error("订单支付金额小于等于0: " + wxOrder.toString()); + throw new MallinkException(ErrorCode.REFUND_PAY_ORDER_IS_ZERO); + } + 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()); + rOrder.setOrderNumber(wxOrder.getOrderNumber()); // 退款订单填写支付订单orderNumber + rOrder.setType(EnumOrderType.MICROPAY.getCode()); + rOrder.setCUserId(wxOrder.getCUserId()); + if (refundWay == EnumRefundWay.B) { + rOrder.setBUserId(bUserId); + } else if (refundWay == EnumRefundWay.AUTO) { + rOrder.setBUserId(0L); // 自动退款, 设置bUserId为0 + } else if (refundWay == EnumRefundWay.ADMIN) { + rOrder.setBUserId(1L); // ADMIN发起退款, 设置bUserId为1 + } else { + rOrder.setBUserId(2L); // 自己发起退款, 设置bUserId为2 + } + rOrder.setMerchantId(wxOrder.getMerchantId()); + rOrder.setPaymentType(EnumPayType.PAY_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 (isReal) { + // 实际支付 + // 向微信提交退款申请 + if (payAccount.getType() == 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()); + if (refundWay == EnumRefundWay.B) { + wxRefundOrderP.setRefund_desc("B端商户退款"); + } else if (refundWay == EnumRefundWay.ADMIN) { + wxRefundOrderP.setRefund_desc("管理端商户退款"); + } else if (refundWay == EnumRefundWay.AUTO) { + wxRefundOrderP.setRefund_desc("超期自动退款"); + } else { + wxRefundOrderP.setRefund_desc("用户自己退款"); + } + wxRefundOrderP.setNotify_url(payAccount.getNotifyUrl() + "/refund"); + + 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()); + if (refundWay == EnumRefundWay.B) { + wxRefundOrderSP.setRefund_desc("B端商户退款"); + } else if (refundWay == EnumRefundWay.ADMIN) { + wxRefundOrderSP.setRefund_desc("管理端商户退款"); + } else if (refundWay == EnumRefundWay.AUTO) { + wxRefundOrderSP.setRefund_desc("超期自动退款"); + } else { + wxRefundOrderSP.setRefund_desc("用户自己退款"); + } + wxRefundOrderSP.setNotify_url(payAccount.getNotifyUrl() + "/refund"); + 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); + } + } + } else { + // 虚拟支付 + // 向微信提交退款申请 + 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()); + if (refundWay == EnumRefundWay.B) { + wxRefundOrderP.setRefund_desc("B端商户退款"); + } else if (refundWay == EnumRefundWay.ADMIN) { + wxRefundOrderP.setRefund_desc("管理端商户退款"); + } else if (refundWay == EnumRefundWay.AUTO) { + wxRefundOrderP.setRefund_desc("超期自动退款"); + } else { + wxRefundOrderP.setRefund_desc("用户自己退款"); + } + wxRefundOrderP.setNotify_url(payAccount.getNotifyUrl() + "/refund"); + + Map returnMap = null; + try { + returnMap = BeanUtils.toStringMap(wxRefundOrderP); + } catch (Exception e) { + logger.error("退款签名异常"); + throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常"); + } + 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); + } + } + } + /** * 微信退款查询 *