Question

I have seen on occasion the case where an order is placed, an authorization is made for payment on the customer card, the customer receives an order confirmation email - but no order exists in Magento's sales_flat_order or sales_flat_order_grid.

The weapon of choice here is to require admin to void the payment in the gateway, ask customer to re-place.

However, we have all quote, quote items, quote payment, quote address. In theory this order is valid, after all, we have authorization and the customer has an order email. The error happened sometime after the order email generation that caused a rollback (the current working theory).

I have created a test one-off script to convert this quote using a sandbox gateway . However, I'm having trouble at generating the payment. I've tried to use checkmo, free, authorizenet, all return the same exception:

PHP Fatal error:  Uncaught exception 'Mage_Core_Exception' with message 'Cannot retrieve payment method instance.' in /var/www/vhosts/magento/app/Mage.php:563
Stack trace:
#0 /var/www/vhosts/magento/app/code/core/Mage/Payment/Model/Info.php(83): Mage::throwException('Cannot retrieve...')

See my code below. Feedback welcomed.

<?php
//.... stuff

$quote = Mage::getModel('sales/quote')->load(745);

$convert = Mage::getModel('sales/convert_quote');

$order = $convert->toOrder($quote);
$order->addressToOrder($quote->getAddress(),$order);

foreach($quote->getAllItems() as $item){
    $orderItem = $convert->itemToOrderItem($item);
    if ($item->getParentItem()) {
       $orderItem->setParentItem($order->getItemByQuoteItemId($item->getParentItem()->getId()));
    }
    $order->addItem($orderItem);
}

$data = array(
        'method' => 'authorizenet',
        'cc_type' => 'VI',
        'cc_number' => '4111111111111111',
        'cc_exp_month' => '1',
        'cc_exp_year' => (date('Y') + 6),
        'cc_cid' => '444'
);

$quote->getShippingAddress()->setPaymentMethod('authorizenet');
$quote->getShippingAddress()->setCollectShippingRates(true);

$payment = $quote->getPayment();
$payment->importData($data);
$quote->save();

$payment = $convert->paymentToOrderPayment($quote->getPayment());

$order->setPayment($quote->getPayment());

$message = '[Notice] - Order converted from quote manually';
$order->addStatusToHistory($order->getStatus(), $message);
$order->place();
$order->save();

$quote->setIsActive(false)->save();
Was it helpful?

Solution

You are sending the order

 $quote->getPayment()

your code should look like this

...

$payment = $convert->paymentToOrderPayment($quote->getPayment());

$order->setPayment($payment);

...
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top