Delete Magento orders via shell script

This brief article is dedicated to the problem, which Magento developers often have to deal with. From time to time, we need to create some test orders during the work process, but web store owners usually want to remove them. Actually, there are a lot of test orders before web store releasing, and after the custom checkout extensions installation. Sometimes, developers make some test orders after installing new feature, adding cart price rules, enabling or adding custom Magento billing and Magento shipping methods.

So, let’s check the following approaches for order deleting:

  1. Delete orders from the database. This one is usually applied before web store releasing: just truncate Magento database tables that names start from sales_orders (assuming that you do not use any database prefix for the Magento tables). Note, that deleting only separate orders this way will be quite difficult, confusing and even dangerous though.
  2. Install a specific extension or even develop your own. It involves some additional development resources, plus, some extensions aren’t free. So, why should we waste time and money for a procedure which will take place only occasionally?
  3. Use custom script. This way can be done using the unsafe temporary scripts which will be removed after the single use or via the shell scripts.

Let’s write our own shell script and call it delete_orders.php. We should put our script to the shell directory in the Magento web store folder. First of all, it is necessary to include the abstract.php script and extend it:

require_once 'abstract.php';

class Shell_Delete_Orders extends Mage_Shell_Abstract

This will provide us all the needed functionality and the security we need. As a result, our script will look like this:

<?php

require_once 'abstract.php';

class Shell_Delete_Orders extends Mage_Shell_Abstract
{
    /**
     * Parse string with id's and return array
     *
     * @param string $string
     * @return array
     */
    protected function _parseString($string)
    {
        $ids = array();
        if (!empty($string)) {
            $ids = explode(',', $string);
            $ids = array_map('trim', $ids);
        }
        return $ids;
    }
    /**
     * Run script
     *
     */
    public function run()
    {
        if ($this->getArg('orders'))
        {
            if($this->getArg('orders') == 'all')
            {
                $collection = Mage::getModel('sales/order')->getCollection();
                foreach($collection as $order)
                {
                    $id = $order->getId();
                    try{
                        $order->delete();
                        echo "order #".$id." is removed".PHP_EOL;
                    }catch(Exception $e){
                        echo "order #".$id." could not be removed: ".$e->getMessage().PHP_EOL;
                    }
                }
                echo "complete.".PHP_EOL;
            }
            else
            {
                $ids = $this->_parseString($this->getArg('orders'));
                foreach($ids as $id){
                    try{
                        Mage::getModel('sales/order')->load($id)->delete();
                        echo "order #".$id." is removed".PHP_EOL;
                    }catch(Exception $e){
                        echo "order #".$id." could not be removed: ".$e->getMessage().PHP_EOL;
                    }
                }
                echo "complete.".PHP_EOL;
            }
        } else {
            echo $this->usageHelp();
        }
    }

    /**
     * Retrieve Usage Help Message
     *
     */
    public function usageHelp()
    {
        return <<<USAGE
Usage:  php -f delete_orders.php -- [options]

  --orders all                          Delete all orders
  --orders <order_id>                   Delete order by id
  help                                  This help

  <order_id>               Comma separated id's of orders

USAGE;
    }
}

$shell = new Shell_Delete_Orders();
$shell->run();
?>

This script can delete all orders from the Magento database or only some of them, specified by ID.

Moreover, the method run() is a heart of our script. It parses the arguments of the script command line interface input and makes the respective actions.
Since it uses only standard Magento sales/order model, so there is nothing extraordinary in it, but this script is all that we need.

The _parseString() only parses the command line input string with the order ID’s we want to delete.
And the usageHelp() method will provide a helpful information, and it should be updated if you want to extend the functionality of the script.

You can extend the script with an ability to delete orders by order number or even more you want. Simply words, just expand the run() method with new conditions and apply proper collection filter. Also, don’t forget to update the usage help properly.

The main advantages of the script are its simplicity and security. It can be run only via a command line of the hosting server (so, it will be done by a person who has an access and will not harm the store), and it does not override any core functionality.

That’s all. Thanks for reading us and we hope this article will save your working hours and efforts.