19

I am creating a module that needs to do a check right before payment is made. If the check fails, it needs to forward the user to the cart with an error.

I have an observer and have verified that it is loading and executing. Right now, I have it hooked into sales_order_payment_place_start.

In the observer function, I have the following code (and only this code for testing):

$url = Mage::getUrl('checkout/cart');//eg to redirect to cart page
$response = Mage::app()->getFrontController()->getResponse();
$response->setRedirect($url);
$response->sendResponse();
exit;

When I get to the final page on check and click the "Place Order" button to submit the order, the button disappears and the "submitting order" message appears and then the button re-appears. If I click it a second time, it forwards to the cart page as expected.

It seems as though the call is ajax'ed, my forward sets a flag, then forwards the ajax request. Upon re-submission the page finds the flag and actually forwards.

That's a guess, but is there any way to accomplish what I am trying to do?

What would be the preferred method of doing this check? Overwriting some controller/model?

3

3 Answers 3

10

After testing several different methods, this is the only one I succeeded with. The

Mage::app()->getResponse()->setRedirect(Mage::getUrl("checkout/cart"))

method is recommended on several other similar questions, but nobody has been able to get it to work.

That being said, you can override the progressAction function in Mage_Checkout_OnepageController and use the following code. This will cause the next check in _expireAjax to fail on the error check and redirect back to the cart page.

The downside of overriding progressAction is that it's going to get checked on each step. If you can create whatever you're trying to verify in a way that it won't fail until the final step then this can work. However if not, the next thing you can override is the saveOrderAction as that doesn't get called until you're placing the order.

if(true){
        $this->getOnepage()->getQuote()->setHasError(true);
        Mage::getSingleton('checkout/session')->addError($this->__('The error message you want to show on the cart page.'));
    }
3
  • I believe there is another method that will work with an observer, if it works, I will update this answer with the additional method.
    – jesseconnr
    Feb 14, 2014 at 17:45
  • 1
    Mage::app()->getResponse()->setRedirect($someUrl) worked just fine for me. It may be due to the event which you are observing. I'd assume that somewhere along the execution process it becomes too late to utilize and won't work. The event which I was observing, was the controller_action_layout_load_before event. Oct 23, 2015 at 19:54
  • Same here, but the event Meogi mentioned didn't work for me, it only worked with this one: controller_front_init_before Feb 18, 2016 at 16:01
6

If you want to redirect this would do the job.

Mage::app()->getResponse()->setRedirect(Mage::getUrl("checkout/cart"))
2
  • If use this, and then sendResponse() and exit, it has the same issue as above. The forward only happens upon the second click of the "Place Order" button.
    – Jamersan
    Feb 14, 2014 at 13:26
  • A little more info/testing on your proposed solution: If I use only this above, it forwards but after it processes the order and empties the cart. If I use this and exit, it does nothing. If I use this, and then sendResponse() and exit, it has the same issue as above. The forward only happens upon the second click of the "Place Order" button.
    – Jamersan
    Feb 14, 2014 at 13:43
3

Based on some code at the link provided by stackexchange where this "may have been solved already".. I was able to get this to work: As I suspected, on the ajax you need to send a response to get it to trigger the forward.

$url = Mage::getUrl('checkout/cart');
$response = Mage::app()->getFrontController()->getResponse();
$response->setRedirect($url);

$controllerAction = $observer->getEvent()->getControllerAction();
$result = array();
$result['error'] = '-1';
$result['message'] = 'My error message';
$controllerAction->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
exit;

Not the answer you're looking for? Browse other questions tagged or ask your own question.