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('订单已完成'); } $payable->update([ 'pay_sn' => $payLog->pay_sn, 'pay_way' => $payLog->pay_way, '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; //签约单,云库存直接发货 if ($payable->consignor === null) { (new OrderService())->orderInDepositstock($payable); } } $payable->save(); } elseif ($payable instanceof DealerDeliveryBill) { if (! $payable->isPending()) { throw new BizException('提货单状态不是待打款'); } $payable->pay_sn = $payLog->pay_sn; $payable->pay_at = $payLog->pay_at; $payable->out_trade_no = $payLog->out_trade_no; $payable->pay_way = $payLog->pay_way; $payable->status = DealerDeliveryBillStatus::Paid; $payable->save(); // 将云仓库存变更为本地库存 $dealerProductLogs = []; foreach ($payable->deliveryProducts as $deliveryProduct) { DealerUserProduct::where([ 'user_id' => $payable->user_id, 'product_id' => $deliveryProduct->product_id, ])->update([ 'stock' => DB::raw("stock + {$deliveryProduct->qty}"), ]); $dealerProductLogs[] = [ 'user_id' => $payable->user_id, 'product_id' => $deliveryProduct->product_id, 'type' => DealerUserProductLog::TYPE_TRANSFER_IN, 'qty' => $deliveryProduct->qty, 'remark' => "云库存转本地库存,提货单【{$payable->sn}】", 'is_deposit' => false, 'created_at' => $payable->updated_at, 'updated_at' => $payable->updated_at, ]; } DealerUserProductLog::insert($dealerProductLogs); //如果云仓库提货单存在关联订单,则该订单直接处理云仓部分的发货 if ($payable->order_id) { $dealerOrder = DealerOrder::find($payable->order_id); (new OrderService())->shippingOrder($dealerOrder, 'deposit_qty'); } } 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; } }