Prevent Magento to empty cart after failed payments

The question:

How can I stop Magento to empty cart after the customer fails to pay with a card?

The customer can use a different card but the cart already becomes empty and he/she needs to put all the items back into card again which makes the site loose customer.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

In your payment method’s controller you’ll have an action for failed/rejected/canceled orders.

Let’s say it’s called failAction(). Then you can add something like the following to your function.

public function failAction() {
...
    if(Mage::getSingleton('checkout/session')->getLastRealOrderId()){
        if ($lastQuoteId = Mage::getSingleton('checkout/session')->getLastQuoteId()){
            $quote = Mage::getModel('sales/quote')->load($lastQuoteId);
            $quote->setIsActive(true)->save();
        }
        Mage::getSingleton('core/session')->addError(Mage::helper('module_name')->__('Inform the customer for failed transaction'));
        $this->_redirect('checkout/cart'); //Redirect to cart
        return;
    }
...
 }

Method 2

/app/code/core/Mage/Checkout/controllers/OnepageController.php this file is the actual controller file, but depends up on the payment method extensions it will change with Namespace/Modulename/Checkout/controllers/OnepageController.php

Find function saveOrderAction()

find these lines

$this->getOnepage()->getQuote()->save();
        /**
         * when there is redirect to third party, we don't want to save order yet.
         * we will save the order in return action.
         */
        if (isset($redirectUrl)) {
            $result['redirect'] = $redirectUrl;
        }

        $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));

comment this line //$this->getOnepage()->getQuote()->save();
and add below codes inside the if condition so the condition will look like ..

    if (isset($redirectUrl)) {
                $result['redirect'] = $redirectUrl;
                $this->getOnepage()->getQuote()->setIsActive(1) ;
            }
    $this->getOnepage()->getQuote()->save();
   $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));

This is i have done with the third party Payment extension.

Method 3

For Naveen answer, if any one using IWD extension, then function saveOrderAction() is in app/code/community/IWD/Opc/controllers/JsonController.php

Method 4

Below is the solutions for Magento 2.3.5. Please override Failure.php(Core file path: /vendor/magento/module-checkout/Controller/Onepage) and change public function as below

public function execute()
{
    
    $objectManager = MagentoFrameworkAppObjectManager::getInstance();
    $_checkoutSession = $objectManager->create('MagentoCheckoutModelSession');
    $_quoteFactory = $objectManager->create('MagentoQuoteModelQuoteFactory');
    
    $order = $_checkoutSession->getLastRealOrder();
    $quote = $_quoteFactory->create()->loadByIdWithoutStore($order->getQuoteId());
    if ($quote->getId()) {
        $quote->setIsActive(1)->setReservedOrderId(null)->save();
        $_checkoutSession->replaceQuote($quote);
        $resultRedirect = $this->resultRedirectFactory->create();
        $resultRedirect->setPath('checkout/cart');
        //$this->messageManager->addWarningMessage('Payment Failed.');
        return $resultRedirect;
    }
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment