11
votes

This is one of the most vital problems I have found since I started testing Magento for my web store. It's kind of a no-brainer that it's absolutely unnecessary and harmful to sales to empty cart before payment confirmation, which unfortunately, Magento does.

If the user selects PayPal (website standard) for payment method and for some reason clicks "Back to xxxx" (your business name at PayPal) on the PayPal payment page without paying, PayPal would redirect the user back to http://www.example.com/checkout/cart/, which now is an EMPTY cart.

I think it should be after payment confirmation / PayPal IPN that the cart be empty-ed, instead of any point before that.

Even if the user wants to continue again, he or she'd be annoyed from searching and adding all the products again and would very probably just leave.

Any idea how I can work around this?

5
Hey, can you please confirm which of the below solution worked for you Since it will help others like me to test and get the workaround. Thanksechoashu
@echoashu, tried all of them but nothing worked for me.datasn.io
@echoashu, for me also did not work. I am using onepage checkout.Teja Bhagavan Kollepara

5 Answers

6
votes

This worked for me:

File: ~/app/code/core/Mage/Checkout/controllers/OnepageController.php

Replace this:

$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));

With this one:

/**
 * 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->getOnepage()->getQuote()->setIsActive(1) ;
}
$this->getOnepage()->getQuote()->save();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
4
votes

For Paypal I found the cancel action inside the app/code/core/Mage/Paypal/controllers/StandardController.php cancelAction

I changed the code like that for cancel action

public function cancelAction()
{
    $session = Mage::getSingleton('checkout/session');
    $cart = Mage::getSingleton('checkout/cart');
    $session->setQuoteId($session->getPaypalStandardQuoteId(true));
    if ($session->getLastRealOrderId()) {
        $incrementId = $session->getLastRealOrderId();
        if (empty($incrementId)) {
            $session->addError($this->__('Your payment failed, Please try again later'));
            $this->_redirect('checkout/cart');
            return;
        }
        $order = Mage::getModel('sales/order')->loadByIncrementId($session->getLastRealOrderId());
        $session->getQuote()->setIsActive(false)->save();
        $session->clear();
        try {
            $order->setActionFlag(Mage_Sales_Model_Order::ACTION_FLAG_CANCEL, true);
            $order->cancel()->save();
        } catch (Mage_Core_Exception $e) {
            Mage::logException($e);
        }
        $items = $order->getItemsCollection();
        foreach ($items as $item) {
            try {
                $cart->addOrderItem($item);
            } catch (Mage_Core_Exception $e) {
                $session->addError($this->__($e->getMessage()));
                Mage::logException($e);
                continue;
            }
        }
        $cart->save();
        $session->addError($this->__('Your payment failed. Please try again later'));
    }
    $this->_redirect('checkout/cart');
}

It worked pretty good for me and there is no need to change any other place for that.

It marks the current order as Cancelled and restores the cart with using that order and redirects the user to cart again.

0
votes

/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 ..

//$this->getOnepage()->getQuote()->save();
        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.

-1
votes

Since Magento version 1.6.0.0 (juli 2011) you can enable "Persistent Shopping Cart"

under

System > Configuration > Customers > Persistent Shopping Cart

This should solve this problem.

Use these settings to make it work

Enable Persistence = Yes
Persistence Lifetime (seconds) = 31536000
Enable "Remember Me" = Yes
"Remember Me" Default Value = Yes
Clear Persistence on Log Out = No
Persist Shopping Cart = Yes

Good luck :)

-1
votes

Your issue is with the way Mage_Checkout_OnepageController::saveOrderAction() behaves.

More specific: open app/code/core/Mage/Checkout/controllers/OnepageController.php

    $this->getOnepage()->getQuote()->save();//this makes the cart empty (sets the quote as converted to order)
    if (isset($redirectUrl)) {
        $result['redirect'] = $redirectUrl;
    }

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

You can replace the last part:

$this->getOnepage()->getQuote()->save();//....

with:

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