diff --git a/addons/shopro/library/ccblife/CcbPaymentService.php b/addons/shopro/library/ccblife/CcbPaymentService.php index 4b22e81..c2b782a 100644 --- a/addons/shopro/library/ccblife/CcbPaymentService.php +++ b/addons/shopro/library/ccblife/CcbPaymentService.php @@ -705,6 +705,11 @@ class CcbPaymentService /** * 记录支付请求 * + * ⚠️ 幂等性说明: + * 1. 当用户多次点击支付按钮时,会复用同一个pay_flow_id + * 2. 本方法会先检查是否已存在记录,如果存在则更新,否则插入 + * 3. 这样可以避免唯一键冲突,并记录最新的支付串生成时间 + * * @param int $orderId 订单ID * @param array $paymentData 支付数据 */ @@ -714,18 +719,43 @@ class CcbPaymentService $order = Order::find($orderId); $user = Db::name('user')->where('id', $order['user_id'])->field('ccb_user_id')->find(); - // 记录到建行支付日志表 - Db::name('ccb_payment_log')->insert([ + $payFlowId = $paymentData['pay_flow_id'] ?? ''; + + // 检查是否已存在记录(根据pay_flow_id唯一键) + $existingLog = Db::name('ccb_payment_log') + ->where('pay_flow_id', $payFlowId) + ->find(); + + $logData = [ 'order_id' => $orderId, 'order_sn' => $order['order_sn'], - 'pay_flow_id' => $paymentData['pay_flow_id'] ?? '', // ✅ 使用真实的支付流水号 'payment_string' => $paymentData['payment_string'] ?? '', 'user_id' => $order['user_id'], 'ccb_user_id' => $user['ccb_user_id'] ?? '', 'amount' => $order['pay_fee'], // 使用Shopro的pay_fee字段 'status' => 0, // 待支付 - 'create_time' => time() - ]); + ]; + + if ($existingLog) { + // 已存在记录,更新支付串(保留原create_time,重置status为待支付) + // 注意:用户重复点击支付时,会生成新的支付串,需要更新 + Db::name('ccb_payment_log') + ->where('pay_flow_id', $payFlowId) + ->update([ + 'payment_string' => $logData['payment_string'], + 'status' => 0, // 重置为待支付(因为是新的支付串) + 'amount' => $logData['amount'], // 更新金额(订单金额可能变化) + ]); + + Log::info('[建行支付] 更新支付日志 pay_flow_id:' . $payFlowId . ' order_id:' . $orderId); + } else { + // 不存在记录,插入新记录 + $logData['pay_flow_id'] = $payFlowId; + $logData['create_time'] = time(); + Db::name('ccb_payment_log')->insert($logData); + + Log::info('[建行支付] 插入支付日志 pay_flow_id:' . $payFlowId . ' order_id:' . $orderId); + } } /**