PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/includes/modules/payment/paypal/classes/IPN/IPN.class.php

https://github.com/vaughnpaul/NOS
PHP | 299 lines | 221 code | 35 blank | 43 comment | 37 complexity | bca2b5a3752939e0d05f2840d9e694bc MD5 | raw file
  1. <?php
  2. /*
  3. $Id: IPN.class.php,v 2.8 2004/09/11 devosc Exp $
  4. osCommerce, Open Source E-Commerce Solutions
  5. http://www.oscommerce.com
  6. DevosC, Developing open source Code
  7. http://www.devosc.com
  8. Copyright (c) 2003 osCommerce
  9. Copyright (c) 2004 DevosC.com
  10. Released under the GNU General Public License
  11. */
  12. //admin workaround!
  13. $modules_directory = defined('DIR_FS_CATALOG_MODULES') ? DIR_FS_CATALOG_MODULES : DIR_WS_MODULES;
  14. require_once($modules_directory . 'payment/paypal/classes/Client/Connector.class.php');
  15. class PayPal_IPN extends PayPal_Client_Connector {
  16. function PayPal_IPN($post_vars) {
  17. global $debug;
  18. if (!in_array($post_vars['payment_type'],array('instant','echeck'))) {
  19. if ($debug->enabled) $debug->add(UNKNOWN_TXN_TYPE,sprintf(UNKNOWN_TXN_TYPE_MSG,$post_vars['payment_type']));
  20. } else if(strlen($post_vars['txn_id']) == 17) {
  21. $this->init($post_vars); //Looks like a PayPal transaction
  22. } else {
  23. if ($debug->enabled) $debug->add(UNKNOWN_POST,sprintf(UNKNOWN_POST_MSG,$_SERVER['REMOTE_ADDR']));
  24. }
  25. $this->setTestMode('Off');
  26. register_shutdown_function(array($this,'_PayPal_IPN'));
  27. }
  28. function _PayPal_IPN() {
  29. global $debug;
  30. if ($debug->enabled) $debug->sendEmail();
  31. }
  32. function init($post_vars) {
  33. global $debug;
  34. $debug_string = '';
  35. $this->key = array();
  36. $this->response_string = 'cmd=_notify-validate';
  37. reset($post_vars);
  38. foreach ($post_vars as $var => $val) {
  39. $var = urldecode($var); $val = tep_db_prepare_input(urldecode($val));
  40. if ($debug->enabled) $debug_string .= $var . '=' . $val .'&';
  41. if (!strcasecmp($var,'cmd') || !eregi("^[_0-9a-z-]{1,32}$",$var)) {
  42. unset($var); unset($val);
  43. } elseif (tep_not_null($var)) {
  44. if($var === 'custom') {
  45. $this->setTxnSignature($val);
  46. } else {
  47. $this->key[$var] = $val;
  48. }
  49. $this->response_string .= '&' . urlencode($var) . '=' . urlencode($val);
  50. }
  51. }
  52. if ($debug->enabled) $debug->init($debug_string);
  53. unset($post_vars, $debug_string);
  54. }
  55. function insert($paypal_id = '') {
  56. global $debug;
  57. $key_vars = array(
  58. 'txn_type', 'reason_code', 'payment_type',
  59. 'payment_status', 'pending_reason', 'invoice',
  60. 'mc_currency', 'first_name', 'last_name',
  61. 'payer_business_name', 'address_name', 'address_street',
  62. 'address_city', 'address_state', 'address_zip',
  63. 'address_country', 'address_status', 'payer_email',
  64. 'payer_id', 'payer_status', 'business',
  65. 'receiver_email', 'receiver_id', 'txn_id',
  66. 'parent_txn_id', 'mc_gross', 'mc_fee',
  67. 'payment_gross', 'payment_fee', 'settle_amount',
  68. 'settle_currency', 'exchange_rate', 'for_auction',
  69. 'auction_buyer_id', 'auction_multi_item',
  70. 'quantity', 'tax', 'notify_version',
  71. 'verify_sign', 'memo'
  72. );
  73. $sql_data_array = $this->setSQLDataElements($key_vars);
  74. $sql_data_array['num_cart_items'] = $this->txnType('cart') ? $this->key['num_cart_items'] : '1';
  75. $sql_data_array['payment_date'] = $this->datetime_to_sql_format($this->key['payment_date']);
  76. $sql_data_array['payment_time_zone'] = $this->paymentTimeZone($this->key['payment_date']);
  77. $sql_data_array['auction_closing_date'] = $this->datetime_to_sql_format($this->key['auction_closing_date']);
  78. $sql_data_array['date_added'] = 'now()';
  79. tep_db_perform(TABLE_PAYPAL, $sql_data_array);
  80. $this->ipnID = tep_db_insert_id();
  81. $this->updatePaymentStatusHistory( !empty($paypal_id) ? $paypal_id : $this->ipnID );
  82. if($this->isAuction()) $this->processAuction($this->ipnID);
  83. if($debug->enabled) $debug->add(IPN_TXN_INSERT,sprintf(IPN_TXN_INSERT_MSG,$this->ipnID));
  84. return $this->ipnID;
  85. }
  86. function updatePaymentStatusHistory($paypal_id) {
  87. $sql_data_array = $this->setSQLDataElements(array('payment_status', 'pending_reason', 'reason'));
  88. $sql_data_array['paypal_id'] = $paypal_id;
  89. $sql_data_array['date_added'] = 'now()';
  90. tep_db_perform(TABLE_PAYPAL_PAYMENT_STATUS_HISTORY, $sql_data_array);
  91. }
  92. function updateStatus($paypal_id) {
  93. $key_vars = array(
  94. 'first_name', 'last_name', 'payer_business_name',
  95. 'address_name', 'address_street', 'address_city',
  96. 'address_state','address_zip', 'address_country',
  97. 'address_status',
  98. 'mc_gross', 'mc_currency', 'mc_fee',
  99. 'settle_amount', 'settle_currency',
  100. 'exchange_rate',
  101. 'payment_status'
  102. );
  103. $sql_data_array = $this->setSQLDataElements($key_vars);
  104. $sql_data_array['last_modified'] = 'now()';
  105. tep_db_perform(TABLE_PAYPAL, $sql_data_array, 'update', "paypal_id = '" . (int)$paypal_id . "'");
  106. $this->updatePaymentStatusHistory($paypal_id);
  107. }
  108. function updateOrderStatus($paypal_id,$status) {
  109. //Orders
  110. $sql_data_array = array(
  111. 'orders_status' => tep_db_input($status),
  112. 'last_modified' => 'now()'
  113. );
  114. tep_db_perform(TABLE_ORDERS, $sql_data_array, 'update', "payment_id = '" . (int)$paypal_id . "'");
  115. //Orders Status History
  116. $sql_query = tep_db_query("select orders_id from " . TABLE_ORDERS . " where payment_id = '" . (int)$paypal_id . "'");
  117. $sql_result = tep_db_fetch_array($sql_query);
  118. $sql_data_array = array(
  119. 'orders_id' => $sql_result['orders_id'],
  120. 'orders_status_id' => tep_db_input($status),
  121. 'date_added' => 'now()'
  122. );
  123. tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array, 'insert');
  124. }
  125. function queryTxnID($txn_id) {
  126. $sql_query = tep_db_query("select paypal_id from " . TABLE_PAYPAL . " where txn_id = '" . tep_db_input($txn_id) . "' limit 0,1");
  127. return tep_db_fetch_array($sql_query);
  128. }
  129. function queryPendingStatus($txn_id) {
  130. $sql_query = tep_db_query("select paypal_id, payment_status, pending_reason from " . TABLE_PAYPAL . " where txn_id = '" . tep_db_input($txn_id) . "' limit 0,1");
  131. return tep_db_fetch_array($sql_query);
  132. }
  133. function authenticate($domain, $success = 'VERIFIED') {
  134. $paypal_response = $this->getResponse($domain);
  135. $paypal_verification = $this->getVerificationResponse($paypal_response);
  136. return strstr($paypal_verification,$success);
  137. }
  138. function uniqueTxnID() {
  139. global $debug;
  140. if (isset($this->uniqueTxnID)) {
  141. return $this->uniqueTxnID;
  142. } else {
  143. $txn_id_query = tep_db_query("select txn_id from " . TABLE_PAYPAL . " where txn_id = '" . tep_db_input($this->txnID()) . "' limit 0,1");
  144. if (!tep_db_num_rows($txn_id_query)) { //txn_id doesn't exist
  145. $this->uniqueTxnID = true;
  146. return $this->uniqueTxnID;
  147. } else {
  148. if($debug->enabled) $debug->add(TXN_DUPLICATE,sprintf(TXN_DUPLICATE_MSG,$this->txnID()));
  149. $this->uniqueTxnID = false;
  150. return $this->uniqueTxnID;
  151. }
  152. }
  153. }
  154. function validPayment($amount,$currency) {
  155. if (MODULE_PAYMENT_PAYPAL_IPN_CART_TEST == 'Off') return true;
  156. return parent::validPayment($amount,$currency);
  157. }
  158. //returns TABLE_PAYPAL.paypal_id
  159. function ID() {
  160. return $this->ipnID;
  161. }
  162. function txnID() {
  163. return $this->key['txn_id'];
  164. }
  165. //returns the transaction type (paypal.txn_type)
  166. function txnType($txnTypeName = '') {
  167. if(!empty($txnTypeName)) {
  168. return ($this->key['txn_type'] === $txnTypeName);
  169. }
  170. return $this->key['txn_type'];
  171. }
  172. function paymentStatus($statusName = '') {
  173. if(!empty($statusName)) {
  174. return ($this->key['payment_status'] == $statusName);
  175. }
  176. return $this->key['payment_status'];
  177. }
  178. function isCartPayment() {
  179. return in_array($this->key['txn_type'],array('web_accept','cart'));
  180. }
  181. function isReversal() {
  182. return in_array($this->key['payment_status'],array('Refunded','Reversed','Canceled_Reversal'));
  183. }
  184. function reversalType() {
  185. return $this->key['payment_status'];
  186. }
  187. function datetime_to_sql_format($paypalDateTime) {
  188. $months = array('Jan' => '01', 'Feb' => '02', 'Mar' => '03', 'Apr' => '04', 'May' => '05', 'Jun' => '06', 'Jul' => '07', 'Aug' => '08', 'Sep' => '09', 'Oct' => '10', 'Nov' => '11', 'Dec' => '12');
  189. $array = explode(" ",$paypalDateTime);
  190. $time = explode(":",$array[0]);
  191. $hour = $time[0];$minute = $time[1];$second = $time[2];
  192. $month = $months[$array[1]];
  193. $day = substr_replace($array[2],'',-1,1);
  194. $year = $array[3];
  195. return ($year . "-" . $month . "-" . $day . " " . $hour . ":" . $minute . ":" . $second);
  196. }
  197. function paymentTimeZone($paypalDateTime) {
  198. $array = explode(" ",$paypalDateTime);
  199. return $array[4];
  200. }
  201. function setSQLDataElements($varnames) {
  202. $sql_data_array = array();
  203. $nVars = count($varnames);
  204. for($i=0; $i<$nVars; $i++) {
  205. if(isset($this->key[$varnames[$i]]) && !empty($this->key[$varnames[$i]]) && trim($this->key[$varnames[$i]]) != '')
  206. $sql_data_array[$varnames[$i]] = $this->key[$varnames[$i]];
  207. }
  208. return $sql_data_array;
  209. }
  210. function isAuction() {
  211. return (isset($this->key['for_auction']) && $this->key['for_auction'] === 'true');
  212. }
  213. function processAuction($paypal_id) {
  214. if(defined('TABLE_PAYPAL_AUCTION')) {
  215. if($this->isAuction() && strlen($this->key['item_number']) > 0) {
  216. $items = explode(',', $this->key['item_number']);
  217. foreach($items as $key => $item_id) {
  218. // Save the auction IDs for correlation later
  219. $txn_check = tep_db_query("select auction_buyer_id from " . TABLE_PAYPAL_AUCTION . " where paypal_id = '" . (int)$paypal_id . "' and item_number = '" . tep_db_input($item_id) . "'");
  220. if (!tep_db_num_rows($txn_check)) {
  221. $sql_data_array = $this->setSQLDataElements(array('auction_buyer_id','auction_multi_item'));
  222. $sql_data_array['paypal_id'] = (int)$paypal_id;
  223. $sql_data_array['item_number'] = $item_id;
  224. tep_db_perform(TABLE_PAYPAL_AUCTION, $sql_data_array);
  225. }
  226. }
  227. }
  228. }
  229. }
  230. function setTxnSignature($txnSignature = '') {
  231. if(!isset($this->txnSignature)) $this->txnSignature = $txnSignature;
  232. }
  233. function txnSignature() {
  234. return $this->txnSignature;
  235. }
  236. /*
  237. //Test that the store owner's 'custom' transaction signature doesn't exist
  238. //Really this is only for preventing mistakes via the IPN Test Panel
  239. function uniqueTxnSignature() {
  240. global $debug;
  241. if(!$this->isTestMode()) return true;
  242. if (isset($this->uniqueTxnSignature)) {
  243. return $this->uniqueTxnSignature;
  244. } else {
  245. $txn_sign_query = tep_db_query("select txn_sign from " . TABLE_PAYPAL . " where txn_sign = '" . tep_db_input($this->txnSignature()) . "' limit 0,1");
  246. if (!tep_db_num_rows($txn_sign_query)) { //txn_sign doesn't exist
  247. $this->uniqueTxnSignature = true;
  248. return $this->uniqueTxnSignature;
  249. } else {
  250. if($debug->enabled) $debug->add(TXN_DUPLICATE_SIGNATURE,sprintf(TXN_DUPLICATE_SIGNATURE_MSG,$this->txnSignature()));
  251. $this->uniqueTxnSignature = false;
  252. return $this->uniqueTxnSignature;
  253. }
  254. }
  255. }*/
  256. }//end class
  257. ?>