Error Magento y PayPal Express

27 Agosto 2010 at 11:30 by Adrián Pérez

MagentoHace unos días publiqué una entrada hablando sobre cómo integrar Magento (1.4.1.1) con PayPal Express. Todo parecía funcionar de fábula cuando se realizaban compras desde cuentas de PayPal. Sin embargo, si el comprador no tenía una cuenta de PayPal y únicamente quería efectuar un pago con tarjeta de crédito, la compra se realizaba de forma satisfactoria pero mostraba el siguiente mensaje al final del proceso de venta:

"El pago no se puede procesar mediante su cuenta de paypal en este momento"

¡Toma ya! La compra se realiza correctamente pero se le dice al comprador justo lo contrario. Feo, feo.

Después de mucho pelearme contacté con el soporte técnico de PayPal, quien ha estado ayudándome (y mucho) a solucionar la incidencia.

El problema es el siguiente:

Cuando se realiza el proceso de compra, se utiliza una función de PayPal llamada "DoExpressCheckoutPayment". En las compras que funcionan, el campo "successpageredirectrequested" está a "false", mientras que las compras que también funcionan pero a las que se les muestra el mensaje de error anterior, este campo está a "true".

En palabras del soporte ténico de PayPal:

De acuerdo con este enlace
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_nvp_r_DoExpressCheckoutPayment

"Flag to indicate whether you need to redirect the customer to back to PayPal after completing the transaction. "

Es una opción para indicar si se necesitar redirigir al comprador de nuevo a PayPal tras completar la transacción, que no tiene mucho sentido ya que la transacción ya ha finalizado correctamente.

Finalmente, he aquí la conclusión por parte de PayPal:

SUCCESSPAGEREDIRECTREQUESTED se solía utilizar en versiones muy antiguas de PayPal, y tenía como propósito indicar que el comprador había pagado con tarjeta directamente, para que las integraciones que así lo tuvieran dispuesto, redirigieran al comprador de nuevo a la página de PayPal por si quería abrir una cuenta para usarla en un futuro (en vez de seguir pagando como invitado).

Parece que esto ya no está en vigor, por lo que una redirección final provocaría un error.

Es decir, Magento está usando un método obsoleto, y esto está devolviendo un mensaje de error falso, en el proceso de compra.

Siguiendo las indicaciones de este foro de discusión (y también los consejos del soporte de PayPal), he pasado a modificar el archivo app/code/core/Mage/Paypal/Controller/Express/Abstract.php

Concretamente, de la siguiente función, he comentado las líneas en negrita:

public function placeOrderAction()
{
try {
$this->_initCheckout();
$this->_checkout->place($this-

>_initToken());

// prepare session to success or cancellation page
$session = $this->_getCheckoutSession();
$session->clearHelperData();

// "last successful quote"
$quoteId = $this->_getQuote()->getId();
$session->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId);

// an order may be created
$order = $this->_checkout->getOrder();
if ($order) {
$session->setLastOrderId($order->getId())
->setLastRealOrderId($order->getIncrementId());
// as well a billing agreement can be created
$agreement = $this->_checkout->getBillingAgreement();
if ($agreement) {
$session->setLastBillingAgreementId($agreement->getId());
}
}

// recurring profiles may be created along with the order or without it
$profiles = $this->_checkout->getRecurringPaymentProfiles();
if ($profiles) {
$ids = array();
foreach($profiles as $profile) {
$ids[] = $profile->getId();
}
$session->setLastRecurringProfileIds($ids);
}

// redirect if PayPal specified some URL (for example, to Giropay bank)
$url = $this->_checkout->getRedirectUrl();
//if ($url) {
//$this->getResponse()->setRedirect($url);
// return;
//}

$this->_initToken(false); // no need in token anymore
$this->_redirect('checkout/onepage/success');
return;
}
catch (Mage_Core_Exception $e) {
$this->_getSession()->addError($e->getMessage());
}
catch (Exception $e) {
$this->_getSession()->addError($this->__('Unable to place the order.'));
Mage::logException($e);
}
$this->_redirect('*/*/review');
}

Con esto se evita la redirección por parte de Magento al recibir el parámetro obsoleto, y se consigue completar correctamente el proceso de compra, esta vez, sin mensajes de error.

ATENCIÓN: Se recomienda realizar todos los tests que se crean convenientes antes de adaptar esta solución a tu sitio web en producción.

PD: Sí, ya he contactado con Magento para avisarles de este error, que podéis ver explicado aquí (si tenéis cuenta en Magento).