211 lines
8.3 KiB
PHP
211 lines
8.3 KiB
PHP
<?php
|
|
namespace common\forms;
|
|
|
|
use common\core\BaseModel;
|
|
use common\enums\ImSessionStatusEnum;
|
|
use common\enums\OrderAcceptEnum;
|
|
use common\enums\SystemNoticeTypeEnum;
|
|
use common\events\OrderEvent;
|
|
use common\helpers\FuncHelper;
|
|
use common\models\oldDb\ImMessageSession;
|
|
use common\models\oldDb\Order;
|
|
use common\models\oldDb\OrderRefund;
|
|
use common\models\oldDb\PaymentOrder;
|
|
use common\models\oldDb\PaymentRefund;
|
|
use common\models\oldDb\SystemNotice;
|
|
use common\services\EplPayService;
|
|
use common\services\WechatService;
|
|
use yii\base\Exception;
|
|
|
|
class OrderRefundForm extends BaseModel
|
|
{
|
|
public function rules()
|
|
{
|
|
return [
|
|
|
|
];
|
|
}
|
|
|
|
public function refund($order_id)
|
|
{
|
|
$order = Order::find()->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;
|
|
}
|
|
}
|
|
}
|