Even with very little PHP knowledge, you can always diagnose issues thanks to Magento's error reporting mechanism.
This error indicates the exact file & line of code which are responsible for it, so take the following steps:
- Navigate through
app/code/core/Mage/Payment/Model/
& open Observer.php
,
- Scroll to line 46
The line of code in 1.7 reads as follows:
if ($order->getPayment()->getMethodInstance()->getCode() != 'free') {
Now, the error message also tells you that the following code is what is causing the issue:
Call to a member function getMethodInstance()
So after you read the line of code on line 46, you'll see that that method is applied to the $order
object, this is defined just above line 46 (on line 44):
$order = $observer->getEvent()->getOrder();
Now, knowing PHP you'd know that if the event did not catch the order correctly, the error would have been thrown here, I.E. on line 44, but it wasn't which means that it was caught correctly.
THUS, you can establish that the issue is with your payment method, because $order->getPayment()
is a non object
according to the error message.
You're likely using a modified payment method of some sorts which needs to be diagnosed.
One general remark here: You're trying to set the full customer session object (Mage::getSingleton('customer/session')
) as the quote's customer. You should do Mage::getSingleton('customer/session')->getCustomer()
.
As for the whole process, I have been doing this in the past as follows:
$quote = Mage::getSingleton('checkout/session')->getQuote();
$quote->assignCustomer(Mage::getSingleton('customer/session')->getCustomer());
$quote->collectTotals()
->getPayment()->setMethod('purchaseorder');
$convert = Mage::getModel('sales/convert_quote');
$order = $convert->toOrder($quote)
->setBillingAddress(
$convert->addressToOrderAddress($quote->getBillingAddress())
)
->setShippingAddress(
$convert->addressToOrderAddress($quote->getShippingAddress())
)
->setPayment(
$convert->paymentToOrderPayment($quote->getPayment())
);
foreach ($quote->getAllItems() as $quoteItem) {
$orderItem = $convert->itemToOrderItem($quoteItem);
if ($quoteItem->getParentItem()) {
$orderItem->setParentItem(
$order->getItemByQuoteItemId($quoteItem->getParentItem()->getId())
);
}
$order->addItem($orderItem);
}
$order->save();
I'm manually setting the payment method on the quote to 'purchaseorder'
. You should see if this works for you too and/or fits your needs.
Best Answer
Use following code in your observer to get the order:
on success event.