The Paypal Express Checkout payment method has a bug when configurated in Magento. The bug occurs during the shopping cart process, when a user decides to register. On finalizing the process i.e. saving the user (new customer) in the database, the system does not recognize the user data, and displays the user as an ‘orphan’ client; as if it had been placed by a ‘guest’.
The bug made the payment method practically useless, as it resulted in a loss of some of the most important benefits, such as: the option to make refunds directly from the Magento admin to the Paypal account, which sent the order payment.
On several Magento forums, both in Spanish and English, there have been many complaints and enquiries with respect to the bug, but there was no solution… Until now. Interactiv4 took charge of the situation and decided to seek out the cause of the bug and find a solution to offer to the community
The problem
Without going into too much technical detail. When utilizing Paypal Express Checkout; during the final step of the payment process, once you have returned from the Paypal page where the payment has been authorized and you have reviewed and confirmed the order, you should run the following function: Mage_Paypal_Model_Express_Checkout->place().
This function should save the order in the system; associating it correctly with the corresponding user. What’s more if the user hadn’t previously existed in the database, it will be responsible on checking data to see if the user chose the option to register and to create an account with the order transaction.
Theoretically, Mage_Paypal_Model_Express_Checkout->place() is not actually failing its task, it is not even trying to complete it. At no point does it check the “checkout_method” chosen by the user. If the user doesn’t exist, then it makes the decision to keep it as a ‘guest’, clearing the user data and putting them in the ‘Not Logged In’ client group. As you will see here:

if (!$this->_quote->getCustomerId()) {
  $this->_quote->setCustomerIsGuest(true)
  -> setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID)
  -> setCustomerEmail($this->_quote->getBillingAddress()->getEmail());
}

The technical solution
The solution to the issue is in fact quite simple. We just need to extend the class and discipline it to carry out the action that is necessary, i.e. to check whether the user chose to register during the purchase process or not. If so, it should create the user in the system and relate the personal data to the order processed in the system.
To achieve this we must ‘overwrite’ the method Mage_Paypal_Model_Express_Checkout->place(), which in turn will change the way the code will make necessary checks at the chosen ‘checkout-method’.

$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;
}
if ($isNewCustomer) {
  try { $this->_involveNewCustomer(); }
  catch (Exception $e) { Mage::logException($e); }
}

Some methods that are acknowledged as ‘private’ in the parent, need also to be extended. And although not required, we also made the decision to overwrite the  Mage_Paypal_Model_Express_Checkout->returnFromPaypal() method, since this function replaces the shipping and billing entered by the customer during the checkout process, on returning the Paypal API response from your system.
We believe it is now entirely ‘usable’ and much less confusing than the data that is currently being saved in the system and correctly uses the data introduced by the user in the purchase form, and not those from the users Paypal account, as these are not always the same. We have to take into account that there will always be users who pay with cards / business accounts, although in our system they are still added as private users.
The Extension
With the problem detected, the solution executed and installed in various Interactiv4 projects that use ‘Paypal Express Checkout’ as a payment form, we have packaged the extension and you can download and install it in just a couple of minutes, problem solved!
The solution is free, a gift to the community from Interactiv4. To support all users, and the project ‘Extension Buffet’, in which Interactiv4 participates, and which is going to be launched very soon. ‘Extension Buffet’ aims to be the place to publish and obtain quality Magento extensions. We recommend that you register to receive launch updates, it’s definitely going to be worth it.
Whilst we are waiting for the launch of Extension Buffet, for those who just can’t wait, we will leave you with a link to where registered users can download the Paypal Express Checkout bug solution.
We welcome all comments and suggestions to improve this ‘fix’.
By: @oreales