266 lines
6.6 KiB
PHP
266 lines
6.6 KiB
PHP
<?php
|
|
|
|
namespace App\Service\Amqp\Refund;
|
|
|
|
use App\Constants\Common\OrderCode;
|
|
use App\Constants\Common\PayCode;
|
|
use App\Constants\Common\RefundCode;
|
|
use App\Lib\Log;
|
|
use App\Model\Order;
|
|
use App\Model\PayOrder;
|
|
use App\Model\RefundOrder;
|
|
use App\Service\Common\Pay\Wx\WxJsRechargeOrderService;
|
|
use App\Service\ServiceTrait\Api\OrderTrait;
|
|
use Exception;
|
|
use Hyperf\Di\Annotation\Inject;
|
|
use Psr\Container\ContainerExceptionInterface;
|
|
use Psr\Container\NotFoundExceptionInterface;
|
|
|
|
class RefundService
|
|
{
|
|
use OrderTrait;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
public int $orderId;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
public int $type;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
public string $reason;
|
|
|
|
/**
|
|
* @var PayOrder
|
|
*/
|
|
#[Inject]
|
|
protected PayOrder $payOrderModel;
|
|
|
|
/**
|
|
* @var Order
|
|
*/
|
|
#[Inject]
|
|
protected Order $orderModel;
|
|
|
|
/**
|
|
* @var RefundOrder
|
|
*/
|
|
#[Inject]
|
|
protected RefundOrder $refundOrderModel;
|
|
|
|
/**
|
|
* @var Log
|
|
*/
|
|
#[Inject]
|
|
protected Log $log;
|
|
|
|
|
|
/**
|
|
* @var mixed
|
|
*/
|
|
protected mixed $payInfo;
|
|
|
|
/**
|
|
* @var mixed
|
|
*/
|
|
protected mixed $orderInfo;
|
|
|
|
/**
|
|
* @var mixed
|
|
*/
|
|
protected mixed $refundInfo;
|
|
|
|
/**
|
|
* @var float
|
|
*/
|
|
public float $refundAmount;
|
|
|
|
/**
|
|
* @var float
|
|
*/
|
|
protected float $isRefundMoney;
|
|
|
|
/**
|
|
* @return void
|
|
* @throws Exception
|
|
* @throws ContainerExceptionInterface
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
public function handle(): void
|
|
{
|
|
$errMsg = null;
|
|
|
|
try {
|
|
$this->getOrderInfo();
|
|
|
|
$this->checkOrder();
|
|
|
|
$this->getPayAndRefundOrder();
|
|
|
|
$this->getAllRefundMoneyByOrderId();
|
|
|
|
$this->checkRefundAmount();
|
|
|
|
$this->insertRefundOrder();
|
|
|
|
$this->refund();
|
|
} catch (Exception $e) {
|
|
$this->log->error('RefundOrderConsumer:RefundService:error:'.$e->getMessage());
|
|
$errArr = explode(":", $e->getMessage());
|
|
$errMsg = $errArr[0];
|
|
}
|
|
|
|
$this->updateRefund($errMsg);
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
private function insertRefundOrder(): void
|
|
{
|
|
$this->refundInfo = new RefundOrder();
|
|
|
|
$this->refundInfo->user_id = $this->orderInfo->user_id;
|
|
$this->refundInfo->order_type = $this->type;
|
|
$this->refundInfo->order_id = $this->orderId;
|
|
$this->refundInfo->pay_id = $this->payInfo->id;
|
|
$this->refundInfo->refund_status = RefundCode::WAIT_REFUND;
|
|
$this->refundInfo->refund_money = $this->refundAmount;
|
|
$this->refundInfo->refund_type = $this->payInfo->recharge_type;
|
|
$this->refundInfo->refund_order_sno = $this->generateRefundOrderNo($this->type, $this->orderInfo->user_id);
|
|
$this->refundInfo->reason = $this->reason;
|
|
|
|
if (!$this->refundInfo->save()) throw new Exception('退款订单创建失败');
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
protected function getPayAndRefundOrder(): void
|
|
{
|
|
$this->payInfo = $this->payOrderModel->getInfoByOrderIdAndType($this->orderId, $this->type);
|
|
|
|
// $this->refundInfo = $this->refundOrderModel->getInfoByOrderIdAndTypeWaitRefund($this->orderId,$this->type);
|
|
|
|
if (!$this->payInfo) throw new Exception('订单信息不存在');
|
|
|
|
if ($this->payInfo->status != PayCode::FINISH_PAY) throw new Exception('订单支付状态不是成功');
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
protected function getOrderInfo(): void
|
|
{
|
|
$this->orderInfo = match ($this->type) {
|
|
OrderCode::ORDER_TYPE_GOOD => $this->orderModel->getInfoById($this->orderId),
|
|
default => null,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
protected function checkOrder(): void
|
|
{
|
|
if (empty($orderInfo)) throw new Exception('订单信息不存在:'.json_encode(['order_id' => $this->orderId,'order_type' => $this->type]));
|
|
|
|
if (!in_array($orderInfo->status,OrderCode::CAN_REFUND_STATUS)) throw new Exception('订单状态不能退款:'.json_encode($this->orderInfo->toArray()));
|
|
|
|
//余额订单必须退款全部金额
|
|
if ($this->type == OrderCode::ORDER_TYPE_BALANCE && $this->refundAmount != $this->orderInfo->actual_price) throw new Exception('余额订单必须退款全部金额:'.json_encode($this->orderInfo->toArray()));
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
protected function getAllRefundMoneyByOrderId(): void
|
|
{
|
|
$this->isRefundMoney = $this->refundOrderModel->getSuccessMoneyByOrderId($this->orderId,$this->type);
|
|
}
|
|
|
|
// protected function getUser()
|
|
// {
|
|
// //todo 获取用户信息
|
|
// }
|
|
|
|
/**
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
protected function checkRefundAmount(): void
|
|
{
|
|
// 等于支付金额 减去 已退款金额 减去 本次退款金额 小于 0 就是错误的 大于等于 0 就是正确的
|
|
if ($this->orderInfo->actual_price - $this->isRefundMoney - $this->refundAmount < 0) throw new Exception('退款金额不能大于订单金额');
|
|
|
|
$this->refundAmount = 0;
|
|
}
|
|
|
|
/**
|
|
* @param null $errMsg
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
protected function updateRefund($errMsg = null): void
|
|
{
|
|
$status = RefundCode::REFUND_FAIL;
|
|
|
|
if (empty($errMsg)) {
|
|
$status = RefundCode::WAIT_BY_PAY_TOOL;
|
|
$errMsg = '等待支付工具退款';
|
|
}
|
|
|
|
$this->refundInfo->refund_status = $status;
|
|
$this->refundInfo->remark = $errMsg;
|
|
|
|
if (!$this->refundInfo->save()) throw new Exception('退款订单更新失败');
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throws ContainerExceptionInterface
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
protected function refund(): void
|
|
{
|
|
$rechargeService = match ($this->refundInfo->refund_type)
|
|
{
|
|
PayCode::ALIPAY => $this->setAliPayRefund(),
|
|
PayCode::WECHAT_PAY => $this->setWechatPayRefund(),
|
|
};
|
|
|
|
$rechargeService->setConfig();
|
|
$rechargeService->setRefundNotify();
|
|
|
|
$rechargeService->refund(
|
|
$this->refundAmount,
|
|
(float)$this->orderInfo->actual_price,
|
|
$this->orderInfo->order_no,
|
|
$this->refundInfo->refund_no,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return null
|
|
*/
|
|
protected function setAliPayRefund()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return WxJsRechargeOrderService
|
|
*/
|
|
protected function setWechatPayRefund(): WxJsRechargeOrderService
|
|
{
|
|
return new WxJsRechargeOrderService();
|
|
}
|
|
} |