OrderRefuseLogic.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. namespace addons\Course\common\logic;
  3. use addons\Course\common\enums\CourseEnum;
  4. use addons\Course\common\models\AddonsCourseBought;
  5. use addons\Course\common\models\AddonsCourseOrders;
  6. use common\enums\AddonsEnum;
  7. use common\enums\PayTypeEnum;
  8. use common\enums\StatusEnum;
  9. use common\enums\UserWalletEnum;
  10. use common\globals\GlobalInvoke;
  11. use common\models\common\CapitalLog;
  12. use common\models\common\PaymentTrade;
  13. use common\models\common\PaymentTradeOrder;
  14. use common\models\mall\MallAddons;
  15. use common\models\order\Order;
  16. use common\models\order\OrderRefund;
  17. use common\traits\ErrorTrait;
  18. use Exception;
  19. use services\common\UserWalletService;
  20. class OrderRefuseLogic
  21. {
  22. use ErrorTrait;
  23. //实体店订单退单
  24. public function refuseOrder($params)
  25. {
  26. $trans = \Yii::$app->db->beginTransaction();
  27. try {
  28. //获取订单数据
  29. $order = AddonsCourseOrders::getOne([
  30. ['mall_id' => $params['mall_id']],
  31. ['id' => $params['order_id']],
  32. ['refund_status' => 1],
  33. ]);
  34. if (empty($order)) throw new Exception('查无此退单订单数据');
  35. if ($order['pay_type'] > 0 && $params['refund_price'] > 0) {
  36. //获取trade_order数据
  37. $trade_order = PaymentTradeOrder::getOne([
  38. ['order_type' => 'Course'],
  39. ['order_no' => $order['order_no']],
  40. ], true, [], 'id desc');
  41. if (empty($trade_order)) throw new Exception('查无此退单订单数据');
  42. //查找流水单号
  43. $payment_trade = PaymentTrade::findOne([
  44. 'id' => $trade_order['trade_id'],
  45. 'mall_id' => $params['mall_id'],
  46. 'is_pay' => StatusEnum::ENABLED
  47. ]);
  48. if (empty($payment_trade)) throw new Exception('未查询到支付记录');
  49. //组合支付生成流水支付退款数据
  50. $mallOrder = new Order();
  51. $mallOrder->mall_id = $params['mall_id'];
  52. //实例化售后信息
  53. $refund = new OrderRefund();
  54. $refund->mall_id = $params['mall_id'];
  55. $refund->id = $order->id;
  56. $refund->order_id = $order->id;
  57. $refund->order_no = $order->order_no;
  58. $refund->refund_price = $params['refund_price'];
  59. $refund->reality_refund_price = $params['refund_price'];
  60. $insert_wallet = [];
  61. $condition = [
  62. 'where'=>[
  63. ['source_table' => [AddonsCourseOrders::tableName(), '%addons_course_orders']],
  64. ['source_table_id' => $params['order_id']],
  65. ['mall_id' => $params['mall_id']],
  66. ],
  67. ];
  68. $data = [
  69. 'condition' => $condition,
  70. 'params' => $params
  71. ];
  72. $insert_wallet = self::getOrderCommissionData($insert_wallet, $data, 'commission', $order);
  73. $payment_trade->addRefundItem($refund, $mallOrder, CourseEnum::ADDONS_NAME);
  74. //系统、第三方支付方式支付
  75. $list = $payment_trade->getRefundFeeList($order->id, CourseEnum::ADDONS_NAME);
  76. foreach ($list as $item) {
  77. if (in_array($item->pay_type, [PayTypeEnum::BALANCE, PayTypeEnum::SCORE, PayTypeEnum::JOINPAY, PayTypeEnum::ALI, PayTypeEnum::JOINPAY_FAST_PAY, PayTypeEnum::WECHAT, PayTypeEnum::SANDPAY_FAST_PAY])) {
  78. $refund_price = $item->getRefundFee($params, $refund);
  79. // 退款金额需要大于0 组合支付金额过小的情况下 分配子订单退款金额可能为0
  80. if ($refund_price > 0) {
  81. //原路返回
  82. $originUserId = $order->user_id;
  83. // $order->user_id = $orderUserId;
  84. $res = \Yii::$app->services->pay->refund(
  85. $refund->refund_price,
  86. $refund_price,
  87. $payment_trade->out_trade_no,
  88. $order,
  89. '课程订单主动退款',
  90. UserWalletEnum::REFUND,
  91. UserWalletEnum::REFUND_ORDER,
  92. $item->pay_type
  93. );
  94. $order->user_id = $originUserId;
  95. if ($res === false) throw new \Exception('退款失败');
  96. }
  97. } elseif (
  98. // 当res返回为false 说明没有相对于的退款方式
  99. $res = GlobalInvoke::exec(GlobalInvoke::INVOKE_ORDER_REFUND, $params['mall_id'], [
  100. 'id' => $refund->id,
  101. 'mall_id' => $refund->mall_id,
  102. 'refund' => $refund,
  103. 'params' => $params,
  104. 'order_no' => $order['order_no'],
  105. 'refund_order_no' => $refund['order_no'],
  106. 'payment_trade_id' => $item->getTradeId(),
  107. 'refund_price' => $item->getRefundFee($params, $refund),
  108. 'pay_type' => $item->pay_type,
  109. ])
  110. ) {
  111. // 当res不为空 进此判断
  112. list($boolean, $msg) = $res;
  113. if ($boolean === false) {
  114. $this->setError($msg);
  115. return false;
  116. }
  117. } else {
  118. }
  119. }
  120. // 设置为已退款
  121. $payment_trade->setRefund($refund->id, CourseEnum::ADDONS_NAME);
  122. }
  123. //退款成功
  124. $order->refund_status = 2;
  125. $order->refund_at = time();
  126. $order->order_status = -2;
  127. if (!$order->save()) throw new Exception('修改售后状态失败'. AddonsCourseOrders::$static_error);
  128. //删除用户购买课程记录
  129. AddonsCourseBought::updateAll(['status' => StatusEnum::DELETE, 'is_pay' => 0], ['mall_id' => $params['mall_id'], 'order_id' => $order->id, 'user_id' => $order->user_id]);
  130. $trans->commit();
  131. //操作钱包的数据不为空时,发起操作钱包数据的异步
  132. if (!empty($insert_wallet)) {
  133. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  134. if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
  135. }
  136. return true;
  137. } catch (\Exception $e) {
  138. $trans->rollBack();
  139. throw new Exception($e->getMessage());
  140. }
  141. }
  142. public static function getOrderCommissionData($insert_wallet = [], $data = [], $capitalType = 'commission', $order){
  143. // $wallet_type = $params['wallet_type'];
  144. CapitalLog::$capitalType = "{$capitalType}";
  145. $list = CapitalLog::getList($data['condition'],0);
  146. // print_r($list);exit;
  147. if (!empty($list)) {
  148. foreach ($list as $k => $val) {
  149. $score_refund_price = $val['change_num'] * ($data['params']['balance_pre'] / 100) * -1;//处理为负数
  150. $score_refund_price = bcmul($score_refund_price, 1, 2);
  151. //admin_hander_refund 为后台主动退款时
  152. $insert_wallet[] = [
  153. 'mall_id' => $order['mall_id'],
  154. 'user_id' => $val['user_id'],
  155. 'is_frozen' => false,
  156. 'wallet_type' => $capitalType,// 暂定退回积分
  157. 'money' => $score_refund_price,
  158. 'desc' => '后台主动退款-订单('.$order['id'].')',
  159. 'source_table' => AddonsCourseOrders::tableName(),
  160. 'source_table_id' => $order['id'],
  161. 'from_type' => UserWalletEnum::REFUND,
  162. 'capital_type' => UserWalletEnum::REFUND_ORDER,
  163. 'order_no' => $order['order_no'],
  164. 'not_add_total' => true,
  165. 'admin_handler_refund' => UserWalletEnum::ADMIN_HANDLER_REFUND,
  166. ];//写入积分操作
  167. }
  168. }
  169. return $insert_wallet;
  170. }
  171. }