wechatPayService = new WeChatPayService($terminal, $userId); $this->balancePayService = new BalancePayService(); } catch (\Exception $e) { $this->setError('混合支付服务初始化失败:' . $e->getMessage()); } } /** * @notes 获取真实支付对象 * @return mixed */ function realPay() { return $this->wechatPayService->realPay(); } /** * @notes 混合支付(余额+微信) * @param $from 订单类型 * @param $order 订单信息 * @return array|false * @author 系统 * @date 2024/12/19 */ public function pay($from, $order) { Db::startTrans(); try { $user = User::findOrEmpty($order['user_id']); if ($user->isEmpty()) { throw new \Exception('用户不存在'); } // 记录调试日志 file_put_contents( runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_pay_debug_' . date('Y-m-d') . '.log', "[" . date('Y-m-d H:i:s') . "] 混合支付开始 - 用户ID: {$order['user_id']}, 订单号: {$order['sn']}, 订单金额: {$order['order_amount']}" . PHP_EOL, FILE_APPEND | LOCK_EX ); $userBalance = $user['user_money']; // 用户余额 $orderAmount = $order['order_amount']; // 订单金额 // 记录余额信息 file_put_contents( runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_pay_debug_' . date('Y-m-d') . '.log', "[" . date('Y-m-d H:i:s') . "] 用户余额: {$userBalance}, 订单金额: {$orderAmount}" . PHP_EOL, FILE_APPEND | LOCK_EX ); // 如果余额足够支付全部订单,直接使用余额支付 if ($userBalance >= $orderAmount) { file_put_contents( runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_pay_debug_' . date('Y-m-d') . '.log', "[" . date('Y-m-d H:i:s') . "] 余额充足,使用纯余额支付" . PHP_EOL, FILE_APPEND | LOCK_EX ); $result = $this->balancePayService->pay($from, $order); if ($result === false) { throw new \Exception('余额支付失败:' . $this->balancePayService->getError()); } Db::commit(); return $result; } // 余额不足,使用混合支付 $balanceAmount = $userBalance; // 使用全部余额 $wechatAmount = $orderAmount - $balanceAmount; // 剩余金额用微信支付 file_put_contents( runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_pay_debug_' . date('Y-m-d') . '.log', "[" . date('Y-m-d H:i:s') . "] 使用混合支付 - 余额部分: {$balanceAmount}, 微信部分: {$wechatAmount}" . PHP_EOL, FILE_APPEND | LOCK_EX ); // 先扣除用户余额 if ($balanceAmount > 0) { User::update([ 'user_money' => ['dec', $balanceAmount] ], ['id' => $order['user_id']]); // 记录余额流水 AccountLogLogic::add( $order['user_id'], AccountLogEnum::BNW_DEC_ORDER, AccountLogEnum::DEC, $balanceAmount, $order['sn'], '混合支付-余额部分' ); file_put_contents( runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_pay_debug_' . date('Y-m-d') . '.log', "[" . date('Y-m-d H:i:s') . "] 余额扣除成功,扣除金额: {$balanceAmount}" . PHP_EOL, FILE_APPEND | LOCK_EX ); } // 创建微信支付订单(金额为剩余需要支付的金额) $wechatOrder = $order; $wechatOrder['order_amount'] = $wechatAmount; $wechatOrder['balance_amount'] = $balanceAmount; // 记录已使用的余额金额 file_put_contents( runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_pay_debug_' . date('Y-m-d') . '.log', "[" . date('Y-m-d H:i:s') . "] 开始创建微信支付订单,金额: {$wechatAmount}" . PHP_EOL, FILE_APPEND | LOCK_EX ); $result = $this->wechatPayService->pay($from, $wechatOrder); if ($result === false) { throw new \Exception('微信支付创建失败:' . $this->wechatPayService->getError()); } // 在返回结果中添加混合支付信息 $result['pay_way'] = PayEnum::MIXED_PAY; $result['balance_amount'] = $balanceAmount; $result['wechat_amount'] = $wechatAmount; $result['total_amount'] = $orderAmount; file_put_contents( runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_pay_debug_' . date('Y-m-d') . '.log', "[" . date('Y-m-d H:i:s') . "] 混合支付创建成功" . PHP_EOL, FILE_APPEND | LOCK_EX ); Db::commit(); return $result; } catch (\Exception $e) { Db::rollback(); file_put_contents( runtime_path() . 'log' . DIRECTORY_SEPARATOR . 'mixed_pay_debug_' . date('Y-m-d') . '.log', "[" . date('Y-m-d H:i:s') . "] 混合支付失败: " . $e->getMessage() . PHP_EOL, FILE_APPEND | LOCK_EX ); $this->setError($e->getMessage()); return false; } } /** * @notes 混合支付退款 * @param $order 订单信息 * @param $refundAmount 退款金额 * @param $afterSaleId 售后ID * @return bool */ public function refund($order, $refundAmount, $afterSaleId) { try { // 获取订单的余额支付金额和微信支付金额 $balanceAmount = $order['balance_amount'] ?? 0; $wechatAmount = $order['order_amount'] - $balanceAmount; // 按比例退款 if ($refundAmount >= $order['order_amount']) { // 全额退款 $refundBalanceAmount = $balanceAmount; $refundWechatAmount = $wechatAmount; } else { // 部分退款,按比例分配 $refundRatio = $refundAmount / $order['order_amount']; $refundBalanceAmount = $balanceAmount * $refundRatio; $refundWechatAmount = $wechatAmount * $refundRatio; } // 退回余额 if ($refundBalanceAmount > 0) { $this->balancePayService->refund($order, $refundBalanceAmount, $afterSaleId); } // 微信退款 if ($refundWechatAmount > 0) { // 这里需要调用微信退款接口 $refundData = [ 'out_trade_no' => $order['sn'], 'out_refund_no' => 'refund_' . $order['sn'] . '_' . time(), 'total_fee' => $wechatAmount * 100, // 原订单金额(分) 'refund_fee' => $refundWechatAmount * 100, // 退款金额(分) ]; $this->wechatPayService->refund($refundData); } return true; } catch (\Exception $e) { $this->setError($e->getMessage()); return false; } } }