188 lines
7.7 KiB
PHP
188 lines
7.7 KiB
PHP
<?php
|
|
|
|
namespace common\forms;
|
|
|
|
use common\core\BaseModel;
|
|
use common\enums\ProductOrderEnum;
|
|
use common\helpers\FuncHelper;
|
|
use common\models\oldDb\PaymentProductOrder;
|
|
use common\models\oldDb\PaymentProductRefund;
|
|
use common\models\oldDb\ProductOrder;
|
|
use common\models\oldDb\ProductOrderRefund;
|
|
use common\services\EplPayService;
|
|
use common\services\WechatService;
|
|
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
|
|
use yii\base\Exception;
|
|
use function GuzzleHttp\Promise\all;
|
|
|
|
class ProductRefundForm extends BaseModel
|
|
{
|
|
public function rules()
|
|
{
|
|
return [
|
|
|
|
];
|
|
}
|
|
|
|
public function refund($post, $type = '')
|
|
{
|
|
if (isset($post['user_id']) && $post['user_id'] > 0) {
|
|
$user_id = $post['user_id'];
|
|
}else{
|
|
$user_id = \Yii::$app->user->identity->getId();
|
|
}
|
|
|
|
$productOrder = ProductOrder::find()->where([
|
|
'user_id' => $user_id,
|
|
'id' => $post['order_id']
|
|
])->one();
|
|
if(!$productOrder || $productOrder->cancel_status){
|
|
throw new Exception('订单不存在');
|
|
}
|
|
|
|
$productOrderRefund = ProductOrderRefund::find()->with(['order'])->where([
|
|
'order_id' => $post['order_id'],
|
|
'user_id' => $user_id,
|
|
|
|
])->andWhere(['in','status', [0, 1]])->one();
|
|
if($productOrderRefund){
|
|
throw new Exception('请勿重复操作');
|
|
}
|
|
// $productOrderStatus = $productOrder->status;
|
|
$t = \Yii::$app->db->beginTransaction();
|
|
try {
|
|
//更新订单退款状态
|
|
$productOrder->status = ProductOrderEnum::REFUNDING; //状态变为退款中
|
|
$productOrder->refund_status = 1; //退款中
|
|
$productOrder->refund_time = time();
|
|
$productOrder->saveOrFail();
|
|
|
|
//生成订单退款记录
|
|
$productOrderRefund = new ProductOrderRefund();
|
|
$productOrderRefund->user_id = $productOrder->user_id;
|
|
$productOrderRefund->order_id = $productOrder->id;
|
|
$productOrderRefund->refund_no = FuncHelper::generate_order_no('RF');
|
|
$productOrderRefund->refund_price = $productOrder->total_pay_price;
|
|
|
|
if( $type == 'auto'){
|
|
$productOrderRefund->status = 1; //直接退款,不需要申请
|
|
$productOrderRefund->reason = '处方失效自动退款';
|
|
$productOrderRefund->remark = '处方失效自动退款';
|
|
$productOrderRefund->saveOrFail();
|
|
//微信退款操作
|
|
$this->refundMoney($productOrderRefund);
|
|
}else{
|
|
$productOrderRefund->reason = $post['reason'] ?? '';
|
|
$productOrderRefund->remark = $post['remark'] ?? '主动申请退款';
|
|
$productOrderRefund->refund_images = $post['refund_images'] ?? '';
|
|
$productOrderRefund->status = 0; //申请退款
|
|
$productOrderRefund->refund_type = 1; //退货退款
|
|
$productOrderRefund->saveOrFail();
|
|
}
|
|
|
|
$t->commit();
|
|
}catch (Exception $exception){
|
|
$t->rollBack();
|
|
throw $exception;
|
|
}
|
|
return ['操作成功'];
|
|
}
|
|
|
|
/**
|
|
* 退款操作
|
|
* @param $productOrderRefund
|
|
* @return true
|
|
* @throws Exception
|
|
* @throws InvalidConfigException
|
|
* @throws \yii\db\Exception
|
|
*/
|
|
public function refundMoney($productOrderRefund)
|
|
{
|
|
$orderNo = $productOrderRefund->order->order_no;
|
|
$productOrder = ProductOrder::findOne([
|
|
'order_no' => $orderNo,
|
|
'is_pay' => 1
|
|
]);
|
|
$paymentProductOrder = PaymentProductOrder::findOne([
|
|
'order_no' => $orderNo,
|
|
'is_pay' => 1
|
|
]);
|
|
if (!$productOrder || !$paymentProductOrder) {
|
|
throw new Exception('无效的订单号');
|
|
}
|
|
$price = $productOrderRefund->refund_price;
|
|
if(bccomp($paymentProductOrder->amount,$price,2)==-1){
|
|
throw new Exception('退款金额大于可退款金额');
|
|
}
|
|
$transaction = \Yii::$app->db->beginTransaction();
|
|
try {
|
|
$paymentProductRefund = new PaymentProductRefund();
|
|
$paymentProductRefund->refund_no = $productOrderRefund->refund_no;
|
|
$paymentProductRefund->amount = $price;
|
|
$paymentProductRefund->is_pay = 0;
|
|
$paymentProductRefund->pay_type = 0;
|
|
$paymentProductRefund->created_at = time();
|
|
$paymentProductRefund->saveOrFail();
|
|
if(bccomp($price,0,2)<=0) {
|
|
$paymentProductRefund->is_pay = 1;
|
|
$paymentProductRefund->save();
|
|
|
|
$productOrder->refund_status = 3;//已退款
|
|
$productOrder->staus = ProductOrderEnum::REFUND;//订单状态变成已退款
|
|
$productOrder->save();
|
|
|
|
$productOrderRefund->is_refund = 1;
|
|
$productOrderRefund->refund_time = time();
|
|
$productOrderRefund->save();
|
|
|
|
//药品库存回滚
|
|
$DrugRollBackForm = new DrugRollBackForm();
|
|
$DrugRollBackForm->rollBack($productOrder->order_type == 1?$productOrder->p_id:$productOrder->id,$productOrder->order_type == 1?1:0);
|
|
}else{
|
|
switch ($paymentProductOrder->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($paymentProductOrder->amount,100,0);
|
|
$refund_amount = bcmul($price,100,0);
|
|
|
|
$result = WechatService::getInstance()->payment->refund->byTransactionId($paymentProductOrder->transaction_id, $paymentProductRefund->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' => $paymentProductRefund->refund_no,
|
|
'transaction_id' => $paymentProductOrder->transaction_id,
|
|
'total_pay_price' => $paymentProductOrder->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 true;
|
|
} catch (\Exception $exception){
|
|
$transaction->rollBack();
|
|
throw $exception;
|
|
}
|
|
}
|
|
} |