validate([ 'package_id' => ['required', 'exists:packages,id'], 'locale' => ['nullable', 'string'], ]); $payload = [ 'package_id' => (int) $validated['package_id'], 'locale' => $validated['locale'] ?? app()->getLocale(), ]; $request->session()->put(self::SESSION_KEY, $payload); $request->session()->put('selected_package_id', $payload['package_id']); return Socialite::driver('facebook') ->scopes(['email']) ->fields(['name', 'email', 'first_name', 'last_name']) ->redirect(); } public function callback(Request $request): RedirectResponse { $payload = $request->session()->get(self::SESSION_KEY, []); $packageId = $payload['package_id'] ?? null; $locale = $payload['locale'] ?? null; try { $facebookUser = Socialite::driver('facebook')->user(); } catch (\Throwable $e) { Log::warning('Facebook checkout login failed', ['message' => $e->getMessage()]); $this->flashError($request, __('checkout.facebook_error_fallback')); return $this->redirectBackToWizard($packageId, $locale); } $email = $facebookUser->getEmail(); if (! $email) { $this->flashError($request, __('checkout.facebook_missing_email')); return $this->redirectBackToWizard($packageId, $locale); } $raw = $facebookUser->getRaw(); $givenName = $raw['first_name'] ?? null; $familyName = $raw['last_name'] ?? null; $request->session()->put('checkout_facebook_profile', array_filter([ 'email' => $email, 'name' => $facebookUser->getName(), 'given_name' => $givenName, 'family_name' => $familyName, 'avatar' => $facebookUser->getAvatar(), 'locale' => $raw['locale'] ?? null, ])); $existing = User::where('email', $email)->first(); if (! $existing) { $request->session()->put('checkout_facebook_profile', array_filter([ 'email' => $email, 'name' => $facebookUser->getName(), 'given_name' => $givenName, 'family_name' => $familyName, 'avatar' => $facebookUser->getAvatar(), 'locale' => $raw['locale'] ?? null, ])); $request->session()->put('checkout_facebook_status', 'prefill'); return $this->redirectBackToWizard($packageId, $locale); } $user = DB::transaction(function () use ($existing, $facebookUser, $email) { $existing->forceFill([ 'name' => $facebookUser->getName() ?: $existing->name, 'pending_purchase' => true, 'email_verified_at' => $existing->email_verified_at ?? now(), ])->save(); if (! $existing->tenant) { $this->createTenantForUser($existing, $facebookUser->getName(), $email); } return $existing->fresh(); }); if (! $user->tenant) { $this->createTenantForUser($user, $facebookUser->getName(), $email); } Auth::login($user, true); $request->session()->regenerate(); $request->session()->forget(self::SESSION_KEY); $request->session()->forget('checkout_facebook_profile'); $request->session()->put('checkout_facebook_status', 'signin'); if ($packageId) { $this->ensurePackageAttached($user, (int) $packageId); } return $this->redirectBackToWizard($packageId, $locale); } private function createTenantForUser(User $user, ?string $displayName, string $email): Tenant { $tenantName = trim($displayName ?: Str::before($email, '@')) ?: 'Fotospiel Tenant'; $slugBase = Str::slug($tenantName) ?: 'tenant'; $slug = $slugBase; $counter = 1; while (Tenant::where('slug', $slug)->exists()) { $slug = $slugBase.'-'.$counter; $counter++; } $tenant = Tenant::create([ 'user_id' => $user->id, 'name' => $tenantName, 'slug' => $slug, 'email' => $email, 'contact_email' => $email, 'is_active' => true, 'is_suspended' => false, 'subscription_tier' => 'free', 'subscription_status' => 'free', 'subscription_expires_at' => null, 'settings' => json_encode([ 'branding' => [ 'logo_url' => null, 'primary_color' => '#FF5A5F', 'secondary_color' => '#FFF8F5', 'font_family' => 'Inter, sans-serif', ], 'features' => [ 'photo_likes_enabled' => false, 'event_checklist' => false, 'custom_domain' => false, 'advanced_analytics' => false, ], 'custom_domain' => null, 'contact_email' => $email, 'event_default_type' => 'general', ]), ]); $user->forceFill(['tenant_id' => $tenant->id])->save(); return $tenant; } private function ensurePackageAttached(User $user, int $packageId): void { $tenant = $user->tenant; if (! $tenant) { return; } $package = Package::find($packageId); if (! $package) { return; } if ($tenant->packages()->where('package_id', $packageId)->exists()) { return; } $tenant->packages()->attach($packageId, [ 'price' => $package->price, 'purchased_at' => now(), 'expires_at' => now()->addYear(), 'active' => $package->price <= 0, ]); } private function redirectBackToWizard(?int $packageId, ?string $locale = null): RedirectResponse { if ($packageId) { return redirect()->to(CheckoutRoutes::wizardUrl($packageId, $locale)); } $firstPackageId = Package::query()->orderBy('price')->value('id'); if ($firstPackageId) { return redirect()->to(CheckoutRoutes::wizardUrl($firstPackageId, $locale)); } return redirect()->route('packages', [ 'locale' => LocaleConfig::canonicalize($locale ?? app()->getLocale()), ]); } private function flashError(Request $request, string $message): void { $request->session()->flash('checkout_facebook_error', $message); } }