feat(payment): implement beautiful payment confirmation page with real-time status checking
- Add PaymentSuccessController with authentication and subscription selection logic - Create PaymentConfirmation Livewire component with polling mechanism - Implement real-time subscription status verification via Polar provider API - Add confetti animation for successful payment confirmation - Design responsive payment success page with dark mode support - Fix Polar provider field mapping (updated_at -> modified_at) - Add comprehensive error handling and logging - Support multiple subscription status states (verifying, activated, pending, error) - Implement automatic polling with 30-second intervals (max 5 attempts) - Add fallback redirects and user-friendly status messages
This commit is contained in:
64
app/Http/Controllers/PaymentSuccessController.php
Normal file
64
app/Http/Controllers/PaymentSuccessController.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Subscription;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class PaymentSuccessController extends Controller
|
||||
{
|
||||
// Middleware is now registered in bootstrap/app.php for Laravel 12
|
||||
|
||||
/**
|
||||
* Show payment confirmation page after successful checkout
|
||||
*/
|
||||
public function show(Request $request): View
|
||||
{
|
||||
$user = $request->user();
|
||||
$sessionToken = $request->get('customer_session_token');
|
||||
|
||||
Log::info('PaymentSuccessController: Showing payment confirmation', [
|
||||
'user_id' => $user->id,
|
||||
'session_token' => $sessionToken,
|
||||
]);
|
||||
|
||||
// Get the most recent subscription for this user created in the last 15 minutes
|
||||
// This ensures we're checking the subscription from the current payment session
|
||||
$recentMinutes = 15;
|
||||
$subscription = Subscription::where('user_id', $user->id)
|
||||
->where('created_at', '>=', now()->subMinutes($recentMinutes))
|
||||
->whereIn('status', ['pending_payment', 'incomplete', 'trialing', 'active']) // Likely statuses for new subscriptions
|
||||
->orderBy('created_at', 'desc')
|
||||
->first();
|
||||
|
||||
// If no recent subscription found, fall back to the most recent one overall
|
||||
if (! $subscription) {
|
||||
Log::info('PaymentSuccessController: No recent subscription found, falling back to most recent', [
|
||||
'user_id' => $user->id,
|
||||
'minutes_checked' => $recentMinutes,
|
||||
]);
|
||||
|
||||
$subscription = Subscription::where('user_id', $user->id)
|
||||
->orderBy('created_at', 'desc')
|
||||
->first();
|
||||
}
|
||||
|
||||
Log::info('PaymentSuccessController: Subscription selected for status checking', [
|
||||
'user_id' => $user->id,
|
||||
'subscription_id' => $subscription?->id,
|
||||
'provider_subscription_id' => $subscription?->provider_subscription_id,
|
||||
'provider' => $subscription?->provider,
|
||||
'status' => $subscription?->status,
|
||||
'created_at' => $subscription?->created_at,
|
||||
'is_recent' => $subscription && $subscription->created_at->diffInMinutes(now()) <= $recentMinutes,
|
||||
]);
|
||||
|
||||
return view('payment.success', [
|
||||
'user' => $user,
|
||||
'subscription' => $subscription,
|
||||
'sessionToken' => $sessionToken,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user