A Qcodo based CMS/ecommerce framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
13 KiB

12 years ago
  1. <?php
  2. if(!defined('QUASICMS') ) die("No quasi.");
  3. if (!defined("PAYPALEXPRESSRETURNMODULE.CLASS.PHP")){
  4. define("PAYPALEXPRESSRETURNMODULE.CLASS.PHP",1);
  5. /**
  6. * Class PayPalExpressReturnModule - provides the return URL actions to complete a
  7. * PayPay Express Checkout transaction.
  8. *
  9. * This module contains the actions performed to complete a PayPal transaction when
  10. * the customer is returned to this site after approving the payment at paypal.com. It
  11. * must be registered in the database as a module and assigned to a ContentBlock on
  12. * the page name given as the RETURNURL or CANCELURL to PayPal. This module will
  13. * determine the type of action to take based on the page name, so they must be named
  14. * either PayPalExpressReturn or PayPalExpressCancel.
  15. *
  16. * For the PayPal payment action, all of the actions normally completed in the CheckOutModule
  17. * by simpler methods are completed here - ie. Payment status is determined and if approved
  18. * PaymentAction::completeOrder() is called, saving the status, totals and sending the email.
  19. * In the case of a delayed payment (eg. echecks), a message is displayed and no further
  20. * action is taken - the final steps are then to be completed by PayPalIPNAction which will
  21. * respond to payment notification and complete the order when/if it is approved.
  22. *
  23. *@todo
  24. * - display messages; confirmation, delay or cancellation. to show
  25. * - add button or options to continue ..? (they could just use the menu ..)
  26. *
  27. *@author Erik Winn <erikwinnmail@yahoo.com>
  28. *
  29. *
  30. * $Id: PayPalExpressReturnModule.class.php 420 2008-12-10 03:36:18Z erikwinn $
  31. *@version 0.1
  32. *
  33. *@copyright (C) 2008 by Erik Winn
  34. *@license GPL v.2
  35. This program is free software; you can redistribute it and/or modify
  36. it under the terms of the GNU General Public License as published by
  37. the Free Software Foundation; either version 2 of the License, or
  38. (at your option) any later version.
  39. This program is distributed in the hope that it will be useful,
  40. but WITHOUT ANY WARRANTY; without even the implied warranty of
  41. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  42. GNU General Public License for more details.
  43. You should have received a copy of the GNU General Public License
  44. along with this program; if not, write to the Free Software
  45. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
  46. *
  47. *@package Quasi
  48. * @subpackage Modules
  49. */
  50. class PayPalExpressReturnModule extends CheckOutConfirmationModule
  51. {
  52. /**
  53. * This instance of the order is recreated from the database when the user is returned to our site.
  54. * Although this may change, currently the order id is passed as a GET value from paypal. this is
  55. * not entirely secure, we may need to tighten this up, not clear how yet ...
  56. *@todo
  57. * - load order safely, see comment above ..
  58. * - handle cancelations ..
  59. *
  60. *@var Order objOrder - recreated instance of the order to be completed (or removed)
  61. */
  62. protected $objOrder;
  63. /**
  64. * This is a PayPalExpressCheckoutAction - we use the final calls only.
  65. *@var PaymentAction objPaymentAction - the payment action employed
  66. */
  67. protected $objPaymentAction;
  68. /**
  69. * This label is used in the template to show whatever message is appropriate for the status
  70. * of the payment transaction.
  71. *@var QLabel lblMessages - displays messages regarding order payment status
  72. */
  73. // public $lblMessages;
  74. /**
  75. * Module constructor
  76. * NOTE: This module ignores the required extra parameters ..
  77. *@param QPanel - objContentBlock parent controller object.
  78. *@param mixed - extra parameters, ignored
  79. */
  80. public function __construct( QPanel $objContentBlock, $mixParameters=null)
  81. {
  82. $objOrder = Order::LoadById($_REQUEST['orderid']);
  83. if(!$objOrder)
  84. throw new QCallerException('PayPal Return error for order ' . $_REQUEST['orderid']);
  85. try {
  86. parent::__construct($objContentBlock, $objContentBlock, $objOrder);
  87. } catch (QCallerException $objExc) {
  88. $objExc->IncrementOffset();
  89. throw $objExc;
  90. }
  91. //reset the template
  92. // $this->strTemplate = __QUASI_CORE_TEMPLATES__ . '/PayPalExpressReturnModule.tpl.php';
  93. if( IndexPage::$strPageRequest == 'PayPalExpressReturn')
  94. $this->handleCompletion();
  95. elseif( IndexPage::$strPageRequest == 'PayPalExpressCancel')
  96. $this->handleCancellation();
  97. }
  98. /**
  99. * This overrides the display initialization in CheckOutConfirmationModule
  100. */
  101. protected function init()
  102. {
  103. $this->aryCheckOutItemViews = array();
  104. //construct the list of items
  105. $aryOrderItems = $this->objOrder->GetOrderItemArray();
  106. foreach( $aryOrderItems as $objOrderItem)
  107. {
  108. $objItemView = new CheckOutItemView( $this, $objOrderItem, false );
  109. $this->aryCheckOutItemViews[] = $objItemView;
  110. }
  111. $this->objOrderTotalsView = new OrderTotalsView($this, $this->objOrder, false);
  112. $intShippingAddressId = $this->objOrder->GetShippingAddress()->Id;
  113. $intBillingAddressId = $this->objOrder->GetBillingAddress()->Id;
  114. $this->objShippingAddressView = new AddressView($this,
  115. $intShippingAddressId,
  116. 'ShippingAddress: ');
  117. $this->objShippingAddressView->CssClass = 'ShippingAddressReview';
  118. $this->objShippingAddressView->AutoRenderChildren = true;
  119. $this->objBillingAddressView = new AddressView($this,
  120. $intBillingAddressId,
  121. 'BillingAddress: ');
  122. $this->objBillingAddressView->CssClass = 'BillingAddressReview';
  123. $this->objBillingAddressView->AutoRenderChildren = true;
  124. if($this->objOrder->PaymentMethodId)
  125. {
  126. $objPaymentMethod = PaymentMethod::Load($this->objOrder->PaymentMethodId);
  127. $this->pnlPaymentMethod = new QPanel($this);
  128. $this->pnlPaymentMethod->HtmlEntities = false;
  129. $this->pnlPaymentMethod->CssClass = 'PaymentMethodReview';
  130. $this->pnlPaymentMethod->AutoRenderChildren = true;
  131. $strText = '<div class="heading">' . Quasi::Translate('Payment Method') . ':</div>'
  132. . sprintf( '<div class="heading"> %s </div> <br /> %s ',
  133. $objPaymentMethod->Title,
  134. $objPaymentMethod->Description
  135. );
  136. $this->pnlPaymentMethod->Text = $strText;
  137. }
  138. if($this->objOrder->ShippingMethodId)
  139. {
  140. $objShippingMethod = ShippingMethod::Load($this->objOrder->ShippingMethodId);
  141. $this->pnlShippingMethod = new QPanel($this);
  142. $this->pnlShippingMethod->HtmlEntities = false;
  143. $this->pnlShippingMethod->CssClass = 'ShippingMethodReview';
  144. $this->pnlShippingMethod->AutoRenderChildren = true;
  145. $strText = '<div class="heading">' . Quasi::Translate('Shipping Method') . ':</div>'
  146. . sprintf( '<div class="heading"> %s </div> <br /> %s ',
  147. $objShippingMethod->Title,
  148. $objShippingMethod->Description
  149. );
  150. $this->pnlShippingMethod->Text = $strText;
  151. }
  152. }
  153. /**
  154. * This function handles a successful return from PayPal.
  155. *@todo
  156. * - load order safely, this is a quick cludge that needs work ..
  157. * - make order completion messages configurable, error, approved and pending ..
  158. */
  159. public function handleCompletion()
  160. {
  161. $this->objPaymentAction = new PayPalExpressCheckoutAction($this->objOrder);
  162. $this->objPaymentAction->getExpressCheckoutDetails();
  163. $this->objPaymentAction->doExpressCheckoutPayment();
  164. $blnIsPending = ( 'PENDING' == strtoupper($this->objPaymentAction->PaypalTransaction->PaymentStatus));
  165. $strApprovedText = '<div class="heading">' . Quasi::Translate("Thank You for your purchase") . '! </div>';
  166. $strApprovedText .= '<p>' . Quasi::Translate('Your Order Number is') . ': ' . $this->objOrder->Id . ' </p>';
  167. if( $blnIsPending)
  168. $strApprovedText .= '<p>' . Quasi::Translate('Your PayPal payment is being approved - it will be processed as soon as it has been approved.') . ' </p>';
  169. $strApprovedText .= '<p>' . Quasi::Translate('We will email you shortly with a confirmation of your order') . '.</p><p> '
  170. . Quasi::Translate('Please make sure that you have given a correct email address with which to contact you') . '. </p>';
  171. $strDeclinedText = '<p>' . Quasi::Translate("We're Sorry - Your payment has been declined") . '. </p>';
  172. $strErrorMessage = '';
  173. if($this->objPaymentAction->HasErrors)
  174. $strErrorMessage = '<p>' . Quasi::Translate('Oops, there was an error during the transaction!') . ' </p><p>'
  175. . $this->objPaymentAction->Errors . '</p><p>' . $this->objPaymentAction->StatusText . '</p>';
  176. if($this->objPaymentAction->Approved || $blnIsPending)
  177. $this->lblMessage->Text = $strApprovedText;
  178. else
  179. $this->lblMessage->Text = $strDeclinedText;
  180. if($this->objPaymentAction->HasErrors)
  181. $this->lblMessage->Text .= $strErrorMessage;
  182. //clear the shopping cart here for pending payments .. completeOrder() only does this if approved.
  183. if( !$this->objPaymentAction->HasErrors && ( $this->objPaymentAction->Approved || $blnIsPending) )
  184. IndexPage::$objShoppingCart->DeleteAllShoppingCartItems();
  185. //all ok? then finish up .. otherwise we'll wait for IPN to complete the order.
  186. if($this->objPaymentAction->Approved)
  187. $this->objPaymentAction->completeOrder();
  188. }
  189. /**
  190. * This fuction handles cancelation returns from PayPal, ie, if the user does not complete payment
  191. * process but hits "Cancel" at paypal ..
  192. */
  193. public function handleCancellation()
  194. {
  195. /* $objOrderStatusHistory = new OrderStatusHistory();
  196. $objOrderStatusHistory->OrderId = $this->objOrder->Id;
  197. $objOrderStatusHistory->StatusId = OrderStatusType::Cancelled;
  198. $objOrderStatusHistory->Save(); */
  199. $this->objOrder->Delete();
  200. Quasi::Redirect(__QUASI_SUBDIRECTORY__ . '/index.php/CheckOut');
  201. }
  202. public function Validate(){return true;}
  203. public function __get($strName)
  204. {
  205. switch ($strName)
  206. {
  207. case 'Order':
  208. return $this->objOrder ;
  209. default:
  210. try {
  211. return parent::__get($strName);
  212. } catch (QCallerException $objExc) {
  213. $objExc->IncrementOffset();
  214. throw $objExc;
  215. }
  216. }
  217. }
  218. public function __set($strName, $mixValue)
  219. {
  220. switch ($strName)
  221. {
  222. case 'Order':
  223. try {
  224. return ($this->objOrder = QType::Cast($mixValue, 'Order' ));
  225. } catch (QInvalidCastException $objExc) {
  226. $objExc->IncrementOffset();
  227. throw $objExc;
  228. }
  229. default:
  230. try {
  231. return (parent::__set($strName, $mixValue));
  232. } catch (QCallerException $objExc) {
  233. $objExc->IncrementOffset();
  234. throw $objExc;
  235. }
  236. }
  237. }
  238. }//end class
  239. }//end define
  240. ?>