PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/kernel/shop/classes/ezpaymentcallbackchecker.php

https://github.com/zerustech/ezpublish
PHP | 308 lines | 208 code | 43 blank | 57 comment | 21 complexity | 2cf7c5f71ffba0a9cc4090b13e8cff42 MD5 | raw file
  1. <?php
  2. /**
  3. * File containing the eZPaymentCallbackChecker class.
  4. *
  5. * @copyright Copyright (C) eZ Systems AS. All rights reserved.
  6. * @license For full copyright and license information view LICENSE file distributed with this source code.
  7. * @version //autogentag//
  8. * @package kernel
  9. */
  10. /*!
  11. \class eZPaymentCallbackChecker ezpaymentcallbackchecker.php
  12. \brief Routines for support callback(postbacks) in redirectional
  13. payment gateways.
  14. */
  15. class eZPaymentCallbackChecker
  16. {
  17. /**
  18. * Constructor
  19. *
  20. * @param string $iniFile
  21. */
  22. public function __construct( $iniFile )
  23. {
  24. $this->logger = eZPaymentLogger::CreateForAdd( 'var/log/eZPaymentChecker.log' );
  25. $this->ini = eZINI::instance( $iniFile );
  26. }
  27. /*!
  28. Parses 'POST' response and create array with received data.
  29. */
  30. function createDataFromPOST()
  31. {
  32. $this->logger->writeTimedString( 'createDataFromPOST' );
  33. $this->callbackData = array();
  34. foreach( $_POST as $key => $value )
  35. {
  36. $this->callbackData[$key] = $value;
  37. $this->logger->writeTimedString( "$key = $value" );
  38. }
  39. return ( count( $this->callbackData ) > 0 );
  40. }
  41. /*!
  42. Parses 'GET' response and create array with received data.
  43. */
  44. function createDataFromGET()
  45. {
  46. $this->logger->writeTimedString( 'createDataFromGET' );
  47. $this->callbackData = array();
  48. $query_string = eZSys::serverVariable( 'QUERY_STRING' );
  49. if( $query_string )
  50. {
  51. $key_value_pairs = explode( '&', $query_string );
  52. foreach( $key_value_pairs as $key_value )
  53. {
  54. $data = explode( '=', $key_value );
  55. $this->callbackData[$data[0]] = $data[1];
  56. $this->logger->writeTimedString( "$data[0] = $data[1]" );
  57. }
  58. }
  59. return ( count( $this->callbackData ) > 0 );
  60. }
  61. /*!
  62. Sends POST request.
  63. */
  64. function sendPOSTRequest( $server, $port, $serverMethod, $request, $timeout=30)
  65. {
  66. $pos = strpos($server, '://');
  67. if( $pos !== false )
  68. $server = substr($server, $pos+3);
  69. $fp = fsockopen( $server, $port, $errno, $errstr, $timeout );
  70. if( $fp )
  71. {
  72. $theCall = "POST $serverMethod HTTP/1.0\r\n" .
  73. "Host: $server\r\n" .
  74. "Content-Type: application/x-www-form-urlencoded\r\n" .
  75. "Content-Length: ".strlen( $request )."\r\n\r\n" .
  76. $request."\r\n\r\n";
  77. if ( !fputs( $fp, "$theCall", strlen( $theCall ) ) )
  78. {
  79. $this->logger->writeTimedString( "Could not write to server socket: $server:$port", 'sendPOSTRequest failed' );
  80. return null;
  81. }
  82. return $this->handleResponse( $fp );
  83. }
  84. $this->logger->writeTimedString( "Unable to open socket on $server:$port. errno = $errno, errstr = $errstr", 'sendPOSTRequest failed' );
  85. return null;
  86. }
  87. /*!
  88. Asks paypal's server to validate callback.
  89. */
  90. function requestValidation()
  91. {
  92. return false;
  93. }
  94. /*!
  95. Creates order and payment objects by orderID.
  96. After this 'checkAmount', 'checkCurrency' can be called.
  97. */
  98. function setupOrderAndPaymentObject( $orderID )
  99. {
  100. if ( isset( $orderID ) && $orderID > 0 )
  101. {
  102. $this->paymentObject = eZPaymentObject::fetchByOrderID( $orderID );
  103. if ( isset( $this->paymentObject ) )
  104. {
  105. $this->order = eZOrder::fetch( $orderID );
  106. if ( isset( $this->order ) )
  107. {
  108. return true;
  109. }
  110. $this->logger->writeTimedString( "Unable to fetch order object with orderID=$orderID", 'setupOrderAndPaymentObject failed' );
  111. return false;
  112. }
  113. $this->logger->writeTimedString( "Unable to fetch payment object with orderID=$orderID", 'setupOrderAndPaymentObject failed' );
  114. return false;
  115. }
  116. $this->logger->writeTimedString( "Invalid orderID=$orderID", 'setupOrderAndPaymentObject failed' );
  117. return false;
  118. }
  119. /*!
  120. Approves payment and continues workflow.
  121. */
  122. function approvePayment( $continueWorkflow=true )
  123. {
  124. if( $this->paymentObject )
  125. {
  126. $this->paymentObject->approve();
  127. $this->paymentObject->store();
  128. $this->logger->writeTimedString( 'payment was approved' );
  129. return ( $continueWorkflow ? $this->continueWorkflow() : null );
  130. }
  131. $this->logger->writeTimedString( "payment object is not set", 'approvePayment failed' );
  132. return null;
  133. }
  134. /*!
  135. Continues workflow.
  136. */
  137. function continueWorkflow()
  138. {
  139. if( $this->paymentObject )
  140. {
  141. $workflowID = $this->paymentObject->attribute( 'workflowprocess_id' );
  142. if( $workflowID )
  143. {
  144. return eZPaymentObject::continueWorkflow( $workflowID );
  145. }
  146. $this->logger->writeTimedString( "workflowID is not set", 'continueWorkflow failed' );
  147. return null;
  148. }
  149. $this->logger->writeTimedString( "payment object is not set", 'continueWorkflow failed' );
  150. return null;
  151. }
  152. /*!
  153. Returns value of specified field.
  154. */
  155. function getFieldValue( $field )
  156. {
  157. if ( isset( $this->callbackData[$field] ) )
  158. {
  159. return $this->callbackData[ $field ];
  160. }
  161. $this->logger->writeTimedString( "field $field does not exist.", 'getFieldValue failed' );
  162. return null;
  163. }
  164. /*!
  165. Reads ip list from ini file and searches in it
  166. server's ip.
  167. */
  168. function checkServerIP()
  169. {
  170. $remoteHostIP = eZSys::clientIP();
  171. $serverIPList = $this->ini->variable( 'ServerSettings', 'ServerIP');
  172. if ( $serverIPList === false )
  173. {
  174. $this->logger->writeTimedString( "Skipped the IP check because ServerIP is not set in the settings. Remote host is: $remoteHostIP.", 'checkServerIP' );
  175. return true;
  176. }
  177. if ( is_array( $serverIPList ) && in_array( $remoteHostIP, $serverIPList ) )
  178. {
  179. return true;
  180. }
  181. $this->logger->writeTimedString( "server with ip = $remoteHostIP does not exist.", 'checkServerIP failed' );
  182. $this->logger->writeTimedString( $serverIPList, 'serverIPList from ini file is' );
  183. return false;
  184. }
  185. /*!
  186. Simple amount checking.
  187. */
  188. function checkAmount( $amount )
  189. {
  190. $orderAmount = $this->order->attribute( 'total_inc_vat' );
  191. // To avoid floating errors, round the value down before checking.
  192. $shopINI = eZINI::instance( 'shop.ini' );
  193. $precisionValue = (int)$shopINI->variable( 'MathSettings', 'RoundingPrecision' );
  194. if ( round( $orderAmount, $precisionValue ) === round( $amount, $precisionValue ) )
  195. {
  196. return true;
  197. }
  198. $this->logger->writeTimedString( "Order amount ($orderAmount) and received amount ($amount) do not match.", 'checkAmount failed' );
  199. return false;
  200. }
  201. /*!
  202. Simple currency checking. It's up to the payment solution to use the currency that
  203. are set in the product collection for the order.
  204. */
  205. function checkCurrency( $currency )
  206. {
  207. //get the order currency
  208. $productCollection = $this->order->productCollection();
  209. $orderCurrency = $productCollection->attribute( 'currency_code' );
  210. if ( $orderCurrency == $currency )
  211. {
  212. return true;
  213. }
  214. $this->logger->writeTimedString( "Order currency ($orderCurrency) and received currency ($currency).", 'checkCurrency failed' );
  215. return false;
  216. }
  217. function checkDataField( $field, $value )
  218. {
  219. $isValid = false;
  220. if( isset( $this->callbackData[$field] ) )
  221. {
  222. $isValid = ( $this->callbackData[$field] == $value );
  223. }
  224. //__DEBUG__
  225. if( !$isValid )
  226. {
  227. $this->logger->writeTimedString('check Field ----');
  228. $this->logger->writeTimedString("ERROR - receiving value doesn't match!!!");
  229. $this->logger->writeTimedString("Field :".$field);
  230. $this->logger->writeTimedString("Value :".$this->callbackData[$field]);
  231. $this->logger->writeTimedString("Expected value :".$value);
  232. $this->logger->writeTimedString('----');
  233. }
  234. //___end____
  235. return $isValid;
  236. }
  237. // you must override below
  238. /*!
  239. Postback request which will be sent to payment server.
  240. */
  241. function buildRequestString()
  242. {
  243. $this->logger->writeTimedString( 'You must override this function.', 'buildRequestString failed' );
  244. return null;
  245. }
  246. /*!
  247. Handles server response.
  248. */
  249. function handleResponse( $socket )
  250. {
  251. $this->logger->writeTimedString( 'You must override this function.', 'handlePOSTResponse failed' );
  252. return null;
  253. }
  254. public $logger;
  255. public $ini;
  256. public $callbackData;
  257. public $paymentObject;
  258. public $order;
  259. }
  260. ?>