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