Magento: Order State and Order Status

Magento Icon

I built a module a couple of weeks ago for a client who needed to be able to change the status of orders at any time, as well as having a couple of custom order statuses. It appeared that the best way to change the status or state was by using the setState() method on the order object. Before we get into that, let’s take a look at how Magento sets up the default states and statuses:

Magento sets them up in this file in the Sales model config file: app/code/core/Mage/Sales/etc/config.xml under global > sales > order. There in the ‘statuses’ tag, you’ll see the 8 default statuses (some of which you probably didn’t know existed). In the ‘states’ tag, you’ll see that Magento is setting up 7 different order states. There is also a ‘statuses’ tag as a child of the states. Here is where which statuses are able to be a part of each state. For example, under the ‘processing’ state, the only available status is ‘processing’ (as you can see, you can set the default status for any particular state by adding default=”1″ to the status).

Knowing which statuses are a part of which states is very important. When using the setState() method, you need to make sure that the status/state you are trying to change the order to. Another important thing to take note of is that the ‘complete’ and ‘closed’ states are protected, and you cannot use setState() to change an order to either of those states without overriding the order model to allow the passing of false (setState() passes your parameters to a protected function _setState() which hard-codes true into the ‘shouldProtectState’ parameter).

Ok, now on to the setState() method. This method not only allows you to change the state and status, it also adds the change to the order’s Comments History and allows you to notify the customer. This method can take up to 4 parameters, which I’ll list in order:

  • $state (string): This is the state you would like to change the order to. Must match the xml tag in config.xml
  • $status (string or true): This is the status you would like to change the order to. Since by default Magento only has one status per state it either has to be the correct status name, or if you pass true it will just get the default status for the state you are passing.
  • $comment (string): If you want to pass in a string to add to the comments, you can do so. By default it just passes a blank string
  • $isCustomerNotified (bool): Leave this parameter off if you do not want the customer to be notified, otherwise pass in true

So, if I wanted to change the order status to “Cancelled”, and I don’t want the customer notified, this is how I would do it:

$order->setState('cancelled', true, 'Cancelled order due to bad credit card');

Other statuses and states can be added by creating your own module and adding them via your config.xml. You can also add statuses to the other states. This would allow you to change the statuses of your orders right from the order view in the admin.

This entry was posted in Magento. Bookmark the permalink.

10 Responses to Magento: Order State and Order Status

  1. NH says:

    Thanks for this, it really gave me a head start on making our Order pipeline more flexible.

  2. A small correction: it’s better to use predefined constants eg. Mage_Sales_Model_Order::STATE_CANCELED

  3. Gloopy says:

    I have set my custom order status’s in magento admin, but there is no option or drop sown in the customers order to select these or am i doing something wrong ??

  4. Thanks you very much for you post. I had confused with Magento state and status for a long time. Your post is great.

    I have a question here. What’s your plan to change the status of orders at any time? Thanks.

  5. Magento says:

    And the status have been removed from the config.xml file. It now can find in database table sales_order_status.

    Take a look at this http://tweetorials.tumblr.com/post/9954863818/more-on-order-state-and-status

  6. Mike says:

    Hi,

    Great post.

    I do not want to notify the customer when the order is set to complete.
    So, I left the last parameter like you mentioned in your post.

    But, in magento admin back-end, under “comment history”, I see the below text
    Aug 20, 2013 9:05:54 AM | Complete | Customer Notified.

    It is supposed to say “Customer not notified” right?

    Thanks

    • Josh Pratt says:

      Mike – At least at the time that I wrote this, the last parameter was defaulted to ‘false’, so it shouldn’t notify the customer. Check your setState() method in the code and make sure that is still the case. Otherwise, you can try to add the extra parameter as false and see if that works too.

      • Mike says:

        Thanks for the quick response, Josh.

        I tried both ways – leaving it empty and manually adding “false”.

        It still shows that text, “Aug 20, 2013 9:05:54 AM | Complete | Customer Notified.”

        Any other thoughts on this?

        Thanks

  7. Sarah says:

    Hi Josh! Thanks for the post, it was useful for me to understand the difference and connection between order statuses and states. But I don’t think I have enough knowledge and skill to build my module, so I prefer using ready solutions. For order statuses I’m using this one http://amasty.com/order-status.html

    • Josh Pratt says:

      Sarah – Which is ok too. Sometimes those modules come a little bloated, or override core files that can cause conflicts if you start using a lot of 3rd party modules. But hopefully that module works for you.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>