Zen Cart PHP Cross Reference Customer Relationship Management

Source: /ipn_main_handler.php - 479 lines - 26143 bytes - Summary - Text - Print

Description: ipn_main_handler.php callback handler for PayPal IPN notifications

   1  <?php
   2  /**
   3   * ipn_main_handler.php callback handler for PayPal IPN notifications
   4   *
   5   * @package paymentMethod
   6   * @copyright Copyright 2003-2012 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 GIT: $Id: Author: DrByte  Tue Aug 28 16:48:39 2012 -0400 Modified in v1.5.1 $
  10   */
  11  if (!defined('TEXT_RESELECT_SHIPPING')) define('TEXT_RESELECT_SHIPPING', 'You have changed the items in your cart since shipping was last calculated, and costs may have changed. Please verify/re-select your shipping method.');
  12  
  13  /**
  14   * handle Express Checkout processing:
  15   */
  16  if (isset($_GET['type']) && $_GET['type'] == 'ec') {
  17    // this is an EC handler request
  18    require ('includes/application_top.php');
  19  
  20  // Validate Cart for checkout
  21    $_SESSION['valid_to_checkout'] = true;
  22    $_SESSION['cart']->get_products(true);
  23    if ($_SESSION['valid_to_checkout'] == false || $_SESSION['cart']->count_contents() <= 0) {
  24      $messageStack->add_session('shopping_cart', ERROR_CART_UPDATE, 'error');
  25      zen_redirect(zen_href_link(FILENAME_SHOPPING_CART));
  26    }
  27  
  28    // Stock Check to prevent checkout if cart contents rules violations exist
  29    if ( STOCK_CHECK == 'true' && STOCK_ALLOW_CHECKOUT != 'true' && isset($_SESSION['cart']) ) {
  30      $products = $_SESSION['cart']->get_products();
  31      for ($i=0, $n=sizeof($products); $i<$n; $i++) {
  32        if (zen_check_stock($products[$i]['id'], $products[$i]['quantity'])) {
  33          zen_redirect(zen_href_link(FILENAME_SHOPPING_CART));
  34          break;
  35        }
  36      }
  37    }
  38    // if cart contents has changed since last pass, reset
  39    if (isset($_SESSION['cart']->cartID)) {
  40      if (isset($_SESSION['cartID'])) {  // This will only be set if customer has been to the checkout_shipping page. Will *not* be set if starting via EC Shortcut button, so don't want to redirect in that case.
  41        if ($_SESSION['cart']->cartID != $_SESSION['cartID']) {
  42          if (isset($_SESSION['shipping'])) {
  43            unset($_SESSION['shipping']);
  44            $messageStack->add_session('checkout_shipping', TEXT_RESELECT_SHIPPING, 'error');
  45            zen_redirect(zen_href_link(FILENAME_CHECKOUT_SHIPPING, '', 'SSL'));
  46          }
  47        }
  48      }
  49  //  } else {
  50  //    zen_redirect(zen_href_link(FILENAME_TIME_OUT));
  51    }
  52  
  53    require(DIR_WS_CLASSES . 'payment.php');
  54    // See if we were sent a request to clear the session for PayPal.
  55    if (isset($_GET['clearSess']) || isset($_GET['amp;clearSess']) || isset($_GET['ec_cancel']) || isset($_GET['amp;ec_cancel'])) {
  56      // Unset the PayPal EC information.
  57      unset($_SESSION['paypal_ec_temp']);
  58      unset($_SESSION['paypal_ec_token']);
  59      unset($_SESSION['paypal_ec_payer_id']);
  60      unset($_SESSION['paypal_ec_payer_info']);
  61    }
  62    // See if the paypalwpp module is enabled.
  63    if (defined('MODULE_PAYMENT_PAYPALWPP_STATUS') && MODULE_PAYMENT_PAYPALWPP_STATUS == 'True') {
  64      $paypalwpp_module = 'paypalwpp';
  65      // init the payment object
  66      $payment_modules = new payment($paypalwpp_module);
  67      // set the payment, if they're hitting us here then we know
  68      // the payment method selected right now.
  69      $_SESSION['payment'] = $paypalwpp_module;
  70      // check to see if we have a token sent back from PayPal.
  71      if (!isset($_SESSION['paypal_ec_token']) || empty($_SESSION['paypal_ec_token'])) {
  72        // We have not gone to PayPal's website yet in order to grab
  73        // a token at this time.  This will send the customer over to PayPal's
  74        // website to login and return a token
  75        $$paypalwpp_module->ec_step1();
  76      } else {
  77        // This will push on the second step of the paypal ec payment
  78        // module, as we already have a PayPal express checkout token
  79        // at this point.
  80        $$paypalwpp_module->ec_step2();
  81      }
  82    }
  83  ?>
  84  <html>
  85  Processing...
  86  </html>
  87    <?php
  88  
  89    /**
  90     * If we got here, we are an IPN transaction (not Express Checkout):
  91     */
  92  
  93  } else {
  94    /**
  95     * detect odd cases of extra-url-encoded POST data coming back from PayPal
  96     */
  97    foreach(array('receiver_email', 'payer_email', 'business', 'txn_type', 'transaction_subject', 'custom', 'payment_date', 'item_number', 'item_name', 'first_name', 'last_name') as $key) {
  98      if (isset($_POST[$key]) && strstr($_POST[$key], '%')) {
  99        $_POST[$key] = urldecode($_POST[$key]);
 100      }
 101    }
 102    /**
 103     * detect type of transaction
 104     */
 105    $isECtransaction = ((isset($_POST['txn_type']) && $_POST['txn_type']=='express_checkout') || (isset($_POST['custom']) && in_array(substr($_POST['custom'], 0, 3), array('EC-', 'DP-', 'WPP')))); /*|| $_POST['txn_type']=='cart'*/
 106    $isDPtransaction = (isset($_POST['custom']) && in_array(substr($_POST['custom'], 0, 3), array('DP-', 'WPP')));
 107    /**
 108     * set paypal-specific application_top parameters
 109     */
 110    $current_page_base = 'paypalipn';
 111    $loaderPrefix = 'paypal_ipn';
 112    $show_all_errors = FALSE;
 113    require ('includes/application_top.php');
 114  
 115    $extraDebug = (defined('IPN_EXTRA_DEBUG_DETAILS') && IPN_EXTRA_DEBUG_DETAILS == 'All');
 116  
 117    if (  (defined('MODULE_PAYMENT_PAYPALWPP_DEBUGGING') && strstr(MODULE_PAYMENT_PAYPALWPP_DEBUGGING, 'Log')) ||
 118        (defined('MODULE_PAYMENT_PAYPAL_IPN_DEBUG') && strstr(MODULE_PAYMENT_PAYPAL_IPN_DEBUG, 'Log')) ||
 119        ($_REQUEST['ppdebug'] == 'on' && strstr(EXCLUDE_ADMIN_IP_FOR_MAINTENANCE, $_SERVER['REMOTE_ADDR'])) || $extraDebug  ) {
 120      $show_all_errors = true;
 121      $debug_logfile_path = ipn_debug_email('Breakpoint: 0 - Initializing debugging.');
 122      $logdir = defined('DIR_FS_LOGS') ? DIR_FS_LOGS : 'includes/modules/payment/paypal/logs';
 123      if ($debug_logfile_path == '') $debug_logfile_path = $logdir . '/ipn_debug_php_errors-'.time().'.log';
 124      @ini_set('log_errors', 1);
 125      @ini_set('log_errors_max_len', 0);
 126      @ini_set('display_errors', 0); // do not output errors to screen/browser/client (only to log file)
 127      @ini_set('error_log', DIR_FS_CATALOG . $debug_logfile_path);
 128      error_reporting(version_compare(PHP_VERSION, 5.3, '>=') ? E_ALL & ~E_DEPRECATED & ~E_NOTICE : version_compare(PHP_VERSION, 5.4, '>=') ? E_ALL & ~E_DEPRECATED & ~E_NOTICE & ~E_STRICT : E_ALL & ~E_NOTICE);
 129    }
 130  
 131    ipn_debug_email('Breakpoint: Flag Status:' . "\nisECtransaction = " . (int)$isECtransaction . "\nisDPtransaction = " . (int)$isDPtransaction);
 132    /**
 133     * do confirmation post-back to PayPal and extract the results for subsequent use
 134     */
 135    $info  = ipn_postback();
 136    $new_status = 1;
 137    ipn_debug_email('Breakpoint: 1 - Collected data from PayPal notification');
 138  
 139    /**
 140     * validate transaction -- email address, matching txn record, etc
 141     */
 142    if (!ipn_validate_transaction($info, $_POST, 'IPN') === true) {
 143      if (!$isECtransaction && $_POST['txn_type'] != '') {
 144        ipn_debug_email('IPN FATAL ERROR :: Transaction did not validate. ABORTED.');
 145        die();
 146      }
 147    }
 148  
 149    if ($isDPtransaction) {
 150      ipn_debug_email('IPN NOTICE :: This is a Website Payments Pro transaction.  The rest of this log file is INFORMATION ONLY, and is not used for real processing.');
 151    }
 152  
 153    ipn_debug_email('Breakpoint: 2 - Validated transaction components');
 154    if ($_POST ['exchange_rate'] == '')  $_POST [exchange_rate] = 1;
 155    if ($_POST ['num_cart_items'] == '') $_POST [num_cart_items] = 1;
 156    if ($_POST ['settle_amount'] == '')  $_POST [settle_amount] = 0;
 157  
 158    /**
 159     * is this a sandbox transaction?
 160     */
 161    if (isset($_POST['test_ipn']) && $_POST['test_ipn'] == 1) {
 162      ipn_debug_email('IPN NOTICE :: Processing SANDBOX transaction.');
 163    }
 164    if (isset($_POST['test_internal']) && $_POST['test_internal'] == 1) {
 165      ipn_debug_email('IPN NOTICE :: Processing INTERNAL TESTING transaction.');
 166    }
 167    if (isset($_POST['pending_reason']) && $_POST['pending_reason'] == 'unilateral') {
 168      ipn_debug_email('*** NOTE: TRANSACTION IS IN *unilateral* STATUS, pending creation of a PayPal account for this receiver_email address.' . "\n" . 'Please create the account, or make sure the PayPal account is *Verified*.');
 169    }
 170  
 171    ipn_debug_email('Breakpoint: 3 - Communication method verified');
 172    /**
 173     * Lookup transaction history information in preparation for matching and relevant updates
 174     */
 175    $lookupData  = ipn_lookup_transaction($_POST);
 176    $ordersID    = $lookupData['order_id'];
 177    $paypalipnID = $lookupData['paypal_ipn_id'];
 178    $txn_type    = $lookupData['txn_type'];
 179    $parentLookup = $txn_type;
 180  
 181    ipn_debug_email('Breakpoint: 4 - ' . 'Details:  txn_type=' . $txn_type . '    ordersID = '. $ordersID . '  IPN_id=' . $paypalipnID . "\n\n" . '   Relevant data from POST:' . "\n     " . 'txn_type = ' . $txn_type . "\n     " . 'parent_txn_id = ' . ($_POST['parent_txn_id'] =='' ? 'None' : $_POST['parent_txn_id']) . "\n     " . 'txn_id = ' . $_POST['txn_id']);
 182  
 183    if (!$isECtransaction && !isset($_POST['parent_txn_id']) && $txn_type != 'cleared-echeck') {
 184      if (defined('MODULE_PAYMENT_PAYPAL_PDTTOKEN') && MODULE_PAYMENT_PAYPAL_PDTTOKEN != '') {
 185        ipn_debug_email('IPN NOTICE :: IPN pausing: waiting for PDT to process. Sleeping 10 seconds ...');
 186        sleep(10);
 187      }
 188      if (ipn_get_stored_session($session_stuff) === false) {
 189        ipn_debug_email('IPN ERROR :: No pending Website Payments Standard session data available.  Might be a duplicate transaction already entered via PDT.');
 190        $ipnFoundSession = false;
 191      }
 192    }
 193  
 194    if ($ipnFoundSession == FALSE && !$isECtransaction && !$isDPtransaction && $txn_type != 'cleared-echeck') {
 195      ipn_debug_email('NOTICE: IPN Processing Aborted due to missing matching transaction data, as per earlier debug message. Perhaps this transaction was already entered via PDT? Thus there is no need to process this incoming IPN notification.');
 196      die();
 197    }
 198  
 199    // this is used to determine whether a record needs insertion. ie: original echeck notice failed, but now we have cleared, so need parent record established:
 200    $new_record_needed = ($txn_type == 'unique' ? true : false);
 201    /**
 202     * evaluate what type of transaction we're processing
 203     */
 204    $txn_type = ipn_determine_txn_type($_POST, $txn_type);
 205    ipn_debug_email('Breakpoint: 5 - Transaction type (txn_type) = ' . $txn_type . '   [parentLookup='.$parentLookup.']');
 206  
 207    if ($_POST['payment_type'] == 'instant' && $isDPtransaction && ((isset($_POST['auth_status']) && $_POST['auth_status'] == 'Completed') || $_POST['payment_status'] == 'Completed')) {
 208      ipn_debug_email('IPN NOTICE :: DP/Website Payments Pro notice -- IPN Ignored');
 209      die();
 210    }
 211  
 212    /**
 213     * take action based on transaction type and corresponding requirements
 214     */
 215    switch ($txn_type) {
 216      case ($_POST['txn_type'] == 'send_money'):
 217      case ($_POST['txn_type'] == 'merch_payment'):
 218      case ($_POST['txn_type'] == 'new_case'):
 219      case ($_POST['txn_type'] == 'masspay'):
 220        // these types are irrelevant to ZC transactions
 221        ipn_debug_email('IPN NOTICE :: Transaction txn_type not relevant to Zen Cart processing. IPN handler aborted.' . $_POST['txn_type']);
 222        die();
 223        break;
 224      case (substr($_POST['txn_type'],0,7) == 'subscr_'):
 225        // For now we filter out subscription payments
 226        ipn_debug_email('IPN NOTICE :: Subscription payment - Not currently supported by Zen Cart. IPN handler aborted.');
 227        die();
 228        break;
 229  
 230      case 'pending-unilateral':
 231        // cannot process this order because the merchant's PayPal account isn't valid yet
 232        ipn_debug_email('IPN NOTICE :: Please create a valid PayPal account and follow the steps to *Verify* it. IPN handler aborted.');
 233        die();
 234        break;
 235      case 'pending-address':
 236      case 'pending-intl':
 237      case 'pending-multicurrency':
 238      case 'pending-verify':
 239        if (!$isECtransaction) {
 240          ipn_debug_email('IPN NOTICE :: '.$txn_type.' transaction -- inserting initial record for reference purposes');
 241          $sql_data_array = ipn_create_order_array($ordersID, $txn_type);
 242          zen_db_perform(TABLE_PAYPAL, $sql_data_array);
 243          $sql_data_array = ipn_create_order_history_array($paypalipnID);
 244          zen_db_perform(TABLE_PAYPAL_PAYMENT_STATUS_HISTORY, $sql_data_array);
 245          die();
 246          break;
 247        }
 248      case (($txn_type == 'express_checkout' || $isECtransaction) && !strstr($txn_type, 'cleared') && $parentLookup != 'parent'):
 249        if ($_POST['payment_status'] == 'Completed') {
 250          // This is an express-checkout transaction -- IPN may not be needed
 251          if (isset($_POST['auth_status']) && $_POST['auth_status'] == 'Completed') {
 252            ipn_debug_email('IPN NOTICE :: Express Checkout payment notice on completed order -- IPN Ignored');
 253            die();
 254          }
 255        }
 256        if ($_POST['payment_type'] == 'instant' && isset($_POST['auth_status']) && $_POST['auth_status'] == 'Pending') {
 257          ipn_debug_email('IPN NOTICE :: EC/DP notice on pre-auth order -- IPN Ignored');
 258          die();
 259        }
 260        ipn_debug_email('Breakpoint: 5 - midstream checkpoint');
 261        if (!(substr($txn_type,0,8) == 'pending-' && (int)$ordersID <= 0) && !($new_record_needed && $txn_type == 'echeck-cleared') && $txn_type != 'unique' && $txn_type != 'echeck-denied' && $txn_type != 'voided') {
 262          ipn_debug_email('Breakpoint: 5 - Record does not need to be processed since it is not new and is not an update. See earlier notices. Processing aborted.');
 263          break;
 264        }
 265  
 266      case ($txn_type == 'cart'):
 267        ipn_debug_email('IPN NOTICE :: This is a detailed-cart transaction');
 268  
 269      case ($txn_type == 'cart' && !$isECtransaction):
 270        ipn_debug_email('IPN NOTICE :: This is a detailed-cart transaction (i)');
 271  
 272      case (substr($txn_type,0,8) == 'pending-' && (int)$ordersID <= 0):
 273      case ($new_record_needed && $txn_type == 'echeck-cleared'):
 274      case 'unique':
 275        /**
 276         * delete IPN session from PayPal table -- housekeeping
 277         */
 278        $db->Execute("delete from " . TABLE_PAYPAL_SESSION . " where session_id = '" . zen_db_input(str_replace('zenid=', '', $_POST['custom'])) . "'");
 279        /**
 280         * require shipping class
 281         */
 282        require(DIR_WS_CLASSES . 'shipping.php');
 283        /**
 284         * require payment class
 285         */
 286        require(DIR_WS_CLASSES . 'payment.php');
 287        $payment_modules = new payment($_SESSION['payment']);
 288        $shipping_modules = new shipping($_SESSION['shipping']);
 289        /**
 290         * require order class
 291         */
 292        require(DIR_WS_CLASSES . 'order.php');
 293        $order = new order;
 294        /**
 295         * require order_total class
 296         */
 297        require(DIR_WS_CLASSES . 'order_total.php');
 298        $order_total_modules = new order_total();
 299        $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_BEFORE_ORDER_TOTALS_PROCESS');
 300        $order_totals = $order_total_modules->process();
 301        $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_TOTALS_PROCESS');
 302  
 303        if (valid_payment($order->info['total'], $_SESSION['currency']) === false && !$isECtransaction && !$isDPtransaction) {
 304          ipn_debug_email('IPN NOTICE :: Failed because of currency mismatch.');
 305          die();
 306        }
 307        if ($ipnFoundSession === false && !$isECtransaction && !$isDPtransaction) {
 308          ipn_debug_email('IPN NOTICE :: Unique but no session - Assumed to be a personal payment, rather than a new Website Payments Standard transaction. Ignoring.');
 309          die();
 310        }
 311        if (!strstr($txn_type, 'denied') && !strstr($txn_type, 'failed') && !strstr($txn_type, 'voided')) {
 312          $insert_id = $order->create($order_totals);
 313          $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_CREATE');
 314          ipn_debug_email('Breakpoint: 5a - built order -- OID: ' . $insert_id);
 315          $sql_data_array = ipn_create_order_array($insert_id, $txn_type);
 316          ipn_debug_email('Breakpoint: 5b - PP table OID: ' . print_r($sql_data_array, true));
 317          zen_db_perform(TABLE_PAYPAL, $sql_data_array);
 318          ipn_debug_email('Breakpoint: 5c - PP table OID saved');
 319          $pp_hist_id = $db->Insert_ID();
 320          $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_PAYMENT_MODULES_AFTER_ORDER_CREATE');
 321          ipn_debug_email('Breakpoint: 5d - PP hist ID: ' . $pp_hist_id);
 322          $sql_data_array = ipn_create_order_history_array($pp_hist_id);
 323          ipn_debug_email('Breakpoint: 5e - PP hist_data:' . print_r($sql_data_array, true));
 324          zen_db_perform(TABLE_PAYPAL_PAYMENT_STATUS_HISTORY, $sql_data_array);
 325          ipn_debug_email('Breakpoint: 5f - PP hist saved');
 326          $new_status = MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID;
 327          ipn_debug_email('Breakpoint: 5g - new status code: ' . $new_status);
 328          if ($_POST['payment_status'] =='Pending') {
 329            $new_status = (defined('MODULE_PAYMENT_PAYPAL_PROCESSING_STATUS_ID') && (int)MODULE_PAYMENT_PAYPAL_PROCESSING_STATUS_ID > 0 ? (int)MODULE_PAYMENT_PAYPAL_PROCESSING_STATUS_ID : 2);
 330            ipn_debug_email('Breakpoint: 5h - newer status code: ' . (int)$new_status);
 331            $sql = "UPDATE " . TABLE_ORDERS  . "
 332                    SET orders_status = " . (int)$new_status . "
 333                    WHERE orders_id = '" . (int)$insert_id . "'";
 334            $db->Execute($sql);
 335            ipn_debug_email('Breakpoint: 5i - order table updated');
 336          }
 337          $sql_data_array = array('orders_id' => (int)$insert_id,
 338                                  'orders_status_id' => (int)$new_status,
 339                                  'date_added' => 'now()',
 340                                  'comments' => 'PayPal status: ' . $_POST['payment_status'] . ' ' . $_POST['pending_reason']. ' @ '.$_POST['payment_date'] . (($_POST['parent_txn_id'] !='') ? "\n" . ' Parent Trans ID:' . $_POST['parent_txn_id'] : '') . "\n" . ' Trans ID:' . $_POST['txn_id'] . "\n" . ' Amount: ' . $_POST['mc_gross'] . ' ' . $_POST['mc_currency'],
 341                                  'customer_notified' => 0
 342                                  );
 343          ipn_debug_email('Breakpoint: 5j - order stat hist update:' . print_r($sql_data_array, true));
 344          zen_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
 345          if (MODULE_PAYMENT_PAYPAL_ADDRESS_OVERRIDE == '1') {
 346            $sql_data_array['comments'] = '**** ADDRESS OVERRIDE ALERT!!! **** CHECK PAYPAL ORDER DETAILS FOR ACTUAL ADDRESS SELECTED BY CUSTOMER!!';
 347            $sql_data_array['customer_notified'] = -1;
 348            zen_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
 349          }
 350          ipn_debug_email('Breakpoint: 5k - OSH update done');
 351          $order->create_add_products($insert_id, 2);
 352          ipn_debug_email('Breakpoint: 5L - adding products');
 353          $_SESSION['order_number_created'] = $insert_id;
 354          $GLOBALS[$_SESSION['payment']]->transaction_id = $_POST['txn_id'];
 355          $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_CREATE_ADD_PRODUCTS');
 356          $order->send_order_email($insert_id, 2);
 357          ipn_debug_email('Breakpoint: 5m - emailing customer');
 358          $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_SEND_ORDER_EMAIL');
 359          /** Prepare sales-tracking data for use by notifier class **/
 360          $ototal = $order_subtotal = $credits_applied = 0;
 361          for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {
 362            if ($order_totals[$i]['code'] == 'ot_subtotal') $order_subtotal = $order_totals[$i]['value'];
 363            if ($$order_totals[$i]['code']->credit_class == true) $credits_applied += $order_totals[$i]['value'];
 364            if ($order_totals[$i]['code'] == 'ot_total') $ototal = $order_totals[$i]['value'];
 365          }
 366          $commissionable_order = ($order_subtotal - $credits_applied);
 367          $commissionable_order_formatted = $currencies->format($commissionable_order);
 368          $_SESSION['order_summary']['order_number'] = $insert_id;
 369          $_SESSION['order_summary']['order_subtotal'] = $order_subtotal;
 370          $_SESSION['order_summary']['credits_applied'] = $credits_applied;
 371          $_SESSION['order_summary']['order_total'] = $ototal;
 372          $_SESSION['order_summary']['commissionable_order'] = $commissionable_order;
 373          $_SESSION['order_summary']['commissionable_order_formatted'] = $commissionable_order_formatted;
 374          $_SESSION['order_summary']['coupon_code'] = $order->info['coupon_code'];
 375          $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES', 'paypalipn');
 376          $_SESSION['cart']->reset(true);
 377          ipn_debug_email('Breakpoint: 5n - emptying cart');
 378          $ordersID = $insert_id;
 379          $paypalipnID = $pp_hist_id;
 380          ipn_debug_email('Breakpoint: 6 - Completed IPN order add.' . '    ordersID = '. $ordersID . '  IPN tracking record = ' . $paypalipnID);
 381          if (!($new_record_needed && $txn_type == 'echeck-cleared'))  break;
 382        }
 383      case 'parent':
 384      case 'cleared-address':
 385      case 'cleared-multicurrency':
 386      case 'cleared-echeck':
 387      case 'cleared-authorization':
 388      case 'cleared-verify':
 389      case 'cleared-intl':
 390      case 'cleared-review':
 391      case 'echeck-denied':
 392      case 'echeck-cleared':
 393      case 'denied-address':
 394      case 'denied-multicurrency':
 395      case 'denied-echeck':
 396      case 'failed-echeck':
 397      case 'denied-intl':
 398      case 'denied':
 399      case 'voided':
 400      case 'express-checkout-cleared':
 401        ipn_debug_email('IPN NOTICE :: Storing order/update details for order #' . $ordersID . ' txn_id: ' . $_POST['txn_id'] . ' PP IPN ID: ' . $paypalipnID);
 402        if ($txn_type == 'parent') {
 403          $sql_data_array = ipn_create_order_array($ordersID, $txn_type);
 404          zen_db_perform(TABLE_PAYPAL, $sql_data_array);
 405          $paypalipnID = $db->Insert_ID();
 406        } else {
 407          $sql_data_array = ipn_create_order_update_array($txn_type);
 408          zen_db_perform(TABLE_PAYPAL, $sql_data_array, 'update', "txn_id='" . ($txn_type == 'cleared-authorization' ? $_POST['parent_txn_id'] : $_POST['txn_id']) . "'");
 409          $sql = "select paypal_ipn_id from " . TABLE_PAYPAL . " where txn_id=:txn:";
 410          $sql = $db->bindVars($sql, ':txn:', $_POST['txn_id'], 'string');
 411          $result = $db->Execute($sql);
 412          $paypalipnID = $result->fields['paypal_ipn_id'];
 413        }
 414        $sql_data_array = ipn_create_order_history_array($paypalipnID);
 415        zen_db_perform(TABLE_PAYPAL_PAYMENT_STATUS_HISTORY, $sql_data_array);
 416        ipn_debug_email('IPN NOTICE :: Added PP status-history record for order #' . $ordersID . ' txn_id: ' . $_POST['txn_id'] . ' (updated/child) PP IPN ID: ' . $paypalipnID);
 417  
 418        switch ($txn_type) {
 419          case 'voided':
 420          case ($_POST['payment_status'] == 'Refunded' || $_POST['payment_status'] == 'Reversed' || $_POST['payment_status'] == 'Voided'):
 421            //payment_status=Refunded or payment_status=Voided
 422            $new_status = MODULE_PAYMENT_PAYPALWPP_REFUNDED_STATUS_ID;
 423            if (defined('MODULE_PAYMENT_PAYPAL_REFUND_ORDER_STATUS_ID') && (int)MODULE_PAYMENT_PAYPAL_REFUND_ORDER_STATUS_ID > 0 && !$isECtransaction) $new_status = MODULE_PAYMENT_PAYPAL_REFUND_ORDER_STATUS_ID;
 424            break;
 425          case 'echeck-denied':
 426          case 'denied-echeck':
 427          case 'failed-echeck':
 428            //payment_status=Denied or failed
 429            $new_status = ($isECtransaction ? MODULE_PAYMENT_PAYPALWPP_REFUNDED_STATUS_ID : MODULE_PAYMENT_PAYPAL_REFUND_ORDER_STATUS_ID);
 430            break;
 431          case 'echeck-cleared':
 432            $new_status = (defined('MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID') ? MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID : 2);
 433            break;
 434          case ($txn_type=='express-checkout-cleared' || substr($txn_type,0,8) == 'cleared-'):
 435            //express-checkout-cleared
 436            $new_status = ($isECtransaction && defined('MODULE_PAYMENT_PAYPALWPP_ORDER_STATUS_ID') ? MODULE_PAYMENT_PAYPALWPP_ORDER_STATUS_ID : MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID);
 437            if ((int)$new_status == 0) $new_status = 2;
 438            break;
 439          case 'pending-auth':
 440            // pending authorization
 441            $new_status = ($isECtransaction ? MODULE_PAYMENT_PAYPALWPP_REFUNDED_STATUS_ID : MODULE_PAYMENT_PAYPAL_REFUND_ORDER_STATUS_ID);
 442            break;
 443          case (substr($txn_type,0,7) == 'denied-'):
 444            // denied for any other reason - treat as pending for now
 445          case (substr($txn_type,0,8) == 'pending-'):
 446            // pending anything
 447            $new_status = ($isECtransaction ? MODULE_PAYMENT_PAYPALWPP_ORDER_PENDING_STATUS_ID : MODULE_PAYMENT_PAYPAL_PROCESSING_STATUS_ID);
 448            break;
 449        }
 450        // update order status history with new information
 451        ipn_debug_email('IPN NOTICE :: Set new status ' . $new_status . " for order ID = " .  $ordersID . ($_POST['pending_reason'] != '' ? '.   Reason_code = ' . $_POST['pending_reason'] : '') );
 452        if ((int)$new_status == 0) $new_status = 1;
 453        if (in_array($_POST['payment_status'], array('Refunded', 'Reversed', 'Denied', 'Failed'))
 454             || substr($txn_type,0,8) == 'cleared-' || $txn_type=='echeck-cleared' || $txn_type == 'express-checkout-cleared') {
 455          ipn_update_orders_status_and_history($ordersID, $new_status, $txn_type);
 456          $zco_notifier->notify('NOTIFY_PAYPALIPN_STATUS_HISTORY_UPDATE', array($ordersID, $new_status, $txn_type));
 457        }
 458        break;
 459      default:
 460        // can't understand result found. Thus, logging and aborting.
 461        ipn_debug_email('IPN WARNING :: Could not process for txn type: ' . $txn_type . "\n" . ' postdata=' . str_replace('&', " \n&", urldecode(print_r($_POST, TRUE))));
 462    }
 463    // debug info only
 464    switch (TRUE) {
 465      case ($txn_type == 'pending-echeck' && (int)$ordersID > 0):
 466        ipn_debug_email('IPN NOTICE :: Pending echeck transaction for existing order. No action required. Waiting for echeck to clear.');
 467        break;
 468      case ($txn_type == 'pending-multicurrency' && (int)$ordersID > 0):
 469        ipn_debug_email('IPN NOTICE :: Pending multicurrency transaction for existing order. No action required. Waiting for merchant to "accept" the order via PayPal account console.');
 470        break;
 471      case ($txn_type == 'pending-address' && (int)$ordersID > 0):
 472        ipn_debug_email('IPN NOTICE :: "Pending address" transaction for existing order. No action required. Waiting for address approval by store owner via PayPal account console.');
 473        break;
 474      case ($txn_type == 'pending-paymentreview' && (int)$ordersID > 0):
 475        ipn_debug_email('IPN NOTICE :: "Pending payment review" transaction for existing order. No action required. Waiting for PayPal to complete their Payment Review. Do not ship order until review is completed.');
 476        break;
 477    }
 478  }
 479  

title

Description

title

Description

title

Description

title

title

Body