Suspected Fraud transactions in Magento

What happens

It’s been a long-standing issue with Magento that it will sometimes mark orders that have been paid via Paypal as being Suspected Fraud – no invoice is issued, so the customer isn’t sent their order confirmation email, and the order ends up in limbo, because you can’t invoice the order manually (there’s no invoice button) and you can’t change its status manually. What’s worse is that if the customer logs into their account, they may see that their order has been marked as Suspected Fraud, which doesn’t score highly on the customer relationship front.

Why it happens

The most common reason is that because of either exchange rates or tax rounding, the amount of money which Paypal charges the customer is out by 1p compared to the amount of money that Magento thinks should have been charged. When Paypal tells Magento that the order has been paid and how much money has been paid, Magento sees this difference and flags it up to the user as Suspected Fraud

What do do Suspected Fraud transactions – Part I

Fear not. There are a couple of things which can be done. The first is to change the Suspected Fraud order status so that it falls not under the “Payment Review” order state, as it does by default, but instead falls under the Processing order state. To do this, in the admin panel, go to System -> Order Statuses – you should see something similar to the image below, which shows you that the Suspected Fraud status is assigned to the Payment Review state.

assign status

First, let’s unassign it – which is easy enough to do by clicking the “Unassign” link at the right hand end of the relevant row. This will move it, after the screen refreshes, to join the unassigned statuses at the bottom of the list. To assign it to a new state, click the “Assign Status to State” button at the top, and on the window that follows choose the Suspected Fraud status from the first dropdown, the Processing state from the second dropdown, and leave the tickbox unticked (as shown below). Then click the Save Status Assignment button.

assign status

This only solves one problem (and then only for orders that come in after you’ve done this). You can now manually update the status of an order to be processing, and you should also be able to invoice the order manually. That’s all a bit of a pain, though, and

What do do about it – Part II

If you get Suspected Fraud orders relatively frequently, then it’s a bit of a pain to have to invoice items manually – so we’ve created a simple script which will do it for you. We talk you through how the script works below, and the script itself can be downloaded at the bottom of this point.

As usual, we start by hooking into Magento. This assumes that the script is in your web root, but change the URL in the first line if that’s not the case.

<?php
require_once('app/Mage.php');
Mage::app();

Next we want to grab a collection which contains all Suspected Fraud orders – to do this, we filter down the sales / order collection by matching only those orders which have a status of “fraud”.

$orders = Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('status', 'fraud');

Now we’re going to loop through all those orders, load them, update their order state to processing, and their order status to processing, then save them. For information on the distinction between order statuses and order states, look out for a new blog post from us in the coming weeks.

foreach ($orders as $order) {
	$orderId = $order->getId();
	$fullOrder = Mage::getModel('sales/order')->load($orderId);
	$fullOrder->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true);
	$fullOrder->setStatus('processing', false);
	$fullOrder->save();

Since the order hasn’t been invoiced, we also want to invoice the order – this should also trigger the order confirmation email to be sent to the customer.

	try {
		if(!$fullOrder->canInvoice()) {
			Mage::throwException(Mage::helper('core')->__('Cannot create an invoice.'));
		}
		$invoice = Mage::getModel('sales/service_order', $fullOrder)->prepareInvoice();
		if (!$invoice->getTotalQty()) {
			Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
		}
		$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
		$invoice->register();
		$transactionSave = Mage::getModel('core/resource_transaction')->addObject($invoice)->addObject($invoice->getOrder());
		$transactionSave->save();
	} catch (Mage_Core_Exception $e) {
	}
}
?>

And that’s it. The script can either be run manually by visiting the relevant page in your browser (it’s not designed to give much in the way of output) or automatically by scheduling a cron job – the latter method you may find useful if you get Suspected Fraud orders on a regular basis.