Automatically cancel pending orders older than 90 minutes

There are situations where you might with to automatically cancel orders older than 90 minutes. They stay in “pending_payment” state. This usually happen when the customer didn’t complete the checkout due any reason.

We created observer class “Inchoo_Order_Model_Observer” with public method “cancelPendingOrders“.
We are calling this method over cron script, take a look at our config.xml file below and everting will be clear.
In this method we filtered orders which have state “pending_payment” and older than 90 minutes. Also we set limit to 10 orders, because we want to process them in one loop.
Before save order we set new order state to “canceled_pendings“. All canceled orders will have new state “canceled_pendings“.

class Inchoo_Order_Model_Observer
{
public function cancelPendingOrders()
{
$orderCollection = Mage::getResourceModel('sales/order_collection');
 
$orderCollection
->addFieldToFilter('state', 'pending_payment')
->addFieldToFilter('created_at', array(
'lt' => new Zend_Db_Expr("DATE_ADD('".now()."', INTERVAL -'90:00' HOUR_MINUTE)")))
->getSelect()
->order('e.entity_id')
->limit(10)
;
 
$orders ="";
foreach($orderCollection->getItems() as $order)
{
$orderModel = Mage::getModel('sales/order');
$orderModel->load($order['entity_id']);
 
if(!$orderModel->canCancel())
continue;
 
$orderModel->cancel();
$orderModel->setStatus('canceled_pendings');
$orderModel->save();
 
}
 
}
 
}

Below you can see chunk of config.xml file where we set cron execution every 5 minutes.

<crontab>
<jobs>
<order_cancel_orders>
<schedule><cron_expr>*/5 * * * *</cron_expr></schedule>
<run><model>order/observer::cancelPendingOrders</model></run>
</order_cancel_orders>
</crontab>
</config>

That’s it 😉