transferApp; // 检查是否配置了回调URL if (empty($app->order_callback_url)) { // 没有配置回调URL,直接完成 $order->updateStatus(TransferStatus::COMPLETED); return true; } // 准备回调数据 $callbackData = [ 'out_order_id' => $order->out_order_id, 'status' => $order->status->value, 'status_text' => $order->status->getDescription(), 'amount' => $order->out_amount, 'internal_amount' => $order->amount, 'user_id' => $order->user_id, 'processed_at' => $order->processed_at?->toDateTimeString(), 'callback_data' => $order->callback_data, 'timestamp' => now()->timestamp, ]; // 发送回调 $result = ExternalApiService::sendCallback($app, $callbackData); if ($result['success']) { // 回调成功 $order->updateStatus(TransferStatus::CALLBACK); Log::info('Transfer callback sent successfully', [ 'order_id' => $order->id, 'out_order_id' => $order->out_order_id, 'callback_url' => $app->order_callback_url ]); // 检查回调响应,决定是否完成订单 $responseData = $result['data'] ?? []; if (isset($responseData['code']) && $responseData['code'] == 0) { $order->updateStatus(TransferStatus::COMPLETED); } return true; } else { // 回调失败,记录错误但不更新订单状态(等待重试) Log::error('Transfer callback failed', [ 'order_id' => $order->id, 'out_order_id' => $order->out_order_id, 'callback_url' => $app->order_callback_url, 'error' => $result['message'] ]); return false; } } catch (\Exception $e) { Log::error('Transfer callback exception', [ 'order_id' => $order->id, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return false; } } /** * 重试回调 * * @param TransferOrder $order 订单对象 * @param int $maxRetries 最大重试次数 * @return bool */ public static function retryCallback(TransferOrder $order, int $maxRetries = 3): bool { // 检查重试次数(可以通过callback_data中的retry_count字段记录) $callbackData = $order->callback_data; $retryCount = $callbackData['retry_count'] ?? 0; if ($retryCount >= $maxRetries) { Log::warning('Transfer callback max retries reached', [ 'order_id' => $order->id, 'retry_count' => $retryCount ]); return false; } // 增加重试次数 $callbackData['retry_count'] = $retryCount + 1; $order->update(['callback_data' => $callbackData]); // 重新发送回调 return self::sendCallback($order); } /** * 批量处理待回调的订单 * * @param int $limit 处理数量限制 * @return int 处理的订单数量 */ public static function processPendingCallbacks(int $limit = 50): int { $processedCount = 0; // 查找需要回调的订单 $orders = TransferOrder::where('status', TransferStatus::PROCESSING) ->whereHas('transferApp', function ($query) { $query->whereNotNull('order_callback_url'); }) ->where('created_at', '>', now()->subHours(24)) // 只处理24小时内的订单 ->limit($limit) ->get(); foreach ($orders as $order) { if (self::sendCallback($order)) { $processedCount++; } } return $processedCount; } /** * 批量重试失败的回调 * * @param int $limit 处理数量限制 * @return int 处理的订单数量 */ public static function retryFailedCallbacks(int $limit = 30): int { $processedCount = 0; // 查找回调失败的订单(状态为PROCESSING且创建时间超过5分钟) $orders = TransferOrder::where('status', TransferStatus::PROCESSING) ->whereHas('transferApp', function ($query) { $query->whereNotNull('order_callback_url'); }) ->where('created_at', '<', now()->subMinutes(5)) ->where('created_at', '>', now()->subHours(24)) ->limit($limit) ->get(); foreach ($orders as $order) { if (self::retryCallback($order)) { $processedCount++; } } return $processedCount; } /** * 处理接收到的回调 * * @param array $data 回调数据 * @return bool */ public static function handleIncomingCallback(array $data): bool { try { // 验证必要字段 if (!isset($data['out_order_id']) || !isset($data['out_id'])) { Log::warning('Invalid callback data received', $data); return false; } // 查找订单 $order = TransferOrder::where('out_order_id', $data['out_order_id']) ->where('out_id', $data['out_id']) ->first(); if (!$order) { Log::warning('Callback order not found', $data); return false; } // 验证订单状态 if ($order->isFinalStatus()) { Log::info('Callback received for completed order', [ 'order_id' => $order->id, 'current_status' => $order->status->value ]); return true; } // 更新订单状态 $success = $data['success'] ?? true; $message = $data['message'] ?? null; if ($success) { $order->updateStatus(TransferStatus::COMPLETED, $message); } else { $order->updateStatus(TransferStatus::FAILED, $message); } Log::info('Callback processed successfully', [ 'order_id' => $order->id, 'out_order_id' => $data['out_order_id'], 'success' => $success ]); return true; } catch (\Exception $e) { Log::error('Callback processing exception', [ 'error' => $e->getMessage(), 'data' => $data ]); return false; } } }