Keep Users Logged In After Payment Success/Failed Redirection in Laravel: A Step-by-Step Guide

featured_img1737466402.webp

Keep Users Logged In After Payment Success/Failed Redirection in Laravel: A Step-by-Step Guide

Table of Contents

    The issue of the user logging out after a successful payment redirection in Laravel is commonly caused by discrepancies in session management. This could be due to mismatched domains, session configuration, or issues with the SESSION_COOKIE or session driver.

    This guide will walk you through the steps to resolve this issue effectively.

    Step 1: Configure Session Settings Correctly

    Set the Global variable correct in .env file

                                            
                                                SESSION_DRIVER=database
                                                SESSION_LIFETIME=120
                                                SESSION_ENCRYPT=false
                                                SESSION_PATH=/
                                                SESSION_DOMAIN=.domain.com
                                                SESSION_HTTP_ONLY=true
                                                SESSION_SAME_SITE=None
                                            
                                    

    Verify the SESSION_DOMAIN matches your domain and includes subdomains if needed.

    Tip: After updating the .env file, clear and refresh the config cache by running:

                                        
                                            php artisan config:clear 
                                            php artisan cache:clear
                                        
                                    

    Step 2: Use Database Sessions Driver

    In laravel Database storage is a great choice for handling Secure and scalable session handling Many Requests.

    Generate the session table

                                        
                                            php artisan session:table 
                                            php artisan migrate
                                        
                                    

    Step 3: Handle CSRF Token Mismatch

    Laravel’s CSRF protection can interfere with payment gateway callbacks. To prevent token mismatch errors, add payment-related routes to the CSRF exception list in the middleware.

    Update your app/Http/Middleware/VerifyCsrfToken.php or in latest laravel bootstrap/app.php file:

                                        
                                            $middleware->validateCsrfTokens(except: [
                                                    'payment/success',
                                                    'payment/failed'
                                                ]);
                                        
                                    

    Step 4: Define GET/POST Callback Routes.

    Payment gateways typically redirect users via GET or POST requests. Define these routes in your routes/web.php file:

                                        
                                        use App\Http\Controllers\PG\PaymentController;
    
                                        //PG success_url
                                        Route::match(['get', 'post'], 'payment/success', [PaymentController::class, 'paymentSuccess'])->name('payment.success');
                                        //PG failure_url
                                        Route::match(['get', 'post'], 'payment/failed',  [PaymentController::class, 'paymentFailed'])->name('payment.failed');
                                       
                                        
                                   

    Step 5: Verify Session expired, and user is re-authenticated

    To keep users logged in after a payment success or failure redirection in Laravel, using the user_id from the payment gateway response can be an effective another approach

    Ensure that the payment gateway sends the user_id back in its success or failure response payload. Typically, this is passed as a parameter when redirecting back to your application.

    Create the PaymentController to handle Callback Methods

                                        
                                            php artisan make:controller PaymentController 
                                        
                                    

    Update the methods to check and log in the user if their session is expired.

                                         
                                                    namespace App\Http\Controllers\PG;
    
                                                    use App\Http\Controllers\Controller;
                                                    use Illuminate\Http\Request;
                                                    use App\Models\TransactionModel;
                                                    use Illuminate\Support\Facades\Auth;
                                                    class PaymentController extends Controller
                                                    {
                                                
                                                        public function paymentSuccess(Request $request){
                                                            try {                   
                                                    
                                                                $txn_ref_id = $request->req_id??null;
                                                                $status = $request->status??null;
                                                                $order_id = $request->order_id??null;
                                                                $user_id = $request->user_id??null;
                                                    
                                                                // Attempt to log in the user
                                                                if ($user_id && !Auth::check()) {
                                                                    $user = User::find($user_id);
                                                                    if ($user) {
                                                                        Auth::login($user);
                                                                    }
                                                                }
                                                    
                                                                if($txn_ref_id && $status){
                                                                    $this->updatePaymentStatus($txn_ref_id,$order_id,$status);
                                                                    return redirect()->route('dashboard')->with('success', 'Payment successful!');
                                                                }
                                                            
                                                            return redirect()->route('dashboard')->with("error","Your payment could not be processed. Please try again.");
                                                    
                                                            } catch (\Exception $e) {
                                                                return response()->json(['message' => 'Your payment could not be processed. Please try again.', 'error' => $e->getMessage()], 500);
                                                            }
                                                    
                                                        }                   
                                                
                                                    
                                                        public function paymentFailed(Request $request){
                                                            try {
                                                                $txn_ref_id = $request->req_id??null;
                                                                $status = $request->status??null;
                                                                $order_id = $request->order_id??null;
                                                                $user_id = $request->user_id??null;
                                                            
                                                                // Attempt to log in the user
                                                                if ($user_id && !Auth::check()) {
                                                                    $user = User::find($user_id);
                                                                    if ($user) {
                                                                        Auth::login($user);
                                                                    }
                                                                }
                                                    
                                                                if($txn_ref_id && $status){
                                                                    $this->updatePaymentStatus($txn_ref_id,$order_id,$status);
                                                                    return redirect()->route('dashboard')->with('error', 'Payment failed. Please try again.');
                                                                }
                                                            
                                                            return redirect()->route('user.biller')->with("error","Your payment could not be processed. Please try again.");
                                                    
                                                            } catch (\Exception $e) {
                                                                return response()->json(['message' => 'Your payment could not be processed. Please try again.', 'error' => $e->getMessage()], 500);
                                                            }
                                                        
                                                        }
                                                    
                                                
                                                        public function updatePaymentStatus($txn_ref_id,$order_id,$status){
                                                            $existingPgTransaction = TransactionModel::query()
                                                            ->where('txn_ref_id', $txn_ref_id)
                                                            ->where('order_id', $order_id)
                                                            ->first();
                                                    
                                                            if($existingPgTransaction){
                                                                $txn_status = $status=="Success"?"SUCCESS":"FAILED";
                                                                $existingPgTransaction->update(['txn_status' => $txn_status]);
                                                            }     
                                                        }                         
                                                    }
                                        
                                    

    By implementing these steps, you ensure users remain logged in even after being redirected from the payment gateway, providing a seamless user experience.

    Did this solution work for you? Drop a like or comment below!

    Satish Parmar

    Satish Parmar

    Experienced Full-Stack Web Developer

    I'm a passionate full-stack developer and blogger from India, dedicated to sharing web development tips and solutions. As the creator of TipInfoTrove.com, my goal is to help developers and tech enthusiasts solve real-world challenges with expertise in PHP, Laravel, JavaScript, Vue, React, and more. Through detailed guides and practical insights, I strive to empower others to excel in their projects and stay ahead in the ever-evolving world of technology.

    1 Comments

    Khushal Makwana Reply

    This is helpful for me..

    Post Comment

    Your email address will not be published. Required fields are marked *