We are using a custom module that requires the status: "complete" (I can't change the module because it uses ioncube)

We are also using a payment system that doesn't offer the status option: "complete"

So my question is: How can I force an order to go to the status complete?

PS: This doesn't work:

$order = Mage::getSingleton('sales/order');
$order->setState(Mage_Sales_Model_Order::STATE_COMPLETE, true);
  • The solution provided here: magento.stackexchange.com/a/244601/15769 It works for me.<br/> I hope that It'll be useful for anyone that use Magento<br/> Thanks @ctrl-z pls
    – user15769
    Commented Feb 6, 2019 at 14:32

4 Answers 4


It's not allowed to manually set the order state to 'complete' and you should be getting this exception when you call setState on the order with the 'complete' state:

The Order State "complete" must not be set manually.

The reason for this is simple: The 'complete' state (and status, since it's the only state with a status of 'complete') is intended to indicate that an order has been completely filled. I.e. it has been placed, invoiced and shipped to the customer.

Once the order has been invoiced and shipped, Magento will set this state on the order automatically.

If your payment system "doesn't allow" the 'complete' status, then I would not trust it, especially with it being ionCube encoded. If, however, it's because it's handling the invoicing outside of Magento, then you'll need to manually generate an "Offline" invoice for the order so that Magento will recognize that it has been paid for.

Don't try to short-change yourself by working around the problem of the orders not hitting the completed state like they normally should. Instead, fix the actual problem by making sure that orders are both invoiced and shipped in Magento so that they will be marked as complete by the system.

  • This doesn't answer the question. While it does address reasons this shouldn't be done, that's not a catch-all for everything. I myself have acquired a situation where most of Magento for order processing is skipped and the order needs to be set to the complete status.
    – Navarr
    Commented Mar 26, 2015 at 13:09
  • 1
    @Navarr actually it does... see the part about manually generating an offline invoice for the order. Do that, and the order will move to complete regardless of the payment processor being used.
    – davidalger
    Commented Mar 26, 2015 at 19:05
  • 3
    or, you know: stackoverflow.com/a/8906785/43790
    – Navarr
    Commented Mar 26, 2015 at 19:26
  • 2
    @Navarr Sure, one could write directly to the db via SQL too, but that doesn't negate it being a protected state per the model implementation. The best answers don't blindly answer to "let's accomplish x" without addressing the underlying matter. Anyhow, this is the last I'll be commenting here regarding this.
    – davidalger
    Commented Mar 26, 2015 at 20:35
  • Engin Check light lit on the car's dashboard. I did not know how to fix the issue. I then removed the fuse that switches that little light on. I think my engine is working fine now. Commented Feb 17, 2018 at 23:02

To change the state:

$order->setData('state', Mage_Sales_Model_Order::STATE_COMPLETE);

To change the status:


And then $order->save();

You have to change the state using setData to avoid the exception telling you that you can't manually call setState


Try this.

$order = Mage::getModel('sales/order')->load(Mage::getSingleton('checkout/session')->getLastOrderId());
$order2 = Mage::getModel('sales/order')->load($order_id); 
$order2->setData('state', "new");

It works for me on my project ..

  • Aha, so you've 'restarted' the order and then set it to: new->pending->completed? Commented Jul 15, 2013 at 10:18
  • no I loaded the order and then assigned the new status and state to the order.
    – Kuldeep
    Commented Jul 16, 2013 at 10:37
  • This is state/status new/pending, which is no problem. The actual problem is how to set it to 'complete' manually.
    – 7ochem
    Commented Oct 29, 2015 at 13:14
$oResource = Mage::getSingleton('core/resource'); 

$oConnection = $oResource->getConnection('core_write'); 

$sSql = "UPDATE " . ' ' . $oResource->getTableName('sales_flat_order') .
        " SET status = '" . Mage_Sales_Model_Order::STATE_COMPLETE . "', state = '" . Mage_Sales_Model_Order::STATE_COMPLETE . "' WHERE
entity_id = " . $oOrder->getId();

  • I would discourage the use of direct SQL execution and rely on the Magento ORM implementation.
    – 7ochem
    Commented Oct 29, 2015 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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