
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.
Khushal Makwana Reply
This is helpful for me..