diff --git a/addons/shopro/library/traits/model/order/OrderOper.php b/addons/shopro/library/traits/model/order/OrderOper.php index 18d3077..c945af9 100644 --- a/addons/shopro/library/traits/model/order/OrderOper.php +++ b/addons/shopro/library/traits/model/order/OrderOper.php @@ -824,19 +824,41 @@ trait OrderOper public function paymentProcess($order, $notify) { - $order->status = Order::STATUS_PAYED; - $order->paytime = time(); - $order->transaction_id = $notify['transaction_id']; - $order->payment_json = $notify['payment_json']; - $order->pay_type = $notify['pay_type']; - $order->pay_fee = $notify['pay_fee']; - - // 组合支付更新付款金额 - if ($order->pay_type == 'group') { - $order->total_fee = bcsub($order->total_fee, $order->pay_money, 2); + $orderId = is_object($order) ? (int) $order->id : (int) ($order['id'] ?? 0); + if ($orderId <= 0) { + return $order; } - $order->save(); + $firstPaid = false; + $order = Db::transaction(function () use ($orderId, $notify, &$firstPaid) { + $order = Order::where('id', $orderId)->lock(true)->find(); + if (!$order) { + return null; + } + if ((int) $order->status > Order::STATUS_NOPAY) { + \think\Log::info('[order_pay] paymentProcess skip duplicate order_id=' . $orderId); + return $order; + } + + $firstPaid = true; + $order->status = Order::STATUS_PAYED; + $order->paytime = time(); + $order->transaction_id = $notify['transaction_id']; + $order->payment_json = $notify['payment_json']; + $order->pay_type = $notify['pay_type']; + $order->pay_fee = $notify['pay_fee']; + + if ($order->pay_type == 'group') { + $order->total_fee = bcsub($order->total_fee, $order->pay_money, 2); + } + + $order->save(); + return $order; + }); + + if (!$order || !$firstPaid) { + return $order; + } try { saveUserMessage([ @@ -855,12 +877,10 @@ trait OrderOper \think\Log::error('[order_pay] operAdd failed: ' . $e->getMessage()); } - // 组合支付扣除用户余额 if ($order->pay_type == 'group') { User::where(['id' => $user->id])->setDec('money', $order->pay_money); } - // 预约抢购标记成已使用 if ($order->activity_type === 'robbuy') { RobOrderModel::where([ 'user_id' => $user->id, @@ -876,7 +896,6 @@ trait OrderOper \think\Log::error('[order_pay] order_payed_after hook failed: ' . $e->getMessage()); } - // 支付成功后续使用异步队列处理 try { \think\Queue::push('\addons\shopro\job\OrderPayed@payed', ['order' => $order, 'user' => $user], 'shopro-high'); } catch (\Throwable $e) {