Home » Php » php – Mark a Magento order as complete programmatically

php – Mark a Magento order as complete programmatically

Posted by: admin July 12, 2020 Leave a comment


I’m trying to mark a “Processing” order as Complete when I get a certain response back from a third party service. I’ve got everything set up for this, but the only problem is that orders are staying in the Processing state.

I’m generating an invoice (I don’t think I need this though, as each item is marked as “invoiced” in the Magento backend) and a shipment like so:

$order = Mage::getModel('sales/order')... (etc)
$shipment = $order->prepareShipment($quantities);

$invoice = $order->prepareInvoice($quantities);

This doesn’t seem to be doing it though – I get no errors back from this code, but the order remains as processing. In the backend I can still see the “Ship” button at the top of the order, and each item is in the “invoiced” state.

Any tips would be greatly appreciated.

How to&Answers:

You can take a look at this article (in Russian).

Here is the code from the article:

$order = $observer->getEvent()->getOrder();

if (!$order->getId()) {
    return false;

if (!$order->canInvoice()) {
    return false;

$savedQtys = array();
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($savedQtys);
if (!$invoice->getTotalQty()) {
    return false;


$transactionSave = Mage::getModel('core/resource_transaction')




    'Order marked as complete automatically',

This method is in app/code/local/Mage/Sales/Model/Order.php (in v1.6.1)

938:    public function setStateUnprotected($state, $status = false, $comment = '', $isCustomerNotified = null)

In Magento this method has been removed. Try this instead:

    $order->setData('state', "complete");
    $history = $order->addStatusHistoryComment('Order marked as complete automatically.', false);


I’m doing this that way:

$order->setState('complete', true, $this->__('Your Order History Message Here.'))


Code for processing order programmatically.
Can be put on success event or cron

$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);

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

$history = $order->addStatusHistoryComment('Order is complete', false);



Magento will automatically mark an order as complete if:

  • Payment has been made.
  • An invoice exists.
  • A shipment exists.

If you cannot do that, try to create a custom ‘state’ and set that. In the meantime, to set the order to processing, try this:

 $order = Mage::getModel('sales/order')->load($id);
 $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();

Should work without errors. Tested in Magento


In my case, I needed the end users to see completed in the order grid, but the order state really made no difference. So I did just went to

System->Order Status
Create a new Status called Completed (note the d so it’s easy to differentiate)
Assign that status to the state Processing/pending, whatever.

This worked for our client — but wouldn’t work if you heavily depend on order state (Different than order status).