route('pricing'); } // Normalise provider and model to lowercase $provider = strtolower($provider); $model = $model ? strtolower($model) : null; // Build referral data for session (includes hashed IP for fraud detection) $referral = [ 'provider' => $provider, 'model' => $model, 'referred_at' => now()->toIso8601String(), 'ip_hash' => PrivacyHelper::hashIp($request->ip()), ]; // Track the referral visit in stats (raw inbound count) TreePlantingStats::incrementReferrals($provider, $model); // Store in session (primary) - includes hashed IP $request->session()->put(self::REFERRAL_SESSION, $referral); // Cookie data - exclude IP for privacy (GDPR compliance) // Provider/model is sufficient for referral attribution $cookieData = [ 'provider' => $provider, 'model' => $model, 'referred_at' => $referral['referred_at'], ]; // Set 30-day cookie (backup for session expiry) $cookie = Cookie::make( name: self::REFERRAL_COOKIE, value: json_encode($cookieData), minutes: self::COOKIE_LIFETIME, path: '/', domain: config('session.domain'), secure: config('app.env') === 'production', httpOnly: true, sameSite: 'lax' ); // Redirect to pricing with ref=agent parameter return redirect() ->route('pricing', ['ref' => 'agent']) ->withCookie($cookie); } /** * Get the agent referral from session or cookie. * * @return array{provider: string, model: ?string, referred_at: string, ip_hash?: string}|null */ public static function getReferral(Request $request): ?array { // Try session first $referral = $request->session()->get(self::REFERRAL_SESSION); if ($referral) { return $referral; } // Fall back to cookie $cookie = $request->cookie(self::REFERRAL_COOKIE); if ($cookie) { try { $decoded = json_decode($cookie, true); if (is_array($decoded) && isset($decoded['provider'])) { return $decoded; } } catch (\Throwable) { // Cookie invalid — ignore } } return null; } /** * Clear the agent referral from session and cookie. */ public static function clearReferral(Request $request): void { $request->session()->forget(self::REFERRAL_SESSION); Cookie::queue(Cookie::forget(self::REFERRAL_COOKIE)); } }