subscription = $subscription; $this->sessionToken = $sessionToken; // Validate that we have a subscription to check if (! $this->subscription) { Log::warning('PaymentConfirmation: No subscription provided', [ 'user_id' => auth()->id(), 'session_token' => $sessionToken, ]); $this->status = 'error'; $this->errorMessage = 'No subscription found for this payment session.'; return; } // Validate subscription belongs to current user if ($this->subscription->user_id !== auth()->id()) { Log::warning('PaymentConfirmation: Subscription does not belong to current user', [ 'user_id' => auth()->id(), 'subscription_user_id' => $this->subscription->user_id, 'subscription_id' => $this->subscription->id, ]); $this->status = 'error'; $this->errorMessage = 'Invalid subscription for this user.'; return; } Log::info('PaymentConfirmation: Mounted with subscription', [ 'user_id' => auth()->id(), 'subscription_id' => $this->subscription->id, 'provider' => $this->subscription->provider, 'provider_subscription_id' => $this->subscription->provider_subscription_id, 'current_status' => $this->subscription->status, 'created_at' => $this->subscription->created_at, 'minutes_ago' => $this->subscription->created_at->diffInMinutes(now()), ]); // Initial status check $this->checkSubscriptionStatus(); // Debug: If subscription is already active, show confetti immediately if ($this->subscription && $this->subscription->status === 'active') { $this->status = 'activated'; $this->showConfetti = true; $this->pollCount = $this->maxPolls; Log::info('PaymentConfirmation: Active subscription detected, showing confetti immediately', [ 'subscription_id' => $this->subscription->id, 'status' => $this->subscription->status, ]); } } /** * Check subscription status via payment provider */ public function checkSubscriptionStatus(): void { if (! $this->subscription || $this->pollCount >= $this->maxPolls) { if ($this->pollCount >= $this->maxPolls) { Log::info('PaymentConfirmation: Max polls reached, redirecting to dashboard', [ 'subscription_id' => $this->subscription?->id, 'poll_count' => $this->pollCount, ]); $this->redirect(route('dashboard')); } $this->isChecking = false; return; } // Set loading state $this->isChecking = true; // Increment poll count first $this->pollCount++; try { Log::info('PaymentConfirmation: Syncing subscription with provider', [ 'subscription_id' => $this->subscription->id, 'provider_subscription_id' => $this->subscription->provider_subscription_id, 'provider' => $this->subscription->provider, 'provider_checkout_id' => $this->subscription->provider_checkout_id, 'poll_count' => $this->pollCount, ]); // Use the same sync method as the billing page $syncSuccess = $this->subscription->syncWithProvider(); // Refresh the subscription from database to get updated status $this->subscription->refresh(); Log::info('PaymentConfirmation: Subscription sync completed', [ 'subscription_id' => $this->subscription->id, 'sync_success' => $syncSuccess, 'current_status' => $this->subscription->status, 'provider_subscription_id' => $this->subscription->provider_subscription_id, ]); // Check if subscription is now active if (in_array($this->subscription->status, ['active', 'trialing'])) { $this->status = 'activated'; $this->showConfetti = true; // Stop polling when activated $this->pollCount = $this->maxPolls; Log::info('PaymentConfirmation: Subscription activated successfully', [ 'subscription_id' => $this->subscription->id, 'final_status' => $this->subscription->status, ]); return; } // Continue polling if not active and max polls not reached if ($this->pollCount < $this->maxPolls) { $this->status = 'verifying'; } else { // Max polls reached, determine final status $this->status = in_array($this->subscription->status, ['active', 'trialing']) ? 'activated' : 'pending'; Log::info('PaymentConfirmation: Max polls reached, final status determined', [ 'final_status' => $this->status, 'subscription_status' => $this->subscription->status, ]); } } catch (\Exception $e) { Log::error('PaymentConfirmation: Error syncing subscription', [ 'subscription_id' => $this->subscription->id, 'error' => $e->getMessage(), 'poll_count' => $this->pollCount, ]); // Don't immediately set error status, continue trying unless max polls reached if ($this->pollCount >= $this->maxPolls) { $this->errorMessage = 'Unable to verify payment status after multiple attempts. Please check your subscription page.'; $this->status = 'error'; } } finally { // Always reset loading state $this->isChecking = false; } } /** * Get polling interval in milliseconds */ public function getPollingIntervalProperty(): int { return 30000; // 30 seconds } /** * Check if polling should continue */ public function getShouldContinuePollingProperty(): bool { return $this->status === 'verifying' && $this->pollCount < $this->maxPolls; } /** * Get status display text */ public function getStatusTextProperty(): string { return match ($this->status) { 'verifying' => 'Verifying your payment...', 'activated' => 'Payment successful! Your subscription is now active.', 'pending' => 'Payment is being processed. Please check your subscription page.', 'error' => 'Unable to verify payment status.', default => 'Checking payment status...', }; } /** * Get status icon */ public function getStatusIconProperty(): string { return match ($this->status) { 'verifying' => 'clock', 'activated' => 'check-circle', 'pending' => 'clock', 'error' => 'exclamation-triangle', default => 'clock', }; } /** * Get status color */ public function getStatusColorProperty(): string { return match ($this->status) { 'verifying' => 'blue', 'activated' => 'green', 'pending' => 'yellow', 'error' => 'red', default => 'gray', }; } public function render(): Factory|View { return view('livewire.payment-confirmation'); } }