phplaravelsession

Cart session cleared after external payment POST request—How to reload cart on failed payment?


I'm working with Laravel-10.32.1 and the package mindscms/laravelshoppingcart- 2.1, and I'm encountering an issue with cart persistence when integrating an external payment provider. In my Laravel app, I send the order total to an external payment provider for processing. The cart is only cleared after successful payment. However, when the user interacts with the payment form (e.g., by clicking "Back" or if the payment fails), the cart is unexpectedly cleared. The external payment provider sends a POST request back to my server, and this starts a new session (likely due to the request coming from an external source). Even though I only clear the cart after successful payment in the controller, the cart disappears due to the session reset triggered by the POST request, without calling ::destroy.

$validPayment = $this->verifyResponse($request);

    // get the basket
    $orderId = ltrim($request->ORDER, '0');
    $order = Order::find($orderId);

    // If borica payment is successful
    if ($validPayment) {
        // update paid price
        $order->amount_paid = $request->AMOUNT;
        $order->save();

        $this->orderService->finish($order);
        $this->orderMailService->sendNotifications($order);
        // Cart is destroyed
        Cart::destroy();
        // redirect to success
        return redirect(URL::signedRoute('checkout.success', ['order' => $order->number]));
    }

    // redirect with errors
    $message = '......';
    if ($request->has('STATUSMSG')) {
        $message = $request->STATUSMSG;
    } else {
        if (array_key_exists($request->RC, $this->errorMessages)) {
            $message = $this->errorMessages[$request->RC];
        }
    }
    // Cart should not be destroyed but it is
    // redirect
    return redirect()->route('checkout.index')->withErrors([$message]);

One approach I’m considering is creating a separate table to store carts temporarily, before sending the user to the payment provider. This table would track the cart contents by order number. Upon a failed payment or session reset, I could check this table and reload the cart if necessary. Is there a better or more standardized way to handle cart persistence in Laravel when dealing with session resets caused by external payment provider redirects? I'm looking for advice on how to avoid losing cart data during the payment process.


Solution

  • This issue is due to new browser rules for cookies. Browsers now declare cookies with no samesite= attribute as samsite=LAX instead of the old behaviour of samesite=None

    This results in the behaviour you are exhibiting, when you leave a website via POST to another website, the cookies are cleared automatically for security.

    You need to change your code so that all cookies that are created, are created as samesite=None so that the cookies are retained when this event occurs.

    For the PHP Session cookies (if your using PHP itself for session cookies that is) you need to edit the PHP.ini and make sure these 2 options are set as shown:

    session.cookie_secure = On
    session.cookie_samesite = "None"