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