where([ 'user_id' => \Yii::$app->user->identity->id, 'id' => $order_id ])->with('session')->one(); if(!$order || $order->cancel_status){ throw new Exception('订单不存在'); } switch($order->is_pay){ case 0://未支付 $t = \Yii::$app->db->beginTransaction(); try { $order->cancel_status = 1; $order->cancel_time = time(); $order->cancel_remark = '主动取消订单'; $order->saveOrFail(); //生成系统消息 $SystemNotice=new SystemNotice(); $SystemNotice->content='您已主动取消订单'; $SystemNotice->base_type=SystemNoticeTypeEnum::ORDER_CANCEL; $SystemNotice->scene_type=1;//用户端 $SystemNotice->user_id=\Yii::$app->user->identity->getId(); $SystemNotice->notice_at=date('Y-m-d H:i:s',time()); $SystemNotice->saveOrFail(); $event = new OrderEvent([ 'order' => $order, ]); \Yii::$app->trigger(Order::EVENT_CANCELED, $event); $t->commit(); return []; } catch (\Exception $exception) { $t->rollBack(); throw $exception; } break; case 1://已支付 if($order->accept_status!=OrderAcceptEnum::WAIT_ACCEPT){ throw new Exception('只有待接诊状态可以取消订单'); } $ims_id = $order->session->ims_id; $ImMessageSession = ImMessageSession::findOne($ims_id); if(!$ImMessageSession){ throw new Exception('未接诊订单会话不存在'); } $t = \Yii::$app->db->beginTransaction(); try { //生成记录 $orderRefund = new OrderRefund(); $orderRefund->user_id = $order->user_id; $orderRefund->order_id = $order->id; $orderRefund->refund_no = FuncHelper::generate_order_no('RF'); $orderRefund->refund_price = $order->total_pay_price; $orderRefund->remark = '主动取消订单'; $orderRefund->saveOrFail(); //取消状态 $order->cancel_status = 1; $order->cancel_time = time(); $order->cancel_remark = '主动取消订单'; //接诊状态 $order->accept_status = OrderAcceptEnum::CANCEL; //退款状态 $order->refund_status = 1; $order->refund_time = time(); $order->saveOrFail(); //会话修改为已结束 $ImMessageSession->status = ImSessionStatusEnum::END; $ImMessageSession->saveOrFail(); //生成系统消息 $SystemNotice=new SystemNotice(); $SystemNotice->content='您已主动取消订单'; $SystemNotice->base_type=SystemNoticeTypeEnum::ORDER_CANCEL; $SystemNotice->scene_type=1;//用户端 $SystemNotice->user_id=\Yii::$app->user->identity->getId(); $SystemNotice->notice_at=date('Y-m-d H:i:s',time()); $SystemNotice->saveOrFail(); //退款操作 $this->refundMoney($orderRefund); //可能报错 无效的订单号 $t->commit(); }catch (Exception $exception){ $t->rollBack(); throw $exception; } break; } } public function refundMoney($orderRefund) { $orderNo = $orderRefund->order->order_no; $order = Order::findOne([ 'order_no' => $orderNo, 'is_pay' => 1 ]); $paymentOrder = PaymentOrder::findOne([ 'order_no' => $orderNo, 'is_pay' => 1 ]); if (!$order || !$paymentOrder) { throw new Exception('无效的订单号'); } $price = $orderRefund->refund_price; if(bccomp($paymentOrder->amount,$price,2)==-1){ throw new Exception('退款金额大于可退款金额'); } $transaction = \Yii::$app->db->beginTransaction(); try { $paymentRefund = new PaymentRefund(); $paymentRefund->refund_no = $orderRefund->refund_no; $paymentRefund->amount = $price; $paymentRefund->is_pay = 0; $paymentRefund->pay_type = 0; $paymentRefund->created_at = time(); $paymentRefund->saveOrFail(); if(bccomp($price,0,2)<=0) { $paymentRefund->is_pay = 1; $paymentRefund->save(); $orderRefund->is_refund = 1; $orderRefund->refund_time = time(); $orderRefund->save(); }else{ switch ($order->pay_type) { case 1://微信退款 if(\Yii::$app instanceof \yii\web\Application){ $notifyUrl = \Yii::$app->request->hostInfo."/member/v1/callback/refund-notify/"; }else{ //如果是job中调用的 $notifyUrl = \Yii::$app->getHostInfo()."/member/v1/callback/refund-notify/"; } $order_amount = bcmul($paymentOrder->amount,100,0); $refund_amount = bcmul($price,100,0); $result = WechatService::getInstance()->payment->refund->byTransactionId($paymentOrder->transaction_id, $paymentRefund->refund_no,$order_amount, $refund_amount, [ 'refund_desc' => '订单申请退款', 'notify_url' => $notifyUrl ]); if($result['return_code']!='SUCCESS' || $result['result_code']!='SUCCESS'){ $error = isset($result['err_code_des']) ? $result['err_code_des'] : $result['return_msg']; throw new Exception($error); } break; case 2://易票联退款 $eplResult = EplPayService::getInstance()->refund([ 'refund_no' => $paymentRefund->refund_no, 'transaction_id' => $paymentOrder->transaction_id, 'total_pay_price' => $paymentOrder->amount, 'refund_price' => $price, ]); if(!isset($eplResult['returnCode']) || $eplResult['returnCode'] != '0000'){ throw new Exception($eplResult['returnMsg']); } break; default: throw new Exception('退款失败,请联系客服'); break; } //其他状态变更在回调 } $transaction->commit(); return []; }catch (\Exception $exception){ $transaction->rollBack(); throw $exception; } } }