PageRenderTime 59ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/includes/modules/payment/paypalwpp.php

https://github.com/happyxlq/lt_svn
PHP | 2970 lines | 2068 code | 275 blank | 627 comment | 718 complexity | 9f0912611febbb9394825e30cebc86de MD5 | raw file
Possible License(s): AGPL-1.0, BSD-3-Clause, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * paypalwpp.php payment module class for Paypal Express Checkout / Website Payments Pro / Payflow Pro payment methods
  4. *
  5. * @package paymentMethod
  6. * @copyright Copyright 2003-2007 Zen Cart Development Team
  7. * @copyright Portions Copyright 2003 osCommerce
  8. * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
  9. * @version $Id: paypalwpp.php 7620 2007-12-11 19:12:46Z drbyte $
  10. */
  11. /**
  12. * load the communications layer code
  13. */
  14. require_once(DIR_FS_CATALOG . DIR_WS_MODULES . 'payment/paypal/paypal_curl.php');
  15. /**
  16. * the PayPal payment module with Express Checkout
  17. *
  18. * currently supports US-NVP
  19. *
  20. */
  21. class paypalwpp extends base {
  22. /**
  23. * name of this module
  24. *
  25. * @var string
  26. */
  27. var $code;
  28. /**
  29. * displayed module title
  30. *
  31. * @var string
  32. */
  33. var $title;
  34. /**
  35. * displayed module description
  36. *
  37. * @var string
  38. */
  39. var $description;
  40. /**
  41. * module status - set based on various config and zone criteria
  42. *
  43. * @var string
  44. */
  45. var $enabled;
  46. /**
  47. * the zone to which this module is restricted for use
  48. *
  49. * @var string
  50. */
  51. var $zone;
  52. /**
  53. * array holding accepted DP/gateway card types
  54. *
  55. * @var array
  56. */
  57. var $cards = array();
  58. /**
  59. * JS code used for gateway/DP mode
  60. *
  61. * @var string
  62. */
  63. var $cc_type_javascript = '';
  64. /**
  65. * JS code used for gateway/DP mode
  66. *
  67. * @var string
  68. */
  69. var $cc_type_check = '';
  70. /**
  71. * debugging flag
  72. *
  73. * @var boolean
  74. */
  75. var $enableDebugging = false;
  76. /**
  77. * is DP enabled ?
  78. *
  79. * @var boolean
  80. */
  81. var $enableDirectPayment = false;
  82. /**
  83. * Determines whether payment page is displayed or not
  84. *
  85. * @var boolean
  86. */
  87. var $showPaymentPage = false;
  88. var $flagDisablePaymentAddressChange = false;
  89. /**
  90. * sort order of display
  91. *
  92. * @var int
  93. */
  94. var $sort_order = 0;
  95. /**
  96. * Button Source / BN code -- enables the module to work for Zen Cart
  97. *
  98. * @var string
  99. */
  100. var $buttonSourceEC = 'ZenCart-EC_us';
  101. /**
  102. * order status setting for pending orders
  103. *
  104. * @var int
  105. */
  106. var $order_pending_status = 1;
  107. /**
  108. * order status setting for completed orders
  109. *
  110. * @var int
  111. */
  112. var $order_status = DEFAULT_ORDERS_STATUS_ID;
  113. /**
  114. * Debug tools
  115. */
  116. var $_logDir = 'includes/modules/payment/paypal/logs/';
  117. var $_logLevel = 0;
  118. /**
  119. * class constructor
  120. */
  121. function paypalwpp() {
  122. include_once(zen_get_file_directory(DIR_FS_CATALOG . DIR_WS_LANGUAGES . $_SESSION['language'] . '/modules/payment/', 'paypalwpp.php', 'false'));
  123. global $order;
  124. $this->code = 'paypalwpp';
  125. $this->codeTitle = MODULE_PAYMENT_PAYPALWPP_TEXT_ADMIN_TITLE_EC;
  126. $this->codeVersion = '1.3.8a';
  127. $this->enableDirectPayment = (MODULE_PAYMENT_PAYPALWPP_DIRECT_ENABLED == 'True');
  128. $this->enabled = (MODULE_PAYMENT_PAYPALWPP_STATUS == 'True');
  129. // Set the title & description text based on the mode we're in ... EC vs DP vs admin
  130. if (IS_ADMIN_FLAG === true) {
  131. $this->description = sprintf(MODULE_PAYMENT_PAYPALWPP_TEXT_ADMIN_DESCRIPTION, ' (rev' . $this->codeVersion . ')');
  132. switch (MODULE_PAYMENT_PAYPALWPP_MODULE_MODE) {
  133. case ('PayPal'):
  134. if (MODULE_PAYMENT_PAYPALWPP_DIRECT_ENABLED == 'True') {
  135. $this->title = MODULE_PAYMENT_PAYPALWPP_TEXT_ADMIN_TITLE_WPP;
  136. } else {
  137. $this->title = MODULE_PAYMENT_PAYPALWPP_TEXT_ADMIN_TITLE_EC;
  138. }
  139. break;
  140. case ('Payflow-UK'):
  141. $this->title = MODULE_PAYMENT_PAYPALWPP_TEXT_ADMIN_TITLE_PRO20;
  142. break;
  143. case ('Payflow-US'):
  144. if (defined('MODULE_PAYMENT_PAYPALWPP_PAYFLOW_EC') && MODULE_PAYMENT_PAYPALWPP_PAYFLOW_EC == 'Yes') {
  145. $this->title = MODULE_PAYMENT_PAYPALWPP_TEXT_ADMIN_TITLE_PF_EC;
  146. } else {
  147. $this->title = MODULE_PAYMENT_PAYPALWPP_TEXT_ADMIN_TITLE_PF_GATEWAY;
  148. }
  149. break;
  150. default:
  151. $this->title = MODULE_PAYMENT_PAYPALWPP_TEXT_ADMIN_TITLE_EC;
  152. }
  153. if ($this->enabled) {
  154. if ( (MODULE_PAYMENT_PAYPALWPP_MODULE_MODE == 'PayPal' && (MODULE_PAYMENT_PAYPALWPP_APISIGNATURE == '' || MODULE_PAYMENT_PAYPALWPP_APIUSERNAME == '' || MODULE_PAYMENT_PAYPALWPP_APIPASSWORD == ''))
  155. || (substr(MODULE_PAYMENT_PAYPALWPP_MODULE_MODE,0,7) == 'Payflow' && (MODULE_PAYMENT_PAYPALWPP_PFPARTNER == '' || MODULE_PAYMENT_PAYPALWPP_PFVENDOR == '' || MODULE_PAYMENT_PAYPALWPP_PFUSER == '' || MODULE_PAYMENT_PAYPALWPP_PFPASSWORD == ''))
  156. ) $this->title .= '<span class="alert"><strong> NOT CONFIGURED YET</strong></span>';
  157. if (MODULE_PAYMENT_PAYPALWPP_SERVER =='sandbox') $this->title .= '<strong><span class="alert"> (sandbox active)</span></strong>';
  158. if (MODULE_PAYMENT_PAYPALWPP_DEBUGGING =='Log File' || MODULE_PAYMENT_PAYPALWPP_DEBUGGING =='Log and Email') $this->title .= '<strong> (Debug)</strong>';
  159. if (!function_exists('curl_init')) $this->title .= '<strong><span class="alert"> CURL NOT FOUND. Cannot Use.</span></strong>';
  160. }
  161. } else {
  162. $this->description = MODULE_PAYMENT_PAYPALWPP_TEXT_DESCRIPTION;
  163. $this->title = MODULE_PAYMENT_PAYPALWPP_EC_TEXT_TITLE; //pp
  164. if (!$this->in_special_checkout() && $this->enableDirectPayment == true) {
  165. $this->title = MODULE_PAYMENT_PAYPALWPP_TEXT_TITLE; //cc
  166. }
  167. }
  168. if ((!defined('PAYPAL_OVERRIDE_CURL_WARNING') || (defined('PAYPAL_OVERRIDE_CURL_WARNING') && PAYPAL_OVERRIDE_CURL_WARNING != 'True')) && !function_exists('curl_init')) $this->enabled = false;
  169. $this->enableDebugging = (MODULE_PAYMENT_PAYPALWPP_DEBUGGING == 'Log File' || MODULE_PAYMENT_PAYPALWPP_DEBUGGING =='Log and Email');
  170. $this->emailAlerts = (MODULE_PAYMENT_PAYPALWPP_DEBUGGING == 'Log File' || MODULE_PAYMENT_PAYPALWPP_DEBUGGING =='Log and Email' || MODULE_PAYMENT_PAYPALWPP_DEBUGGING == 'Alerts Only');
  171. $this->doDPonly = (MODULE_PAYMENT_PAYPALWPP_MODULE_MODE =='Payflow-US' && !(defined('MODULE_PAYMENT_PAYPALWPP_PAYFLOW_EC') && MODULE_PAYMENT_PAYPALWPP_PAYFLOW_EC == 'Yes'));
  172. $this->showPaymentPage = (MODULE_PAYMENT_PAYPALWPP_SKIP_PAYMENT_PAGE == 'No') ? true : false;
  173. $this->sort_order = MODULE_PAYMENT_PAYPALWPP_SORT_ORDER;
  174. $this->buttonSourceEC = 'ZenCart-EC_us';
  175. $this->buttonSourceDP = 'ZenCart-DP_us';
  176. if (MODULE_PAYMENT_PAYPALWPP_MODULE_MODE == 'Payflow-UK') {
  177. $this->buttonSourceEC = 'ZenCart-EC_uk';
  178. $this->buttonSourceDP = 'ZenCart-DP_uk';
  179. }
  180. if (MODULE_PAYMENT_PAYPALWPP_MODULE_MODE == 'Payflow-US') {
  181. $this->buttonSourceEC = 'ZenCart-ECGW_us';
  182. $this->buttonSourceDP = 'ZenCart-GW_us';
  183. }
  184. $this->order_pending_status = MODULE_PAYMENT_PAYPALWPP_ORDER_PENDING_STATUS_ID;
  185. if ((int)MODULE_PAYMENT_PAYPALWPP_ORDER_STATUS_ID > 0) {
  186. $this->order_status = MODULE_PAYMENT_PAYPALWPP_ORDER_STATUS_ID;
  187. }
  188. $this->new_acct_notify = MODULE_PAYMENT_PAYPALWPP_NEW_ACCT_NOTIFY;
  189. $this->zone = (int)MODULE_PAYMENT_PAYPALWPP_ZONE;
  190. if (is_object($order)) $this->update_status();
  191. if (PROJECT_VERSION_MAJOR != '1' && substr(PROJECT_VERSION_MINOR, 0, 3) != '3.8') $this->enabled = false;
  192. // offer credit card choices for pull-down menu -- only needed for UK version
  193. $this->cards = array();
  194. if (MODULE_PAYMENT_PAYPALWPP_MODULE_MODE == 'Payflow-UK') {
  195. if (CC_ENABLED_VISA=='1') $this->cards[] = array('id' => 'Visa', 'text' => 'Visa');
  196. if (CC_ENABLED_MC=='1') $this->cards[] = array('id' => 'MasterCard', 'text' => 'MasterCard');
  197. if (CC_ENABLED_MAESTRO=='1') $this->cards[] = array('id' => 'Maestro', 'text' => 'Maestro');
  198. if (CC_ENABLED_SWITCH=='1') $this->cards[] = array('id' => 'Switch', 'text' => 'Switch');
  199. if (CC_ENABLED_SOLO=='1') $this->cards[] = array('id' => 'Solo', 'text' => 'Solo');
  200. }
  201. // if operating in markflow mode, start EC process when submitting order
  202. if (!$this->in_special_checkout() && $this->enableDirectPayment == false) {
  203. $this->form_action_url = zen_href_link('ipn_main_handler.php', 'type=ec&markflow=1&clearSess=1&stage=final', 'SSL', true, true, true);
  204. }
  205. // debug setup
  206. if (!@is_writable($this->_logDir)) $this->_logDir = DIR_FS_CATALOG . $this->_logDir;
  207. if (!@is_writable($this->_logDir)) $this->_logDir = DIR_FS_SQL_CACHE;
  208. // Regular mode:
  209. if ($this->enableDebugging) $this->_logLevel = PEAR_LOG_INFO;
  210. // DEV MODE:
  211. if (defined('PAYPAL_DEV_MODE') && PAYPAL_DEV_MODE == 'true') $this->_logLevel = PEAR_LOG_DEBUG;
  212. if (IS_ADMIN_FLAG === true) $this->tableCheckup();
  213. }
  214. /**
  215. * Sets payment module status based on zone restrictions etc
  216. */
  217. function update_status() {
  218. global $order, $db;
  219. if ($this->enabled && (int)$this->zone > 0) {
  220. $check_flag = false;
  221. $sql = "SELECT zone_id
  222. FROM " . TABLE_ZONES_TO_GEO_ZONES . "
  223. WHERE geo_zone_id = :zoneId
  224. AND zone_country_id = :countryId
  225. ORDER BY zone_id";
  226. $sql = $db->bindVars($sql, ':zoneId', $this->zone, 'integer');
  227. $sql = $db->bindVars($sql, ':countryId', $order->billing['country']['id'], 'integer');
  228. $check = $db->Execute($sql);
  229. while (!$check->EOF) {
  230. if ($check->fields['zone_id'] < 1) {
  231. $check_flag = true;
  232. break;
  233. } elseif ($check->fields['zone_id'] == $order->billing['zone_id']) {
  234. $check_flag = true;
  235. break;
  236. }
  237. $check->MoveNext();
  238. }
  239. if (!$check_flag) {
  240. $this->enabled = false;
  241. }
  242. // module cannot be used for purchase > $10,000 USD
  243. $order_amount = $this->calc_order_amount($order->info['total'], 'USD');
  244. if ($order_amount > 10000) $this->enabled = false;
  245. }
  246. }
  247. /**
  248. * Validate the credit card information via javascript (Number, Owner, and CVV Lengths)
  249. */
  250. function javascript_validation() {
  251. if ($this->in_special_checkout() || $this->enableDirectPayment == false) {
  252. // if we are in express-checkout flow or if DirectPayment is disabled (ie: just mark flow) then no JS validation req'd
  253. return false;
  254. }
  255. return ' if (payment_value == "' . $this->code . '") {' . "\n" .
  256. ' var cc_firstname = document.checkout_payment.paypalec_cc_firstname.value;' . "\n" .
  257. ' var cc_lastname = document.checkout_payment.paypalec_cc_lastname.value;' . "\n" .
  258. ' var cc_number = document.checkout_payment.paypalec_cc_number.value;' . "\n" .
  259. ' var cc_checkcode = document.checkout_payment.paypalwpp_cc_checkcode.value;' . "\n" .
  260. ' if (cc_firstname == "" || cc_lastname == "" || eval(cc_firstname.length) + eval(cc_lastname.length) < ' . CC_OWNER_MIN_LENGTH . ') {' . "\n" .
  261. ' error_message = error_message + "' . MODULE_PAYMENT_PAYPALWPP_TEXT_JS_CC_OWNER . '";' . "\n" .
  262. ' error = 1;' . "\n" .
  263. ' }' . "\n" .
  264. ' if (cc_number == "" || cc_number.length < ' . CC_NUMBER_MIN_LENGTH . ') {' . "\n" .
  265. ' error_message = error_message + "' . MODULE_PAYMENT_PAYPALWPP_TEXT_JS_CC_NUMBER . '";' . "\n" .
  266. ' error = 1;' . "\n" .
  267. ' }' . "\n" .
  268. ' }' . "\n";
  269. }
  270. /**
  271. * Display Credit Card Information Submission Fields on the Checkout Payment Page
  272. */
  273. function selection() {
  274. global $order;
  275. $this->cc_type_check =
  276. 'var value = document.checkout_payment.paypalec_cc_type.value;' .
  277. 'if (value == "Switch" || value == "Solo") {' .
  278. ' document.checkout_payment.paypalec_cc_issue_month.disabled = false;' .
  279. ' document.checkout_payment.paypalec_cc_issue_year.disabled = false;' .
  280. ' document.checkout_payment.paypalec_cc_checkcode.disabled = true;' .
  281. ' if (document.checkout_payment.paypalec_cc_issuenumber) document.checkout_payment.paypalec_cc_issuenumber.disabled = true;' .
  282. '} else if (value == "Maestro") {' .
  283. ' document.checkout_payment.paypalec_cc_issuenumber.disabled = false;' .
  284. ' if (document.checkout_payment.paypalec_cc_issue_month) document.checkout_payment.paypalec_cc_issue_month.disabled = true;' .
  285. ' if (document.checkout_payment.paypalec_cc_issue_year) document.checkout_payment.paypalec_cc_issue_year.disabled = true;' .
  286. ' document.checkout_payment.paypalec_cc_checkcode.disabled = false;' .
  287. '} else {' .
  288. ' if (document.checkout_payment.paypalec_cc_issuenumber) document.checkout_payment.paypalec_cc_issuenumber.disabled = true;' .
  289. ' document.checkout_payment.paypalec_cc_checkcode.disabled = false;' .
  290. '}';
  291. if (sizeof($this->cards) == 0 || $this->enableDirectPayment == false) $this->cc_type_check = '';
  292. /**
  293. * if we are NOT processing via the gateway, we will only display MarkFlow payment option, and no CC fields
  294. */
  295. if ($this->enableDirectPayment == false) {
  296. return array('id' => $this->code,
  297. 'module' => '<img align="absmiddle" src="' . MODULE_PAYMENT_PAYPALWPP_MARK_BUTTON_IMG . '" alt="' . MODULE_PAYMENT_PAYPALWPP_MARK_BUTTON_TXT . '" />' . MODULE_PAYMENT_PAYPALWPP_MARK_BUTTON_TXT,
  298. 'info'=>'<li>If you <b>have paypal account</b>, you can pay your order by your paypal account.</li>
  299. <li>If you <b>don\'t have paypal account</b>, it doesn\'t matter. You canalso pay via paypal with you credit card or bank debit card.</li>
  300. <li>Payment can be submitted in any currency.</li>
  301. <li>Our paypal account is : <b>'.MODULE_PAYMENT_PAYPALWPP_APIUSERNAME.'</b></li>
  302. <a onclick="javascript:window.open(\'https://www.paypal.com/us/cgi-bin/webscr?cmd=xpt/cps/popup/OLCWhatIsPayPal-outside\',\'olcwhatispaypal\',\'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=400, height=350\');" class="hand">
  303. <img border="0" alt="Solution Graphics" src="https://www.paypal.com/en_US/i/bnr/horizontal_solution_PP.gif"/></a>
  304. <a onclick="javascript:window.open(\'https://www.paypal.com/verified/pal='.MODULE_PAYMENT_PAYPALWPP_APIUSERNAME.'\',\'olcwhatispaypal\',\'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=400, height=350\');" class="hand">
  305. <img border="0" src="includes/templates/chanelwatches/images/logo/PaypalVerify.gif"/>
  306. </a>'
  307. );
  308. }
  309. /**
  310. * if we ARE processing via the gateway, prepare and display both the CC fields and the PP option
  311. */
  312. $expires_month = array();
  313. $expires_year = array();
  314. $issue_year = array();
  315. for ($i = 1; $i < 13; $i++) {
  316. $expires_month[] = array('id' => sprintf('%02d', $i), 'text' => strftime('%B - (%m)',mktime(0,0,0,$i,1,2000)));
  317. }
  318. $today = getdate();
  319. for ($i = $today['year']; $i < $today['year'] + 10; $i++) {
  320. $expires_year[] = array('id' => strftime('%y', mktime(0,0,0,1,1,$i)), 'text' => strftime('%Y',mktime(0,0,0,1,1,$i)));
  321. }
  322. $onFocus = ' onfocus="methodSelect(\'pmt-' . $this->code . '\')"';
  323. $fieldsArray = array();
  324. $fieldsArray[] = array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_FIRSTNAME,
  325. 'field' => zen_draw_input_field('paypalec_cc_firstname', $order->billing['firstname'], 'id="'.$this->code.'-cc-ownerf"'. $onFocus) .
  326. '<script type="text/javascript">function paypalec_cc_type_check() { ' . $this->cc_type_check . ' } </script>',
  327. 'tag' => $this->code.'-cc-ownerf');
  328. $fieldsArray[] = array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_LASTNAME,
  329. 'field' => zen_draw_input_field('paypalec_cc_lastname', $order->billing['lastname'], 'id="'.$this->code.'-cc-ownerl"'. $onFocus),
  330. 'tag' => $this->code.'-cc-ownerl');
  331. if (sizeof($this->cards)>0) $fieldsArray[] = array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_TYPE,
  332. 'field' => zen_draw_pull_down_menu('paypalec_cc_type', $this->cards, '', 'onchange="paypalec_cc_type_check();" onblur="paypalec_cc_type_check();"' . 'id="'.$this->code.'-cc-type"'. $onFocus),
  333. 'tag' => $this->code.'-cc-type');
  334. $fieldsArray[] = array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_NUMBER,
  335. 'field' => zen_draw_input_field('paypalec_cc_number', $ccnum, 'id="'.$this->code.'-cc-number"' . $onFocus),
  336. 'tag' => $this->code.'-cc-number');
  337. $fieldsArray[] = array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_EXPIRES,
  338. 'field' => zen_draw_pull_down_menu('paypalec_cc_expires_month', $expires_month, '', 'id="'.$this->code.'-cc-expires-month"' . $onFocus) . '&nbsp;' . zen_draw_pull_down_menu('paypalec_cc_expires_year', $expires_year, '', 'id="'.$this->code.'-cc-expires-year"' . $onFocus),
  339. 'tag' => $this->code.'-cc-expires-month');
  340. $fieldsArray[] = array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_CHECKNUMBER,
  341. 'field' => zen_draw_input_field('paypalec_cc_checkcode', '', 'size="4" maxlength="4"' . ' id="'.$this->code.'-cc-cvv"' . $onFocus) . '&nbsp;<small>' . MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_CHECKNUMBER_LOCATION . '</small><script type="text/javascript">paypalec_cc_type_check();</script>',
  342. 'tag' => $this->code.'-cc-cvv');
  343. if (MODULE_PAYMENT_PAYPALWPP_MODULE_MODE == 'PayPal') $fieldsArray[] = array('title' => '<br /><img src="' . MODULE_PAYMENT_PAYPALWPP_MARK_BUTTON_IMG . '" alt="' . MODULE_PAYMENT_PAYPALWPP_MARK_BUTTON_TXT . '" /><span style="font-size:11px; font-family: Arial, Verdana;"> ' . MODULE_PAYMENT_PAYPALWPP_MARK_BUTTON_TXT . '</span>');
  344. $selection = array('id' => $this->code,
  345. 'module' => MODULE_PAYMENT_PAYPALWPP_TEXT_TITLE,
  346. 'fields' => $fieldsArray);
  347. if (MODULE_PAYMENT_PAYPALWPP_MODULE_MODE == 'Payflow-UK' && (CC_ENABLED_SOLO=='1' || CC_ENABLED_SWITCH=='1')) {
  348. // add extra fields for Switch/Solo cards
  349. for ($i = $today['year'] - 10; $i <= $today['year']; $i++) {
  350. $issue_year[] = array('id' => strftime('%y',mktime(0,0,0,1,1,$i)), 'text' => strftime('%Y',mktime(0,0,0,1,1,$i)));
  351. }
  352. array_splice($selection['fields'], 4, 0,
  353. array(array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_ISSUE,
  354. 'field' => zen_draw_pull_down_menu('paypalec_cc_issue_month', $expires_month, '', 'id="'.$this->code.'-cc-issue-month"' . $onFocus ) . '&nbsp;' . zen_draw_pull_down_menu('paypalec_cc_issue_year', $issue_year, '', 'id="'.$this->code.'-cc-issue-year"' . $onFocus),
  355. 'tag' => $this->code.'-cc-issue-month')));
  356. }
  357. /* @TODO -- convert this to handle Issue Number
  358. if (MODULE_PAYMENT_PAYPALWPP_MODULE_MODE == 'Payflow-UK' && CC_ENABLED_MAESTRO=='1') {
  359. // add extra field for Maestro cards
  360. array_splice($selection['fields'], 4, 0,
  361. array(array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_MAESTRO_ISSUENUMBER,
  362. 'field' => zen_draw_pull_down_menu('paypalec_cc_issuenumber', $expires_month, '', 'id="'.$this->code.'-cc-issue-month"' . $onFocus ),
  363. 'tag' => $this->code.'-cc-issue-month')));
  364. }
  365. */
  366. return $selection;
  367. }
  368. /**
  369. * This is the credit card check done between checkout_payment and
  370. * checkout_confirmation (called from checkout_confirmation).
  371. * Evaluates the Credit Card Type for acceptance and the validity of the Credit Card Number & Expiration Date
  372. */
  373. function pre_confirmation_check() {
  374. // If this is an EC checkout, do nothing.
  375. if ($this->in_special_checkout() || $this->enableDirectPayment == false) {
  376. return false;
  377. }
  378. include(DIR_WS_CLASSES . 'cc_validation.php');
  379. $cc_validation = new cc_validation();
  380. $result = $cc_validation->validate($_POST['paypalec_cc_number'],
  381. $_POST['paypalec_cc_expires_month'], $_POST['paypalec_cc_expires_year'],
  382. $_POST['paypalec_cc_issue_month'], $_POST['paypalec_cc_issue_year']);
  383. $error = '';
  384. switch ($result) {
  385. case -1:
  386. $error = sprintf(TEXT_CCVAL_ERROR_UNKNOWN_CARD, substr($cc_validation->cc_number, 0, 4));
  387. break;
  388. case -2:
  389. case -3:
  390. case -4:
  391. $error = TEXT_CCVAL_ERROR_INVALID_DATE;
  392. break;
  393. case false:
  394. $error = TEXT_CCVAL_ERROR_INVALID_NUMBER;
  395. break;
  396. }
  397. $_POST['paypalec_cc_checkcode'] = preg_replace('/[^0-9]/i', '', $_POST['paypalec_cc_checkcode']);
  398. $_POST['paypalec_cc_issuenumber'] = preg_replace('/[^0-9]/i', '', $_POST['paypalec_cc_issuenumber']);
  399. if (($result === false) || ($result < 1) ) {
  400. $this->terminateEC(MODULE_PAYMENT_PAYPALWPP_TEXT_CARD_ERROR . '<br />' . $error, false, FILENAME_CHECKOUT_PAYMENT);
  401. }
  402. $this->cc_card_type = $cc_validation->cc_type;
  403. $this->cc_card_number = $cc_validation->cc_number;
  404. $this->cc_expiry_month = $cc_validation->cc_expiry_month;
  405. $this->cc_expiry_year = $cc_validation->cc_expiry_year;
  406. $this->cc_checkcode = $_POST['paypalec_cc_checkcode'];
  407. }
  408. /**
  409. * Display Credit Card Information for review on the Checkout Confirmation Page
  410. */
  411. function confirmation() {
  412. if ($this->in_special_checkout() || $this->enableDirectPayment == false) {
  413. $confirmation = array('title' => '', 'fields' => array());
  414. } else {
  415. $confirmation = array('title' => '',
  416. 'fields' => array(array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_FIRSTNAME,
  417. 'field' => $_POST['paypalec_cc_firstname']),
  418. array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_LASTNAME,
  419. 'field' => $_POST['paypalec_cc_lastname']),
  420. array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_TYPE,
  421. 'field' => $this->cc_card_type),
  422. array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_NUMBER,
  423. 'field' => substr($_POST['paypalec_cc_number'], 0, 4) . str_repeat('X', (strlen($_POST['paypalec_cc_number']) - 8)) . substr($_POST['paypalec_cc_number'], -4)),
  424. array('title' => MODULE_PAYMENT_PAYPALWPP_TEXT_CREDIT_CARD_EXPIRES,
  425. 'field' => strftime('%B, %Y', mktime(0,0,0,$_POST['paypalec_cc_expires_month'], 1, '20' . $_POST['paypalec_cc_expires_year'])))));
  426. }
  427. return $confirmation;
  428. }
  429. /**
  430. * Prepare the hidden fields comprising the parameters for the Submit button on the checkout confirmation page
  431. */
  432. function process_button() {
  433. if ($this->in_special_checkout() || $this->enableDirectPayment == false) {
  434. $process_button_string = '';
  435. } else {
  436. $_SESSION['paypal_ec_markflow'] = 1;
  437. $process_button_string = zen_draw_hidden_field('ec_cc_type', $_POST['paypalec_cc_type']) .
  438. zen_draw_hidden_field('ec_cc_expdate_month', $_POST['paypalec_cc_expires_month']) .
  439. zen_draw_hidden_field('ec_cc_expdate_year', $_POST['paypalec_cc_expires_year']) .
  440. zen_draw_hidden_field('ec_cc_issuedate_month', $_POST['paypalec_cc_issue_month']) .
  441. zen_draw_hidden_field('ec_cc_issuedate_year', $_POST['paypalec_cc_issue_year']) .
  442. zen_draw_hidden_field('ec_cc_number', $_POST['paypalec_cc_number']) .
  443. zen_draw_hidden_field('ec_cc_checkcode', $_POST['paypalec_cc_checkcode']) .
  444. zen_draw_hidden_field('ec_payer_firstname', $_POST['paypalec_cc_firstname']) .
  445. zen_draw_hidden_field('ec_payer_lastname', $_POST['paypalec_cc_lastname']);
  446. }
  447. return $process_button_string;
  448. }
  449. /**
  450. * Prepare and submit the final authorization to PayPal via the appropriate means as configured
  451. */
  452. function before_process() {
  453. global $order, $doPayPal;
  454. $options = array();
  455. $optionsShip = array();
  456. $optionsNVP = array();
  457. $options = $this->getLineItemDetails();
  458. //$this->zcLog('before_process - 1', 'Have line-item details:' . "\n" . print_r($options, true));
  459. $doPayPal = $this->paypal_init();
  460. if ($this->in_special_checkout() || $this->enableDirectPayment == false) {
  461. $this->zcLog('before_process - EC-1', 'Beginning EC mode');
  462. /****************************************
  463. * Do EC checkout
  464. ****************************************/
  465. // do not allow blank address to be sent to PayPal
  466. if ($_SESSION['paypal_ec_payer_info']['ship_street_1'] != '' && $_SESSION['paypal_ec_payer_info']['ship_address_status'] != 'None') {
  467. $options = array_merge($options,
  468. array('SHIPTONAME' => $_SESSION['paypal_ec_payer_info']['ship_name'],
  469. 'SHIPTOSTREET' => $_SESSION['paypal_ec_payer_info']['ship_street_1'],
  470. 'SHIPTOSTREET2'=> $_SESSION['paypal_ec_payer_info']['ship_street_2'],
  471. 'SHIPTOCITY' => $_SESSION['paypal_ec_payer_info']['ship_city'],
  472. 'SHIPTOSTATE' => $_SESSION['paypal_ec_payer_info']['ship_state'],
  473. 'SHIPTOZIP' => $_SESSION['paypal_ec_payer_info']['ship_postal_code'],
  474. 'SHIPTOCOUNTRYCODE'=> $_SESSION['paypal_ec_payer_info']['ship_country_code'],
  475. ));
  476. $this->zcLog('before_process - EC-2', 'address overrides added:' . "\n" . print_r($options, true));
  477. }
  478. $this->zcLog('before_process - EC-3', 'address info added:' . "\n" . print_r($options, true));
  479. // If the customer has changed their shipping address,
  480. // override the shipping address in PayPal with the shipping
  481. // address that is selected in Zen Cart.
  482. if ($order->delivery['street_address'] != $_SESSION['paypal_ec_payer_info']['ship_street_1'] && $_SESSION['paypal_ec_payer_info']['ship_street_1'] != '') {
  483. $_GET['markflow'] = 2;
  484. if (($address_arr = $this->getOverrideAddress()) !== false) {
  485. // set the override var
  486. $options['ADDROVERRIDE'] = 1;
  487. // set the address info
  488. $options['SHIPTONAME'] = $address_arr['entry_firstname'] . ' ' . $address_arr['entry_lastname'];
  489. $options['SHIPTOSTREET'] = $address_arr['entry_street_address'];
  490. if ($address_arr['entry_suburb'] != '') $options['SHIPTOSTREET2'] = $address_arr['entry_suburb'];
  491. $options['SHIPTOCITY'] = $address_arr['entry_city'];
  492. $options['SHIPTOZIP'] = $address_arr['entry_postcode'];
  493. $options['SHIPTOSTATE'] = $address_arr['zone_code'];
  494. $options['SHIPTOCOUNTRYCODE'] = $address_arr['countries_iso_code_2'];
  495. }
  496. }
  497. // if these optional parameters are blank, remove them from transaction
  498. if (isset($options['SHIPTOSTREET2']) && trim($options['SHIPTOSTREET2']) == '') unset($options['SHIPTOSTREET2']);
  499. if (isset($options['SHIPTOPHONE']) && trim($options['SHIPTOPHONE']) == '') unset($options['SHIPTOPHONE']);
  500. // if State is not supplied, repeat the city so that it's not blank, otherwise PayPal croaks
  501. if ((!isset($options['SHIPTOSTATE']) || trim($options['SHIPTOSTATE']) == '') && $options['SHIPTOCITY'] != '') $options['SHIPTOSTATE'] = $options['SHIPTOCITY'];
  502. $options['BUTTONSOURCE'] = $this->buttonSourceEC;
  503. $options['CURRENCY'] = $this->selectCurrency($order->info['currency']);
  504. $order_amount = $this->calc_order_amount($order->info['total'], $options['CURRENCY']);
  505. // unused at present:
  506. // $options['CUSTOM'] = '';
  507. // $options['INVNUM'] = '';
  508. // $options['DESC'] = '';
  509. // debug output
  510. $this->zcLog('before_process - EC-4', 'info being submitted:' . "\n" . $_SESSION['paypal_ec_token'] . ' ' . $_SESSION['paypal_ec_payer_id'] . ' ' . number_format($order_amount, 2) . "\n" . print_r($options, true));
  511. $response = $doPayPal->DoExpressCheckoutPayment($_SESSION['paypal_ec_token'],
  512. $_SESSION['paypal_ec_payer_id'],
  513. number_format((isset($options['AMT']) ? $options['AMT'] : $order_amount), 2),
  514. $options);
  515. $this->zcLog('before_process - EC-5', 'resultset:' . "\n" . urldecode(print_r($response, true)));
  516. // CHECK RESPONSE -- if error, actions are taken in the errorHandler
  517. $error = $this->_errorHandler($response, 'DoExpressCheckoutPayment');
  518. // SUCCESS
  519. $this->payment_type = MODULE_PAYMENT_PAYPALWPP_EC_TEXT_TYPE;
  520. $this->responsedata = $response;
  521. if ($response['PAYMENTTYPE'] != '') $this->payment_type .= ' (' . urldecode($response['PAYMENTTYPE']) . ')';
  522. $this->transaction_id = trim($response['PNREF'] . ' ' . $response['TRANSACTIONID']);
  523. if (empty($response['PENDINGREASON']) ||
  524. $response['PENDINGREASON'] == 'none' ||
  525. $response['PENDINGREASON'] == 'completed' ||
  526. $response['PAYMENTSTATUS'] == 'Completed') {
  527. $this->payment_status = 'Completed';
  528. if ($this->order_status > 0) $order->info['order_status'] = $this->order_status;
  529. } else {
  530. $this->payment_status = 'Pending (' . $response['PENDINGREASON'] . ')';
  531. $order->info['order_status'] = $this->order_pending_status;
  532. }
  533. $this->avs = 'N/A';
  534. $this->cvv2 = 'N/A';
  535. $this->correlationid = $response['CORRELATIONID'];
  536. $this->transactiontype = $response['TRANSACTIONTYPE'];
  537. $this->payment_time = urldecode($response['ORDERTIME']);
  538. $this->feeamt = urldecode($response['FEEAMT']);
  539. $this->taxamt = urldecode($response['TAXAMT']);
  540. $this->pendingreason = $response['PENDINGREASON'];
  541. $this->reasoncode = $response['REASONCODE'];
  542. // $this->numitems = $_SESSION['cart']->count_contents();
  543. $this->numitems = sizeof($order->products);
  544. $this->amt = urldecode($response['AMT'] . ' ' . $response['CURRENCYCODE']);
  545. $this->auth_code = (isset($this->response['AUTHCODE'])) ? $this->response['AUTHCODE'] : $this->response['TOKEN'];
  546. } else {
  547. /****************************************
  548. * Do DP checkout
  549. ****************************************/
  550. $this->zcLog('before_process - DP-1', 'Beginning DP mode');
  551. // Set state fields depending on what PayPal wants to see for that country
  552. $this->setStateAndCountry($order->billing);
  553. if (zen_not_null($order->delivery['street_address'])) {
  554. $this->setStateAndCountry($order->delivery);
  555. }
  556. // Validate credit card data
  557. include(DIR_WS_CLASSES . 'cc_validation.php');
  558. $cc_validation = new cc_validation();
  559. $response = $cc_validation->validate($_POST['ec_cc_number'], $_POST['ec_cc_expdate_month'], $_POST['ec_cc_expdate_year'],
  560. $_POST['ec_cc_issuedate_month'], $_POST['ec_cc_issuedate_year']);
  561. $error = '';
  562. switch ($response) {
  563. case -1:
  564. $error = sprintf(TEXT_CCVAL_ERROR_UNKNOWN_CARD, substr($cc_validation->cc_number, 0, 4));
  565. break;
  566. case -2:
  567. case -3:
  568. case -4:
  569. $error = TEXT_CCVAL_ERROR_INVALID_DATE;
  570. break;
  571. case false:
  572. $error = TEXT_CCVAL_ERROR_INVALID_NUMBER;
  573. break;
  574. }
  575. $this->zcLog('before_process - DP-2', 'CC validation results: ' . $error . '(' . $response . ')');
  576. if ($response == false || $response < 1) {
  577. $this->terminateEC($error, false, FILENAME_CHECKOUT_PAYMENT);
  578. }
  579. if (!in_array($cc_validation->cc_type, array('Visa', 'MasterCard', 'Switch', 'Solo', 'Discover', 'American Express', 'Maestro'))) {
  580. $this->terminateEC(MODULE_PAYMENT_PAYPALWPP_TEXT_BAD_CARD, false, FILENAME_CHECKOUT_PAYMENT);
  581. }
  582. $this->zcLog('before_process - DP-3', 'CC info: ' . $cc_validation->cc_type . ' ' . substr($cc_validation->cc_number, 0, 4) . str_repeat('X', (strlen($cc_validation->cc_number) - 8)) . substr($cc_validation->cc_number, -4));
  583. // if CC validation passed, continue using the validated data
  584. $cc_type = $cc_validation->cc_type;
  585. $cc_number = $cc_validation->cc_number;
  586. $cc_first_name = $_POST['ec_payer_firstname'];
  587. $cc_last_name = $_POST['ec_payer_lastname'];
  588. $cc_checkcode = $_POST['ec_cc_checkcode'];
  589. $cc_expdate_month = $cc_validation->cc_expiry_month;
  590. $cc_expdate_year = $cc_validation->cc_expiry_year;
  591. $cc_issuedate_month = $_POST['ec_cc_issuedate_month'];
  592. $cc_issuedate_year = $_POST['ec_cc_issuedate_year'];
  593. $cc_owner_ip = zen_get_ip_address();
  594. // If they're still here, set some of the order object's variables.
  595. $order->info['cc_type'] = $cc_type;
  596. $order->info['cc_number'] = substr($cc_number, 0, 4) . str_repeat('X', (strlen($cc_number) - 8)) . substr($cc_number, -4);
  597. $order->info['cc_owner'] = $cc_first_name . ' ' . $cc_last_name;
  598. $order->info['cc_expires'] = $cc_expdate_month . substr($cc_expdate_year, -2);
  599. $order->info['ip_address'] = $cc_owner_ip;
  600. // Set currency
  601. $my_currency = $this->selectCurrency($order->info['currency'], 'DP');
  602. /*
  603. // if CC is switch or solo, must be GBP
  604. if (in_array($cc_type, array('Switch', 'Solo', 'Maestro'))) {
  605. $my_currency = 'GBP';
  606. }
  607. */
  608. $order_amount = $this->calc_order_amount($order->info['total'], $my_currency);
  609. // Initialize the paypal caller object.
  610. $doPayPal = $this->paypal_init();
  611. $optionsAll = array_merge($options,
  612. array('STREET' => $order->billing['street_address'],
  613. 'ZIP' => $order->billing['postcode']));
  614. $optionsNVP = array('CITY' => $order->billing['city'],
  615. 'STATE' => $order->billing['state'],
  616. 'COUNTRYCODE' => $order->billing['country']['iso_code_2'],
  617. 'EXPDATE' => $cc_expdate_month . $cc_expdate_year );
  618. $optionsShip = array();
  619. if (isset($order->delivery) && $order->delivery['street_address'] != '') {
  620. $optionsShip= array('SHIPTONAME' => ($order->delivery['name'] == '' ? $order->delivery['firstname'] . ' ' . $order->delivery['lastname'] : $order->delivery['name']),
  621. 'SHIPTOSTREET' => $order->delivery['street_address'],
  622. 'SHIPTOSTREET2'=> $order->delivery['suburb'],
  623. 'SHIPTOCITY' => $order->delivery['city'],
  624. 'SHIPTOZIP' => $order->delivery['postcode'],
  625. 'SHIPTOSTATE' => $order->delivery['state'],
  626. 'SHIPTOCOUNTRYCODE'=> $order->delivery['country']['iso_code_2']);
  627. }
  628. // if these optional parameters are blank, remove them from transaction
  629. if (isset($optionsShip['SHIPTOSTREET2']) && trim($optionsShip['SHIPTOSTREET2']) == '') unset($optionsShip['SHIPTOSTREET2']);
  630. if (isset($optionsShip['SHIPTOPHONE']) && trim($optionsShip['SHIPTOPHONE']) == '') unset($optionsShip['SHIPTOPHONE']);
  631. // if State is not supplied, repeat the city so that it's not blank, otherwise PayPal croaks
  632. if (!isset($optionsShip['SHIPTOSTATE']) || trim($optionsShip['SHIPTOSTATE']) == '') $optionsShip['SHIPTOSTATE'] = $optionsShip['SHIPTOCITY'];
  633. // Payment Transaction/Authorization Mode
  634. $optionsNVP['PAYMENTACTION'] = (MODULE_PAYMENT_PAYPALWPP_TRANSACTION_MODE == 'Auth Only') ? 'Authorization' : 'Sale';
  635. // if (in_array($cc_type, array('Switch', 'Solo'))) {
  636. // $optionsNVP['PAYMENTACTION'] = 'Authorization';
  637. // }
  638. $optionsAll['BUTTONSOURCE'] = $this->buttonSourceDP;
  639. $optionsAll['CURRENCY'] = $my_currency;
  640. $optionsAll['IPADDRESS'] = $cc_owner_ip;
  641. if ($cc_issuedate_month && $cc_issuedate_year) {
  642. $optionsAll['CARDSTART'] = $cc_issuedate_month . substr($cc_issuedate_year, -2);
  643. }
  644. // unused at present:
  645. // $options['CUSTOM'] = '';
  646. // $options['INVNUM'] = '';
  647. // $options['DESC'] = '';
  648. $this->zcLog('before_process - DP-4', 'optionsAll: ' . print_r($optionsAll, true) . "\n" . 'optionsNVP: ' . print_r($optionsNVP, true) . "\n" . 'optionsShip' . print_r($optionsShip, true) . "\n" . 'Rest of data: ' . "\n" . number_format($order_amount, 2) . ' ' . $cc_expdate_month . ' ' . substr($cc_expdate_year, -2) . ' ' . $cc_first_name . ' ' . $cc_last_name . ' ' . $cc_type);
  649. $response = $doPayPal->DoDirectPayment(number_format($order_amount, 2),
  650. $cc_number,
  651. $cc_checkcode,
  652. $cc_expdate_month . substr($cc_expdate_year, -2),
  653. $cc_first_name, $cc_last_name,
  654. $cc_type,
  655. $optionsAll, array_merge($optionsNVP, $optionsShip));
  656. $this->zcLog('before_process - DP-5', 'resultset:' . "\n" . print_r($response, true));
  657. // CHECK RESPONSE
  658. $error = $this->_errorHandler($response, 'DoDirectPayment');
  659. $this->feeamt = '';
  660. $this->taxamt = '';
  661. $this->pendingreason = '';
  662. $this->reasoncode = '';
  663. $this->numitems = sizeof($order->products);
  664. $this->responsedata = $response;
  665. if ($response['PNREF']) {
  666. // PNREF only comes from payflow mode
  667. $this->payment_type = MODULE_PAYMENT_PAYPALWPP_PF_TEXT_TYPE;
  668. $this->transaction_id = $response['PNREF'];
  669. $this->payment_status = (MODULE_PAYMENT_PAYPALWPP_TRANSACTION_MODE == 'Auth Only') ? 'Authorization' : 'Completed';
  670. $this->avs = 'AVSADDR: ' . $response['AVSADDR'] . ', AVSZIP: ' . $response['AVSZIP'] . ', IAVS: ' . $response['IAVS'];
  671. $this->cvv2 = $response['CVV2MATCH'];
  672. $this->amt = $order_amount . ' ' . $my_currency;
  673. $this->payment_time = date('Y-m-d h:i:s');
  674. $this->responsedata['CURRENCYCODE'] = $my_currency;
  675. $this->responsedata['EXCHANGERATE'] = $order->info['currency_value'];
  676. $this->auth_code = $this->response['AUTHCODE'];
  677. } else {
  678. // here we're in NVP mode
  679. $this->transaction_id = $response['TRANSACTIONID'];
  680. $this->payment_type = MODULE_PAYMENT_PAYPALWPP_DP_TEXT_TYPE;
  681. $this->payment_status = (MODULE_PAYMENT_PAYPALWPP_TRANSACTION_MODE == 'Auth Only') ? 'Authorization' : 'Completed';
  682. $this->pendingreason = (MODULE_PAYMENT_PAYPALWPP_TRANSACTION_MODE == 'Auth Only') ? 'authorization' : '';
  683. $this->avs = $response['AVSCODE'];
  684. $this->cvv2 = $response['CVV2MATCH'];
  685. $this->correlationid = $response['CORRELATIONID'];
  686. $this->payment_time = urldecode($response['TIMESTAMP']);
  687. $this->amt = urldecode($response['AMT'] . ' ' . $response['CURRENCYCODE']);
  688. $this->auth_code = (isset($this->response['AUTHCODE'])) ? $this->response['AUTHCODE'] : $this->response['TOKEN'];
  689. $this->transactiontype = 'cart';
  690. }
  691. }
  692. }
  693. /**
  694. * When the order returns from the processor, this stores the results in order-status-history and logs data for subsequent use
  695. */
  696. function after_process() {
  697. global $insert_id, $db, $order;
  698. // add a new OSH record for this order's PP details
  699. $commentString = "Transaction ID: :transID: " .
  700. (isset($this->responsedata['PPREF']) ? "\nPPRef: " . $this->responsedata['PPREF'] : "") .
  701. (isset($this->responsedata['AUTHCODE'])? "\nAuthCode: " . $this->responsedata['AUTHCODE'] : "") .
  702. "\nPayment Type: :pmtType: " .
  703. "\nTimestamp: :pmtTime: " .
  704. "\nPayment Status: :pmtStatus: " .
  705. ($this->avs != 'N/A' ? "\nAVS Code: ".$this->avs."\nCVV2 Code: ".$this->cvv2 : '') .
  706. "\nAmount: :orderAmt: ";
  707. $commentString = $db->bindVars($commentString, ':transID:', $this->transaction_id, 'noquotestring');
  708. $commentString = $db->bindVars($commentString, ':pmtType:', $this->payment_type, 'noquotestring');
  709. $commentString = $db->bindVars($commentString, ':pmtTime:', $this->payment_time, 'noquotestring');
  710. $commentString = $db->bindVars($commentString, ':pmtStatus:', $this->payment_status, 'noquotestring');
  711. $commentString = $db->bindVars($commentString, ':orderAmt:', $this->amt, 'noquotestring');
  712. $sql_data_array= array(array('fieldName'=>'orders_id', 'value'=>$insert_id, 'type'=>'integer'),
  713. array('fieldName'=>'orders_status_id', 'value'=>$order->info['order_status'], 'type'=>'integer'),
  714. array('fieldName'=>'date_added', 'value'=>'now()', 'type'=>'noquotestring'),
  715. array('fieldName'=>'customer_notified', 'value'=>0, 'type'=>'integer'),
  716. array('fieldName'=>'comments', 'value'=>$commentString, 'type'=>'string'));
  717. $db->perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
  718. // store the PayPal order meta data -- used for later matching and back-end processing activities
  719. $paypal_order = array('order_id' => $insert_id,
  720. 'txn_type' => $this->transactiontype,
  721. 'module_name' => $this->code,
  722. 'module_mode' => MODULE_PAYMENT_PAYPALWPP_MODULE_MODE,
  723. 'reason_code' => $this->reasoncode,
  724. 'payment_type' => $this->payment_type,
  725. 'payment_status' => $this->payment_status,
  726. 'pending_reason' => $this->pendingreason,
  727. 'invoice' => urldecode($_SESSION['paypal_ec_token'] . $this->responsedata['PPREF']),
  728. 'first_name' => $_SESSION['paypal_ec_payer_info']['payer_firstname'],
  729. 'last_name' => $_SESSION['paypal_ec_payer_info']['payer_lastname'],
  730. 'payer_business_name' => $_SESSION['paypal_ec_payer_info']['payer_business'],
  731. 'address_name' => $_SESSION['paypal_ec_payer_info']['ship_name'],
  732. 'address_street' => $_SESSION['paypal_ec_payer_info']['ship_street_1'],
  733. 'address_city' => $_SESSION['paypal_ec_payer_info']['ship_city'],
  734. 'address_state' => $_SESSION['paypal_ec_payer_info']['ship_state'],
  735. 'address_zip' => $_SESSION['paypal_ec_payer_info']['ship_postal_code'],
  736. 'address_country' => $_SESSION['paypal_ec_payer_info']['ship_country'],
  737. 'address_status' => $_SESSION['paypal_ec_payer_info']['ship_address_status'],
  738. 'payer_email' => $_SESSION['paypal_ec_payer_info']['payer_email'],
  739. 'payer_id' => $_SESSION['paypal_ec_payer_id'],
  740. 'payer_status' => $_SESSION['paypal_ec_payer_info']['payer_status'],
  741. 'payment_date' => trim(preg_replace('/[^0-9-:]/', ' ', $this->payment_time)),
  742. 'business' => '',
  743. 'receiver_email' => (substr(MODULE_PAYMENT_PAYPALWPP_MODULE_MODE,0,7) == 'Payflow' ? MODULE_PAYMENT_PAYPALWPP_PFVENDOR : str_replace('_api1', '', MODULE_PAYMENT_PAYPALWPP_APIUSERNAME)),
  744. 'receiver_id' => '',
  745. 'txn_id' => $this->transaction_id,
  746. 'parent_txn_id' => '',
  747. 'num_cart_items' => (float)$this->numitems,
  748. 'mc_gross' => (float)$this->amt,
  749. 'mc_fee' => (float)urldecode($this->feeamt),
  750. 'mc_currency' => $this->responsedata['CURRENCYCODE'],
  751. 'settle_amount' => (float)urldecode($this->responsedata['SETTLEAMT']),
  752. 'settle_currency' => $this->responsedata['CURRENCYCODE'],
  753. 'exchange_rate' => (urldecode($this->responsedata['EXCHANGERATE']) > 0 ? urldecode($this->responsedata['EXCHANGERATE']) : 1.0),
  754. 'notify_version' => '0',
  755. 'verify_sign' =>'',
  756. 'date_added' => 'now()',
  757. 'memo' => '{Record generated by payment module}'
  758. );
  759. zen_db_perform(TABLE_PAYPAL, $paypal_order);
  760. // Unregister the paypal session variables, making it necessary to start again for another purchase
  761. unset($_SESSION['paypal_ec_temp']);
  762. unset($_SESSION['paypal_ec_token']);
  763. unset($_SESSION['paypal_ec_payer_id']);
  764. unset($_SESSION['paypal_ec_payer_info']);
  765. unset($_SESSION['paypal_ec_final']);
  766. unset($_SESSION['paypal_ec_markflow']);
  767. }
  768. /**
  769. * Build admin-page components
  770. *
  771. * @param int $zf_order_id
  772. * @return string
  773. */
  774. function admin_notification($zf_order_id) {
  775. global $db;
  776. $module = $this->code;
  777. $output = '';
  778. $response = $this->_GetTransactionDetails($zf_order_id);
  779. //$response = $this->_TransactionSearch('2006-12-01T00:00:00Z', $zf_order_id);
  780. $sql = "SELECT * from " . TABLE_PAYPAL . " WHERE order_id = :orderID
  781. AND parent_txn_id = '' AND order_id > 0
  782. ORDER BY paypal_ipn_id DESC LIMIT 1";
  783. $sql = $db->bindVars($sql, ':orderID', $zf_order_id, 'integer');
  784. $ipn = $db->Execute($sql);
  785. if ($ipn->RecordCount() == 0) $ipn->fields = array();
  786. if (file_exists(DIR_FS_CATALOG . DIR_WS_MODULES . 'payment/paypal/paypalwpp_admin_notification.php')) require(DIR_FS_CATALOG . DIR_WS_MODULES . 'payment/paypal/paypalwpp_admin_notification.php');
  787. return $output;
  788. }
  789. /**
  790. * Used to read details of an existing transaction. FOR FUTURE USE.
  791. */
  792. function _GetTransactionDetails($oID) {
  793. global $db, $messageStack, $doPayPal;
  794. $doPayPal = $this->paypal_init();
  795. // look up history on this order from PayPal table
  796. $sql = "select * from " . TABLE_PAYPAL . " where order_id = :orderID AND parent_txn_id = '' ";
  797. $sql = $db->bindVars($sql, ':orderID', $oID, 'integer');
  798. $zc_ppHist = $db->Execute($sql);
  799. if ($zc_ppHist->RecordCount() == 0) return false;
  800. $txnID = $zc_ppHist->fields['txn_id'];
  801. /**
  802. * Read data from PayPal
  803. */
  804. $response = $doPayPal->GetTransactionDetails($txnID);
  805. $error = $this->_errorHandler($response, 'GetTransactionDetails', 10007);
  806. if ($error === false) {
  807. return false;
  808. } else {
  809. return $response;
  810. }
  811. }
  812. /**
  813. * Used to read details of existing transactions. FOR FUTURE USE.
  814. */
  815. function _TransactionSearch($startDate = '', $oID = '', $criteria = '') {
  816. global $db, $messageStack, $doPayPal;
  817. $doPayPal = $this->paypal_init();
  818. // look up history on this order from PayPal table
  819. $sql = "select * from " . TABLE_PAYPAL . " where order_id = :orderID AND parent_txn_id = '' ";
  820. $sql = $db->bindVars($sql, ':orderID', $oID, 'integer');
  821. $zc_ppHist = $db->Execute($sql);
  822. if ($zc_ppHist->RecordCount() == 0) return false;
  823. $txnID = $zc_ppHist->fields['txn_id'];
  824. $startDate = $zc_ppHist->fields['payment_date'];
  825. $timeval = time();
  826. if ($startDate == '') $startDate = date('Y-m-d', $timeval) . 'T' . date('h:i:s', $timeval) . 'Z';
  827. /**
  828. * Read data from PayPal
  829. */
  830. $response = $doPayPal->TransactionSearch($startDate, $txnID, $email, $criteria);
  831. $error = $this->_errorHandler($response, 'TransactionSearch');
  832. if ($error === false) {
  833. return false;
  834. } else {
  835. return $response;
  836. }
  837. }
  838. /**
  839. * Display appropriate error message when needed
  840. */
  841. function get_error() {
  842. include_once(zen_get_file_directory(DIR_FS_CATALOG . DIR_WS_LANGUAGES . $_SESSION['language'] . '/modules/payment/', 'paypalwpp.php', 'false'));
  843. $error = array('title' => MODULE_PAYMENT_PAYPALWPP_ERROR_HEADING,
  844. 'error' => ((isset($_GET['error'])) ? stripslashes(urldecode($_GET['error'])) : MODULE_PAYMENT_PAYPALWPP_TEXT_CARD_ERROR));
  845. return $error;
  846. }
  847. /**
  848. * Evaluate installation status of this module. Returns true if the status key is found.
  849. */
  850. function check() {
  851. global $db;
  852. if (!isset($this->_check)) {
  853. $check_query = $db->Execute("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_PAYPALWPP_STATUS'");
  854. $this->_check = !$check_query->EOF;
  855. }
  856. return $this->_check;
  857. }
  858. /**
  859. * Installs all the configuration keys for this module
  860. */
  861. function install() {
  862. global $db;
  863. $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable this Payment Module', 'MODULE_PAYMENT_PAYPALWPP_STATUS', 'True', 'Do you want to enable this payment module?', '6', '25', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");
  864. $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Direct Payment', 'MODULE_PAYMENT_PAYPALWPP_DIRECT_ENABLED', 'False', 'Would you like to enable credit card payments through PayPal DIRECTLY on your website? <br />(<strong…

Large files files are truncated, but you can click here to view the full file