|
|
|
@@ -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<WxPayOrder> 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<WxRefundOrder> 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<String, String> 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<String, String> 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); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |