El método de pago «Paypal Express Checkout» tiene un fallo en Magento que consiste en que si el usuario decide registrarse durante el proceso de compra, al finalizar este proceso no se guarda el usuario (customer) en la base de datos, quedando la orden de compra «huerfana» de cliente, como si la compra hubiera sido realizada por un invitado (guest).

Este bug hace practicamente «inservible» este método de pago, ya que se pierden gran parte de las ventajas que tiene, como por ejemplo: la posibilidad de hacer reembolsos online directamente desde el admin de Magento a la cuenta Paypal desde la que se produjo el pago original.

En los distintos foros de Magento, tanto en español como en inglés hay multitud de quejas y consultas con respecto a este bug, pero ninguna solución. En Interactiv4 nos hemos hecho cargo de la situación y hemos decidido encontrar la causa del problema y compartir con la comunidad una solución.

El problema

Sin entrar en muchos detalles técnicos, diremos que, en la parte final del proceso de compra con el método de pago «Paypal Express Checkout» seleccionado, después de retornar desde la página de Paypal en la cual el usuario ha autorizado el pago y haberse producido el review y confirmación del pedido, se ejecuta a la función Mage_Paypal_Model_Express_Checkout->place().

Esta función debiera salvar la orden en el sistema, asociándola al usuario correspondiente. Además, si el usuario no exisitiera previamente en la base de datos, debiera responsabilizarse de comprobar si el usuario eligió la opción de registrarse y crear / guardar este usuario en el sistema junto con la orden en una «transaction».

Pues bien, Mage_Paypal_Model_Express_Checkout->place() no es que fallé en este cometido, es que no trata de cumplirlo. En ningún momento comprueba cual es el «checkout_method» elegido por el usuario. Hace tabla rasa y simplemente, si el usuario no existe en la base de datos, toma la decisión de guardarlo como «invitado», asignandole el grupo de cliente «NOT LOGGED IN«, como se ve en este código:

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

La solución técnica

La solución pasa por extender la clase y dotarla del comportamiento que debiera tener, es decir, comprobar si el usuario decidió registrarse durante el proceso de compra, y si fué así, crear ese usuario en el sistema y relacionarlo con la orden procesada.

Tendremos que «sobreescribir» el método Mage_Paypal_Model_Express_Checkout->place() para cambiar el código de manera que se hagan las comprobaciones necesarias sobre el «checkout_method» elegido.

$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); }
}

Algunos métodos que estan declarados como «private» en el parent, necesitan extenderse también, y aunque no es necesario, decidimos sobreescribir el método Mage_Paypal_Model_Express_Checkout->returnFromPaypal(), ya que esta función sustituye los datos de envio y de facturación introducidos por el usuario durante el checkout por los que devuelve la API de Paypal en su respuesta desde su sistema.

Nos parece más «usable» y menos confuso que los datos que se guarden como buenos en el sistema sean los introducidos por el usuario en el formulario de compra de la tienda, y no los que tenga como usuario en la cuenta de Paypal, que no tienen porque ser los mismos. Tengamos en cuenta que habrá usuarios que paguen con tarjetas / cuentas de empresa, aunque en nuestro sistema se den de alta como usuarios particulares.

La Extensión

Con el problema detectado, la solución implementada e instalada en algunos proyectos de Interactiv4 que utilizan «Paypal Express Checkout» como método de pago, hemos empaquetado una extensión que podeis descargar e instalar en un par de minutos, que resuelve este problema.

Esta solución es un «regalo» que queremos aportar a la comunidad y al proyecto «Extensión Buffet«, en el que participa Interactiv4, y que va a ser lanzado en muy poco tiempo. «Extensión Buffet» pretende ser un lugar donde publicar y obtener extensiones para Magento de cálidad. Os recomiendo que os apunteis para ser avisados de la apertura, porque merecerá la pena.

Mientras se abre «Extensión Buffet» y para todos aquellos que no podais esperar, os dejamos por aquí un enlace para descargaros la solución a este bug de «Paypal Express Checkout» con el registro de usuarios.

Se agradecen comentarios y sugerencias para mejorar este «fix».

By: @oreales