*/ class Mage_XmlConnect_Model_Paypal_Mep_Checkout { /**#@+ * Keys for passthrough variables in sales/quote_payment and sales/order_payment * Uses additional_information as storage */ const PAYMENT_INFO_PAYER_EMAIL = 'paypal_payer_email'; const PAYMENT_INFO_TRANSACTION_ID = 'paypal_mep_checkout_transaction_id'; /**#@-*/ /** * Payment method type * * @var string */ protected $_methodType = Mage_XmlConnect_Model_Payment_Method_Paypal_Mep::MEP_METHOD_CODE; /** * Quote model * * @var Mage_Sales_Model_Quote */ protected $_quote = null; /** * Checkout session model * * @var Mage_Checkout_Model_Session */ protected $_checkoutSession; /** * XmlConnect default helper * * @var Mage_XmlConnect_Helper_Data */ protected $_helper; /** * Set quote instances * * @throws Mage_Core_Exception * @param array $params */ public function __construct($params = array()) { $this->_checkoutSession = Mage::getSingleton('checkout/session'); if (isset($params['quote']) && $params['quote'] instanceof Mage_Sales_Model_Quote) { $this->_quote = $params['quote']; } else { Mage::throwException( Mage::helper('xmlconnect')->__('Quote instance is required.') ); } } /** * Prepare quote, reserve order ID for specified quote * * @return string */ public function initCheckout() { $this->_quote->reserveOrderId()->save(); /** * Reset multishipping flag before any manipulations with quote address * addAddress method for quote object related on this flag */ if ($this->_quote->getIsMultiShipping()) { $this->_quote->setIsMultiShipping(false); $this->_quote->save(); } /* * want to load the correct customer information by assigning to address * instead of just loading from sales/quote_address */ $customer = Mage::getSingleton('customer/session')->getCustomer(); if ($customer) { $this->_quote->assignCustomer($customer); } if (!Mage::getSingleton('customer/session')->isLoggedIn() && Mage::getSingleton('checkout/session')->getQuote()->isAllowedGuestCheckout() ) { $this->_prepareGuestQuote(); } return $this->_quote->getReservedOrderId(); } /** * Save shipping and billing address information to quote * * @param array $data * @return array */ public function saveShipping($data) { if (empty($data)) { return array('error' => 1, 'message' => Mage::helper('xmlconnect')->__('Invalid data.')); } $address = $this->_quote->getBillingAddress(); $this->_applyCountryWorkarounds($data); /** @var $model Mage_XmlConnect_Model_Application */ $model = Mage::helper('xmlconnect')->getApplication(); $paypalMepAllowSpecific = $model->getData('config_data[payment:paypalmep/allowspecific]'); if ($paypalMepAllowSpecific !== null) { if ((int)$paypalMepAllowSpecific > 0) { $allowedCountries = explode(',', $model->getData('config_data[payment][paypalmep/applicable]')); $allowedCountries = array_map('trim', $allowedCountries); if (!in_array(trim($data['country_id']), $allowedCountries)) { return array( 'error' => 1, 'message' => Mage::helper('xmlconnect')->__('Buyer country is not allowed by store.') ); } } } if (empty($data['firstname']) && empty($data['lastname'])) { if (Mage::getSingleton('customer/session')->isLoggedIn()) { $customer = Mage::getSingleton('customer/session')->getCustomer(); $data['firstname'] = $customer->getFirstname(); $data['lastname'] = $customer->getLastname(); } else { $data['firstname'] = Mage::helper('xmlconnect')->__('Guest'); $data['lastname'] = Mage::helper('xmlconnect')->__('Guest'); } } $address->addData($data); $this->_ignoreAddressValidation(); $address->implodeStreetAddress(); if (!$this->_quote->isVirtual()) { $billing = clone $address; $billing->unsAddressId()->unsAddressType(); $shipping = $this->_quote->getShippingAddress(); $shippingMethod = $shipping->getShippingMethod(); $shipping->addData($billing->getData())->setSameAsBilling(1)->setShippingMethod($shippingMethod) ->setCollectShippingRates(true); } $this->_quote->collectTotals()->save(); return array(); } /** * Specify quote shipping method * * @param string $shippingMethod * @return array */ public function saveShippingMethod($shippingMethod) { if (empty($shippingMethod)) { return array('error' => 1, 'message' => Mage::helper('xmlconnect')->__('Invalid shipping method.')); } $rate = $this->_quote->getShippingAddress()->getShippingRateByCode($shippingMethod); if (!$rate) { return array('error' => 1, 'message' => Mage::helper('xmlconnect')->__('Invalid shipping method.')); } $shippingAddress = $this->_quote->getShippingAddress(); if (!$this->_quote->getIsVirtual() && $shippingAddress) { if ($shippingMethod != $shippingAddress->getShippingMethod()) { $this->_ignoreAddressValidation(); $this->_quote->getShippingAddress()->setShippingMethod($shippingMethod); $this->_quote->collectTotals()->save(); } } return array(); } /** * Specify quote payment method * * @param array $data * @return array */ public function savePayment($data) { if ($this->_quote->isVirtual()) { $this->_quote->getBillingAddress()->setPaymentMethod($this->_methodType); } else { $this->_quote->getShippingAddress()->setPaymentMethod($this->_methodType); } $payment = $this->_quote->getPayment(); $data['method'] = $this->_methodType; $payment->importData($data); $email = isset($data['payer']) ? $data['payer'] : null; $payment->setAdditionalInformation(self::PAYMENT_INFO_PAYER_EMAIL, $email); $payment->setAdditionalInformation( self::PAYMENT_INFO_TRANSACTION_ID, isset($data['transaction_id']) ? $data['transaction_id'] : null ); $this->_quote->setCustomerEmail($email); $this->_quote->collectTotals()->save(); return array(); } /** * Place the order when customer returned from paypal * Until this moment all quote data must be valid * * @return array */ public function saveOrder() { $this->_ignoreAddressValidation(); $order = Mage::getModel('sales/service_quote', $this->_quote)->submit(); $this->_quote->save(); $this->_getCheckoutSession()->clear(); /** * Prepare session to success or cancellation page */ $quoteId = $this->_quote->getId(); $this->_getCheckoutSession()->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId) ->setLastOrderId($order->getId())->setLastRealOrderId($order->getIncrementId()); if ($order->getState() == Mage_Sales_Model_Order::STATE_PROCESSING && Mage::getSingleton('customer/session')->isLoggedIn() ) { try { $order->sendNewOrderEmail(); } catch (Exception $e) { Mage::logException($e); } } return array(); } /** * Get last order increment id by order id * * @return string */ public function getLastOrderId() { $lastId = $this->_getCheckoutSession()->getLastOrderId(); $orderId = false; if ($lastId) { $order = Mage::getModel('sales/order'); $order->load($lastId); $orderId = $order->getIncrementId(); } return $orderId; } /** * Make sure addresses will be saved without validation errors * * @return null */ protected function _ignoreAddressValidation() { $this->_quote->getBillingAddress()->setShouldIgnoreValidation(true); if (!$this->_quote->getIsVirtual()) { $this->_quote->getShippingAddress()->setShouldIgnoreValidation(true); } } /** * Get frontend checkout session object * * @return Mage_Checkout_Model_Session */ protected function _getCheckoutSession() { return $this->_checkoutSession; } /** * Prepare quote for guest checkout order submit * * @return Mage_XmlConnect_Model_Paypal_Mep_Checkout */ protected function _prepareGuestQuote() { $quote = $this->_quote; $quote->setCustomerId(null)->setCustomerIsGuest(true) ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID); return $this; } /** * Adopt specified request array from PayPal * * @param array $request * @return null */ protected function _applyCountryWorkarounds(&$request) { $request['country_id'] = isset($request['country_id']) ? trim($request['country_id']) : null; if (empty($request['country_id'])) { $request['country_id'] = strtoupper(Mage::getStoreConfig('general/country/default')); } else { $request['country_id'] = strtoupper($request['country_id']); } } }