resolveOrderId($request); $fallback = $this->resolveFallbackUrl(); if (! $orderId) { return redirect()->to($fallback); } try { $order = $this->orders->retrieve($orderId); } catch (LemonSqueezyException $exception) { Log::warning('Lemon Squeezy return failed to load order', [ 'order_id' => $orderId, 'error' => $exception->getMessage(), 'status' => $exception->status(), ]); return redirect()->to($fallback); } $customData = $this->extractCustomData($order); $status = Str::lower((string) Arr::get($order, 'attributes.status', '')); $successUrl = $customData['success_url'] ?? null; $cancelUrl = $customData['return_url'] ?? null; $target = $this->isSuccessStatus($status) ? $successUrl : $cancelUrl; $target = $this->resolveSafeRedirect($target, $fallback); return redirect()->to($target); } protected function resolveOrderId(Request $request): ?string { $candidate = $request->query('order_id') ?? $request->query('order'); if (! is_string($candidate) || $candidate === '') { return null; } return $candidate; } protected function resolveFallbackUrl(): string { return rtrim((string) config('app.url', url('/')), '/') ?: url('/'); } /** * @param array $order * @return array */ protected function extractCustomData(array $order): array { $customData = Arr::get($order, 'attributes.custom_data', []); return is_array($customData) ? $customData : []; } protected function isSuccessStatus(string $status): bool { return in_array($status, ['paid', 'completed'], true); } protected function resolveSafeRedirect(?string $target, string $fallback): string { if (! $target) { return $fallback; } if (Str::startsWith($target, ['/'])) { return $target; } $appHost = parse_url($fallback, PHP_URL_HOST); $targetHost = parse_url($target, PHP_URL_HOST); if ($appHost && $targetHost && Str::lower($appHost) === Str::lower($targetHost)) { return $target; } return $fallback; } }