1
votes

I created a custom payment method in which orders grid, after installation of this payment extension, has another column that displays order statuses from payment gateway.

The requirement is that the orders in grid should not get cancelled when it is in some particular payment gateway status say Delivered, processing etc. It should get cancelled when the payment gateway status is say pending

I need to make an api call to payment gateway asking to cancel order. If the order is say pending the order gets cancelled. If the order is not pending the API throws a response with error code and error message, saying that the order cannot be cancelled.

There is a PHP-Library which handles all the API calls. when I call cancelOrder API service in above case if the order cannot be cancelled, the PHP library throws exception using the error code of API as exception code and error message as exception message.

For this I implemented an Observer that handles Order_save_before event. In observer I wrote the code that uses PHP Library's cancelOrder() method (which internally makes cancelOrder api call)the order gets cancelled when the payment gateway's status is pending and throws exception if it cannot be cancelled.

If I open the individual order which was created by my payment method and cancel the order by clicking the cancel button the exception gets cascaded and display's at the top giving exception message that the order cannot be cancelled.

But when I try to cancel the order from the orders grid by selecting the order, selecting cancel from drop down and hit submit, the page gets redirected to exception page saying an exception occurred. I don't understand how to undo or prevent cancellation of the order and handle the exception in this case. My code is as given below.

public function cancelOrderObserver(Varien_Event_Observer $Observer)
{
try
   {
        //code that cancels order if it is pending else throws exception saying cannot cancel order;
   }
catch (Exception $e){
    Mage::throwException(Mage::helper('adminhtml')->__($e->getMessage()));
}

Please help me on this.

Let me know if you need some more explanation about the issue.

2
Check the var/report directory. Also perhaps you might disable mass action - remove it from grid. Also it seems that your observer isn't called when massaction is done, while I am not sure. What exception do you get when you are in massacction? - Jevgeni Smirnov
Thanks for your reply Jevgeni. I get the same exception as that of individual order i.e "Sorry your order is already processed". The difference is in massCancel it throws exception and redirects to exception page and in Individual order cancellation, it displays exception message at the top. - naquiuddin
Well you might overwrite controller's massCancel action I think. Well this would be another question I guess. - Jevgeni Smirnov
Jevgeni, you were saying like we can uncancel the Order. How can I do this? Please update your answer with this solution. I try putting an if loop to check exception code in catch () {} and uncancel the order. - naquiuddin

2 Answers

1
votes
order_cancel_after 

doesn't suit your needs, because at this stage order is already canceled.

I would try something like

order_save_before

There you should chek wheter order is canceled or not. And uncancel it in case it is.

UPDATE 1

Well my main point of "uncancel" was to rollback actions taken during ->cancel() call.

Currently I thought of other option. You can try to observer predispatch call(if following event exists for massCancel action) and check with your service if an order can be canceled. And if not, then remove order from request. Something like this. But I am not sure about this.

0
votes

sales_order_save_before event:

$_order->setActionFlag(Mage_Sales_Model_Order::ACTION_FLAG_CANCEL, false);