Files
xk-api-yii/common/forms/OrderRefundForm.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;
}
}
}