I was originally drafting this to ask a question, but in the process I actually fixed the problem, so I'm posting this in hopes it helps someone else.
I have Magento CE 220.127.116.11 and I'm having a problem with account registration at checkout when the customer pays using PayPal. We use Templates Master's FireCheckout. Here's the scenario:
- Customer fills out checkout form, elects to create an account for later use, and picks PayPal as payment option
- Customer redirects to PP, logs in, confirms payment, is directed back to our site on the PayPal Express Review page
- Customer clicks final Place Order button, PayPal responds with an error (i.e. 10736 - city/state/zipcode mismatch)
- Customer doesn't know the issue, so clicks Place Order again.
- Magento session still has their account type as "register", but because of how the PayPal UK module handles PayPal Express for PayFlow customers, the customer account creation wasn't rolled back and the account was already created. So then, upon secondary submission, they are presented with the error "That customer email already exists".
- Customer tries and tries, sometimes eventually figuring it out, sometimes giving up.
This can easily be tested using the PP sandbox in Negative testing mode.
- Create an item that has free shipping and costs exactly $107.36, grand total
- Place an order with this item and pick PayPal as the checkout method.
- Follow through the entire process, you should get the 10736 error on the file submission.
- Try submitting again, you should get the "This customer email already exists" error
I have dug through some of the code and found that it is due in part to the
Mage_Paypal_Model_Express_Checkout class in their
_prepareNewCustomerQuote method. This creates and saves the customer record before the order is even placed. This is unlike the standard checkout, which creates a customer record and sets it on the quote but doesn't actually commit the customer record to the DB. It is then able to roll back the customer creation SQL call and not commit the changes, allowing the subsequent attempts to do it. But this rollback doesn't work in PP Express because it already committed the record.
I tried a few things to resolve this (see
Mage_Paypal_Model_Express_Checkout around line 990):
- I tried commenting out the
Mage_Paypal_Model_Express_Checkout. That resulted in successfully allowing the order once the error was fixed, but it never actually saved the customer record.
- I then tried adding setCustomerId(true) when it sets the customer on the quote. I copied this from the standard checkout class: $quote->setCustomer($customer)->setCustomerId(true);. THIS FIXED IT! See answer below for details.