all(); // Log entire payload for debugging Log::info('[Stripe Webhook] Received payload', [ 'type' => $payload['type'] ?? 'unknown', 'object' => $payload['data']['object'] ?? null, ]); $object = $payload['data']['object'] ?? []; $metadata = $object['metadata'] ?? []; // Log raw metadata Log::info('[Stripe Webhook] Raw metadata received', $metadata); $userId = $metadata['user_id'] ?? null; $plan = $metadata['plan'] ?? null; $app = $metadata['app'] ?? null; // Log extracted metadata values Log::info('[Stripe Webhook] Extracted Metadata', [ 'user_id' => $userId, 'plan' => $plan, 'app' => $app, ]); // Only handle relevant event types $eventType = $payload['type'] ?? ''; if (!in_array($eventType, [ 'checkout.session.completed', 'invoice.payment_succeeded', 'customer.subscription.created', 'customer.subscription.updated', ])) { Log::info('[Stripe Webhook] Ignored event type', ['event_type' => $eventType]); return response()->json(['status' => 'ignored']); } if (!$userId || !$plan) { Log::warning('[Stripe Webhook] Missing user_id or plan in metadata'); return response()->json(['status' => 'ignored']); } $user = User::find($userId); if (!$user) { Log::warning('[Stripe Webhook] User not found', ['user_id' => $userId]); return response()->json(['status' => 'user not found']); } // Normalize plan name (remove _m if monthly) Log::info('[Stripe Webhook] Normalizing plan', ['original_plan' => $plan]); $normalizedPlan = str_ends_with($plan, '_m') ? str_replace('_m', '', $plan) : $plan; Log::info('[Stripe Webhook] Normalized plan', ['normalized_plan' => $normalizedPlan]); // Always update user_type if valid plan if (in_array($normalizedPlan, ['basic', 'gold', 'platinum'])) { $user->update([ 'user_type' => $normalizedPlan, 'access' => null, 'trial_ends_at' => null, ]); Log::info('[Stripe Webhook] ✅ User type updated successfully', [ 'user_id' => $user->id, 'plan' => $normalizedPlan, ]); } else { Log::warning('[Stripe Webhook] ⚠️ Invalid or unrecognized plan type', ['plan' => $normalizedPlan]); } // Save subscription $subscriptionId = $object['subscription'] ?? $object['id'] ?? null; $priceId = $object['items']['data'][0]['price']['id'] ?? ($object['display_items'][0]['price']['id'] ?? null); Log::info('[Stripe Webhook] Subscription info', [ 'subscription_id' => $subscriptionId, 'price_id' => $priceId, ]); if ($subscriptionId) { $user->subscriptions()->updateOrCreate( ['stripe_id' => $subscriptionId], [ 'type' => 'default', 'stripe_status' => $object['status'] ?? 'active', 'stripe_price' => $priceId, 'quantity' => 1, 'trial_ends_at' => $object['trial_end'] ?? null, 'ends_at' => $object['cancel_at'] ?? null, ] ); Log::info('[Stripe Webhook] Subscription saved/updated', [ 'user_id' => $user->id, 'subscription_id' => $subscriptionId, ]); } else { Log::warning('[Stripe Webhook] No subscription ID found in payload', $object); } return response()->json(['status' => 'ok']); } }