*/ class Mage_XmlConnect_Paypal_MeclController extends Mage_XmlConnect_Controller_Action { /** * Config mode type * * @var string */ protected $_configType = 'xmlconnect/payment_method_paypal_config'; /** * Config method type * * @var string */ protected $_configMethod = Mage_XmlConnect_Model_Payment_Method_Paypal_Mecl::MECL_METHOD_CODE; /** * Checkout mode type * * @var string */ protected $_checkoutType = 'xmlconnect/paypal_mecl_checkout'; /** * Paypal Mobile Express Checkout Library * * @var Mage_XmlConnect_Model_Payment_Method_Paypal_Mecl */ protected $_checkout = null; /** * PayPal Mobile Express Checkout Library config model * * @var Mage_XmlConnect_Model_Payment_Method_Paypal_Config */ protected $_config = null; /** * Checkout Quote * * @var Mage_Sales_Model_Quote */ protected $_quote = false; /** * Instantiate config */ protected function _construct() { parent::_construct(); $this->_config = Mage::getModel($this->_configType, array($this->_configMethod)); } /** * Make sure customer is logged in * * @return null */ public function preDispatch() { parent::preDispatch(); if (!Mage::getSingleton('customer/session')->isLoggedIn() && !Mage::getSingleton('checkout/session')->getQuote()->isAllowedGuestCheckout() ) { $this->setFlag('', self::FLAG_NO_DISPATCH, true); $this->_message( $this->__('Customer not logged in.'), self::MESSAGE_STATUS_ERROR, array('logged_in' => '0') ); return; } } /** * Start Mobile Express Checkout by requesting initial token and dispatching customer to PayPal */ public function startAction() { try { $this->_initCheckout(); $customer = Mage::getSingleton('customer/session')->getCustomer(); if ($customer && $customer->getId()) { $this->_checkout->setCustomerWithAddressChange( $customer, null, $this->_getQuote()->getShippingAddress() ); } $token = $this->_checkout->start(Mage::getUrl('*/*/return'), Mage::getUrl('*/*/cancel')); if ($token) { $this->_initToken($token); /** @var $message Mage_XmlConnect_Model_Simplexml_Element */ $message = Mage::getModel('xmlconnect/simplexml_element', ''); $message->addChild('status', self::MESSAGE_STATUS_SUCCESS); $message->addChild('token', $token); $this->getResponse()->setBody($message->asNiceXml()); } else { $this->_message($this->__('Token has not been set.'), self::MESSAGE_STATUS_ERROR); } } catch (Mage_Core_Exception $e) { $this->_message($e->getMessage(), self::MESSAGE_STATUS_ERROR); } catch (Exception $e) { $this->_message($this->__('Unable to start Mobile Express Checkout.'), self::MESSAGE_STATUS_ERROR); Mage::logException($e); } } /** * Return from PayPal and dispatch customer to order review page * (GetExpressCheckoutDetails method call) */ public function returnAction() { try { $this->_initCheckout(); $this->_checkout->returnFromPaypal($this->_initToken()); $this->_message($this->__('Mobile Express Checkout processed successfully.'), self::MESSAGE_STATUS_SUCCESS); return; } catch (Mage_Core_Exception $e) { $this->_message($e->getMessage(), self::MESSAGE_STATUS_ERROR); } catch (Exception $e) { Mage::logException($e); $this->_message($this->__('Unable to initialize return action.'), self::MESSAGE_STATUS_ERROR); } } /** * Review order after returning from PayPal */ public function reviewAction() { if ($this->_checkApiForward('orderReview', Mage_XmlConnect_Helper_Data::DEVICE_API_V_23)) { return; } try { $this->_initCheckout(); $this->_checkout->prepareOrderReview($this->_initToken()); $this->loadLayout(false); $this->_initLayoutMessages('paypal/session'); $messages = $this->_getSession()->getMessages(true); $messageArray = array(); foreach ($messages->getItems() as $message) { $messageArray[] = $message; } $detailsBlock = $this->getLayout()->getBlock('xmlconnect.cart.paypal.mecl.review'); if (count($messageArray)) { $detailsBlock->setPaypalMessages($messageArray); } $detailsBlock->setQuote($this->_getQuote())->getChild('details')->setQuote($this->_getQuote()) ->getChild('totals')->setQuote($this->_getQuote()); $this->renderLayout(); return; } catch (Mage_Core_Exception $e) { $this->_message($e->getMessage(), self::MESSAGE_STATUS_ERROR); } catch (Exception $e) { $this->_message($this->__('Unable to initialize express checkout review.'), self::MESSAGE_STATUS_ERROR); Mage::logException($e); } } /** * Order review after returning from PayPal */ public function orderReviewAction() { try { $this->_initCheckout(); $this->_checkout->prepareOrderReview($this->_initToken()); $this->loadLayout(false); $this->_initLayoutMessages('paypal/session'); $messages = $this->_getSession()->getMessages(true); $messageArray = array(); foreach ($messages->getItems() as $message) { $messageArray[] = $message; } $detailsBlock = $this->getLayout()->getBlock('xmlconnect.cart.paypal.mecl.review'); if (count($messageArray)) { $detailsBlock->setPaypalMessages($messageArray); } $detailsBlock->setQuote($this->_getQuote())->getChild('details')->setQuote($this->_getQuote()) ->getChild('totals'); $this->renderLayout(); return; } catch (Mage_Core_Exception $e) { $this->_message($e->getMessage(), self::MESSAGE_STATUS_ERROR); } catch (Exception $e) { $this->_message($this->__('Unable to initialize express checkout review.'), self::MESSAGE_STATUS_ERROR); Mage::logException($e); } } /** * Get shipping method list for PayPal */ public function shippingMethodsAction() { try { $this->_initCheckout(); $this->_checkout->prepareOrderReview($this->_initToken()); $this->loadLayout(false); $this->getLayout()->getBlock('xmlconnect.cart.paypal.mecl.shippingmethods')->setQuote($this->_getQuote()); $this->renderLayout(); return; } catch (Mage_Core_Exception $e) { $this->_message($e->getMessage(), self::MESSAGE_STATUS_ERROR); } catch (Exception $e) { $this->_message( $this->__('Unable to initialize express checkout shipping method list.'), self::MESSAGE_STATUS_ERROR ); Mage::logException($e); } } /** * Update shipping method (combined action for ajax and regular request) */ public function saveShippingMethodAction() { try { $this->_initCheckout(); if ($this->getRequest()->getParam('shipping_method', false)) { $this->_checkout->updateShippingMethod($this->getRequest()->getParam('shipping_method')); $this->_getQuote()->save(); $this->_message($this->__('Shipping method successfully updated'), self::MESSAGE_STATUS_SUCCESS); } else { $this->_message($this->__('Shipping method is required'), self::MESSAGE_STATUS_ERROR); } return; } catch (Mage_Core_Exception $e) { $this->_message($e->getMessage(), self::MESSAGE_STATUS_ERROR); } catch (Exception $e) { $this->_message($this->__('Unable to update shipping method.'), self::MESSAGE_STATUS_ERROR); Mage::logException($e); } } /** * Submit the order */ public function placeOrderAction() { try { $requiredAgreements = Mage::helper('checkout')->getRequiredAgreementIds(); if (!empty($requiredAgreements)) { $postedAgreements = array_keys($this->getRequest()->getPost('agreement', array())); if (array_diff($requiredAgreements, $postedAgreements)) { $error = $this->__('Please agree to all the terms and conditions before placing the order.'); $this->_message($error, self::MESSAGE_STATUS_ERROR); return; } } $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) { $orderId = $order->getId(); $realOrderId = $order->getIncrementId(); $session->setLastOrderId($order->getId())->setLastRealOrderId($order->getIncrementId()); } // 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); } $this->_initToken(false); // no need in token anymore /** @var $message Mage_XmlConnect_Model_Simplexml_Element */ $message = Mage::getModel('xmlconnect/simplexml_element', ''); $message->addChild('status', self::MESSAGE_STATUS_SUCCESS); $text = $this->__('Thank you for your purchase! '); $text .= $this->__('Your order # is: %s. ', $realOrderId); $text .= $this->__('You will receive an order confirmation email with details of your order and a link to track its progress.'); $message->addChild('text', $text); $message->addChild('order_id', $orderId); $this->getResponse()->setBody($message->asNiceXml()); return; } catch (Mage_Core_Exception $e) { $this->_message($e->getMessage(), self::MESSAGE_STATUS_ERROR); } catch (Exception $e) { $this->_message($this->__('Unable to place the order.'), self::MESSAGE_STATUS_ERROR); Mage::logException($e); } } /** * Cancel Mobile Express Checkout */ public function cancelAction() { try { // if there is an order - cancel it $orderId = $this->_getCheckoutSession()->getLastOrderId(); $order = ($orderId) ? Mage::getModel('sales/order')->load($orderId) : false; if ($order && $order->getId() && $order->getQuoteId() == $this->_getCheckoutSession()->getQuoteId()) { $order->cancel()->save(); $this->_getCheckoutSession()->unsLastQuoteId()->unsLastSuccessQuoteId()->unsLastOrderId() ->unsLastRealOrderId(); } $this->_initToken(false); $this->_message($this->__('Mobile Express Checkout has been canceled.'), self::MESSAGE_STATUS_SUCCESS); } catch (Mage_Core_Exception $e) { $this->_message($e->getMessage(), self::MESSAGE_STATUS_ERROR); } catch (Exception $e) { $this->_message($this->__('Unable to cancel Mobile Express Checkout.'), self::MESSAGE_STATUS_ERROR); Mage::logException($e); } } /** * Instantiate quote and checkout * * @throws Mage_Core_Exception * @return null */ protected function _initCheckout() { $quote = $this->_getQuote(); if (!$quote->hasItems() || $quote->getHasError()) { Mage::throwException($this->__('Unable to initialize PayPal Mobile Express Checkout.')); } if (!$quote->validateMinimumAmount()) { $error = Mage::getStoreConfig('sales/minimum_order/error_message'); Mage::throwException($error); } $this->_getCheckoutSession()->setCartWasUpdated(false); $this->_checkout = Mage::getSingleton($this->_checkoutType, array( 'config' => $this->_config, 'quote' => $quote )); } /** * Return checkout session object * * @return Mage_Checkout_Model_Session */ protected function _getCheckoutSession() { return Mage::getSingleton('checkout/session'); } /** * Return checkout quote object * * @return Mage_Sale_Model_Quote */ protected function _getQuote() { if (!$this->_quote) { $this->_quote = $this->_getCheckoutSession()->getQuote(); } return $this->_quote; } /** * Search for proper checkout token in request or session or (un)set specified one * Combined getter/setter * * @param string $setToken * @return Mage_Paypal_ExpressController|string */ protected function _initToken($setToken = null) { if (null !== $setToken) { if (false === $setToken) { if (!$this->_getSession()->getExpressCheckoutToken()) { // security measure for avoid unset token twice Mage::throwException($this->__('PayPal Mobile Express Checkout Token does not exist.')); } $this->_getSession()->unsExpressCheckoutToken(); } else { $this->_getSession()->setExpressCheckoutToken($setToken); } return $this; } $setToken = $this->getRequest()->getParam('token'); if ($setToken) { if ($setToken !== $this->_getSession()->getExpressCheckoutToken()) { Mage::throwException($this->__('Wrong PayPal Mobile Express Checkout Token specified.')); } } else { $setToken = $this->_getSession()->getExpressCheckoutToken(); } return $setToken; } /** * PayPal session instance getter * * @return Mage_PayPal_Model_Session */ private function _getSession() { return Mage::getSingleton('paypal/session'); } }