private function transformUser(?User $user): ?array { if (!$user) { return null; } return [ 'id' => $user->id, 'email' => $user->email, 'name' => trim(($user->first_name ?? '').' '.($user->last_name ?? '')) ?: $user->name, 'pending_purchase' => (bool) $user->pending_purchase, 'email_verified_at' => $user->email_verified_at, ]; } /** * Track an abandoned checkout for reminder emails */ public function trackAbandonedCheckout(Request $request): JsonResponse { $request->validate([ 'package_id' => 'required|integer|exists:packages,id', 'last_step' => 'required|integer|min:1|max:4', 'user_id' => 'nullable|integer|exists:users,id', 'email' => 'nullable|email', ]); try { $userId = $request->user_id; $email = $request->email; // Wenn kein user_id aber email, versuche User zu finden if (!$userId && $email) { $user = User::where('email', $email)->first(); $userId = $user?->id; } // Nur tracken wenn wir einen User haben if (!$userId) { return response()->json(['success' => false, 'message' => 'No user found to track']); } $user = User::find($userId); if (!$user) { return response()->json(['success' => false, 'message' => 'User not found']); } // Erstelle oder update abandoned checkout AbandonedCheckout::updateOrCreate( [ 'user_id' => $userId, 'package_id' => $request->package_id, ], [ 'email' => $user->email, 'checkout_state' => null, // Später erweitern 'last_step' => $request->last_step, 'abandoned_at' => now(), 'reminded_at' => null, 'reminder_stage' => 'none', 'expires_at' => now()->addDays(7), // 7 Tage gültig 'converted' => false, ] ); Log::info("Abandoned checkout tracked for user {$userId}, package {$request->package_id}, step {$request->last_step}"); return response()->json(['success' => true]); } catch (\Exception $e) { Log::error('Failed to track abandoned checkout: ' . $e->getMessage()); return response()->json(['success' => false, 'message' => 'Failed to track checkout'], 500); } } }