Just a quick fix for today. Magento appears to have a bug whereby if a user places an order using paypal express when they’re not logged into your site (ie: using the ‘guest checkout’ functionality of magento their email address will not be passed through correctly. One annoying symptom of this is that the user won’t receive any order confirmation, or order update emails.
After a lot of debugging I tracked the problem down to the ‘place’ function in /Mage/Paypal/Model/Express/Checkout.php which looks like this:
/** * Place the order and recurring payment profiles when customer returned from paypal * Until this moment all quote data must be valid * * @param string $token * @param string $shippingMethodCode */ public function place($token, $shippingMethodCode = null) { if ($shippingMethodCode) { $this->updateShippingMethod($shippingMethodCode); } $isNewCustomer = false; switch ($this->_quote->getCheckoutMethod()) { case Mage_Checkout_Model_Type_Onepage::METHOD_GUEST: $this->_prepareGuestQuote(); break; case Mage_Checkout_Model_Type_Onepage::METHOD_REGISTER: $this->_prepareNewCustomerQuote(); $isNewCustomer = true; break; default: $this->_prepareCustomerQuote(); break; }
Here magento uses the ‘checkoutmethod’ to determine which method to call when preparing the ‘quote’ (order to you and me). The problem is that for whatever reason, orders placed by guests come through with the checkout method set to a blank string. They then fall through to the default handling method, which doesn’t set the email address.
Some more digging turned up this thread which mentioned the Magento developers were aware of this problem. A little more googling determined this problem is fixed in 1.7…. so I decided to backport the changes made there into our 1.6 site.
Basically I override the ‘place’ function and invoke a new ‘getcheckoutmethod’ (ripped from the 1.7 class) which sets the correct checkout method. Then I call the original class method, which trundles off and does whatever it has to.
Here’s the code, I’ll get it packaged up and upload it later on today:
class Tallpaul_Paypalexpressfix_Model_Express_Checkout extends Mage_Paypal_Model_Express_Checkout{ /** * Get checkout method blatantly ripped off from magento 1.7 * * @return string */ public function getCheckoutMethod() { if ($this->getCustomerSession()->isLoggedIn()) { return Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER; } else { $this->_quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_GUEST); return $this->_quote->getCheckoutMethod(); } } public function place($token, $shippingMethodCode = null){ $this->getCheckoutMethod(); parent::place($token,$shippingMethodCode); } }
Update: here’s the module [wpdm_file id=10]
Hi! When I try to install this using the “Direct Package File Upload” of Magento Connect Manager I get:
CONNECT ERROR: Package file is invalid
Invalid package name, allowed: [a-zA-Z0-9_-] chars
Invalid version, should be like: x.x.x
Invalid stability
Invalid date, should be YYYY-DD-MM
Invalid channel URL
Empty authors section
Empty package contents section
Can you advise on how to get this installed properly?
Hi, I have no idea unfortunately, I’ve never used the package upload thing and always just drop the files into the right place using FTP.
I’ve changed jobs recently and don’t use magento anymore, so I can’t really help with this I’m afraid.
Why you are returning value from getcheckoutmethod() method ?
I think we only to add this line at the start of Place function.
if (!$this->getCustomerSession()->isLoggedIn()) {
$this->_quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_GUEST);
}
Also there is no need to create a custom module.You can simply upload the modified file “local” directory ( app/code/local/Mage/Paypal/Model/Express ).
Thanks
Thank you so much man!!
i get this…
Fatal error: Cannot access empty property in /home/lillyand/public_html/app/code/core/Mage/Paypal/Model/Express/Checkout.php on line 516
Perfect! Thank you, that totally fixed the issue for me.