6
0
Fork 0
jiqu-library-server/app/Services/PayService.php

173 lines
5.2 KiB
PHP

<?php
namespace App\Services;
use App\Enums\DealerOrderStatus;
use App\Exceptions\BizException;
use App\Exceptions\InvalidPaySerialNumberException;
use App\Models\DealerOrder;
use App\Models\DistributionPreIncomeJob;
use App\Models\Order;
use App\Models\PayLog;
class PayService
{
/**
* 根据支付流水号处理支付成功业务
*
* @param string $sn
* @param array $params
* @return \App\Models\PayLog
*
* @throws \App\Exceptions\BizException
* @throws \App\Exceptions\InvalidPaySerialNumberException
*/
public function handleSuccessByPaySerialNumber(string $paySerialNumber, array $params = []): PayLog
{
$payLog = PayLog::where('pay_sn', $paySerialNumber)->lockForUpdate()->first();
if ($payLog === null) {
throw new InvalidPaySerialNumberException();
}
return $this->handleSuccess($payLog, $params);
}
/**
* 处理支付成功业务
*
* @param \App\Models\PayLog $payLog
* @param array $params
* @return \App\Models\PayLog
*
* @throws \App\Exceptions\BizException
* @throws \App\Exceptions\InvalidPaySerialNumberException
*/
public function handleSuccess(PayLog $payLog, array $params = []): PayLog
{
if (! $payLog->isPending()) {
throw new InvalidPaySerialNumberException();
}
$payLog->update([
'pay_at' => $params['pay_at'] ?? now(),
'out_trade_no' => $params['out_trade_no'] ?? null,
'status' => PayLog::STATUS_SUCCESS,
]);
$payable = $payLog->payable;
if ($payable instanceof Order) {
if ($payable->isPaid()) {
throw new BizException('订单已支付');
}
if ($payable->isCompleted()) {
throw new BizException('订单已完成');
}
// 支付方式
$payWay = $payLog->pay_way;
if ($payLog->isWxpay()) {
// 微信支付
$payWay = Order::PAY_WAY_WXPAY;
} elseif ($payLog->isWallet()) {
// 可提支付
$payWay = Order::PAY_WAY_WALLET;
} elseif ($payLog->isBalance()) {
// 余额支付
$payWay = Order::PAY_WAY_BALANCE;
} elseif ($payLog->isAlipay()) {
// 支付宝
$payWay = Order::PAY_WAY_ALIPAY;
}
$payable->update([
'pay_sn' => $payLog->pay_sn,
'pay_way' => $payWay,
'pay_at' => $payLog->pay_at,
'out_trade_no' => $payLog->out_trade_no,
'status' => Order::STATUS_PAID,
]);
// 增加用户预成长值
$payable->userInfo->incrPreGrowthValue($payable->sales_value, false);
DistributionPreIncomeJob::create([
'jobable_id' => $payable->id,
'jobable_type' => $payable->getMorphClass(),
'remarks' => '支付订单',
]);
} elseif ($payable instanceof DealerOrder) {
if (! $payable->isPendinged()) {
throw new BizException('订单不是待打款');
}
$payable->pay_sn = $payLog->pay_sn;
$payable->pay_time = $payLog->pay_at;
$payable->out_trade_no = $payLog->out_trade_no;
$payable->pay_way = $payLog->pay_way;
if ($payLog->isOffline()) {
$payable->pay_image = $params['pay_image'] ?? null;
$payable->pay_info = $params['pay_info'] ?? null;
$payable->status = DealerOrderStatus::Confirming;
} else {
$payable->paied_time = $payLog->pay_at;
$payable->status = DealerOrderStatus::Paid;
}
$payable->save();
}
return $payLog;
}
/**
* 根据支付流水号处理支付失败业务
*
* @param string $sn
* @param array $params
* @return \App\Models\PayLog
*
* @throws \App\Exceptions\BizException
* @throws \App\Exceptions\InvalidPaySerialNumberException
*/
public function handleFailedByPaySerialNumber(string $paySerialNumber, array $params = []): PayLog
{
$payLog = PayLog::where('pay_sn', $paySerialNumber)->lockForUpdate()->first();
if ($payLog === null) {
throw new InvalidPaySerialNumberException();
}
return $this->handleFailed($payLog, $params);
}
/**
* 处理支付失败业务
*
* @param \App\Models\PayLog $payLog
* @param array $params
* @return \App\Models\PayLog
*
* @throws \App\Exceptions\BizException
* @throws \App\Exceptions\InvalidPaySerialNumberException
*/
public function handleFailed(PayLog $payLog, array $params = []): PayLog
{
if (! $payLog->isPending()) {
throw new InvalidPaySerialNumberException();
}
$payLog->update([
'out_trade_no' => $params['out_trade_no'] ?? null,
'status' => PayLog::STATUS_FAILED,
'failed_reason' => $params['failed_reason'] ?? null,
]);
return $payLog;
}
}