Magento Auto Invoice and Set Custom Order Status Upon Checkout
Yaroslav Rogoza Avatar

Many developers are wondering how to customize Magento behavior once an order has been placed. In particular, sometimes a company would like to change the order status to “Pending” and send an invoice to the customer automatically after completing the Magento one page checkout. The following article offers a simple solution for this.Let’s assume that we need to have the order status set to “Processing” instead of “Pending” for orders paid with the “Credit Card Save” payment method and have the standard invoice sent automatically at the same time.

A custom Magento module will be required for this task. Let’s name it Atwix_Orderhook.

Step 1

First, create a module initializer in /app/etc/modules/Atwix_Orderhook.xml with the following content:

<?xml version="1.0"?>
<config>
    <modules>
        <Atwix_Orderhook>
            <active>true</active>
            <codePool>community</codePool>
        </Atwix_Orderhook>
    </modules>
</config>

Step 2

Create a module configuration file config.xml in /app/code/community/NAMESPACE/MODULENAME/etc/
(replace NAMESPACE and MODULENAME with your own values). In our case the path will be /app/code/community/Atwix/Orderhook/etc/.

config.xml content:

<?xml version="1.0"?>
<config>
    <modules>
        <Atwix_Orderhook>
            <version>1.0</version>
        </Atwix_Orderhook>
    </modules>

    <global>

        <models>            
            <orderhook>
                <class>Atwix_Orderhook_Model</class>
            </orderhook>
        </models>

        <events>
            <sales_order_place_after>
                <observers>
                    <auto_invoice_order>
                        <type>singleton</type>
                        <class>Atwix_Orderhook_Model_Observer</class>
                        <method>implementOrderStatus</method>
                    </auto_invoice_order>
                </observers>
            </sales_order_place_after>
        </events>

    </global>
</config>

As you can see, we have described observer in the events section. Observers allow you to execute some operations after a desired event took place. We need to observe the sales_order_place_after event in our extension. This event takes place after an order has been placed. Also, do not forget to init your Model path in the models section, like the example above.
<class> … </class> section contains a path to the file with observer class. In our case the file is app/code/community/Atwix/Orderhook/Observer.php, which we will create later.
Section <method> … </method> contains the method’s name, which will be called on in the sales_order_place_after event.

Step 3

Create observer file app/code/community/Atwix/Orderhook/Model/Observer.php with the following content:

<?php

class Atwix_Orderhook_Model_Observer 
{
    public function implementOrderStatus($event)
    {
        $order = $event->getOrder();

        if ($this->_getPaymentMethod($order) == 'ccsave') {
            if ($order->canInvoice())
                $this->_processOrderStatus($order);
        }
        return $this;
    }

    private function _getPaymentMethod($order)
    {
        return $order->getPayment()->getMethodInstance()->getCode();
    }

    private function _processOrderStatus($order)
    {
        $invoice = $order->prepareInvoice();

        $invoice->register();
        Mage::getModel('core/resource_transaction')
           ->addObject($invoice)
           ->addObject($invoice->getOrder())
           ->save();

        $invoice->sendEmail(true, '');
        $this->_changeOrderStatus($order);
        return true;
    }

    private function _changeOrderStatus($order)
    {
        $statusMessage = '';
        $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true);        
	$order->save();
    }
}

implementOrderStatus($event) {…} function will be called upon completion of the order’s placement. As you can see, there are some conditions inside that are responsible for the payment method name verification. As we have described above – order status will be changed only if “Credit Card Save” payment method has been used with the order. If you don’t need these conditions – just remove the verification.
_processOrderStatus Method creates an invoice for the order and sends it to the customer.
_changeOrderStatus Method changes the order status to STATE_PROCESSING.

That’s it. You can easily write your own handlers with any functionality from this observer. For example, you can send an additional email or shut down the server after an order has been placed :)

P.S. Here is a list of the order statuses that you can apply to the order object:

/**
 * change order status to 'Completed'
 */
$order->setState(Mage_Sales_Model_Order::STATE_COMPLETE, true)->save();
Similarly, you can change the order status to pending, processing, canceled, closed, held, etc.

/**
 * change order status to "Pending"
 */
$order->setState(Mage_Sales_Model_Order::STATE_NEW, true)->save();

/**
 * change order status to "Pending Paypal"
 */
$order->setState(Mage_Sales_Model_Order::STATE_PENDING_PAYMENT, true)->save();

/**
 * change order status to "Processing"
 */
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();

/**
 * change order status to "Completed"
 */
$order->setState(Mage_Sales_Model_Order::STATE_COMPLETE, true)->save();

/**
 * change order status to "Closed"
 */
$order->setState(Mage_Sales_Model_Order::STATE_CLOSED, true)->save();

/**
 * change order status to "Canceled"
 */
$order->setState(Mage_Sales_Model_Order::STATE_CANCELED, true)->save();

/**
 * change order status to "Held"
 */
$order->setState(Mage_Sales_Model_Order::STATE_HOLDED, true)->save();

You may also want to read:

Read more: