当前位置: 代码迷 >> PHP >> Zencart先生成订单后付款,相仿淘宝后台修改订单价格
  详细解决方案

Zencart先生成订单后付款,相仿淘宝后台修改订单价格

热度:111   发布时间:2016-04-28 17:12:00.0
Zencart先生成订单后付款,类似淘宝后台修改订单价格

Zencart 使用 Paypal 付款,会出现漏单的情况,即 paypal 已经收到客户的付款,但是网站后台没有客户的订单。导致 paypal 漏单的原因大致会是当客户跳转到Paypal 网站付款完毕之后,直接关闭了窗口,或者网络不稳定,没有正常跳转到网站。

解决 Paypal 漏单问题的方案有好几种:

 

一. 开启 Detailed Line Items in Cart 选项。

原理:在 zencart 后台 Module --> Payment --> PayPal Website Payments Standard - IPN 开启 Detailed Line Items in Cart 选项。这个选项会把你所有的订单物品信息传给 paypal,当客户付款成功而后台未能成功生成订单时,也可以通过 paypal 帐号交易信息看到客户购买了哪些物品。

 

二. 使用 Paypal Sessions Viewer 插件找回 Paypal 漏掉的订单。

原理:zencart 购物车的物品,通过 paypal 方式付款,会在 paypal_session 表中保存此次付款的所有记录,如果付款成功后,从 paypal 网站跳转到购物网站并生成了订单时,zencart系统会自动删除这条 paypal_session 记录,如果没有成功跳转到购物网站,没有成功生成订单,那这条付款记录数据就会一直保存在数据库,当使用 Paypal Session Viewer 插件,就能查看这条记录的所有数据,包括客户信息,购物时间,商品信息,如果你确定已收到款,就可以把这条 paypal_session 信息转移到订单中,生成一个订单。

插件下载地址:http://www.zen-cart.cn/english-version-modules/admin-tools/paypal-sessions-viewer

 

三. 修改付款流程,先生成订单后付款。

原理:用过zen-cart的人都知道,zen-cart中下单步骤是下面这样的(其中[]中的表示不是必须的):

1. 购物车(shopping cart)

2. [货运方式(delivery method)]

3. 支付方式(payment method)

4. 订单确认(confirmation)

5. [第三方网站支付]

6. 订单处理(checkout process)——这一步比较重要,因为会在这里将购物车中的信息写入订单

7. 下单成功(checkout success)

这样的流程在正常情况下是没有任何问题的。但是,从第5步到第6部的过程中,用户可能以为付款成功就直接关闭掉网页了,或者由于网络原因造成不能正常跳转到checkout_process页面,这样造成的后果是很严重的,因为订单不能被正常的创建。基于上述的分析, 我们希望稍微地改变一下流程,即在支付之前订单已经创建好了,这样就算在支付时不能从第三方支付网站跳转回来,我们也不会存在用户付款成功却在后台没有订单的情况了。

本人是参照东国先生的这篇 修改zen-cart下单和付款流程以防止漏单 教程去修改的,因为这个教程比较老,而且也没有很全面,所以我根据自己的实际需求,把他做的更完善,更细节化。

经过修改后的蓝图基本是下面这样的:

1. 在checkour_confirmation页面确认订单后,都会直接proccess,并且进入 account_history_info 页面,可以在这里进入付款页面。如下图所示:

2. 如果当时客户没能付款,也可进入自己的后台对历史订单进行付款。如下图所示:

 

3. 未付款的订单,可以在后台修改价格,像淘宝一样拍下宝贝后,店主给你修改价格后再付款一样。如下图所示:

下面我们来正式修改代码,首先我列举出所有要修改的文件:

1. includes/classes/payment.php

2. includes/modules/payment/paypal.php

3. includes/classes/order.php

4. includes/modules/pages/checkout_process/header_php.php

5. includes/modules/pages/account_history_info/header_php.php

6. includes/templates/你的模板目录/templates/tpl_account_history_info_default.php

7. includes/templates/你的模板目录/templates/tpl_account_history_default.php

8. ipn_main_handler.php

9. admin(后台目录)/orders.php

因为先生成订单再付款,付款步骤就会比原来又多了一步,为了简化付款流程,我安装了 Fast And Easy Checkout For Zencart(快速支付) 插件,安装此插件之前,需要安装另外一个插件 Css Js Loader For Zencart,这是快速支付插件的依赖插件。快速支付与先生成订单后支付没什么因果关系,所以如果你不想安装的话完全可以不理。

按步骤修改上面列举的文件:

1. 首先我们需要对现有的支付模块进行一个改造。需要对支付方式的class增加一个字段paynow_action_url,用来表示进行支付的页面 url,另外还需要增加一个函数,paynow_button($order_id),来获取支付表单的参数隐藏域代码。

要增加 paynow_action_url 变量,请在类payment的构造函数中最后加上下面的代码:    

if ( (zen_not_null($module)) && (in_array($module.'.php', $this->modules)) && (isset($GLOBALS[$module]->paynow_action_url)) ) {        $this->paynow_action_url = $GLOBALS[$module]->paynow_action_url;        }

 

要增加paynow_button($order_id)函数,请在payment类的最后一个函数之后加上如下的代码:

function paynow_button($order_id){    if (is_array($this->modules)) {      if (is_object($GLOBALS[$this->selected_module])) {        return $GLOBALS[$this->selected_module]->paynow_button($order_id);      }    }}

 

2. 以paypal支付方式为例子,说明如何具体实现。这里直接修改 paypal.php 文件,注意备份此文件。代码如下所示,可以看到,这里去掉了对 form_action_url 的指定,并给定了 paynow_action_url,因为我们希望用户点击“确认订单”后直接进入checkout_process,所以如果不指定 form_action_url,那么确认订单的表单就会直接提交到 checkout_process 页面了,而 paynow_action_url 就是 以前的 form_action_url 的值。paynow_button 函数的实现也很简单,这里只是将原先的 process_button() 函数的内容剪切过来而已,只不过我们没有使用全局的$order变量,而是使用 $order = new order($order_id),来重新构造的一个对象,这样做是为在历史订单中显示pay now按钮做准备的。paypal.php修改后的文件如下:

  1 <?php  2 /**  3  * paypal.php payment module class for PayPal Website Payments Standard (IPN) method  4  *  5  * @package paymentMethod  6  * @copyright Copyright 2003-2010 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: paypal.php 15735 2010-03-29 07:13:53Z drbyte $ 10  */ 11  12 define('MODULE_PAYMENT_PAYPAL_TAX_OVERRIDE', 'true'); 13  14 /** 15  *  ensure dependencies are loaded 16  */ 17   include_once((IS_ADMIN_FLAG === true ? DIR_FS_CATALOG_MODULES : DIR_WS_MODULES) . 'payment/paypal/paypal_functions.php'); 18  19 /** 20  * paypal.php payment module class for PayPal Website Payments Standard (IPN) method 21  * 22  */ 23 class paypal extends base { 24   /** 25    * string representing the payment method 26    * 27    * @var string 28    */ 29   var $code; 30   /** 31    * $title is the displayed name for this payment method 32    * 33    * @var string 34     */ 35   var $title; 36   /** 37    * $description is a soft name for this payment method 38    * 39    * @var string 40     */ 41   var $description; 42   /** 43    * $enabled determines whether this module shows or not... in catalog. 44    * 45    * @var boolean 46     */ 47   var $enabled; 48   /** 49     * constructor 50     * 51     * @param int $paypal_ipn_id 52     * @return paypal 53     */ 54   function paypal($paypal_ipn_id = '') { 55     global $order, $messageStack; 56     $this->code = 'paypal'; 57     $this->codeVersion = '1.3.9'; 58     if (IS_ADMIN_FLAG === true) { 59       $this->title = MODULE_PAYMENT_PAYPAL_TEXT_ADMIN_TITLE; // Payment Module title in Admin 60       if (IS_ADMIN_FLAG === true && defined('MODULE_PAYMENT_PAYPAL_IPN_DEBUG') && MODULE_PAYMENT_PAYPAL_IPN_DEBUG != 'Off') $this->title .= '<span class="alert"> (debug mode active)</span>'; 61       if (IS_ADMIN_FLAG === true && MODULE_PAYMENT_PAYPAL_TESTING == 'Test') $this->title .= '<span class="alert"> (dev/test mode active)</span>'; 62     } else { 63       $this->title = MODULE_PAYMENT_PAYPAL_TEXT_CATALOG_TITLE; // Payment Module title in Catalog 64     } 65     $this->description = MODULE_PAYMENT_PAYPAL_TEXT_DESCRIPTION; 66     $this->sort_order = MODULE_PAYMENT_PAYPAL_SORT_ORDER; 67     $this->enabled = ((MODULE_PAYMENT_PAYPAL_STATUS == 'True') ? true : false); 68     if ((int)MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID > 0) { 69       $this->order_status = MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID; 70     } 71     if (is_object($order)) $this->update_status(); 72     $this->paynow_action_url = 'https://' . MODULE_PAYMENT_PAYPAL_HANDLER; 73  74     if (PROJECT_VERSION_MAJOR != '1' && substr(PROJECT_VERSION_MINOR, 0, 3) != '3.9') $this->enabled = false; 75  76     // verify table structure 77     if (IS_ADMIN_FLAG === true) $this->tableCheckup(); 78   } 79   /** 80    * calculate zone matches and flag settings to determine whether this module should display to customers or not 81     * 82     */ 83   function update_status() { 84     global $order, $db; 85  86     if ( ($this->enabled == true) && ((int)MODULE_PAYMENT_PAYPAL_ZONE > 0) ) { 87       $check_flag = false; 88       $check_query = $db->Execute("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_PAYPAL_ZONE . "' and zone_country_id = '" . $order->billing['country']['id'] . "' order by zone_id"); 89       while (!$check_query->EOF) { 90         if ($check_query->fields['zone_id'] < 1) { 91           $check_flag = true; 92           break; 93         } elseif ($check_query->fields['zone_id'] == $order->billing['zone_id']) { 94           $check_flag = true; 95           break; 96         } 97         $check_query->MoveNext(); 98       } 99 100       if ($check_flag == false) {101         $this->enabled = false;102       }103     }104   }105   /**106    * JS validation which does error-checking of data-entry if this module is selected for use107    * (Number, Owner, and CVV Lengths)108    *109    * @return string110     */111   function javascript_validation() {112     return false;113   }114   /**115    * Displays payment method name along with Credit Card Information Submission Fields (if any) on the Checkout Payment Page116    *117    * @return array118     */119   function selection() {120     return array('id' => $this->code,121                  'module' => MODULE_PAYMENT_PAYPAL_TEXT_CATALOG_LOGO,122                  'icon' => MODULE_PAYMENT_PAYPAL_TEXT_CATALOG_LOGO123                  );124   }125   /**126    * Normally evaluates the Credit Card Type for acceptance and the validity of the Credit Card Number & Expiration Date127    * Since paypal module is not collecting info, it simply skips this step.128    *129    * @return boolean130    */131   function pre_confirmation_check() {132     return false;133   }134   /**135    * Display Credit Card Information on the Checkout Confirmation Page136    * Since none is collected for paypal before forwarding to paypal site, this is skipped137    *138    * @return boolean139     */140   function confirmation() {141     return false;142   }143   /**144    * Build the data and actions to process when the "Submit" button is pressed on the order-confirmation screen.145    * This sends the data to the payment gateway for processing.146    * (These are hidden fields on the checkout confirmation page)147    *148    * @return string149     */150   function process_button() {151     return false;152   }153   /**154    * Determine the language to use when visiting the PayPal site155    */156   function getLanguageCode() {157     global $order;158     $lang_code = '';159     $orderISO = zen_get_countries($order->customer['country']['id'], true);160     $storeISO = zen_get_countries(STORE_COUNTRY, true);161     if (in_array(strtoupper($orderISO['countries_iso_code_2']), array('US', 'AU', 'DE', 'FR', 'IT', 'GB', 'ES', 'AT', 'BE', 'CA', 'CH', 'CN', 'NL', 'PL'))) {162       $lang_code = strtoupper($orderISO['countries_iso_code_2']);163     } elseif (in_array(strtoupper($storeISO['countries_iso_code_2']), array('US', 'AU', 'DE', 'FR', 'IT', 'GB', 'ES', 'AT', 'BE', 'CA', 'CH', 'CN', 'NL', 'PL'))) {164       $lang_code = strtoupper($storeISO['countries_iso_code_2']);165     } elseif (in_array(strtoupper($_SESSION['languages_code']), array('EN', 'US', 'AU', 'DE', 'FR', 'IT', 'GB', 'ES', 'AT', 'BE', 'CA', 'CH', 'CN', 'NL', 'PL'))) {166       $lang_code = $_SESSION['languages_code'];167       if (strtoupper($lang_code) == 'EN') $lang_code = 'US';168     }169     //return $orderISO['countries_iso_code_2'];170     return strtoupper($lang_code);171   }172   /**173    * Store transaction info to the order and process any results that come back from the payment gateway174    */175   function before_process() {176     return false;177   }178   /**179     * Checks referrer180     *181     * @param string $zf_domain182     * @return boolean183     */184   function check_referrer($zf_domain) {185     return true;186   }187   /**188     * Build admin-page components189     *190     * @param int $zf_order_id191     * @return string192     */193   function admin_notification($zf_order_id) {194     global $db;195     $output = '';196     $sql = "select * from " . TABLE_PAYPAL . " where order_id = '" . (int)$zf_order_id . "' order by paypal_ipn_id DESC LIMIT 1";197     $ipn = $db->Execute($sql);198     if ($ipn->RecordCount() > 0 && file_exists(DIR_FS_CATALOG . DIR_WS_MODULES . 'payment/paypal/paypal_admin_notification.php')) require(DIR_FS_CATALOG . DIR_WS_MODULES . 'payment/paypal/paypal_admin_notification.php');199     return $output;200   }201   /**202    * Post-processing activities203    * When the order returns from the processor, if PDT was successful, this stores the results in order-status-history and logs data for subsequent reference204    *205    * @return boolean206     */207   function after_process() {208     return false;209   }210   /**211    * Used to display error message details212    *213    * @return boolean214     */215   function output_error() {216     return false;217   }218   /**219    * Check to see whether module is installed220    *221    * @return boolean222     */223   function check() {224     global $db;225     if (IS_ADMIN_FLAG === true) {226       global $sniffer;227       if ($sniffer->field_exists(TABLE_PAYPAL, 'zen_order_id'))  $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE COLUMN zen_order_id order_id int(11) NOT NULL default '0'");228     }229     if (!isset($this->_check)) {230       $check_query = $db->Execute("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_PAYPAL_STATUS'");231       $this->_check = $check_query->RecordCount();232     }233     return $this->_check;234   }235   /**236    * Install the payment module and its configuration settings237     *238     */239   function install() {240     global $db, $messageStack;241     if (defined('MODULE_PAYMENT_PAYPAL_STATUS')) {242       $messageStack->add_session('PayPal Website Payments Standard module already installed.', 'error');243       zen_redirect(zen_href_link(FILENAME_MODULES, 'set=payment&module=paypal', 'NONSSL'));244       return 'failed';245     }246     if (defined('MODULE_PAYMENT_PAYPALWPP_STATUS')) {247       $messageStack->add_session('NOTE: PayPal Express Checkout module already installed. You don\'t need Standard if you have Express installed.', 'error');248       zen_redirect(zen_href_link(FILENAME_MODULES, 'set=payment&module=paypalwpp', 'NONSSL'));249       return 'failed';250     }251     $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 PayPal Module', 'MODULE_PAYMENT_PAYPAL_STATUS', 'True', 'Do you want to accept PayPal payments?', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");252     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Business ID', 'MODULE_PAYMENT_PAYPAL_BUSINESS_ID','".STORE_OWNER_EMAIL_ADDRESS."', 'Primary email address for your PayPal account.<br />NOTE: This must match <strong>EXACTLY </strong>the primary email address on your PayPal account settings.  It <strong>IS case-sensitive</strong>, so please check your PayPal profile preferences at paypal.com and be sure to enter the EXACT same primary email address here.', '6', '2', now())");253     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Transaction Currency', 'MODULE_PAYMENT_PAYPAL_CURRENCY', 'Selected Currency', 'Which currency should the order be sent to PayPal as? <br />NOTE: if an unsupported currency is sent to PayPal, it will be auto-converted to USD.', '6', '3', 'zen_cfg_select_option(array(\'Selected Currency\', \'Only USD\', \'Only AUD\', \'Only CAD\', \'Only EUR\', \'Only GBP\', \'Only CHF\', \'Only CZK\', \'Only DKK\', \'Only HKD\', \'Only HUF\', \'Only JPY\', \'Only NOK\', \'Only NZD\', \'Only PLN\', \'Only SEK\', \'Only SGD\', \'Only THB\', \'Only MXN\', \'Only ILS\', \'Only PHP\', \'Only TWD\', \'Only BRL\', \'Only MYR\'), ', now())");254     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Payment Zone', 'MODULE_PAYMENT_PAYPAL_ZONE', '0', 'If a zone is selected, only enable this payment method for that zone.', '6', '4', 'zen_get_zone_class_title', 'zen_cfg_pull_down_zone_classes(', now())");255     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Pending Notification Status', 'MODULE_PAYMENT_PAYPAL_PROCESSING_STATUS_ID', '" . DEFAULT_ORDERS_STATUS_ID .  "', 'Set the status of orders made with this payment module that are not yet completed to this value<br />(\'Pending\' recommended)', '6', '5', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");256     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Order Status', 'MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID', '2', 'Set the status of orders made with this payment module that have completed payment to this value<br />(\'Processing\' recommended)', '6', '6', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");257     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Refund Order Status', 'MODULE_PAYMENT_PAYPAL_REFUND_ORDER_STATUS_ID', '1', 'Set the status of orders that have been refunded made with this payment module to this value<br />(\'Pending\' recommended)', '6', '7', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");258     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_PAYMENT_PAYPAL_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '8', now())");259     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Address Override', 'MODULE_PAYMENT_PAYPAL_ADDRESS_OVERRIDE', '1', 'If set to 1, the customer shipping address selected in Zen Cart will override the customer PayPal-stored address book. The customer will see their address from Zen Cart, but will NOT be able to edit it at PayPal.<br />(An invalid address will be treated by PayPal as not-supplied, or override=0)<br />0=No Override<br />1=ZC address overrides PayPal address choices', '6', '18', 'zen_cfg_select_option(array(\'0\',\'1\'), ', now())");260     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Shipping Address Requirements?', 'MODULE_PAYMENT_PAYPAL_ADDRESS_REQUIRED', '2', 'The buyers shipping address. If set to 0 your customer will be prompted to include a shipping address. If set to 1 your customer will not be asked for a shipping address. If set to 2 your customer will be required to provide a shipping address.<br />0=Prompt<br />1=Not Asked<br />2=Required<br /><br /><strong>NOTE: If you allow your customers to enter their own shipping address, then MAKE SURE you PERSONALLY manually verify the PayPal confirmation details to verify the proper address when filling orders. When using Website Payments Standard (IPN), Zen Cart does not know if they choose an alternate shipping address at PayPal vs the one entered when placing an order.</strong>', '6', '20', 'zen_cfg_select_option(array(\'0\',\'1\',\'2\'), ', now())");261     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Detailed Line Items in Cart', 'MODULE_PAYMENT_PAYPAL_DETAILED_CART', 'No', 'Do you want to give line-item details to PayPal?  If set to True, line-item details will be shared with PayPal if no discounts apply and if tax and shipping are simple. Otherwise an Aggregate cart summary will be sent.', '6', '22', 'zen_cfg_select_option(array(\'No\',\'Yes\'), ', now())");262     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Page Style', 'MODULE_PAYMENT_PAYPAL_PAGE_STYLE', 'Primary', 'Sets the Custom Payment Page Style for payment pages. The value of page_style is the same as the Page Style Name you chose when adding or editing the page style. You can add and edit Custom Payment Page Styles from the Profile subtab of the My Account tab on the PayPal site. If you would like to always reference your Primary style, set this to \"primary.\" If you would like to reference the default PayPal page style, set this to \"paypal\".', '6', '25', now())");263     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Mode for PayPal web services<br /><br />Default:<br /><code>www.paypal.com/cgi-bin/webscr</code><br />or<br /><code>www.paypal.com/us/cgi-bin/webscr</code><br />or for the UK,<br /><code>www.paypal.com/uk/cgi-bin/webscr</code>', 'MODULE_PAYMENT_PAYPAL_HANDLER', 'www.paypal.com/cgi-bin/webscr', 'Choose the URL for PayPal live processing', '6', '73', '', now())");264     // sandbox:  www.sandbox.paypal.com/cgi-bin/webscr265     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added, use_function) values ('PDT Token (Payment Data Transfer)', 'MODULE_PAYMENT_PAYPAL_PDTTOKEN', '', 'Enter your PDT Token value here in order to activate transactions immediately after processing (if they pass validation).', '6', '25', now(), 'zen_cfg_password_display')");266     // Paypal testing options here267     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Debug Mode', 'MODULE_PAYMENT_PAYPAL_IPN_DEBUG', 'Off', 'Enable debug logging? <br />NOTE: This can REALLY clutter your email inbox!<br />Logging goes to the /includes/modules/payment/paypal/logs folder<br />Email goes to the store-owner address.<br />Email option NOT recommended.<br /><strong>Leave OFF for normal operation.</strong>', '6', '71', 'zen_cfg_select_option(array(\'Off\',\'Log File\',\'Log and Email\'), ', now())");268     $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Debug Email Address', 'MODULE_PAYMENT_PAYPAL_DEBUG_EMAIL_ADDRESS','".STORE_OWNER_EMAIL_ADDRESS."', 'The email address to use for PayPal debugging', '6', '72', now())");269 270     $this->notify('NOTIFY_PAYMENT_PAYPAL_INSTALLED');271   }272   /**273    * Remove the module and all its settings274     *275     */276   function remove() {277     global $db;278     $db->Execute("delete from " . TABLE_CONFIGURATION . " where configuration_key LIKE 'MODULE\_PAYMENT\_PAYPAL\_%'");279     $this->notify('NOTIFY_PAYMENT_PAYPAL_UNINSTALLED');280   }281   /**282    * Internal list of configuration keys used for configuration of the module283    *284    * @return array285     */286   function keys() {287     $keys_list = array(288                        'MODULE_PAYMENT_PAYPAL_STATUS',289                        'MODULE_PAYMENT_PAYPAL_BUSINESS_ID',290                        'MODULE_PAYMENT_PAYPAL_PDTTOKEN',291                        'MODULE_PAYMENT_PAYPAL_CURRENCY',292                        'MODULE_PAYMENT_PAYPAL_ZONE',293                        'MODULE_PAYMENT_PAYPAL_PROCESSING_STATUS_ID',294                        'MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID',295                        'MODULE_PAYMENT_PAYPAL_REFUND_ORDER_STATUS_ID',296                        'MODULE_PAYMENT_PAYPAL_SORT_ORDER',297                        'MODULE_PAYMENT_PAYPAL_DETAILED_CART',298                        'MODULE_PAYMENT_PAYPAL_ADDRESS_OVERRIDE' ,299                        'MODULE_PAYMENT_PAYPAL_ADDRESS_REQUIRED' ,300                        'MODULE_PAYMENT_PAYPAL_PAGE_STYLE' ,301                        'MODULE_PAYMENT_PAYPAL_HANDLER',302                        'MODULE_PAYMENT_PAYPAL_IPN_DEBUG',303                         );304 305     // Paypal testing/debug options go here:306     if (IS_ADMIN_FLAG === true) {307       if (isset($_GET['debug']) && $_GET['debug']=='on') {308         $keys_list[]='MODULE_PAYMENT_PAYPAL_DEBUG_EMAIL_ADDRESS';  /* this defaults to store-owner-email-address */309       }310     }311     return $keys_list;312   }313 314   function _getPDTresults($orderAmount, $my_currency, $pdtTX) {315     global $db;316     $ipnData  = ipn_postback('PDT', $pdtTX);317     $respdata = $ipnData['info'];318 319     // parse the data320     $lines = explode("\n", $respdata);321     $this->pdtData = array();322     for ($i=1; $i<count($lines);$i++){323       if (!strstr($lines[$i], "=")) continue;324       list($key,$val) = explode("=", $lines[$i]);325       $this->pdtData[urldecode($key)] = urldecode($val);326     }327 328     if ($this->pdtData['txn_id'] == '' || $this->pdtData['payment_status'] == '') {329       ipn_debug_email('PDT Returned INVALID Data. Must wait for IPN to process instead. ' . "\n" . print_r($this->pdtData, true));330       return FALSE;331     } else {332       ipn_debug_email('PDT Returned Data ' . print_r($this->pdtData, true));333     }334 335     $_POST['mc_gross'] = $this->pdtData['mc_gross'];336     $_POST['mc_currency'] = $this->pdtData['mc_currency'];337     $_POST['business'] = $this->pdtData['business'];338     $_POST['receiver_email'] = $this->pdtData['receiver_email'];339 340     $PDTstatus = (ipn_validate_transaction($respdata, $this->pdtData, 'PDT') && valid_payment($orderAmount, $my_currency, 'PDT') && $this->pdtData['payment_status'] == 'Completed');341     if ($this->pdtData['payment_status'] != '' && $this->pdtData['payment_status'] != 'Completed') {342       ipn_debug_email('PDT WARNING :: Order not marked as "Completed".  Check for Pending reasons or wait for IPN to complete.' . "\n" . '[payment_status] => ' . $this->pdtData['payment_status'] . "\n" . '[pending_reason] => ' . $this->pdtData['pending_reason']);343     }344 345     $sql = "SELECT order_id, paypal_ipn_id, payment_status, txn_type, pending_reason346                 FROM " . TABLE_PAYPAL . "347                 WHERE txn_id = :transactionID OR parent_txn_id = :transactionID348                 ORDER BY order_id DESC  ";349     $sql = $db->bindVars($sql, ':transactionID', $this->pdtData['txn_id'], 'string');350     $ipn_id = $db->Execute($sql);351     if ($ipn_id->RecordCount() != 0) {352       ipn_debug_email('PDT WARNING :: Transaction already exists. Perhaps IPN already added it.  PDT processing ended.');353       $pdtTXN_is_unique = false;354     } else {355       $pdtTXN_is_unique = true;356     }357 358     $PDTstatus = ($pdtTXN_is_unique && $PDTstatus);359 360     return $PDTstatus;361   }362 363 364   function tableCheckup() {365     global $db, $sniffer;366     $fieldOkay1 = (method_exists($sniffer, 'field_type')) ? $sniffer->field_type(TABLE_PAYPAL, 'txn_id', 'varchar(20)', true) : -1;367     $fieldOkay2 = ($sniffer->field_exists(TABLE_PAYPAL, 'module_name')) ? true : -1;368     $fieldOkay3 = ($sniffer->field_exists(TABLE_PAYPAL, 'order_id')) ? true : -1;369 370     if ($fieldOkay1 == -1) {371       $sql = "show fields from " . TABLE_PAYPAL;372       $result = $db->Execute($sql);373       while (!$result->EOF) {374         if  ($result->fields['Field'] == 'txn_id') {375           if  ($result->fields['Type'] == 'varchar(20)') {376             $fieldOkay1 = true; // exists and matches required type, so skip to other checkup377           } else {378             $fieldOkay1 = $result->fields['Type']; // doesn't match, so return what it "is"379             break;380           }381         }382         $result->MoveNext();383       }384     }385 386     if ($fieldOkay1 !== true) {387       // temporary fix to table structure for v1.3.7.x -- may remove in later release388       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE payment_type payment_type varchar(40) NOT NULL default ''");389       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE txn_type txn_type varchar(40) NOT NULL default ''");390       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE payment_status payment_status varchar(32) NOT NULL default ''");391       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE reason_code reason_code varchar(40) default NULL");392       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE pending_reason pending_reason varchar(32) default NULL");393       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE invoice invoice varchar(128) default NULL");394       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE payer_business_name payer_business_name varchar(128) default NULL");395       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE address_name address_name varchar(64) default NULL");396       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE address_street address_street varchar(254) default NULL");397       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE address_city address_city varchar(120) default NULL");398       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE address_state address_state varchar(120) default NULL");399       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE payer_email payer_email varchar(128) NOT NULL default ''");400       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE business business varchar(128) NOT NULL default ''");401       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE receiver_email receiver_email varchar(128) NOT NULL default ''");402       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE txn_id txn_id varchar(20) NOT NULL default ''");403       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE parent_txn_id parent_txn_id varchar(20) default NULL");404     }405     if ($fieldOkay2 !== true) {406       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " ADD COLUMN module_name varchar(40) NOT NULL default '' after txn_type");407       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " ADD COLUMN module_mode varchar(40) NOT NULL default '' after module_name");408     }409     if ($fieldOkay3 !== true) {410       $db->Execute("ALTER TABLE " . TABLE_PAYPAL . " CHANGE zen_order_id order_id int(11) NOT NULL default '0'");411     }412   }413   414   function paynow_button($order_id) {415       global $db, $order, $currencies, $currency;416       require_once(DIR_WS_CLASSES . 'order.php');417       $order = new order($order_id);418       $options = array();419       $optionsCore = array();420       $optionsPhone = array();421       $optionsShip = array();422       $optionsLineItems = array();423       $optionsAggregate = array();424       $optionsTrans = array();425       $buttonArray = array();426   427       $this->totalsum = $order->info['total'];428   429       // save the session stuff permanently in case paypal loses the session430       $_SESSION['ppipn_key_to_remove'] = session_id();431       $db->Execute("delete from " . TABLE_PAYPAL_SESSION . " where session_id = '" . zen_db_input($_SESSION['ppipn_key_to_remove']) . "'");432   433       $sql = "insert into " . TABLE_PAYPAL_SESSION . " (session_id, saved_session, expiry) values (434             '" . zen_db_input($_SESSION['ppipn_key_to_remove']) . "',435             '" . base64_encode(serialize($_SESSION)) . "',436             '" . (time() + (1*60*60*24*2)) . "')";437   438       $db->Execute($sql);439   440       $my_currency = select_pp_currency();441       if(!empty($order->info['currency'])){442           $my_currency=$order->info['currency'];443       }444       $this->transaction_currency = $my_currency;445   446       $this->transaction_amount = ($this->totalsum * $currencies->get_value($my_currency));447   448       $telephone = preg_replace('/\D/', '', $order->customer['telephone']);449       if ($telephone != '') {450           $optionsPhone['H_PhoneNumber'] = $telephone;451           if (in_array($order->customer['country']['iso_code_2'], array('US','CA'))) {452               $optionsPhone['night_phone_a'] = substr($telephone,0,3);453               $optionsPhone['night_phone_b'] = substr($telephone,3,3);454               $optionsPhone['night_phone_c'] = substr($telephone,6,4);455               $optionsPhone['day_phone_a'] = substr($telephone,0,3);456               $optionsPhone['day_phone_b'] = substr($telephone,3,3);457               $optionsPhone['day_phone_c'] = substr($telephone,6,4);458           } else {459               $optionsPhone['night_phone_b'] = $telephone;460               $optionsPhone['day_phone_b'] = $telephone;461           }462       }463   464       $optionsCore = array(465           'lc' => US,466           //'lc' => $order->customer['country']['iso_code_2'],467           'charset' => CHARSET,468           'page_style' => MODULE_PAYMENT_PAYPAL_PAGE_STYLE,469           'custom' => zen_session_name() . '=' . zen_session_id(),470           'invoice' => $order->info['num'],471           'business' => MODULE_PAYMENT_PAYPAL_BUSINESS_ID,472           'return' => zen_href_link(FILENAME_CHECKOUT_PROCESS, 'referer=paypal', 'SSL'),473           'cancel_return' => zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL'),474           'shopping_url' => zen_href_link(FILENAME_SHOPPING_CART, '', 'SSL'),475           'notify_url' => zen_href_link('ipn_main_handler.php', '', 'SSL',false,false,true),476           'redirect_cmd' => '_xclick','rm' => 2,'bn' => 'zencart','mrb' => 'R-6C7952342H795591R','pal' => '9E82WJBKKGPLQ',477       );478       $optionsCust = array(479           'first_name' => replace_accents($order->customer['firstname']),480           'last_name' => replace_accents($order->customer['lastname']),481           'address1' => replace_accents($order->customer['street_address']),482           'city' => replace_accents($order->customer['city']),483           'state' => zen_get_zone_code($order->customer['country']['id'], $order->customer['zone_id'], $order->customer['state']),484           'zip' => $order->customer['postcode'],485           'country' => $order->customer['country']['iso_code_2'],486           'email' => $order->customer['email_address'],487       );488       // address line 2 is optional489       if ($order->customer['suburb'] != '') $optionsCust['address2'] = $order->customer['suburb'];490       // different format for Japanese address layout:491       if ($order->customer['country']['iso_code_2'] == 'JP') $optionsCust['zip'] = substr($order->customer['postcode'], 0, 3) . '-' . substr($order->customer['postcode'], 3);492       if (MODULE_PAYMENT_PAYPAL_ADDRESS_REQUIRED == 2) {493           $optionsCust = array(494               'first_name' => replace_accents($order->delivery['firstname'] != '' ? $order->delivery['firstname'] : $order->billing['firstname']),495               'last_name' => replace_accents($order->delivery['lastname'] != '' ? $order->delivery['lastname'] : $order->billing['lastname']),496               'address1' => replace_accents($order->delivery['street_address'] != '' ? $order->delivery['street_address'] : $order->billing['street_address']),497               'city' => replace_accents($order->delivery['city'] != '' ? $order->delivery['city'] : $order->billing['city']),498               'state' => ($order->delivery['country']['id'] != '' ? zen_get_zone_code($order->delivery['country']['id'], $order->delivery['zone_id'], $order->delivery['state']) : zen_get_zone_code($order->billing['country']['id'], $order->billing['zone_id'], $order->billing['state'])),499               'zip' => ($order->delivery['postcode'] != '' ? $order->delivery['postcode'] : $order->billing['postcode']),500               'country' => ($order->delivery['country']['title'] != '' ? $order->delivery['country']['title'] : $order->billing['country']['title']),501               'country_code' => ($order->delivery['country']['iso_code_2'] != '' ? $order->delivery['country']['iso_code_2'] : $order->billing['country']['iso_code_2']),502               'email' => $order->customer['email_address'],503           );504           if ($order->delivery['suburb'] != '') $optionsCust['address2'] = $order->delivery['suburb'];505           if ($order->delivery['country']['iso_code_2'] == 'JP') $optionsCust['zip'] = substr($order->delivery['postcode'], 0, 3) . '-' . substr($order->delivery['postcode'], 3);506       }507       $optionsShip['no_shipping'] = MODULE_PAYMENT_PAYPAL_ADDRESS_REQUIRED;508       if (MODULE_PAYMENT_PAYPAL_ADDRESS_OVERRIDE == '1') $optionsShip['address_override'] = MODULE_PAYMENT_PAYPAL_ADDRESS_OVERRIDE;509       // prepare cart contents details where possible510       if (MODULE_PAYMENT_PAYPAL_DETAILED_CART == 'Yes') $optionsLineItems = ipn_getLineItemDetails();511       if (sizeof($optionsLineItems) > 0) {512           $optionsLineItems['cmd'] = '_cart';513           //      $optionsLineItems['num_cart_items'] = sizeof($order->products);514           if (isset($optionsLineItems['shipping'])) {515               $optionsLineItems['shipping_1'] = $optionsLineItems['shipping'];516               unset($optionsLineItems['shipping']);517           }518           unset($optionsLineItems['subtotal']);519           // if line-item details couldn't be kept due to calculation mismatches or discounts etc, default to aggregate mode520           if (!isset($optionsLineItems['item_name_1']) || $optionsLineItems['creditsExist'] == TRUE) $optionsLineItems = array();521           //if ($optionsLineItems['amount'] != $this->transaction_amount) $optionsLineItems = array();522           // debug:523           //ipn_debug_email('Line Item Details (if blank, this means there was a data mismatch or credits applied, and thus bypassed): ' . "\n" . print_r($optionsLineItems, true));524           unset($optionsLineItems['creditsExist']);525       }526       $optionsAggregate = array(527           'cmd' => '_ext-enter',528           'item_name' => MODULE_PAYMENT_PAYPAL_PURCHASE_DESCRIPTION_TITLE,529           'item_number' => MODULE_PAYMENT_PAYPAL_PURCHASE_DESCRIPTION_ITEMNUM,530           //'num_cart_items' => sizeof($order->products),531           'amount' => number_format($this->transaction_amount, $currencies->get_decimal_places($my_currency)),532           'shipping' => '0.00',533       );534       if (MODULE_PAYMENT_PAYPAL_TAX_OVERRIDE == 'true') $optionsAggregate['tax'] = '0.00';535       if (MODULE_PAYMENT_PAYPAL_TAX_OVERRIDE == 'true') $optionsAggregate['tax_cart'] = '0.00';536       $optionsTrans = array(537           'upload' => (int)(sizeof($order->products) > 0),538           'currency_code' => $my_currency,539           //'paypal_order_id' => $paypal_order_id,540           //'no_note' => '1',541           //'invoice' => '',542       );543   544       // if line-item info is invalid, use aggregate:545       if (sizeof($optionsLineItems) > 0) $optionsAggregate = $optionsLineItems;546   547       // prepare submission548       $options = array_merge($optionsCore, $optionsCust, $optionsPhone, $optionsShip, $optionsTrans, $optionsAggregate);549       //ipn_debug_email('Keys for submission: ' . print_r($options, true));550   551       // build the button fields552       foreach ($options as $name => $value) {553           // remove quotation marks554           $value = str_replace('"', '', $value);555           // check for invalid chars556           if (preg_match('/[^a-zA-Z_0-9]/', $name)) {557               ipn_debug_email('datacheck - ABORTING - preg_match found invalid submission key: ' . $name . ' (' . $value . ')');558               break;559           }560           // do we need special handling for & and = symbols?561           //if (strpos($value, '&') !== false || strpos($value, '=') !== false) $value = urlencode($value);562   563           $buttonArray[] = zen_draw_hidden_field($name, $value);564       }565       $process_button_string = implode("\n", $buttonArray) . "\n";566   567       $_SESSION['paypal_transaction_info'] = array($this->transaction_amount, $this->transaction_currency);568       return $process_button_string;569   }570 571 }
View Code

 

3. 在网站后台 Orders Status(地给你单状态)中,增加一项 Unpaid(未付款)选项。然后修改 Order.php 中 create 方法,指定如果生成订单的时候,客户选择的付款方式是 Paypal,那么此订单的状态将会是 Unpaid状态。代码如下:

 1   function create($zf_ot_modules, $zf_mode = 2) { 2     global $db; 3     $t1 = date("YmdGhs");  4     srand ((float) microtime() * 10000000);  5     $input = array ("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");  6     $rand_keys = array_rand ($input, 2);  7     $l1 = $input[$rand_keys[0]];  8     $l2 = $input[$rand_keys[1]];  9     $r1 = rand(0,9); 10     $ordernum = $t1.$l1.$l2.$r1; 11 12     if ($this->info['total'] == 0) {13       if (DEFAULT_ZERO_BALANCE_ORDERS_STATUS_ID == 0) {14         $this->info['order_status'] = DEFAULT_ORDERS_STATUS_ID;15       } else {16         if ($_SESSION['payment'] != 'freecharger') {17           $this->info['order_status'] = DEFAULT_ZERO_BALANCE_ORDERS_STATUS_ID;18         }19       }20     }21     //在这个位置增加下面的代码,5是后台添加的Unpaid状态的ID号,不尽相同,注意查看。22     if($_SESSION['payment'] == 'paypal'){23         $this->info['order_status'] = 5;24     }

 

4. 如果是通过Paypal付款后,从Paypal返回网站时,会使用GET方式带入一些数据到 includes/modules/pages/checkout_process/header_php.php 这个页面,而直接生成订单时,并不会有GET数据传输,所以通过 $_GET['referer'] 这条返回值数据,来判断是生成订单,还是付款归来。如果只是生成订单的话,跳转到 tpl_account_history_info_default 页面,如果是付款归来,则跳转到 checkout_success 页面,这样就避免了重复生成订单了。代码如下:

 1   $zco_notifier->notify('NOTIFY_HEADER_START_CHECKOUT_PROCESS'); 2    3   if(isset($_GET['referer']) && $_GET['referer'] == 'paypal'){ 4       //如果是来自paypal的付款,就直接跳转到付款成功页面 5       zen_redirect(zen_href_link(FILENAME_CHECKOUT_SUCCESS, (isset($_GET['action']) && $_GET['action'] == 'confirm' ? 'action=confirm' : ''), 'SSL')); 6   } 7   else{ 8       require(DIR_WS_MODULES . zen_get_module_directory('checkout_process.php')); 9       10       // load the after_process function from the payment modules11       $payment_modules->after_process();12       13       $_SESSION['cart']->reset(true);14       15       // unregister session variables used during checkout16       unset($_SESSION['sendto']);17       unset($_SESSION['billto']);18       unset($_SESSION['shipping']);19       unset($_SESSION['payment']);20       unset($_SESSION['comments']);21       $order_total_modules->clear_posts();//ICW ADDED FOR CREDIT CLASS SYSTEM22       23       // This should be before the zen_redirect:24       $zco_notifier->notify('NOTIFY_HEADER_END_CHECKOUT_PROCESS');25       26       zen_redirect(zen_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id='.$insert_id, 'SSL'));27   }28 29   require(DIR_WS_INCLUDES . 'application_bottom.php');

 

5. 在 tpl_account_history_info_default 页面中显示pay now按钮。打开文件"includes/modules/pages/account_history_info/header.php",在文件的末尾添加下 面的代码:

1 require(DIR_WS_CLASSES . 'order.php');2 $order = new order($_GET['order_id']);3 4 //在这个位置插入下面两行代码5 require_once(DIR_WS_CLASSES . 'payment.php');6 $payment_modules = new payment($order->info['payment_module_code']);

 

6. 打开文件"includes/templates/template_default/templates /tpl_account_history_info_default.php",并在适当的位置加上如下的代码,这里对订单的状态进行了一个判断,当只有订单的 状态在未付款状态,才显示该按钮。代码如下:

 1 <?php 2     //Unpaid是你在后台添加的为付款订单状态 3     if(isset($payment_modules->paynow_action_url) && $payment_modules->paynow_action_url != '' && $order->info['orders_status'] == 'Unpaid'){ 4         echo '<div class="back"><strong>Order has been generated</strong> - please continue to pay</div>'; 5         echo zen_draw_form('checkout_paynow', $payment_modules->paynow_action_url, 'post', 'id="checkout_confirmation" onsubmit="submitonce();" class="right"'); 6         echo('<div>');             7         if (is_array($payment_modules->modules)) {           8             echo $payment_modules->paynow_button($_GET['order_id']); 9         }10         echo zen_image_submit("button_buy_now.gif", "Pay now this order","name='submit'");11         //echo '<input type="image" src="https://www.sandbox.paypal.com/en_US/i/btn/btn_buynow_LG.gif" border="0" name="submit" alt="PayPal——最安全便捷的在线支付方式!">';12         echo ('</div>');13         echo ('</form>');14     }15 ?>

 

7. 修改 tpl_account_history_default.php 页面,判断是否为未付款订单,如果是,则增加一个 pay_now 按钮,然后跳转到 tpl_account_history_info_default.php 页面进行付款,其实跟 view 按钮是一样的,只不过换了一个名称,标明是未付款订单而已。

8. 最关键的地方来了,就是 ipn_main_handler.php 这个文件。Paypal 付款接口返回数据方式有两种,一种是PDT,一种是IPN,PDT是同步传输,付款数据会立即返回到网站,并且是一次性的。IPN则是异步传输,而且如果网站没有收到数据,IPN还会再次循环的发送付款信息到你的网站 ipn_main_handler.php 文件进行处理并写入数据库。最终我们在客户订单中,就能看到客户的Paypal付款信息,如下图:

之前的付款流程中,Paypal 付款数据是通过 PDT 方式传输,修改了付款流程之后,我们不能通过 PDT 方式,只能通过 IPN 方式传输。ipn_main_handler.php 文件就是处理 IPN 数据传输方式的文件。不过,当 ipn_main_handler.php 接收到 Paypal 付款数据后,会根据 Paypal 付款数据生成一个订单,但是我们已经有了订单,只需要把 Paypal 付款信息写入到数据库中,与订单对应即可。所以我们需要修改  ipn_main_handler.php 文件。PDT和IPN详细介绍链接:http://wenku.baidu.com/link?url=xI4DZL8mg9R54aJKfn3zNyP9_yFHkHVvxWltEuAZ9-DXXAS3K3z-z6srRlh_P-EmMXYU-U6oQ_uEwNze7An9PBAUgnPMH-b_iF3d2z7LE_G

首先,我们要确定,通过 IPN 方式返回的 Paypal 付款信息是属于哪个订单的,我在 paypal.php 文件中第 470 行增加了 'invoice' => $order->info['id'],作用就是在付款的时候,把这个信息发送给Paypal,付款成功后,Paypal也会通过IPN返回这条信息到 ipn_main_handler.php。根据这个判断,如果接收到了 invoice 数据,则跳过生成订单的步骤,只写入Paypal付款信息即可。代码如下:

  1 <?php  2 /**  3  * ipn_main_handler.php callback handler for PayPal IPN notifications  4  *  5  * @package paymentMethod  6  * @copyright Copyright 2003-2010 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: ipn_main_handler.php 18014 2010-10-22 03:39:17Z drbyte $ 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 transaction104    */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 parameters109    */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     if ($debug_logfile_path == '') $debug_logfile_path = 'includes/modules/payment/paypal/logs/ipn_debug_php_errors-'.time().'.log';123     @ini_set('log_errors', 1);124     @ini_set('log_errors_max_len', 0);125     @ini_set('display_errors', 0); // do not output errors to screen/browser/client (only to log file)126     @ini_set('error_log', DIR_FS_CATALOG . $debug_logfile_path);127     error_reporting(version_compare(PHP_VERSION, 5.3, '>=') ? E_ALL & ~E_DEPRECATED & ~E_NOTICE : version_compare(PHP_VERSION, 6.0, '>=') ? E_ALL & ~E_DEPRECATED & ~E_NOTICE & ~E_STRICT : E_ALL & ~E_NOTICE);128   }129 130   ipn_debug_email('Breakpoint: Flag Status:' . "\nisECtransaction = " . (int)$isECtransaction . "\nisDPtransaction = " . (int)$isDPtransaction);131   /**132    * do confirmation post-back to PayPal and extract the results for subsequent use133    */134   $info  = ipn_postback();135   $new_status = 1;136   ipn_debug_email('Breakpoint: 1 - Collected data from PayPal notification');137 138   /**139    * validate transaction -- email address, matching txn record, etc140    */141   if (!ipn_validate_transaction($info, $_POST, 'IPN') === true) {142     if (!$isECtransaction && $_POST['txn_type'] != '') {143       ipn_debug_email('IPN FATAL ERROR :: Transaction did not validate. ABORTED.');144       die();145     }146   }147 148   if ($isDPtransaction) {149     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.');150   }151 152   ipn_debug_email('Breakpoint: 2 - Validated transaction components');153   if ($_POST ['exchange_rate'] == '')  $_POST [exchange_rate] = 1;154   if ($_POST ['num_cart_items'] == '') $_POST [num_cart_items] = 1;155   if ($_POST ['settle_amount'] == '')  $_POST [settle_amount] = 0;156 157   /**158    * is this a sandbox transaction?159    */160   if (isset($_POST['test_ipn']) && $_POST['test_ipn'] == 1) {161     ipn_debug_email('IPN NOTICE :: Processing SANDBOX transaction.');162   }163   if (isset($_POST['test_internal']) && $_POST['test_internal'] == 1) {164     ipn_debug_email('IPN NOTICE :: Processing INTERNAL TESTING transaction.');165   }166   if (isset($_POST['pending_reason']) && $_POST['pending_reason'] == 'unilateral') {167     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*.');168   }169 170   ipn_debug_email('Breakpoint: 3 - Communication method verified');171   /**172    * Lookup transaction history information in preparation for matching and relevant updates173    */174   $lookupData  = ipn_lookup_transaction($_POST);175   $ordersID    = $lookupData['order_id'];176   $paypalipnID = $lookupData['paypal_ipn_id'];177   $txn_type    = $lookupData['txn_type'];178   $parentLookup = $txn_type;179 180   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']);181 182   if (!$isECtransaction && !isset($_POST['parent_txn_id']) && $txn_type != 'cleared-echeck') {183     if (defined('MODULE_PAYMENT_PAYPAL_PDTTOKEN') && MODULE_PAYMENT_PAYPAL_PDTTOKEN != '') {184       ipn_debug_email('IPN NOTICE :: IPN pausing: waiting for PDT to process. Sleeping 10 seconds ...');185       sleep(10);186     }187     if (ipn_get_stored_session($session_stuff) === false) {188       ipn_debug_email('IPN ERROR :: No pending Website Payments Standard session data available.  Might be a duplicate transaction already entered via PDT.');189       $ipnFoundSession = false;190     }191   }192 193   if ($ipnFoundSession == FALSE && !$isECtransaction && !$isDPtransaction && $txn_type != 'cleared-echeck') {194     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.');195     die();196   }197 198   // 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:199   $new_record_needed = ($txn_type == 'unique' ? true : false);200   /**201    * evaluate what type of transaction we're processing202    */203   $txn_type = ipn_determine_txn_type($_POST, $txn_type);204   ipn_debug_email('Breakpoint: 5 - Transaction type (txn_type) = ' . $txn_type . '   [parentLookup='.$parentLookup.']');205 206   if ($_POST['payment_type'] == 'instant' && $isDPtransaction && ((isset($_POST['auth_status']) && $_POST['auth_status'] == 'Completed') || $_POST['payment_status'] == 'Completed')) {207     ipn_debug_email('IPN NOTICE :: DP/Website Payments Pro notice -- IPN Ignored');208     die();209   }210 211   /**212    * take action based on transaction type and corresponding requirements213    */214   switch ($txn_type) {215     case ($_POST['txn_type'] == 'send_money'):216     case ($_POST['txn_type'] == 'merch_payment'):217     case ($_POST['txn_type'] == 'new_case'):218     case ($_POST['txn_type'] == 'masspay'):219       // these types are irrelevant to ZC transactions220       ipn_debug_email('IPN NOTICE :: Transaction txn_type not relevant to Zen Cart processing. IPN handler aborted.' . $_POST['txn_type']);221       die();222       break;223     case (substr($_POST['txn_type'],0,7) == 'subscr_'):224       // For now we filter out subscription payments225       ipn_debug_email('IPN NOTICE :: Subscription payment - Not currently supported by Zen Cart. IPN handler aborted.');226       die();227       break;228 229     case 'pending-unilateral':230       // cannot process this order because the merchant's PayPal account isn't valid yet231       ipn_debug_email('IPN NOTICE :: Please create a valid PayPal account and follow the steps to *Verify* it. IPN handler aborted.');232       die();233       break;234     case 'pending-address':235     case 'pending-intl':236     case 'pending-multicurrency':237     case 'pending-verify':238       if (!$isECtransaction) {239         ipn_debug_email('IPN NOTICE :: '.$txn_type.' transaction -- inserting initial record for reference purposes');240         $sql_data_array = ipn_create_order_array($ordersID, $txn_type);241         zen_db_perform(TABLE_PAYPAL, $sql_data_array);242         $sql_data_array = ipn_create_order_history_array($paypalipnID);243         zen_db_perform(TABLE_PAYPAL_PAYMENT_STATUS_HISTORY, $sql_data_array);244         die();245         break;246       }247     case (($txn_type == 'express_checkout' || $isECtransaction) && !strstr($txn_type, 'cleared') && $parentLookup != 'parent'):248       if ($_POST['payment_status'] == 'Completed') {249         // This is an express-checkout transaction -- IPN may not be needed250         if (isset($_POST['auth_status']) && $_POST['auth_status'] == 'Completed') {251           ipn_debug_email('IPN NOTICE :: Express Checkout payment notice on completed order -- IPN Ignored');252           die();253         }254       }255       if ($_POST['payment_type'] == 'instant' && isset($_POST['auth_status']) && $_POST['auth_status'] == 'Pending') {256         ipn_debug_email('IPN NOTICE :: EC/DP notice on pre-auth order -- IPN Ignored');257         die();258       }259       ipn_debug_email('Breakpoint: 5 - midstream checkpoint');260       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') {261         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.');262         break;263       }264 265     case ($txn_type == 'cart'):266       ipn_debug_email('IPN NOTICE :: This is a detailed-cart transaction');267 268     case ($txn_type == 'cart' && !$isECtransaction):269       ipn_debug_email('IPN NOTICE :: This is a detailed-cart transaction (i)');270 271     case (substr($txn_type,0,8) == 'pending-' && (int)$ordersID <= 0):272     case ($new_record_needed && $txn_type == 'echeck-cleared'):273     case 'unique':274       /**275        * delete IPN session from PayPal table -- housekeeping276        */277       $db->Execute("delete from " . TABLE_PAYPAL_SESSION . " where session_id = '" . zen_db_input(str_replace('zenid=', '', $_POST['custom'])) . "'");278       /**279        * require shipping class280        */281       require(DIR_WS_CLASSES . 'shipping.php');282       /**283        * require payment class284        */285       require(DIR_WS_CLASSES . 'payment.php');286       $payment_modules = new payment($_SESSION['payment']);287       $shipping_modules = new shipping($_SESSION['shipping']);288       /**289        * require order class290        */291       //这里判断是否获取到了invoice信息,如果获取到,则提取此订单的信息。292       require(DIR_WS_CLASSES . 'order.php');293       if(isset($_POST['invoice']) && $_POST['invoice'] != ''){294           $order = new order($_POST['invoice']);295       }else{296           $order = new order();297       }298       /**299        * require order_total class300        */301       require(DIR_WS_CLASSES . 'order_total.php');302       $order_total_modules = new order_total();303       $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_BEFORE_ORDER_TOTALS_PROCESS');304       $order_totals = $order_total_modules->process();305       $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_TOTALS_PROCESS');306 307       if (valid_payment($order->info['total'], $_SESSION['currency']) === false && !$isECtransaction && !$isDPtransaction) {308         ipn_debug_email('IPN NOTICE :: Failed because of currency mismatch.');309         //需要注意此处,这里的付款货币匹配检查,因为在发送付款数据到paypal时,我们就根据顾客的订单货币方式做出了设定。310         //并且客户更改当前默认货币也不能改变以生成的订单的货币种类,所以这里的判断可以取消,不然死在这里。311         //die();312       }313       if ($ipnFoundSession === false && !$isECtransaction && !$isDPtransaction) {314         ipn_debug_email('IPN NOTICE :: Unique but no session - Assumed to be a personal payment, rather than a new Website Payments Standard transaction. Ignoring.');315         die();316       }317       if (!strstr($txn_type, 'denied') && !strstr($txn_type, 'failed') && !strstr($txn_type, 'voided')) {318         //这里判断,如果获取到了invoice,则跳过生产订单的步骤,之写入Paypal付款信息。319         if(isset($_POST['invoice']) && $_POST['invoice'] != ''){320             $insert_id = $_POST['invoice'];321             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_CREATE');322             ipn_debug_email('Breakpoint: 5a - built order -- OID: ' . $insert_id);323             $sql_data_array = ipn_create_order_array($insert_id, $txn_type);324             ipn_debug_email('Breakpoint: 5b - PP table OID: ' . print_r($sql_data_array, true));325             zen_db_perform(TABLE_PAYPAL, $sql_data_array);326             ipn_debug_email('Breakpoint: 5c - PP table OID saved');327             $pp_hist_id = $db->Insert_ID();328             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_PAYMENT_MODULES_AFTER_ORDER_CREATE');329             ipn_debug_email('Breakpoint: 5d - PP hist ID: ' . $pp_hist_id);330             $sql_data_array = ipn_create_order_history_array($pp_hist_id);331             ipn_debug_email('Breakpoint: 5e - PP hist_data:' . print_r($sql_data_array, true));332             zen_db_perform(TABLE_PAYPAL_PAYMENT_STATUS_HISTORY, $sql_data_array);333             ipn_debug_email('Breakpoint: 5f - PP hist saved');334             $new_status = MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID;335             ipn_debug_email('Breakpoint: 5g - new status code: ' . $new_status);336             if ($_POST['payment_status'] =='Pending') {337                 $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);338                 ipn_debug_email('Breakpoint: 5h - newer status code: ' . (int)$new_status);339                 $sql = "UPDATE " . TABLE_ORDERS  . "340                   SET orders_status = " . (int)$new_status . "341                   WHERE orders_id = '" . (int)$insert_id . "'";342                 $db->Execute($sql);343                 ipn_debug_email('Breakpoint: 5i - order table updated');344             }345             $sql_data_array = array('orders_id' => (int)$insert_id,346                 'orders_status_id' => (int)$new_status,347                 'date_added' => 'now()',348                 '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'],349                 'customer_notified' => 0350             );351             if ($_POST['payment_status'] =='Completed') {352                 $new_status = (defined('MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID') && (int)MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID > 0 ? (int)MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID : 2);353                 ipn_debug_email('Breakpoint: 5h_1 - newer status code: ' . (int)$new_status);354                 $sql = "UPDATE " . TABLE_ORDERS  . "355                   SET orders_status = " . (int)$new_status . "356                   WHERE orders_id = '" . (int)$insert_id . "'";357                 $db->Execute($sql);358                 ipn_debug_email('Breakpoint: 5i_1 - order table updated');359             }360             $sql_data_array = array('orders_id' => (int)$insert_id,361                 'orders_status_id' => (int)$new_status,362                 'date_added' => 'now()',363                 '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'],364                 'customer_notified' => 0365             );366             ipn_debug_email('Breakpoint: 5j - order stat hist update:' . print_r($sql_data_array, true));367             zen_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);368             if (MODULE_PAYMENT_PAYPAL_ADDRESS_OVERRIDE == '1') {369                 $sql_data_array['comments'] = '**** ADDRESS OVERRIDE ALERT!!! **** CHECK PAYPAL ORDER DETAILS FOR ACTUAL ADDRESS SELECTED BY CUSTOMER!!';370                 $sql_data_array['customer_notified'] = -1;371             }372             zen_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);373             ipn_debug_email('Breakpoint: 5k - OSH update done');374             //$order->create_add_products($insert_id, 2);375             ipn_debug_email('Breakpoint: 5L - adding products');376             $_SESSION['order_number_created'] = $insert_id;377             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_CREATE_ADD_PRODUCTS');378             $order->send_order_email($insert_id, 2);379             ipn_debug_email('Breakpoint: 5m - emailing customer');380             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_SEND_ORDER_EMAIL');381             /** Prepare sales-tracking data for use by notifier class **/382             $ototal = $order_subtotal = $credits_applied = 0;383             for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {384                 if ($order_totals[$i]['code'] == 'ot_subtotal') $order_subtotal = $order_totals[$i]['value'];385                 if ($$order_totals[$i]['code']->credit_class == true) $credits_applied += $order_totals[$i]['value'];386                 if ($order_totals[$i]['code'] == 'ot_total') $ototal = $order_totals[$i]['value'];387             }388             $commissionable_order = ($order_subtotal - $credits_applied);389             $commissionable_order_formatted = $currencies->format($commissionable_order);390             $_SESSION['order_summary']['order_number'] = $insert_id;391             $_SESSION['order_summary']['order_subtotal'] = $order_subtotal;392             $_SESSION['order_summary']['credits_applied'] = $credits_applied;393             $_SESSION['order_summary']['order_total'] = $ototal;394             $_SESSION['order_summary']['commissionable_order'] = $commissionable_order;395             $_SESSION['order_summary']['commissionable_order_formatted'] = $commissionable_order_formatted;396             $_SESSION['order_summary']['coupon_code'] = $order->info['coupon_code'];397             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES', 'paypalipn');398             $_SESSION['cart']->reset(true);399             ipn_debug_email('Breakpoint: 5n - emptying cart');400             $ordersID = $insert_id;401             $paypalipnID = $pp_hist_id;402             ipn_debug_email('Breakpoint: 6 - Completed IPN order add.' . '    ordersID = '. $ordersID . '  IPN tracking record = ' . $paypalipnID);403             if (!($new_record_needed && $txn_type == 'echeck-cleared'))  break;404         }else{405             $insert_id = $order->create($order_totals);406             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_CREATE');407             ipn_debug_email('Breakpoint: 5a - built order -- OID: ' . $insert_id);408             $sql_data_array = ipn_create_order_array($insert_id, $txn_type);409             ipn_debug_email('Breakpoint: 5b - PP table OID: ' . print_r($sql_data_array, true));410             zen_db_perform(TABLE_PAYPAL, $sql_data_array);411             ipn_debug_email('Breakpoint: 5c - PP table OID saved');412             $pp_hist_id = $db->Insert_ID();413             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_PAYMENT_MODULES_AFTER_ORDER_CREATE');414             ipn_debug_email('Breakpoint: 5d - PP hist ID: ' . $pp_hist_id);415             $sql_data_array = ipn_create_order_history_array($pp_hist_id);416             ipn_debug_email('Breakpoint: 5e - PP hist_data:' . print_r($sql_data_array, true));417             zen_db_perform(TABLE_PAYPAL_PAYMENT_STATUS_HISTORY, $sql_data_array);418             ipn_debug_email('Breakpoint: 5f - PP hist saved');419             $new_status = MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID;420             ipn_debug_email('Breakpoint: 5g - new status code: ' . $new_status);421             if ($_POST['payment_status'] =='Pending') {422               $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);423               ipn_debug_email('Breakpoint: 5h - newer status code: ' . (int)$new_status);424               $sql = "UPDATE " . TABLE_ORDERS  . "425                       SET orders_status = " . (int)$new_status . "426                       WHERE orders_id = '" . (int)$insert_id . "'";427               $db->Execute($sql);428               ipn_debug_email('Breakpoint: 5i - order table updated');429             }430             $sql_data_array = array('orders_id' => (int)$insert_id,431                                     'orders_status_id' => (int)$new_status,432                                     'date_added' => 'now()',433                                     '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'],434                                     'customer_notified' => 0435                                     );436             ipn_debug_email('Breakpoint: 5j - order stat hist update:' . print_r($sql_data_array, true));437             zen_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);438             if (MODULE_PAYMENT_PAYPAL_ADDRESS_OVERRIDE == '1') {439               $sql_data_array['comments'] = '**** ADDRESS OVERRIDE ALERT!!! **** CHECK PAYPAL ORDER DETAILS FOR ACTUAL ADDRESS SELECTED BY CUSTOMER!!';440               $sql_data_array['customer_notified'] = -1;441             }442             zen_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);443             ipn_debug_email('Breakpoint: 5k - OSH update done');444             $order->create_add_products($insert_id, 2);445             ipn_debug_email('Breakpoint: 5L - adding products');446             $_SESSION['order_number_created'] = $insert_id;447             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_CREATE_ADD_PRODUCTS');448             $order->send_order_email($insert_id, 2);449             ipn_debug_email('Breakpoint: 5m - emailing customer');450             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_SEND_ORDER_EMAIL');451             /** Prepare sales-tracking data for use by notifier class **/452             $ototal = $order_subtotal = $credits_applied = 0;453             for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {454               if ($order_totals[$i]['code'] == 'ot_subtotal') $order_subtotal = $order_totals[$i]['value'];455               if ($$order_totals[$i]['code']->credit_class == true) $credits_applied += $order_totals[$i]['value'];456               if ($order_totals[$i]['code'] == 'ot_total') $ototal = $order_totals[$i]['value'];457             }458             $commissionable_order = ($order_subtotal - $credits_applied);459             $commissionable_order_formatted = $currencies->format($commissionable_order);460             $_SESSION['order_summary']['order_number'] = $insert_id;461             $_SESSION['order_summary']['order_subtotal'] = $order_subtotal;462             $_SESSION['order_summary']['credits_applied'] = $credits_applied;463             $_SESSION['order_summary']['order_total'] = $ototal;464             $_SESSION['order_summary']['commissionable_order'] = $commissionable_order;465             $_SESSION['order_summary']['commissionable_order_formatted'] = $commissionable_order_formatted;466             $_SESSION['order_summary']['coupon_code'] = $order->info['coupon_code'];467             $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_HANDLE_AFFILIATES', 'paypalipn');468             $_SESSION['cart']->reset(true);469             ipn_debug_email('Breakpoint: 5n - emptying cart');470             $ordersID = $insert_id;471             $paypalipnID = $pp_hist_id;472             ipn_debug_email('Breakpoint: 6 - Completed IPN order add.' . '    ordersID = '. $ordersID . '  IPN tracking record = ' . $paypalipnID);473             if (!($new_record_needed && $txn_type == 'echeck-cleared'))  break;474         }475     }476     case 'parent':477     case 'cleared-address':478     case 'cleared-multicurrency':479     case 'cleared-echeck':480     case 'cleared-authorization':481     case 'cleared-verify':482     case 'cleared-intl':483     case 'cleared-review':484     case 'echeck-denied':485     case 'echeck-cleared':486     case 'denied-address':487     case 'denied-multicurrency':488     case 'denied-echeck':489     case 'failed-echeck':490     case 'denied-intl':491     case 'denied':492     case 'voided':493     case 'express-checkout-cleared':494       ipn_debug_email('IPN NOTICE :: Storing order/update details for order #' . $ordersID . ' txn_id: ' . $_POST['txn_id'] . ' PP IPN ID: ' . $paypalipnID);495       if ($txn_type == 'parent') {496         $sql_data_array = ipn_create_order_array($ordersID, $txn_type);497         zen_db_perform(TABLE_PAYPAL, $sql_data_array);498         $paypalipnID = $db->Insert_ID();499       } else {500         $sql_data_array = ipn_create_order_update_array($txn_type);501         zen_db_perform(TABLE_PAYPAL, $sql_data_array, 'update', "txn_id='" . ($txn_type == 'cleared-authorization' ? $_POST['parent_txn_id'] : $_POST['txn_id']) . "'");502         $sql = "select paypal_ipn_id from " . TABLE_PAYPAL . " where txn_id='" . $_POST['txn_id'] . "'";503         $result = $db->Execute($sql);504         $paypalipnID = $result->fields['paypal_ipn_id'];505       }506       $sql_data_array = ipn_create_order_history_array($paypalipnID);507       zen_db_perform(TABLE_PAYPAL_PAYMENT_STATUS_HISTORY, $sql_data_array);508       ipn_debug_email('IPN NOTICE :: Added PP status-history record for order #' . $ordersID . ' txn_id: ' . $_POST['txn_id'] . ' (updated/child) PP IPN ID: ' . $paypalipnID);509 510       switch ($txn_type) {511         case 'voided':512         case ($_POST['payment_status'] == 'Refunded' || $_POST['payment_status'] == 'Reversed' || $_POST['payment_status'] == 'Voided'):513           //payment_status=Refunded or payment_status=Voided514           $new_status = MODULE_PAYMENT_PAYPALWPP_REFUNDED_STATUS_ID;515           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;516           break;517         case 'echeck-denied':518         case 'denied-echeck':519         case 'failed-echeck':520           //payment_status=Denied or failed521           $new_status = ($isECtransaction ? MODULE_PAYMENT_PAYPALWPP_REFUNDED_STATUS_ID : MODULE_PAYMENT_PAYPAL_REFUND_ORDER_STATUS_ID);522           break;523         case 'echeck-cleared':524           $new_status = (defined('MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID') ? MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID : 2);525           break;526         case ($txn_type=='express-checkout-cleared' || substr($txn_type,0,8) == 'cleared-'):527           //express-checkout-cleared528           $new_status = ($isECtransaction && defined('MODULE_PAYMENT_PAYPALWPP_ORDER_STATUS_ID') ? MODULE_PAYMENT_PAYPALWPP_ORDER_STATUS_ID : MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID);529           if ((int)$new_status == 0) $new_status = 2;530           break;531         case 'pending-auth':532           // pending authorization533           $new_status = ($isECtransaction ? MODULE_PAYMENT_PAYPALWPP_REFUNDED_STATUS_ID : MODULE_PAYMENT_PAYPAL_REFUND_ORDER_STATUS_ID);534           break;535         case (substr($txn_type,0,7) == 'denied-'):536           // denied for any other reason - treat as pending for now537         case (substr($txn_type,0,8) == 'pending-'):538           // pending anything539           $new_status = ($isECtransaction ? MODULE_PAYMENT_PAYPALWPP_ORDER_PENDING_STATUS_ID : MODULE_PAYMENT_PAYPAL_PROCESSING_STATUS_ID);540           break;541       }542       // update order status history with new information543       ipn_debug_email('IPN NOTICE :: Set new status ' . $new_status . " for order ID = " .  $ordersID . ($_POST['pending_reason'] != '' ? '.   Reason_code = ' . $_POST['pending_reason'] : '') );544       if ((int)$new_status == 0) $new_status = 1;545       if (in_array($_POST['payment_status'], array('Refunded', 'Reversed', 'Denied', 'Failed'))546            || substr($txn_type,0,8) == 'cleared-' || $txn_type=='echeck-cleared' || $txn_type == 'express-checkout-cleared') {547         ipn_update_orders_status_and_history($ordersID, $new_status, $txn_type);548         $zco_notifier->notify('NOTIFY_PAYPALIPN_STATUS_HISTORY_UPDATE', array($ordersID, $new_status, $txn_type));549       }550       break;551     default:552       // can't understand result found. Thus, logging and aborting.553       ipn_debug_email('IPN WARNING :: Could not process for txn type: ' . $txn_type . "\n" . ' postdata=' . str_replace('&', " \n&", urldecode(print_r($_POST, TRUE))));554   }555   // debug info only556   switch (TRUE) {557     case ($txn_type == 'pending-echeck' && (int)$ordersID > 0):558       ipn_debug_email('IPN NOTICE :: Pending echeck transaction for existing order. No action required. Waiting for echeck to clear.');559       break;560     case ($txn_type == 'pending-multicurrency' && (int)$ordersID > 0):561       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.');562       break;563     case ($txn_type == 'pending-address' && (int)$ordersID > 0):564       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.');565       break;566     case ($txn_type == 'pending-paymentreview' && (int)$ordersID > 0):567       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.');568       break;569   }570 }
View Code

 

9. 前面的所有流程完成之后,先生成订单后付款的功能就已经搞定了,接下来就是在后台修改为付款订单价格数量及运费的问题了。代码如下:

   1 <?php   2 /**   3  * @package admin   4  * @copyright Copyright 2003-2010 Zen Cart Development Team   5  * @copyright Portions Copyright 2003 osCommerce   6  * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0   7  * @version $Id: orders.php 15994 2010-04-19 17:17:51Z ajeh $   8  */   9   10   require('includes/application_top.php');  11     12   require(DIR_WS_CLASSES . 'currencies.php');  13   $currencies = new currencies();  14   15   include(DIR_WS_CLASSES . 'order.php');  16     17   //订单修改提交后的数据处理代码 EOF  18     19   if(!empty($_POST['ot_total']) && isset($_GET[oID]) && $_GET[oID] !=''){  20     21       $update_order_id=$_GET[oID];  22       $products_list=array();  23       $total_list=array();  24       foreach($_POST['reference_oid'] as $value1){  25           $products_list[$value1]=array();  26       }  27     28       $products_list_loop = $products_list;  29     30       foreach($_POST as $key2=>$value2){  31           foreach ($products_list_loop as $key3=>$value3){  32               if($key3 == ltrim(strrchr($key2,'_'),'_')){  33                   $array_key = substr($key2,0,strripos($key2,'_'));  34                   if($array_key != 'qty'){  35                       $products_list[$key3][$array_key] = $value2 / $_POST['currencies_value'];  36                   }else{  37                       $products_list[$key3][$array_key] = $value2;  38                   }  39               }  40           }  41       }  42     43       $order_total_value=$_POST['ot_total'] / $_POST['currencies_value'];  44       $order_total_text=$currencies->format($order_total_value,true,$_POST['currencies_key'],$_POST['currencies_value']);  45     46       $order_subtotal_value=$_POST['ot_subtotal'] / $_POST['currencies_value'];  47       $order_subtotal_text=$currencies->format($order_subtotal_value,true,$_POST['currencies_key'],$_POST['currencies_value']);  48     49       $order_shipping_value=$_POST['ot_shipping'] / $_POST['currencies_value'];;  50       $order_shipping_text=$currencies->format($order_shipping_value,true,$_POST['currencies_key'],$_POST['currencies_value']);  51     52       //       $order_gv_text=$_POST['ot_gv'];  53       //       $order_gv_value=$_POST['ot_gv'];  54     55       //       $order_coupon_text=$_POST['ot_coupon'];  56       //       $order_coupon_value=$_POST['ot_coupon'];  57     58       foreach($products_list as $key4=>$value4){  59           $sql_update_order_products="update " . TABLE_ORDERS_PRODUCTS . "  60                                       set products_price = " . $products_list[$key4]['price_ex'] . " , final_price = " . $products_list[$key4]['price_ex'] . " , products_quantity = " . $products_list[$key4]['qty'] . "  61                                       where orders_id =  " . $update_order_id . " and products_id =  " . $key4;  62           $db->Execute($sql_update_order_products);  63           //           echo "更新产品价格和数量: " . $sql_update_order_products . "<br />";  64           //           var_dump($db->Execute($sql_update_order_products));  65           //           echo '<br />';  66       }  67     68       if($order_subtotal_text){  69           $sql_update_subtotal="update " . TABLE_ORDERS_TOTAL . "  70                                    set text = '" . $order_subtotal_text . "' , value = " . $order_subtotal_value ."  71                                    where orders_id = " . $update_order_id . " and class = 'ot_subtotal'";  72           $db->Execute($sql_update_subtotal);  73           //           echo "更新产品总价: " . $sql_update_subtotal . "<br />";  74           //           var_dump($db->Execute($sql_update_subtotal));  75           //           echo '<br />';  76       }  77     78       if($order_shipping_text){  79           $sql_update_shipping="update " . TABLE_ORDERS_TOTAL . "  80                                    set text = '" . $order_shipping_text . "' , value = " . $order_shipping_value ."  81                                    where orders_id = " . $update_order_id . " and class = 'ot_shipping'";  82           $db->Execute($sql_update_shipping);  83           //           echo "更新运费价格: " . $sql_update_shipping . "<br />";  84           //           var_dump($db->Execute($sql_update_shipping));  85           //           echo '<br />';  86       }  87     88       if($order_total_text){  89           $sql_update_total="update " . TABLE_ORDERS_TOTAL . "  90                                    set text = '" . $order_total_text . "' , value = " . $order_total_value ."  91                                    where orders_id = " . $update_order_id . " and class = 'ot_total'";  92           $db->Execute($sql_update_total);  93           //           echo "更新订单总价: " . $sql_update_total . "<br />";  94           //           var_dump($db->Execute($sql_update_total));  95           //           echo '<br />';  96     97           $sql_update_order="update " . TABLE_ORDERS . " set order_total = " .$order_total_value . " where orders_id = " . $update_order_id;  98           $db->Execute($sql_update_order);  99           //           echo "更新订单: " . $sql_update_order . '<br />'; 100           //           var_dump($db->Execute($sql_update_order)); 101           //           echo '<br />'; 102       } 103    104       echo "<script language=JavaScript> location.replace(location.href);</script>"; 105       //       echo '<pre>'; 106       //       echo "汇率: ".$_POST['currencies_value'] . '<br />'; 107       //       echo "转成默认货币:" . $order_total_value / $_POST['currencies_value'] . '<br />'; 108       //       echo '<br />'; 109       //       echo "交易货币值: ".$order_total_value."<br />"; 110       //       echo "转成交易货币样式: " . $currencies->format(($order_total_value / $_POST['currencies_value']),true,$_POST['currencies_key'],$_POST['currencies_value']); 111       //       print_r($products_list); 112       //       print_r($_POST); 113       //       echo '</pre>'; 114   } 115    116   //订单修改提交后的数据处理代码 BOF 117    118   // prepare order-status pulldown list 119   $orders_statuses = array(); 120   $orders_status_array = array(); 121   $orders_status = $db->Execute("select orders_status_id, orders_status_name 122                                  from " . TABLE_ORDERS_STATUS . " 123                                  where language_id = '" . (int)$_SESSION['languages_id'] . "' order by orders_status_id"); 124   while (!$orders_status->EOF) { 125     $orders_statuses[] = array('id' => $orders_status->fields['orders_status_id'], 126                                'text' => $orders_status->fields['orders_status_name'] . ' [' . $orders_status->fields['orders_status_id'] . ']'); 127     $orders_status_array[$orders_status->fields['orders_status_id']] = $orders_status->fields['orders_status_name']; 128     $orders_status->MoveNext(); 129   } 130  131   $action = (isset($_GET['action']) ? $_GET['action'] : ''); 132   $order_exists = false; 133   if (isset($_GET['oID']) && trim($_GET['oID']) == '') unset($_GET['oID']); 134   if ($action == 'edit' && !isset($_GET['oID'])) $action = ''; 135  136   if (isset($_GET['oID'])) { 137     $oID = zen_db_prepare_input(trim($_GET['oID'])); 138  139     $orders = $db->Execute("select orders_id from " . TABLE_ORDERS . " 140                             where orders_id = '" . $oID . "'"); 141     $order_exists = true; 142     if ($orders->RecordCount() <= 0) { 143       $order_exists = false; 144       if ($action != '') $messageStack->add_session(ERROR_ORDER_DOES_NOT_EXIST . ' ' . $oID, 'error'); 145       zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')), 'NONSSL')); 146     } 147   } 148  149   if (zen_not_null($action) && $order_exists == true) { 150     switch ($action) { 151       case 'edit': 152       // reset single download to on 153         if ($_GET['download_reset_on'] > 0) { 154           // adjust download_maxdays based on current date 155           $check_status = $db->Execute("select customers_name, customers_email_address, orders_status,orders_num, 156                                       date_purchased from " . TABLE_ORDERS . " 157                                       where orders_id = '" . $_GET['oID'] . "'"); 158           $zc_max_days = zen_date_diff($check_status->fields['date_purchased'], date('Y-m-d H:i:s', time())) + DOWNLOAD_MAX_DAYS; 159  160           $update_downloads_query = "update " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . " set download_maxdays='" . $zc_max_days . "', download_count='" . DOWNLOAD_MAX_COUNT . "' where orders_id='" . $_GET['oID'] . "' and orders_products_download_id='" . $_GET['download_reset_on'] . "'"; 161           $db->Execute($update_downloads_query); 162           unset($_GET['download_reset_on']); 163  164           $messageStack->add_session(SUCCESS_ORDER_UPDATED_DOWNLOAD_ON, 'success'); 165           zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 166         } 167       // reset single download to off 168         if ($_GET['download_reset_off'] > 0) { 169           // adjust download_maxdays based on current date 170           // *** fix: adjust count not maxdays to cancel download 171 //          $update_downloads_query = "update " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . " set download_maxdays='0', download_count='0' where orders_id='" . $_GET['oID'] . "' and orders_products_download_id='" . $_GET['download_reset_off'] . "'"; 172           $update_downloads_query = "update " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . " set download_count='0' where orders_id='" . $_GET['oID'] . "' and orders_products_download_id='" . $_GET['download_reset_off'] . "'"; 173           unset($_GET['download_reset_off']); 174           $db->Execute($update_downloads_query); 175  176           $messageStack->add_session(SUCCESS_ORDER_UPDATED_DOWNLOAD_OFF, 'success'); 177           zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 178         } 179       break; 180       case 'update_order': 181         // demo active test 182         if (zen_admin_demo()) { 183           $_GET['action']= ''; 184           $messageStack->add_session(ERROR_ADMIN_DEMO, 'caution'); 185           zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 186         } 187         $oID = zen_db_prepare_input($_GET['oID']); 188         $status = zen_db_prepare_input($_POST['status']); 189         $comments = zen_db_prepare_input($_POST['comments']); 190         $tracking_number = zen_db_prepare_input($_POST['tracking_number']); 191  192         $order_updated = false; 193         $check_status = $db->Execute("select customers_name, customers_email_address, orders_status,orders_num,tracking_number, 194                                       date_purchased from " . TABLE_ORDERS . " 195                                       where orders_id = '" . $oID . "'"); 196  197         if ( ($check_status->fields['orders_status'] != $status) || zen_not_null($comments)) { 198           $db->Execute("update " . TABLE_ORDERS . " 199                         set orders_status = '" . zen_db_input($status) . "', last_modified = now(), tracking_number = '" . zen_db_input($tracking_number) . "' 200                         where orders_id = '" . $oID . "'"); 201  202           $customer_notified = '0'; 203           if (isset($_POST['notify']) && ($_POST['notify'] == '1')) { 204  205             $notify_comments = ''; 206             if (isset($_POST['notify_comments']) && ($_POST['notify_comments'] == 'on') && zen_not_null($comments)) { 207               $notify_comments = EMAIL_TEXT_COMMENTS_UPDATE . $comments . "\n\n"; 208             } 209             //send emails 210             $message = 211             EMAIL_TEXT_ORDER_NUMBER . ' ' . $check_status->fields['orders_num'] . "\n\n" . 212             EMAIL_TEXT_INVOICE_URL . ' ' . zen_catalog_href_link(FILENAME_CATALOG_ACCOUNT_HISTORY_INFO, 'order_id=' . $oID, 'SSL') . "\n\n" . 213             EMAIL_TEXT_DATE_ORDERED . ' ' . zen_date_long($check_status->fields['date_purchased']) . "\n\n" . 214             strip_tags($notify_comments) . 215             EMAIL_TEXT_STATUS_UPDATED . sprintf(EMAIL_TEXT_STATUS_LABEL, $orders_status_array[$status] ) . 216             EMAIL_TEXT_STATUS_PLEASE_REPLY; 217  218             $html_msg['EMAIL_CUSTOMERS_NAME']    = $check_status->fields['customers_name']; 219             $html_msg['EMAIL_TEXT_ORDER_NUMBER'] = EMAIL_TEXT_ORDER_NUMBER . ' ' . $check_status->fields['orders_num']; 220             $html_msg['EMAIL_TEXT_INVOICE_URL']  = '<a href="' . zen_catalog_href_link(FILENAME_CATALOG_ACCOUNT_HISTORY_INFO, 'order_id=' . $oID, 'SSL') .'">'.str_replace(':','',EMAIL_TEXT_INVOICE_URL).'</a>'; 221             $html_msg['EMAIL_TEXT_DATE_ORDERED'] = EMAIL_TEXT_DATE_ORDERED . ' ' . zen_date_long($check_status->fields['date_purchased']); 222             $html_msg['EMAIL_TEXT_STATUS_COMMENTS'] = nl2br($notify_comments); 223             $html_msg['EMAIL_TEXT_STATUS_UPDATED'] = str_replace('\n','', EMAIL_TEXT_STATUS_UPDATED); 224             $html_msg['EMAIL_TEXT_STATUS_LABEL'] = str_replace('\n','', sprintf(EMAIL_TEXT_STATUS_LABEL, $orders_status_array[$status] )); 225             $html_msg['EMAIL_TEXT_NEW_STATUS'] = $orders_status_array[$status]; 226             $html_msg['EMAIL_TEXT_STATUS_PLEASE_REPLY'] = str_replace('\n','', EMAIL_TEXT_STATUS_PLEASE_REPLY); 227  228             zen_mail($check_status->fields['customers_name'], $check_status->fields['customers_email_address'], EMAIL_TEXT_SUBJECT . ' #' . $check_status->fields['orders_num'], $message, STORE_NAME, EMAIL_FROM, $html_msg, 'order_status'); 229             $customer_notified = '1'; 230  231             //send extra emails 232             if (SEND_EXTRA_ORDERS_STATUS_ADMIN_EMAILS_TO_STATUS == '1' and SEND_EXTRA_ORDERS_STATUS_ADMIN_EMAILS_TO != '') { 233               zen_mail('', SEND_EXTRA_ORDERS_STATUS_ADMIN_EMAILS_TO, SEND_EXTRA_ORDERS_STATUS_ADMIN_EMAILS_TO_SUBJECT . ' ' . EMAIL_TEXT_SUBJECT . ' #' . $check_status->fields['orders_num'], $message, STORE_NAME, EMAIL_FROM, $html_msg, 'order_status_extra'); 234             } 235           } elseif (isset($_POST['notify']) && ($_POST['notify'] == '-1')) { 236             // hide comment 237             $customer_notified = '-1'; 238           } 239  240           $db->Execute("insert into " . TABLE_ORDERS_STATUS_HISTORY . " 241                       (orders_id, orders_status_id, date_added, customer_notified, comments) 242                       values ('" . $oID . "', 243                       '" . zen_db_input($status) . "', 244                       now(), 245                       '" . zen_db_input($customer_notified) . "', 246                       '" . zen_db_input($comments)  . "')"); 247           $order_updated = true; 248         } 249  250         // trigger any appropriate updates which should be sent back to the payment gateway: 251         $order = new order($oID); 252         if ($order->info['payment_module_code']) { 253           if (file_exists(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php')) { 254             require_once(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php'); 255             require_once(DIR_FS_CATALOG_LANGUAGES . $_SESSION['language'] . '/modules/payment/' . $order->info['payment_module_code'] . '.php'); 256             $module = new $order->info['payment_module_code']; 257             if (method_exists($module, '_doStatusUpdate')) { 258               $response = $module->_doStatusUpdate($oID, $status, $comments, $customer_notified, $check_status->fields['orders_status']); 259             } 260           } 261         } 262  263         if ($order_updated == true) { 264          if ($status == DOWNLOADS_ORDERS_STATUS_UPDATED_VALUE) { 265             // adjust download_maxdays based on current date 266             $zc_max_days = zen_date_diff($check_status->fields['date_purchased'], date('Y-m-d H:i:s', time())) + DOWNLOAD_MAX_DAYS; 267  268             $update_downloads_query = "update " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . " set download_maxdays='" . $zc_max_days . "', download_count='" . DOWNLOAD_MAX_COUNT . "' where orders_id='" . $oID . "'"; 269             $db->Execute($update_downloads_query); 270           } 271           $messageStack->add_session(SUCCESS_ORDER_UPDATED, 'success'); 272         } else { 273           $messageStack->add_session(WARNING_ORDER_NOT_UPDATED, 'warning'); 274         } 275         zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 276         break; 277       case 'deleteconfirm': 278         // demo active test 279         if (zen_admin_demo()) { 280           $_GET['action']= ''; 281           $messageStack->add_session(ERROR_ADMIN_DEMO, 'caution'); 282           zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')), 'NONSSL')); 283         } 284         $oID = zen_db_prepare_input($_GET['oID']); 285  286         zen_remove_order($oID, $_POST['restock']); 287  288         zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')), 'NONSSL')); 289         break; 290       case 'delete_cvv': 291         $delete_cvv = $db->Execute("update " . TABLE_ORDERS . " set cc_cvv = '" . TEXT_DELETE_CVV_REPLACEMENT . "' where orders_id = '" . (int)$_GET['oID'] . "'"); 292         zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 293         break; 294       case 'mask_cc': 295         $result  = $db->Execute("select cc_number from " . TABLE_ORDERS . " where orders_id = '" . (int)$_GET['oID'] . "'"); 296         $old_num = $result->fields['cc_number']; 297         $new_num = substr($old_num, 0, 4) . str_repeat('*', (strlen($old_num) - 8)) . substr($old_num, -4); 298         $mask_cc = $db->Execute("update " . TABLE_ORDERS . " set cc_number = '" . $new_num . "' where orders_id = '" . (int)$_GET['oID'] . "'"); 299         zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 300         break; 301  302       case 'doRefund': 303         $order = new order($oID); 304         if ($order->info['payment_module_code']) { 305           if (file_exists(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php')) { 306             require_once(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php'); 307             require_once(DIR_FS_CATALOG_LANGUAGES . $_SESSION['language'] . '/modules/payment/' . $order->info['payment_module_code'] . '.php'); 308             $module = new $order->info['payment_module_code']; 309             if (method_exists($module, '_doRefund')) { 310               $module->_doRefund($oID); 311             } 312           } 313         } 314         zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 315         break; 316       case 'doAuth': 317         $order = new order($oID); 318         if ($order->info['payment_module_code']) { 319           if (file_exists(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php')) { 320             require_once(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php'); 321             require_once(DIR_FS_CATALOG_LANGUAGES . $_SESSION['language'] . '/modules/payment/' . $order->info['payment_module_code'] . '.php'); 322             $module = new $order->info['payment_module_code']; 323             if (method_exists($module, '_doAuth')) { 324               $module->_doAuth($oID, $order->info['total'], $order->info['currency']); 325             } 326           } 327         } 328         zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 329         break; 330       case 'doCapture': 331         $order = new order($oID); 332         if ($order->info['payment_module_code']) { 333           if (file_exists(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php')) { 334             require_once(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php'); 335             require_once(DIR_FS_CATALOG_LANGUAGES . $_SESSION['language'] . '/modules/payment/' . $order->info['payment_module_code'] . '.php'); 336             $module = new $order->info['payment_module_code']; 337             if (method_exists($module, '_doCapt')) { 338               $module->_doCapt($oID, 'Complete', $order->info['total'], $order->info['currency']); 339             } 340           } 341         } 342         zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 343         break; 344       case 'doVoid': 345         $order = new order($oID); 346         if ($order->info['payment_module_code']) { 347           if (file_exists(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php')) { 348             require_once(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php'); 349             require_once(DIR_FS_CATALOG_LANGUAGES . $_SESSION['language'] . '/modules/payment/' . $order->info['payment_module_code'] . '.php'); 350             $module = new $order->info['payment_module_code']; 351             if (method_exists($module, '_doVoid')) { 352               $module->_doVoid($oID); 353             } 354           } 355         } 356         zen_redirect(zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=edit', 'NONSSL')); 357         break; 358     } 359   } 360 ?> 361 <!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"> 362 <html <?php echo HTML_PARAMS; ?>> 363 <head> 364 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo CHARSET; ?>"> 365 <title><?php echo TITLE; ?></title> 366 <link rel="stylesheet" type="text/css" href="includes/stylesheet.css"> 367 <link rel="stylesheet" type="text/css" media="print" href="includes/stylesheet_print.css"> 368 <link rel="stylesheet" type="text/css" href="includes/cssjsmenuhover.css" media="all" id="hoverJS"> 369 <script language="javascript" src="includes/menu.js"></script> 370 <script language="javascript" src="includes/general.js"></script> 371 <script type="text/javascript"> 372   <!-- 373   function init() 374   { 375     cssjsmenu('navbar'); 376     if (document.getElementById) 377     { 378       var kill = document.getElementById('hoverJS'); 379       kill.disabled = true; 380     } 381   } 382   // --> 383 </script> 384 <script language="javascript" type="text/javascript"><!-- 385 function couponpopupWindow(url) { 386   window.open(url,'popupWindow','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,copyhistory=no,width=450,height=280,screenX=150,screenY=150,top=150,left=150') 387 } 388 //--></script> 389 <link rel="stylesheet" type="text/css" href="includes/javascript/spiffyCal/spiffyCal_v2_1.css"> 390 <script language="JavaScript" src="includes/javascript/spiffyCal/spiffyCal_v2_1.js"></script> 391  392 <?php //引入一个jquery库,然后就是控制修改价格的Jquery代码 EOF ?> 393 <script language="JavaScript" src="includes/javascript/jquery.min.js"></script> 394 <script type="text/javascript"> 395 $(document).ready(function(){ 396     $("#orders_edit").click(function(){ 397       $("#orders_submit").show(); 398       $("#orders_reset").show(); 399       $("#orders_edit").hide(); 400       $("#products_list_changes").show(); 401       $("#products_list_default").hide(); 402     }); 403      404     $("#orders_reset").click(function(){ 405       location.replace(location.href); 406     }); 407      408     $("#orders_submit").click(function(){ 409         if($("input[name='ot_total']").val()<0){ 410             alert("总价格为负数,这不符合规定"); 411             return false;   412         } 413     }); 414    415     $("#products_list_changes input").keypress(function(event) {   416       var keyCode = event.which;   417       if (keyCode == 46 || (keyCode >= 48 && keyCode <=57) || keyCode == 8)  418           return true;   419       else   420           return false;   421     }).focus(function() {   422       this.style.imeMode='disabled';   423     });  424 }); 425  426 function init() 427 { 428 cssjsmenu('navbar'); 429 if (document.getElementById) 430 { 431   var kill = document.getElementById('hoverJS'); 432   kill.disabled = true; 433 } 434 } 435  436 function selectAll(){ 437   var checklist = document.getElementsByName ("order_id[]"); 438     if(document.getElementById("select_all").checked) 439     { 440     for(var i=0;i<checklist.length;i++) 441     { 442        checklist[i].checked = 1; 443     } 444   }else{ 445    for(var j=0;j<checklist.length;j++) 446    { 447       checklist[j].checked = 0; 448    } 449  } 450 } 451    452 //加法运算 453 function accAdd(arg1,arg2){ 454     var r1,r2,m; 455     try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 456     try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 457     m=Math.pow(10,Math.max(r1,r2)) 458     return ((arg1*m+arg2*m)/m).toFixed(2); 459   }  460  461 //减法运算 462 function accSub(arg1, arg2) { 463     var r1, r2, m, n; 464     try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 } 465     try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 } 466     m = Math.pow(10, Math.max(r1, r2)); 467     n = (r1 >= r2) ? r1 : r2; 468     return ((arg1 * m - arg2 * m) / m).toFixed(n); 469   } 470  471 //乘法运算 472 function accMul(arg1,arg2) 473 { 474   var m=0,s1=arg1.toString(),s2=arg2.toString(); 475   try{m+=s1.split(".")[1].length}catch(e){} 476   try{m+=s2.split(".")[1].length}catch(e){} 477   return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m) 478 }  479  480 //除法运算 481 function accDiv(arg1, arg2) { 482     var t1 = 0, t2 = 0, r1, r2; 483     try { t1 = arg1.toString().split(".")[1].length } catch (e) { } 484     try { t2 = arg2.toString().split(".")[1].length } catch (e) { } 485     with (Math) { 486         r1 = Number(arg1.toString().replace(".", "")) 487         r2 = Number(arg2.toString().replace(".", "")) 488         return (r1 / r2) * pow(10, t2 - t1); 489     } 490   } 491  492 function change_price_ex(order_id,final_price){ 493     var products_qty_simple = "qty_"+order_id; 494     var products_qty = $("input[name='"+products_qty_simple+"']").val(); 495     var price_ex_value_simple = "price_ex_"+order_id; 496     var price_ex_value = $("input[name='"+price_ex_value_simple+"']").val(); 497      498     if(isNaN(price_ex_value)){ 499         alert("你输入的不是数字,价格将恢复到原始值,请重新输入正确的价格。"); 500         $("input[name='"+price_ex_value_simple+"']").val(final_price); 501         var price_ex_value = $("input[name='"+price_ex_value_simple+"']").val(); 502     }else{ 503         var numindex = parseInt(price_ex_value.indexOf("."),10); 504         if(numindex > 0){ 505             var head = price_ex_value.substring(0,numindex); 506             var bottom = price_ex_value.substring(numindex,numindex+3); 507             var fianlNum = head+bottom; 508             $("input[name='"+price_ex_value_simple+"']").val(fianlNum); 509             var price_ex_value = fianlNum; 510         } 511     } 512     var total_ex_value = (accMul(price_ex_value,products_qty)).toFixed(2); 513     var total_ex = "total_ex_"+order_id; 514     var total_ex_hidden = "total_ex_hidden_"+order_id; 515     var price_inc = "price_inc_"+order_id; 516     var total_inc = "total_inc_"+order_id; 517     $("input[name='"+total_ex+"']").val(total_ex_value); 518     $("#"+total_ex_hidden).text(total_ex_value); 519     $("input[name='"+price_inc+"']").val(price_ex_value); 520     $("input[name='"+total_inc+"']").val(total_ex_value); 521      522     var str=0; 523     $("#price_total p").each(function (i){ 524         str =  accAdd(str,parseFloat($(this).text())); 525     }) 526      527     $("input[name='ot_subtotal']").val(str); 528  529     var ot_subtotal = parseFloat($("input[name='ot_subtotal']").val()); 530     var ot_coupon = $("input[name='ot_coupon']").val(); 531     if(ot_coupon==undefined){ 532         ot_coupon=0; 533     } 534     var ot_gv = $("input[name='ot_gv']").val(); 535     if(ot_gv==undefined){ 536         ot_gv=0; 537     } 538     var ot_shipping = parseFloat($("input[name='ot_shipping']").val()); 539     var ot_total = accSub(accSub(accAdd(ot_subtotal,ot_shipping),ot_coupon),ot_gv); 540     $("input[name='ot_total']").val(ot_total); 541 } 542  543 function change_qty(order_id){ 544     var products_qty_simple = "qty_"+order_id; 545     var products_qty = parseInt($("input[name='"+products_qty_simple+"']").val()); 546     if(isNaN(products_qty) || products_qty==0){ 547         products_qty=""; 548     } 549     var price_ex_value_simple = "price_ex_"+order_id; 550     var price_ex_value = $("input[name='"+price_ex_value_simple+"']").val(); 551     $("input[name='"+products_qty_simple+"']").val(products_qty); 552      553     var total_ex_value = (accMul(price_ex_value,products_qty)).toFixed(2); 554     var total_ex = "total_ex_"+order_id; 555     var total_ex_hidden = "total_ex_hidden_"+order_id; 556     var price_inc = "price_inc_"+order_id; 557     var total_inc = "total_inc_"+order_id; 558     $("input[name='"+total_ex+"']").val(total_ex_value); 559     $("#"+total_ex_hidden).text(total_ex_value); 560     $("input[name='"+total_inc+"']").val(total_ex_value); 561      562     var str=0; 563     $("#price_total p").each(function (i){ 564         str =  accAdd(str,parseFloat($(this).text())); 565     }) 566      567     $("input[name='ot_subtotal']").val(str); 568  569     var ot_subtotal = parseFloat($("input[name='ot_subtotal']").val()); 570     var ot_coupon = $("input[name='ot_coupon']").val(); 571     if(ot_coupon==undefined){ 572         ot_coupon=0; 573     } 574     var ot_gv = $("input[name='ot_gv']").val(); 575     if(ot_gv==undefined){ 576         ot_gv=0; 577     } 578     var ot_shipping = parseFloat($("input[name='ot_shipping']").val()); 579     var ot_total = accSub(accSub(accAdd(ot_subtotal,ot_shipping),ot_coupon),ot_gv); 580     $("input[name='ot_total']").val(ot_total); 581 } 582  583 function change_shipping(shipping_total){ 584     var ot_shipping = $("input[name='ot_shipping']").val(); 585     if(isNaN(ot_shipping)){ 586         alert("你输入的不是数字,运费将恢复到原始值,请重新输入正确的运费。"); 587         $("input[name='ot_shipping']").val(shipping_total); 588         var ot_shipping = parseFloat($("input[name='ot_shipping']").val()); 589     }else{ 590         var numindex = parseInt(ot_shipping.indexOf("."),10); 591         if(numindex > 0){ 592             var head = ot_shipping.substring(0,numindex); 593             var bottom = ot_shipping.substring(numindex,numindex+3); 594             var fianlNum = head+bottom; 595             $("input[name='ot_shipping']").val(fianlNum); 596             var ot_shipping = fianlNum; 597         } 598     } 599     var ot_subtotal = parseFloat($("input[name='ot_subtotal']").val()); 600     var ot_coupon = $("input[name='ot_coupon']").val(); 601     if(ot_coupon==undefined){ 602         ot_coupon=0; 603     } 604     var ot_gv = $("input[name='ot_gv']").val(); 605     if(ot_gv==undefined){ 606         ot_gv=0; 607     } 608     var ot_total = accSub(accSub(accAdd(ot_subtotal,ot_shipping),ot_coupon),ot_gv); 609     $("input[name='ot_total']").val(ot_total); 610 } 611  612 function price_ex_onlive(order_id,final_price){ 613     var products_qty_simple = "qty_"+order_id; 614     var products_qty = $("input[name='"+products_qty_simple+"']").val(); 615     var price_ex_value_simple = "price_ex_"+order_id; 616     var price_ex_value = $("input[name='"+price_ex_value_simple+"']").val(); 617      618     if(price_ex_value==""){ 619         alert("你输入的不是数字,价格将恢复到原始值,请重新输入正确的价格。"); 620         $("input[name='"+price_ex_value_simple+"']").val(final_price); 621         var price_ex_value = $("input[name='"+price_ex_value_simple+"']").val(); 622     } 623     var total_ex_value = (accMul(price_ex_value,products_qty)).toFixed(2); 624     var total_ex = "total_ex_"+order_id; 625     var total_ex_hidden = "total_ex_hidden_"+order_id; 626     var price_inc = "price_inc_"+order_id; 627     var total_inc = "total_inc_"+order_id; 628     $("input[name='"+total_ex+"']").val(total_ex_value); 629     $("#"+total_ex_hidden).text(total_ex_value); 630     $("input[name='"+price_inc+"']").val(price_ex_value); 631     $("input[name='"+total_inc+"']").val(total_ex_value); 632      633     var str=0; 634     $("#price_total p").each(function (i){ 635         str =  accAdd(str,parseFloat($(this).text())); 636     }) 637      638     $("input[name='ot_subtotal']").val(str); 639  640     var ot_subtotal = parseFloat($("input[name='ot_subtotal']").val()); 641     var ot_coupon = $("input[name='ot_coupon']").val(); 642     if(ot_coupon==undefined){ 643         ot_coupon=0; 644     } 645     var ot_gv = $("input[name='ot_gv']").val(); 646     if(ot_gv==undefined){ 647         ot_gv=0; 648     } 649     var ot_shipping = parseFloat($("input[name='ot_shipping']").val()); 650     var ot_total = accSub(accSub(accAdd(ot_subtotal,ot_shipping),ot_coupon),ot_gv); 651     $("input[name='ot_total']").val(ot_total); 652 } 653  654 function qty_onlive(order_id,qty){ 655     var products_qty_simple = "qty_"+order_id; 656     var products_qty = parseInt($("input[name='"+products_qty_simple+"']").val()); 657     if(isNaN(products_qty) || products_qty==0){ 658         alert("你输入的不是数字,数量将恢复到原始值,请重新输入正确的数量。"); 659         products_qty=qty; 660     } 661     var price_ex_value_simple = "price_ex_"+order_id; 662     var price_ex_value = $("input[name='"+price_ex_value_simple+"']").val(); 663     $("input[name='"+products_qty_simple+"']").val(products_qty); 664      665     var total_ex_value = (accMul(price_ex_value,products_qty)).toFixed(2); 666     var total_ex = "total_ex_"+order_id; 667     var total_ex_hidden = "total_ex_hidden_"+order_id; 668     var price_inc = "price_inc_"+order_id; 669     var total_inc = "total_inc_"+order_id; 670     $("input[name='"+total_ex+"']").val(total_ex_value); 671     $("#"+total_ex_hidden).text(total_ex_value); 672     $("input[name='"+total_inc+"']").val(total_ex_value); 673      674     var str=0; 675     $("#price_total p").each(function (i){ 676         str =  accAdd(str,parseFloat($(this).text())); 677     }) 678      679     $("input[name='ot_subtotal']").val(str); 680  681     var ot_subtotal = parseFloat($("input[name='ot_subtotal']").val()); 682     var ot_coupon = $("input[name='ot_coupon']").val(); 683     if(ot_coupon==undefined){ 684         ot_coupon=0; 685     } 686     var ot_gv = $("input[name='ot_gv']").val(); 687     if(ot_gv==undefined){ 688         ot_gv=0; 689     } 690     var ot_shipping = parseFloat($("input[name='ot_shipping']").val()); 691     var ot_total = accSub(accSub(accAdd(ot_subtotal,ot_shipping),ot_coupon),ot_gv); 692     $("input[name='ot_total']").val(ot_total); 693 } 694  695 function shipping_onlive(shipping_total){ 696     var ot_shipping = $("input[name='ot_shipping']").val(); 697     if(ot_shipping==""){ 698         alert("你输入的不是数字,运费将恢复到原始值,请重新输入正确的运费。"); 699         $("input[name='ot_shipping']").val(shipping_total); 700         var ot_shipping = parseFloat($("input[name='ot_shipping']").val()); 701     } 702     var ot_subtotal = parseFloat($("input[name='ot_subtotal']").val()); 703     var ot_coupon = $("input[name='ot_coupon']").val(); 704     if(ot_coupon==undefined){ 705         ot_coupon=0; 706     } 707     var ot_gv = $("input[name='ot_gv']").val(); 708     if(ot_gv==undefined){ 709         ot_gv=0; 710     } 711     var ot_total = accSub(accSub(accAdd(ot_subtotal,ot_shipping),ot_coupon),ot_gv); 712     $("input[name='ot_total']").val(ot_total); 713 } 714  715 <?php //引入一个jquery库,然后就是控制修改价格的Jquery代码 BOF ?> 716  717 </script> 718 </head> 719 <body onLoad="init()"> 720 <div id="spiffycalendar" class="text"></div> 721 <!-- header //--> 722 <div class="header-area"> 723 <?php 724   require(DIR_WS_INCLUDES . 'header.php'); 725 ?> 726 </div> 727 <!-- header_eof //--> 728  729 <!-- body //--> 730 <table border="0" width="100%" cellspacing="2" cellpadding="2"> 731   <tr> 732 <!-- body_text //--> 733  734 <?php if ($action == '') { ?> 735 <!-- search --> 736     <td width="100%" valign="top"><table border="0" width="100%" cellspacing="0" cellpadding="2"> 737       <tr> 738         <td><table border="0" width="100%" cellspacing="0" cellpadding="0"> 739          <tr><?php echo zen_draw_form('search', FILENAME_ORDERS, '', 'get', '', true); ?> 740             <td width="65%" class="pageHeading" align="right"><?php echo zen_draw_separator('pixel_trans.gif', 1, HEADING_IMAGE_HEIGHT); ?></td> 741             <td colspan="2" class="smallText" align="right"> 742 <?php 743 // show reset search 744   if ((isset($_GET['search']) && zen_not_null($_GET['search'])) or $_GET['cID'] !='' or isset($_GET['start']) or isset($_GET['end'])) { 745     echo '<a href="' . zen_href_link(FILENAME_ORDERS, '', 'NONSSL') . '">' . zen_image_button('button_reset.gif', IMAGE_RESET) . '</a><br />'; 746   } 747 ?> 748 <?php 749   echo  'Search by orders num or Customer Information:' . zen_draw_input_field('search') . zen_hide_session_id(); 750   if (isset($_GET['search']) && zen_not_null($_GET['search'])) { 751     $keywords = zen_db_input(zen_db_prepare_input($_GET['search'])); 752     echo '<br/ >' . TEXT_INFO_SEARCH_DETAIL_FILTER . $keywords; 753   } 754 ?> 755             </td> 756           </form> 757  758  759          <?php echo zen_draw_form('search_orders_products', FILENAME_ORDERS, '', 'get', '', true); ?> 760             <td class="pageHeading" align="right"><?php echo zen_draw_separator('pixel_trans.gif', 1, HEADING_IMAGE_HEIGHT); ?></td> 761             <td colspan="2" class="smallText" align="right"> 762 <?php 763 // show reset search orders_products 764   if ((isset($_GET['search_orders_products']) && zen_not_null($_GET['search_orders_products'])) or $_GET['cID'] !='') { 765     echo '<a href="' . zen_href_link(FILENAME_ORDERS, '', 'NONSSL') . '">' . zen_image_button('button_reset.gif', IMAGE_RESET) . '</a><br />'; 766   } 767 ?> 768 <?php 769   echo HEADING_TITLE_SEARCH_DETAIL_ORDERS_PRODUCTS . ' ' . zen_draw_input_field('search_orders_products') . zen_hide_session_id(); 770   if (isset($_GET['search_orders_products']) && zen_not_null($_GET['search_orders_products'])) { 771     $keywords_orders_products = zen_db_input(zen_db_prepare_input($_GET['search_orders_products'])); 772     echo '<br/ >' . TEXT_INFO_SEARCH_DETAIL_FILTER_ORDERS_PRODUCTS . zen_db_prepare_input($keywords_orders_products); 773   } 774 ?> 775             </td> 776           </form> 777  778         </table></td> 779       </tr> 780       <tr> 781           <td width="100%"> 782               <table  cellspacing="0" cellpadding="0" width="100%" border="0"> 783                   <tbody> 784                       <tr> 785                           <td class="pageHeading"></td> 786                         <td class="pageHeading" align="right"><?php echo zen_draw_separator('pixel_trans.gif', 1, HEADING_IMAGE_HEIGHT); ?></td> 787                           <td align="right"> 788                               <table cellspacing="0" cellpadding="0" width="0%" border="0"> 789                                   <tbody> 790                                       <form method="get" action="orders.php" name="new_special"> 791                                           <?php if(!empty($_GET['cID'])) {?> 792                                               <input type="hidden" name="cID" value=<?php echo $_GET['cID']; ?>> 793                                           <?php } ?> 794                                         <script language="javascript"> 795                                             var StartDate = new ctlSpiffyCalendarBox("StartDate", "new_special", "start", "btnDate1","<?php echo (($sInfo->specials_date_available == '0001-01-01') ? '' : zen_date_short($sInfo->specials_date_available)); ?>",scBTNMODE_CUSTOMBLUE); 796                                             var EndDate = new ctlSpiffyCalendarBox("EndDate", "new_special", "end", "btnDate2","<?php echo (($sInfo->expires_date == '0001-01-01') ? '' : zen_date_short($sInfo->expires_date)); ?>",scBTNMODE_CUSTOMBLUE); 797                                         </script> 798                                         <tr> 799                                           <script> 800                                                 document.onreadystatechange = function () {    801                                                      if(document.readyState=="complete") {           802                                                         var obj=document.getElementById("total").innerHTML; 803                                                         document.getElementById("allOrderTotal").innerHTML="$"+obj; 804                                                       }    805                                                   } 806                                                 function showTotal(){ 807                                                     var obj=document.getElementById("total").innerHTML; 808                                                     document.getElementById("allOrderTotal").innerHTML="$"+obj; 809                                                     } 810                                           </script> 811                                           <td align="left" colspan=2>All Order Total: <span id="allOrderTotal"></span></td> 812                                           <td width="5%" align="right"></td> 813                                           <td align="right"><?php echo "Orders start date"; ?>&nbsp;</td> 814                                           <td align="right"><script language="javascript">StartDate.writeControl(); StartDate.dateFormat="<?php echo "yyyy/MM/dd"; ?>";</script></td> 815                                           <td width="5%" align="right"></td> 816                                           <td align="right"><?php echo "Orders end date"; ?>&nbsp;</td> 817                                           <td align="right"><script language="javascript">EndDate.writeControl(); EndDate.dateFormat="<?php echo "yyyy/MM/dd"; ?>";</script></td> 818                                           <td width="180px" align="center"><?php echo zen_image_submit('button_search.gif','')?></td> 819                                         </tr> 820                                     </form> 821                                 </tbody> 822                             </table> 823                           </td> 824                       </tr> 825                   </tbody> 826               </table> 827           </td> 828       </tr> 829 <!-- search --> 830 <?php } ?> 831  832  833 <?php 834   if (($action == 'edit') && ($order_exists == true)) { 835     $order = new order($oID); 836     if ($order->info['payment_module_code']) { 837       if (file_exists(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php')) { 838         require(DIR_FS_CATALOG_MODULES . 'payment/' . $order->info['payment_module_code'] . '.php'); 839         require(DIR_FS_CATALOG_LANGUAGES . $_SESSION['language'] . '/modules/payment/' . $order->info['payment_module_code'] . '.php'); 840         $module = new $order->info['payment_module_code']; 841 //        echo $module->admin_notification($oID); 842       } 843     } 844 ?> 845       <tr> 846         <td width="100%"><table border="0" width="100%" cellspacing="0" cellpadding="0"> 847           <tr> 848             <td class="pageHeading"><?php echo HEADING_TITLE; ?></td> 849             <td class="pageHeading" align="right"><?php echo zen_draw_separator('pixel_trans.gif', 1, HEADING_IMAGE_HEIGHT); ?></td> 850             <td class="pageHeading" align="right"><?php echo '<a href="javascript:history.back()">' . zen_image_button('button_back.gif', IMAGE_BACK) . '</a>'; ?></td> 851           </tr> 852         </table></td> 853       </tr> 854       <tr> 855         <td><table width="100%" border="0" cellspacing="0" cellpadding="2"> 856           <tr> 857             <td colspan="3"><?php echo zen_draw_separator(); ?></td> 858           </tr> 859           <tr> 860             <td valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="2"> 861               <tr> 862                 <td class="main" valign="top"><strong><?php echo ENTRY_CUSTOMER; ?></strong></td> 863                 <td class="main"><?php echo zen_address_format($order->customer['format_id'], $order->customer, 1, '', '<br />'); ?></td> 864               </tr> 865               <tr> 866                 <td colspan="2"><?php echo zen_draw_separator('pixel_trans.gif', '1', '5'); ?></td> 867               </tr> 868               <tr> 869                 <td class="main"><strong><?php echo ENTRY_TELEPHONE_NUMBER; ?></strong></td> 870                 <td class="main"><?php echo $order->customer['telephone']; ?></td> 871               </tr> 872               <tr> 873                 <td class="main"><strong><?php echo ENTRY_EMAIL_ADDRESS; ?></strong></td> 874                 <td class="main"><?php echo '<a href="mailto:' . $order->customer['email_address'] . '">' . $order->customer['email_address'] . '</a>'; ?></td> 875               </tr> 876               <tr> 877                 <td class="main"><strong><?php echo TEXT_INFO_IP_ADDRESS; ?></strong></td> 878                 <td class="main"><?php echo $order->info['ip_address']; ?></td> 879               </tr> 880             </table></td> 881             <td valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="2"> 882               <tr> 883                 <td class="main" valign="top"><strong><?php echo ENTRY_SHIPPING_ADDRESS; ?></strong></td> 884                 <td class="main"><?php echo zen_address_format($order->delivery['format_id'], $order->delivery, 1, '', '<br />'); ?></td> 885               </tr> 886             </table></td> 887             <td valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="2"> 888               <tr> 889                 <td class="main" valign="top"><strong><?php echo ENTRY_BILLING_ADDRESS; ?></strong></td> 890                 <td class="main"><?php echo zen_address_format($order->billing['format_id'], $order->billing, 1, '', '<br />'); ?></td> 891               </tr> 892             </table></td> 893           </tr> 894         </table></td> 895       </tr> 896       <tr> 897         <td><?php echo zen_draw_separator('pixel_trans.gif', '1', '10'); ?></td> 898       </tr> 899       <tr> 900         <td class="main"><strong><?php echo ENTRY_ORDER_ID . $order->info['num']; ?></strong></td> 901       </tr> 902       <tr> 903      <td><table border="0" cellspacing="0" cellpadding="2"> 904         <tr> 905            <td class="main"><strong><?php echo ENTRY_DATE_PURCHASED; ?></strong></td> 906            <td class="main"><?php echo zen_date_long($order->info['date_purchased']); ?></td> 907         </tr> 908         <tr> 909            <td class="main"><strong><?php echo ENTRY_PAYMENT_METHOD; ?></strong></td> 910            <td class="main"><?php echo $order->info['payment_method']; ?></td> 911         </tr> 912 <?php 913     if (zen_not_null($order->info['cc_type']) || zen_not_null($order->info['cc_owner']) || zen_not_null($order->info['cc_number'])) { 914 ?> 915           <tr> 916             <td colspan="2"><?php echo zen_draw_separator('pixel_trans.gif', '1', '10'); ?></td> 917           </tr> 918           <tr> 919             <td class="main"><?php echo ENTRY_CREDIT_CARD_TYPE; ?></td> 920             <td class="main"><?php echo $order->info['cc_type']; ?></td> 921           </tr> 922           <tr> 923             <td class="main"><?php echo ENTRY_CREDIT_CARD_OWNER; ?></td> 924             <td class="main"><?php echo $order->info['cc_owner']; ?></td> 925           </tr> 926           <tr> 927             <td class="main"><?php echo ENTRY_CREDIT_CARD_NUMBER; ?></td> 928             <td class="main"><?php echo $order->info['cc_number'] . (zen_not_null($order->info['cc_number']) && !strstr($order->info['cc_number'],'X') && !strstr($order->info['cc_number'],'********') ? '&nbsp;&nbsp;<a href="' . zen_href_link(FILENAME_ORDERS, '&action=mask_cc&oID=' . $oID, 'NONSSL') . '" class="noprint">' . TEXT_MASK_CC_NUMBER . '</a>' : ''); ?><td> 929           </tr> 930 <?php if (zen_not_null($order->info['cc_cvv'])) { ?> 931           <tr> 932             <td class="main"><?php echo ENTRY_CREDIT_CARD_CVV; ?></td> 933             <td class="main"><?php echo $order->info['cc_cvv'] . (zen_not_null($order->info['cc_cvv']) && !strstr($order->info['cc_cvv'],TEXT_DELETE_CVV_REPLACEMENT) ? '&nbsp;&nbsp;<a href="' . zen_href_link(FILENAME_ORDERS, '&action=delete_cvv&oID=' . $oID, 'NONSSL') . '" class="noprint">' . TEXT_DELETE_CVV_FROM_DATABASE . '</a>' : ''); ?><td> 934           </tr> 935 <?php } ?> 936           <tr> 937             <td class="main"><?php echo ENTRY_CREDIT_CARD_EXPIRES; ?></td> 938             <td class="main"><?php echo $order->info['cc_expires']; ?></td> 939           </tr> 940 <?php 941     } 942 ?> 943         </table></td> 944       </tr> 945 <?php 946       if (method_exists($module, 'admin_notification')) { 947 ?> 948       <tr> 949         <td><?php echo zen_draw_separator('pixel_trans.gif', '1', '10'); ?></td> 950       </tr> 951       <tr> 952         <?php echo $module->admin_notification($oID); ?> 953       </tr> 954       <tr> 955         <td><?php echo zen_draw_separator('pixel_trans.gif', '1', '10'); ?></td> 956       </tr> 957 <?php 958 } 959 ?> 960  961 <?php  962     //从这里开始,设定为付款订单才能修改价格,5为为付款选项的ID 963     if($order->info['orders_status'] == 5){ 964 ?> 965       <tr><form action="" method="post"><td align="right"><input type="hidden" name="currencies_key" value="<?php echo $order->info['currency']; ?>"><input type="hidden" name="currencies_value" value="<?php echo $order->info['currency_value']; ?>"><input type="button" value="编辑" id="orders_edit"><input style="display: none" type="submit" value="提交" id="orders_submit"><input style="display: none" type="button" value="取消" id="orders_reset"></td></tr> 966       <tr id="products_list_changes" style="display: none"> 967         <td><table border="0" width="100%" cellspacing="0" cellpadding="2"> 968           <tr class="dataTableHeadingRow"> 969             <td class="dataTableHeadingContent"><?php echo Image; ?></td> 970             <td class="dataTableHeadingContent" colspan="2"><?php echo TABLE_HEADING_PRODUCTS; ?></td> 971             <td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS_MODEL; ?></td> 972             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TAX; ?></td> 973             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_PRICE_EXCLUDING_TAX; ?></td> 974             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_PRICE_INCLUDING_TAX; ?></td> 975             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_EXCLUDING_TAX; ?></td> 976             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_INCLUDING_TAX; ?></td> 977           </tr>         978  979 <?php 980  981     for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {     982       $price_input='<input onblur="price_ex_onlive('.$order->products[$i]['id'].','.preg_replace( '/[^\d\.]/', '',$currencies->format($order->products[$i]['final_price'], true, $order->info['currency'], $order->info['currency_value'])).')" onKeyUp="change_price_ex('.$order->products[$i]['id'].','.preg_replace( '/[^\d\.]/', '',$currencies->format($order->products[$i]['final_price'], true, $order->info['currency'], $order->info['currency_value'])).')" size="6" type="text" value="';  983       $qty_input = '<input onblur="qty_onlive('.$order->products[$i]['id'].','.$order->products[$i]['qty'].')" onKeyUp="change_qty('.$order->products[$i]['id'].')" size="6" type="text" value="'; 984       $total_input='<input readonly size="6" type="text" value="';  985       echo '          <tr class="dataTableRow">' . "\n" . 986            '            <td><img src="../images/'.$order->products[$i]['image'].'" heiht="80" width="80"/></td>'. 987            '            <td class="dataTableContent" valign="top" align="right" style="color:c00">' . $qty_input . $order->products[$i]['qty'] . '" name="qty_'.$order->products[$i]['id'].'">&nbsp;x</td>' . "\n" . 988            '            <td class="dataTableContent" valign="top"><a href="'.HTTP_SERVER.DIR_WS_CATALOG.'index.php?main_page=product_info&products_id='.$order->products[$i]['id'].'" target=_blank>'. $order->products[$i]['name']; 989  990       if (isset($order->products[$i]['attributes']) && (sizeof($order->products[$i]['attributes']) > 0)) { 991         for ($j = 0, $k = sizeof($order->products[$i]['attributes']); $j < $k; $j++) { 992           echo '<br /><nobr><small>&nbsp;<i> - ' . $order->products[$i]['attributes'][$j]['option'] . ': ' . nl2br(zen_output_string_protected($order->products[$i]['attributes'][$j]['value'])); 993           if ($order->products[$i]['attributes'][$j]['price'] != '0') echo ' (' . $order->products[$i]['attributes'][$j]['prefix'] . $currencies->format($order->products[$i]['attributes'][$j]['price'] * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value']) . ')'; 994           if ($order->products[$i]['attributes'][$j]['product_attribute_is_free'] == '1' and $order->products[$i]['product_is_free'] == '1') echo TEXT_INFO_ATTRIBUTE_FREE; 995           echo '</i></small></nobr>'; 996         } 997       } 998  999       echo '            </a></td>' . "\n" .1000            '            <td class="dataTableContent" valign="top">' . $order->products[$i]['model'] . '</td>' . "\n" .1001            '            <td class="dataTableContent" align="right" valign="top">' . zen_display_tax_value($order->products[$i]['tax']) . '%</td>' . "\n" .1002            '            <td class="dataTableContent" align="right" valign="top"><strong>' .$price_input.1003                           preg_replace( '/[^\d\.]/', '',$currencies->format($order->products[$i]['final_price'], true, $order->info['currency'], $order->info['currency_value'])).1004                           '" name="price_ex_'.$order->products[$i]['id'].'">'.1005                           ($order->products[$i]['onetime_charges'] != 0 ? '<br />' . $currencies->format($order->products[$i]['onetime_charges'], true, $order->info['currency'], $order->info['currency_value']) : '') .1006                         '</strong></td>' . "\n" .1007            '            <td class="dataTableContent" align="right" valign="top"><strong><strong>' . $total_input.1008                         preg_replace( '/[^\d\.]/', '',$currencies->format(zen_add_tax($order->products[$i]['final_price'], $order->products[$i]['tax']), true, $order->info['currency'], $order->info['currency_value'])).1009                           '" name="price_inc_'.$order->products[$i]['id'].'">'.1010                           ($order->products[$i]['onetime_charges'] != 0 ? '<br />' . $currencies->format(zen_add_tax($order->products[$i]['onetime_charges'], $order->products[$i]['tax']), true, $order->info['currency'], $order->info['currency_value']) : '') .1011                         '</strong></td>' . "\n" .1012            '            <td class="dataTableContent" align="right" valign="top"><strong>' . $total_input.1013                           preg_replace( '/[^\d\.]/', '',$currencies->format($order->products[$i]['final_price'] * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value'])) .1014                           '" name="total_ex_'.$order->products[$i]['id'].'">'.1015                           ($order->products[$i]['onetime_charges'] != 0 ? '<br />' . $currencies->format($order->products[$i]['onetime_charges'], true, $order->info['currency'], $order->info['currency_value']) : '') .1016                         '</strong></td>' . "\n" .1017            '            <td class="dataTableContent" align="right" valign="top"><strong>' .$total_input.1018                           preg_replace( '/[^\d\.]/', '',$currencies->format(zen_add_tax($order->products[$i]['final_price'], $order->products[$i]['tax']) * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value'])) .1019                           '" name="total_inc_'.$order->products[$i]['id'].'">'.1020                           ($order->products[$i]['onetime_charges'] != 0 ? '<br />' . $currencies->format(zen_add_tax($order->products[$i]['onetime_charges'], $order->products[$i]['tax']), true, $order->info['currency'], $order->info['currency_value']) : '') .1021                         '</strong></td>' . "\n";1022       echo '          </tr>' . "\n";1023       echo '          <input type="hidden" name="reference_oid[]" value="'.$order->products[$i]['id'].'">';1024     }1025     1026     echo '<div style="display:none" id="price_total">';1027     for ($i=0, $n=sizeof($order->products); $i<$n; $i++){1028         echo '<p id="total_ex_hidden_'.$order->products[$i]['id'].'" >'.preg_replace( '/[^\d\.]/', '',$currencies->format($order->products[$i]['final_price'], true, $order->info['currency'], $order->info['currency_value'])) * $order->products[$i]['qty'].'</p>';1029     }1030     echo '<div>';1031 ?>1032           <tr>1033             <td align="right" colspan="9"><table border="0" cellspacing="0" cellpadding="2">1034 <?php1035     for ($i = 0, $n = sizeof($order->totals); $i < $n; $i++) {1036       echo '              <tr>' . "\n" .1037            '                <td align="right" class="'. str_replace('_', '-', $order->totals[$i]['class']) . '-Text">' . $order->totals[$i]['title'] . '</td>' . "\n" ;1038       if($order->totals[$i]['class'] == "ot_shipping"){1039           echo '                <td align="right"  class="'. str_replace('_', '-', $order->totals[$i]['class']) . '-Amount"><input onblur="shipping_onlive('.preg_replace("/[^\d\.]/", "", $order->totals[$i]['text']).')" onKeyUp="change_shipping('.preg_replace("/[^\d\.]/", "", $order->totals[$i]['text']).')" size="6" type="text" value="' . preg_replace("/[^\d\.]/", "", $order->totals[$i]['text']) . '" name="'.$order->totals[$i]['class'].'"></td>' . "\n";1040       }1041       else{1042           echo '                <td align="right" class="'. str_replace('_', '-', $order->totals[$i]['class']) . '-Amount"><input readonly size="6" type="text" value="' . preg_replace("/[^\d\.]/", "", $order->totals[$i]['text']) . '" name="'.$order->totals[$i]['class'].'"></td>' . "\n";1043       }1044       echo '              </tr>' . "\n";1045     }1046 ?>1047             </table></td>1048           </tr>1049         </table></td>1050       </tr>1051       </form>1052 <?php1053 }1054 ?>1055 <?php //修改为付款订单代码从这里结束 ?>1056 1057       <tr id="products_list_default">1058         <td><table border="0" width="100%" cellspacing="0" cellpadding="2">1059           <tr class="dataTableHeadingRow">1060             <td class="dataTableHeadingContent"><?php echo Image; ?></td>1061             <td class="dataTableHeadingContent" colspan="2"><?php echo TABLE_HEADING_PRODUCTS; ?></td>1062             <td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS_MODEL; ?></td>1063             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TAX; ?></td>1064             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_PRICE_EXCLUDING_TAX; ?></td>1065             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_PRICE_INCLUDING_TAX; ?></td>1066             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_EXCLUDING_TAX; ?></td>1067             <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_INCLUDING_TAX; ?></td>1068           </tr>1069 <?php1070     for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {     1071       echo '          <tr class="dataTableRow">' . "\n" .1072            '            <td><img src="../images/'.$order->products[$i]['image'].'" heiht="80" width="80"/></td>'.1073            '            <td class="dataTableContent" valign="top" align="right" style="color:c00">' . $order->products[$i]['qty'] . '&nbsp;x</td>' . "\n" .1074            '            <td class="dataTableContent" valign="top"><a href="'.HTTP_SERVER.DIR_WS_CATALOG.'index.php?main_page=product_info&products_id='.$order->products[$i]['id'].'" target=_blank>'. $order->products[$i]['name'];1075 1076       if (isset($order->products[$i]['attributes']) && (sizeof($order->products[$i]['attributes']) > 0)) {1077         for ($j = 0, $k = sizeof($order->products[$i]['attributes']); $j < $k; $j++) {1078           echo '<br /><nobr><small>&nbsp;<i> - ' . $order->products[$i]['attributes'][$j]['option'] . ': ' . nl2br(zen_output_string_protected($order->products[$i]['attributes'][$j]['value']));1079           if ($order->products[$i]['attributes'][$j]['price'] != '0') echo ' (' . $order->products[$i]['attributes'][$j]['prefix'] . $currencies->format($order->products[$i]['attributes'][$j]['price'] * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value']) . ')';1080           if ($order->products[$i]['attributes'][$j]['product_attribute_is_free'] == '1' and $order->products[$i]['product_is_free'] == '1') echo TEXT_INFO_ATTRIBUTE_FREE;1081           echo '</i></small></nobr>';1082         }1083       }1084 1085       echo '            </a></td>' . "\n" .1086            '            <td class="dataTableContent" valign="top">' . $order->products[$i]['model'] . '</td>' . "\n" .1087            '            <td class="dataTableContent" align="right" valign="top">' . zen_display_tax_value($order->products[$i]['tax']) . '%</td>' . "\n" .1088            '            <td class="dataTableContent" align="right" valign="top"><strong>' .1089                           $currencies->format($order->products[$i]['final_price'], true, $order->info['currency'], $order->info['currency_value']) .1090                           ($order->products[$i]['onetime_charges'] != 0 ? '<br />' . $currencies->format($order->products[$i]['onetime_charges'], true, $order->info['currency'], $order->info['currency_value']) : '') .1091                         '</strong></td>' . "\n" .1092            '            <td class="dataTableContent" align="right" valign="top"><strong>' .1093                           $currencies->format(zen_add_tax($order->products[$i]['final_price'], $order->products[$i]['tax']), true, $order->info['currency'], $order->info['currency_value']) .1094                           ($order->products[$i]['onetime_charges'] != 0 ? '<br />' . $currencies->format(zen_add_tax($order->products[$i]['onetime_charges'], $order->products[$i]['tax']), true, $order->info['currency'], $order->info['currency_value']) : '') .1095                         '</strong></td>' . "\n" .1096            '            <td class="dataTableContent" align="right" valign="top"><strong>' .1097                           $currencies->format($order->products[$i]['final_price'] * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value']) .1098                           ($order->products[$i]['onetime_charges'] != 0 ? '<br />' . $currencies->format($order->products[$i]['onetime_charges'], true, $order->info['currency'], $order->info['currency_value']) : '') .1099                         '</strong></td>' . "\n" .1100            '            <td class="dataTableContent" align="right" valign="top"><strong>' .1101                           $currencies->format(zen_add_tax($order->products[$i]['final_price'], $order->products[$i]['tax']) * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value']) .1102                           ($order->products[$i]['onetime_charges'] != 0 ? '<br />' . $currencies->format(zen_add_tax($order->products[$i]['onetime_charges'], $order->products[$i]['tax']), true, $order->info['currency'], $order->info['currency_value']) : '') .1103                         '</strong></td>' . "\n";1104       echo '          </tr>' . "\n";1105     }1106 ?>1107           <tr>1108             <td align="right" colspan="9"><table border="0" cellspacing="0" cellpadding="2">1109 <?php1110     for ($i = 0, $n = sizeof($order->totals); $i < $n; $i++) {1111       echo '              <tr>' . "\n" .1112            '                <td align="right" class="'. str_replace('_', '-', $order->totals[$i]['class']) . '-Text">' . $order->totals[$i]['title'] . '</td>' . "\n" .1113            '                <td align="right" class="'. str_replace('_', '-', $order->totals[$i]['class']) . '-Amount">' . $order->totals[$i]['text'] . '</td>' . "\n" .1114            '              </tr>' . "\n";1115     }1116 ?>1117             </table></td>1118           </tr>1119         </table></td>1120       </tr>1121 1122 <?php1123   // show downloads1124   require(DIR_WS_MODULES . 'orders_download.php');1125 ?>1126 1127       <tr>1128         <td><?php echo zen_draw_separator('pixel_trans.gif', '1', '10'); ?></td>1129       </tr>1130       <tr>1131         <td class="main"><table border="1" cellspacing="0" cellpadding="5">1132           <tr>1133             <td class="smallText" align="center"><strong><?php echo TABLE_HEADING_DATE_ADDED; ?></strong></td>1134             <td class="smallText" align="center"><strong><?php echo TABLE_HEADING_CUSTOMER_NOTIFIED; ?></strong></td>1135             <td class="smallText" align="center"><strong><?php echo TABLE_HEADING_STATUS; ?></strong></td>1136             <td class="smallText" align="center"><strong><?php echo TABLE_HEADING_COMMENTS; ?></strong></td>1137           </tr>1138 <?php1139     $orders_history = $db->Execute("select orders_status_id, date_added, customer_notified, comments1140                                     from " . TABLE_ORDERS_STATUS_HISTORY . "1141                                     where orders_id = '" . zen_db_input($oID) . "'1142                                     order by date_added");1143 1144     if ($orders_history->RecordCount() > 0) {1145       while (!$orders_history->EOF) {1146         echo '          <tr>' . "\n" .1147              '            <td class="smallText" align="center">' . zen_datetime_short($orders_history->fields['date_added']) . '</td>' . "\n" .1148              '            <td class="smallText" align="center">';1149         if ($orders_history->fields['customer_notified'] == '1') {1150           echo zen_image(DIR_WS_ICONS . 'tick.gif', TEXT_YES) . "</td>\n";1151         } else if ($orders_history->fields['customer_notified'] == '-1') {1152           echo zen_image(DIR_WS_ICONS . 'locked.gif', TEXT_HIDDEN) . "</td>\n";1153         } else {1154           echo zen_image(DIR_WS_ICONS . 'unlocked.gif', TEXT_VISIBLE) . "</td>\n";1155         }1156         echo '            <td class="smallText">' . $orders_status_array[$orders_history->fields['orders_status_id']] . '</td>' . "\n";1157         echo '            <td class="smallText">' . nl2br(zen_db_output($orders_history->fields['comments'])) . '&nbsp;</td>' . "\n" .1158              '          </tr>' . "\n";1159         $orders_history->MoveNext();1160       }1161     } else {1162         echo '          <tr>' . "\n" .1163              '            <td class="smallText" colspan="5">' . TEXT_NO_ORDER_HISTORY . '</td>' . "\n" .1164              '          </tr>' . "\n";1165     }1166 ?>1167         </table></td>1168       </tr>1169       <tr>1170         <td class="main noprint"><br /><strong><?php echo TABLE_HEADING_COMMENTS; ?></strong></td>1171       </tr>1172       <tr>1173         <td class="noprint"><?php echo zen_draw_separator('pixel_trans.gif', '1', '5'); ?></td>1174       </tr>1175       <tr><?php echo zen_draw_form('status', FILENAME_ORDERS, zen_get_all_get_params(array('action')) . 'action=update_order', 'post', '', true); ?>1176         <td class="main noprint"><?php echo zen_draw_textarea_field('comments', 'soft', '60', '5'); ?></td>1177       </tr>1178       <tr>1179         <td><?php echo zen_draw_separator('pixel_trans.gif', '1', '10'); ?></td>1180       </tr>1181       <tr>1182         <td><table border="0" cellspacing="0" cellpadding="2" class="noprint">1183           <tr>1184             <td><table border="0" cellspacing="0" cellpadding="2">1185               <tr>1186                 <td class="main"><strong><?php echo "Tracking Number:"; ?></strong> <?php echo zen_draw_input_field('tracking_number', $order->info['tracking_number']); ?></td>1187               </tr> 1188               <tr>1189                 <td class="main"><strong><?php echo ENTRY_STATUS; ?></strong> <?php echo zen_draw_pull_down_menu('status', $orders_statuses, $order->info['orders_status']); ?></td>1190               </tr>1191               <tr>1192                 <td class="main"><strong><?php echo ENTRY_NOTIFY_CUSTOMER; ?></strong> [<?php echo zen_draw_radio_field('notify', '1', true) . '-' . TEXT_EMAIL . ' ' . zen_draw_radio_field('notify', '0', FALSE) . '-' . TEXT_NOEMAIL . ' ' . zen_draw_radio_field('notify', '-1', FALSE) . '-' . TEXT_HIDE; ?>]&nbsp;&nbsp;&nbsp;</td>1193                 <td class="main"><strong><?php echo ENTRY_NOTIFY_COMMENTS; ?></strong> <?php echo zen_draw_checkbox_field('notify_comments', '', true); ?></td>1194               </tr>1195               <tr><td><br /></td></tr>1196             </table></td>1197             <td valign="top"><?php echo zen_image_submit('button_update.gif', IMAGE_UPDATE); ?></td>1198           </tr>1199         </table></td>1200       </form></tr>1201       <tr>1202         <td colspan="2" align="right" class="noprint"><?php echo '<a href="' . zen_href_link(FILENAME_ORDERS_INVOICE, 'oID=' . $_GET['oID']) . '" TARGET="_blank">' . zen_image_button('button_invoice.gif', IMAGE_ORDERS_INVOICE) . '</a> <a href="' . zen_href_link(FILENAME_ORDERS_PACKINGSLIP, 'oID=' . $_GET['oID']) . '" TARGET="_blank">' . zen_image_button('button_packingslip.gif', IMAGE_ORDERS_PACKINGSLIP) . '</a> <a href="' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('action'))) . '">' . zen_image_button('button_orders.gif', IMAGE_ORDERS) . '</a>'; ?></td>1203       </tr>1204 <?php1205 // check if order has open gv1206         $gv_check = $db->Execute("select order_id, unique_id1207                                   from " . TABLE_COUPON_GV_QUEUE ."1208                                   where order_id = '" . $_GET['oID'] . "' and release_flag='N' limit 1");1209         if ($gv_check->RecordCount() > 0) {1210           $goto_gv = '<a href="' . zen_href_link(FILENAME_GV_QUEUE, 'order=' . $_GET['oID']) . '">' . zen_image_button('button_gift_queue.gif',IMAGE_GIFT_QUEUE) . '</a>';1211           echo '      <tr><td align="right"><table width="225"><tr>';1212           echo '        <td align="center">';1213           echo $goto_gv . '&nbsp;&nbsp;';1214           echo '        </td>';1215           echo '      </tr></table></td></tr>';1216         }1217 ?>1218 <?php1219   } else {1220 ?>1221       <tr>1222         <td width="100%"><table border="0" width="100%" cellspacing="0" cellpadding="0">1223           <tr>1224             <td class="pageHeading"><?php echo HEADING_TITLE; ?></td>1225             <td class="pageHeading" align="right"><?php echo zen_draw_separator('pixel_trans.gif', 1, HEADING_IMAGE_HEIGHT); ?></td>1226             <td align="right"><table border="0" width="100%" cellspacing="0" cellpadding="0">1227               <tr><?php echo zen_draw_form('orders_num', FILENAME_ORDERS, '', 'get', '', true); ?>1228                 <td class="smallText" align="right"><?php echo 'order_num' . ' ' . zen_draw_input_field('orders_num', '', 'size="12"') . zen_hide_session_id(); ?></td>1229               </form></tr>1230               <tr><?php echo zen_draw_form('status', FILENAME_ORDERS, '', 'get', '', true); ?>1231                 <td class="smallText" align="right">1232                   <?php1233                     echo HEADING_TITLE_STATUS . ' ' . zen_draw_pull_down_menu('status', array_merge(array(array('id' => '', 'text' => TEXT_ALL_ORDERS)), $orders_statuses), $_GET['status'], 'onChange="this.form.submit();"');1234                     echo zen_hide_session_id();1235                   ?>1236                 </td>1237               </form></tr>1238             </table></td>1239           </tr>1240         </table></td>1241       </tr>1242       <tr>1243         <td><table border="0" width="100%" cellspacing="0" cellpadding="0">1244           <tr>1245              <td class="smallText">1246                 <?php echo TEXT_LEGEND . ' ' . zen_image(DIR_WS_IMAGES . 'icon_status_red.gif', TEXT_BILLING_SHIPPING_MISMATCH, 10, 10) . ' ' . TEXT_BILLING_SHIPPING_MISMATCH; ?>1247                 <?php echo zen_image(DIR_WS_IMAGES . 'icon_green_on.gif', IMAGE_ICON_STATUS_ON)."PCB Order"; ?>1248                 <?php echo zen_image(DIR_WS_IMAGES . 'icon_red_on.gif', IMAGE_ICON_STATUS_ON)."PRE Order"; ?>1249                 <?php echo zen_image(DIR_WS_IMAGES . 'icon_yellow_on.gif', IMAGE_ICON_STATUS_ON)."Customer Comments"; ?>1250               </td>1251           <tr>1252             <td valign="top"><table border="0" width="100%" cellspacing="0" cellpadding="2">1253               <tr class="dataTableHeadingRow">1254 <?php1255 // Sort Listing1256           switch ($_GET['list_order']) {1257               case "id-asc":1258               $disp_order = "c.customers_id";1259               break;1260               case "firstname":1261               $disp_order = "c.customers_firstname";1262               break;1263               case "firstname-desc":1264               $disp_order = "c.customers_firstname DESC";1265               break;1266               case "lastname":1267               $disp_order = "c.customers_lastname, c.customers_firstname";1268               break;1269               case "lastname-desc":1270               $disp_order = "c.customers_lastname DESC, c.customers_firstname";1271               break;1272               case "company":1273               $disp_order = "a.entry_company";1274               break;1275               case "company-desc":1276               $disp_order = "a.entry_company DESC";1277               break;1278               default:1279               $disp_order = "c.customers_id DESC";1280           }1281 ?>1282                 <td class="dataTableHeadingContent" align="center"><?php echo TABLE_HEADING_ORDERS_ID; ?></td>1283                 <td class="dataTableHeadingContent" align="left" width="50"><?php echo TABLE_HEADING_PAYMENT_METHOD; ?></td>1284                 <td class="dataTableHeadingContent"><?php echo TABLE_HEADING_CUSTOMERS; ?></td>1285                 <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_ORDER_TOTAL; ?></td>1286                 <td class="dataTableHeadingContent" align="center"><?php echo TABLE_HEADING_DATE_PURCHASED; ?></td>1287                 <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_STATUS; ?></td>1288                 <td class="dataTableHeadingContent" align="center"><?php echo TABLE_HEADING_CUSTOMER_COMMENTS; ?></td>1289                 <td class="dataTableHeadingContent" align="center"><input type="checkbox" id="select_all" onclick="selectAll()"></td>1290                 <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_ACTION; ?>&nbsp;</td>1291               </tr>1292 1293 <?php1294 // Only one or the other search1295 // create search_orders_products filter1296   $search = '';1297   $new_table = '';1298   $new_fields = '';1299   if (isset($_GET['search_orders_products']) && zen_not_null($_GET['search_orders_products'])) {1300     $new_fields = '';1301     $search_distinct = ' distinct ';1302     $new_table = " left join " . TABLE_ORDERS_PRODUCTS . " op on (op.orders_id = o.orders_id) ";1303     $keywords = zen_db_input(zen_db_prepare_input($_GET['search_orders_products']));1304     $search = " and (op.products_model like '%" . $keywords . "%' or op.products_name like '%" . $keywords . "%')";1305     if (substr(strtoupper($_GET['search_orders_products']), 0, 3) == 'ID:') {1306       $keywords = TRIM(substr($_GET['search_orders_products'], 3));1307       $search = " and op.products_id ='" . (int)$keywords . "'";1308     }1309   } else {1310 ?>1311 <?php1312 // create search filter1313   $search = '';1314   if (isset($_GET['search']) && zen_not_null($_GET['search'])) {1315     $search_distinct = ' ';1316     $keywords = zen_db_input(zen_db_prepare_input($_GET['search']));1317     $search = " and (o.customers_city like '%" . $keywords . "%' or o.orders_num like '%" . $keywords ."%' or o.customers_postcode like '%" . $keywords . "%' or o.date_purchased like '%" . $keywords . "%' or o.billing_name like '%" . $keywords . "%' or o.billing_company like '%" . $keywords . "%' or o.billing_street_address like '%" . $keywords . "%' or o.delivery_city like '%" . $keywords . "%' or o.delivery_postcode like '%" . $keywords . "%' or o.delivery_name like '%" . $keywords . "%' or o.delivery_company like '%" . $keywords . "%' or o.delivery_street_address like '%" . $keywords . "%' or o.billing_city like '%" . $keywords . "%' or o.billing_postcode like '%" . $keywords . "%' or o.customers_email_address like '%" . $keywords . "%' or o.customers_name like '%" . $keywords . "%' or o.customers_company like '%" . $keywords . "%' or o.customers_street_address  like '%" . $keywords . "%' or o.customers_telephone like '%" . $keywords . "%' or o.ip_address  like '%" . $keywords . "%')";1318     $new_table = '';1319 //    $new_fields = ", o.customers_company, o.customers_email_address, o.customers_street_address, o.delivery_company, o.delivery_name, o.delivery_street_address, o.billing_company, o.billing_name, o.billing_street_address, o.payment_module_code, o.shipping_module_code, o.ip_address ";1320   }1321   if(isset($_GET['orders_num']) && zen_not_null($_GET['orders_num'])){1322     $search_distinct = ' ';1323     $keywords = zen_db_input(zen_db_prepare_input($_GET['orders_num']));1324     $search = " and (o.orders_num like '%" .$keywords ."%') ";1325     $new_table = '';1326   }1327 } // eof: search orders or orders_products1328     $new_fields = ", o.customers_company, o.customers_email_address, o.customers_street_address, o.delivery_company, o.delivery_name, o.delivery_street_address, o.billing_company, o.billing_name, o.billing_street_address, o.payment_module_code, o.shipping_module_code, o.ip_address ";1329 ?>1330 <?php1331       if (isset($_GET['cID'])) {1332             $cID = zen_db_prepare_input($_GET['cID']);1333           //add code1334           if(isset($_GET['start']) || isset($_GET['end'])){1335               if(!empty($_GET['start']) && empty($_GET['end'])){1336                   $start_time = strtr($_GET['start'], "/", "-");1337                   $order_time = " and o.date_purchased >= '".$start_time."' ";1338               }1339               if(empty($_GET['start']) && !empty($_GET['end'])){1340                   $end_time = strtr($_GET['end'], "/", "-");1341                   $order_time = " and o.date_purchased <= '".$end_time."' ";1342               }1343               if(!empty($_GET['start']) && !empty($_GET['end'])){1344                   $start_time = strtr($_GET['start'], "/", "-");1345                   $end_time = strtr($_GET['end'], "/", "-")." 23:59:59";1346                   $order_time = " and o.date_purchased >= ' " .$start_time. "' and o.date_purchased <= '".$end_time."' ";1347               }1348           1349               $orders_query_raw =   "select o.orders_id, orders_num, o.customers_id, o.customers_name, o.payment_method, o.shipping_method, o.date_purchased, o.last_modified, o.currency, o.currency_value, o.date_purchased, o.order_total as total, s.orders_status_name, ot.text as order_total" .1350                                         $new_fields . "1351                                         from (" . TABLE_ORDERS_STATUS . " s, " .1352                                         TABLE_ORDERS . " o " .1353                                         $new_table . ")1354                                         left join " . TABLE_ORDERS_TOTAL . " ot on (o.orders_id = ot.orders_id and ot.class = 'ot_total') " . "1355                                         where o.customers_id = '" . (int)$cID . "' and o.orders_status = s.orders_status_id ".$order_time." and s.language_id = '" . (int)$_SESSION['languages_id'] . "' order by orders_id DESC";1356           }else{      1357               $orders_query_raw =   "select o.orders_id, orders_num, o.customers_id, o.customers_name, o.payment_method, o.shipping_method, o.date_purchased, o.last_modified, o.currency, o.currency_value, o.order_total as total, s.orders_status_name, ot.text as order_total" .1358                                     $new_fields . "1359                                     from (" . TABLE_ORDERS_STATUS . " s, " .1360                                     TABLE_ORDERS . " o " .1361                                     $new_table . ")1362                                     left join " . TABLE_ORDERS_TOTAL . " ot on (o.orders_id = ot.orders_id and ot.class = 'ot_total') " . "1363                                     where o.customers_id = '" . (int)$cID . "' and o.orders_status = s.orders_status_id and s.language_id = '" . (int)$_SESSION['languages_id'] . "' order by orders_id DESC";1364           }1365 1366       } 1367       elseif ($_GET['status'] != '') {1368       $status = zen_db_prepare_input($_GET['status']);1369       $orders_query_raw = "select o.orders_id, orders_num, o.customers_id, o.customers_name, o.payment_method, o.shipping_method, o.date_purchased, o.last_modified, o.currency, o.currency_value, o.order_total as total, s.orders_status_name, ot.text as order_total" .1370                           $new_fields . "1371                           from (" . TABLE_ORDERS_STATUS . " s, " .1372                           TABLE_ORDERS . " o " .1373                           $new_table . ")1374                           left join " . TABLE_ORDERS_TOTAL . " ot on (o.orders_id = ot.orders_id and ot.class = 'ot_total') " . "1375                           where o.orders_status = s.orders_status_id and s.language_id = '" . (int)$_SESSION['languages_id'] . "' and s.orders_status_id = '" . (int)$status . "'  " .1376                           $search . " order by o.orders_id DESC";1377 1378     }1379     else {1380       //add code1381       if(isset($_GET['start']) || isset($_GET['end'])){1382           if(!empty($_GET['start']) && empty($_GET['end'])){1383               $start_time = strtr($_GET['start'], "/", "-");1384               $order_time = " and orders_status <> 11 and o.date_purchased >= '".$start_time."' ";1385           }1386           if(empty($_GET['start']) && !empty($_GET['end'])){1387               $end_time = strtr($_GET['end'], "/", "-");1388               $order_time = " and orders_status <> 11 and o.date_purchased <= '".$end_time."' ";1389           }1390           if(!empty($_GET['start']) && !empty($_GET['end'])){1391               $start_time = strtr($_GET['start'], "/", "-");1392               $end_time = strtr($_GET['end'], "/", "-")." 23:59:59";1393               $order_time = " and orders_status <> 11 and o.date_purchased >= ' " .$start_time. "' and o.date_purchased <= '".$end_time."' ";1394           }1395           $orders_query_raw = "select " . $search_distinct . " o.orders_id, orders_num, o.customers_id, o.customers_name, o.payment_method, o.shipping_method, o.date_purchased, o.last_modified, o.currency, o.currency_value, o.date_purchased, o.date_purchased, o.order_total as total, s.orders_status_name, ot.text as order_total" .1396                           $new_fields . "1397                           from (" . TABLE_ORDERS_STATUS . " s, " .1398                           TABLE_ORDERS . " o " .1399                           $new_table . ")1400                           left join " . TABLE_ORDERS_TOTAL . " ot on (o.orders_id = ot.orders_id and ot.class = 'ot_total') " . "1401                           where (o.orders_status = s.orders_status_id and s.language_id = '" . (int)$_SESSION['languages_id'] . "')  " .1402                           $search . $order_time. " order by o.orders_id DESC";1403       }else{   1404           $orders_query_raw = "select " . $search_distinct . " o.orders_id, orders_num, o.customers_id, o.customers_name, o.payment_method, o.shipping_method, o.date_purchased, o.last_modified, o.currency, o.currency_value, o.date_purchased, o.order_total as total, s.orders_status_name, ot.text as order_total" .1405                           $new_fields . "1406                           from (" . TABLE_ORDERS_STATUS . " s, " .1407                           TABLE_ORDERS . " o " .1408                           $new_table . ")1409                           left join " . TABLE_ORDERS_TOTAL . " ot on (o.orders_id = ot.orders_id and ot.class = 'ot_total') " . "1410                           where (o.orders_status = s.orders_status_id and s.language_id = '" . (int)$_SESSION['languages_id'] . "')  " .1411                           $search . " order by o.orders_id DESC";1412       }1413     }1414 1415 // Split Page1416 // reset page when page is unknown1417 if (($_GET['page'] == '' or $_GET['page'] <= 1) and $_GET['oID'] != '') {1418   $check_page = $db->Execute($orders_query_raw);1419   $check_count=1;1420   if ($check_page->RecordCount() > MAX_DISPLAY_SEARCH_RESULTS_ORDERS) {1421     while (!$check_page->EOF) {1422       if ($check_page->fields['orders_id'] == $_GET['oID']) {1423         break;1424       }1425       $check_count++;1426       $check_page->MoveNext();1427     }1428     $_GET['page'] = round((($check_count/MAX_DISPLAY_SEARCH_RESULTS_ORDERS)+(fmod_round($check_count,MAX_DISPLAY_SEARCH_RESULTS_ORDERS) !=0 ? .5 : 0)),0);1429   } else {1430     $_GET['page'] = 1;1431   }1432 }1433 1434     //all order total1435     $orders = $db->Execute($orders_query_raw);1436     $total="";1437     while (!$orders->EOF) {1438         $total+=$orders->fields['total'];1439         $orders->MoveNext();1440     }1441     if(!empty($total)){1442         echo '<div id="total" style="display:none">'.$total.'</div>';1443     }1444 1445 //    $orders_query_numrows = '';1446     $orders_split = new splitPageResults($_GET['page'], MAX_DISPLAY_SEARCH_RESULTS_ORDERS, $orders_query_raw, $orders_query_numrows);1447     $orders = $db->Execute($orders_query_raw);1448     echo zen_draw_form('status', FILENAME_ORDERS, '', 'post', '', true);1449     while (!$orders->EOF) {1450     if ((!isset($_GET['oID']) || (isset($_GET['oID']) && ($_GET['oID'] == $orders->fields['orders_id']))) && !isset($oInfo)) {1451         $oInfo = new objectInfo($orders->fields);1452       }1453 1454       if (isset($oInfo) && is_object($oInfo) && ($orders->fields['orders_id'] == $oInfo->orders_id)) {1455         echo '              <tr id="defaultSelected" class="dataTableRowSelected" onmouseover="rowOverEffect(this)" onmouseout="rowOutEffect(this)" onclick="document.location.href=\'' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')) . 'oID=' . $oInfo->orders_id . '&action=edit', 'NONSSL') . '\'">' . "\n";1456       } else {1457         //echo '              <tr class="dataTableRow" onmouseover="rowOverEffect(this)" onmouseout="rowOutEffect(this)" onclick="document.location.href=\'' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID')) . 'oID=' . $orders->fields['orders_id'], 'NONSSL') . '\'">' . "\n";1458         echo '              <tr class="dataTableRow" onmouseover="rowOverEffect(this)" onmouseout="rowOutEffect(this)">' . "\n";1459       }1460 1461       $show_difference = '';1462       if (($orders->fields['delivery_name'] != $orders->fields['billing_name'] and $orders->fields['delivery_name'] != '')) {1463         $show_difference = zen_image(DIR_WS_IMAGES . 'icon_status_red.gif', TEXT_BILLING_SHIPPING_MISMATCH, 10, 10) . '&nbsp;';1464       }1465       if (($orders->fields['delivery_street_address'] != $orders->fields['billing_street_address'] and $orders->fields['delivery_street_address'] != '')) {1466         $show_difference = zen_image(DIR_WS_IMAGES . 'icon_status_red.gif', TEXT_BILLING_SHIPPING_MISMATCH, 10, 10) . '&nbsp;';1467       }1468       $show_payment_type = $orders->fields['payment_module_code'] . '<br />' . $orders->fields['shipping_module_code'];1469 ?>1470 <?php1471                 if(!empty($_GET['cID']) || !empty($_GET['search']) || !empty($_GET['orders_num']) || !empty($_GET['search_orders_products'])){1472                     1473                     $attributes = $db->Execute("select products_options_id1474                                                 from " . TABLE_ORDERS_PRODUCTS_ATTRIBUTES . "1475                                                 where orders_id = '" . $orders->fields['orders_id'] . "' and products_options_id ='5'");1476                     1477                     $order_products = $db->Execute("select products_total_quantity1478                                                     from ". TABLE_ORDERS_PRODUCTS ."1479                                                     where orders_id=" .$orders->fields['orders_id'] . " AND products_total_quantity < 0 ORDER BY products_total_quantity ");1480                 1481                 }1482                 else{1483                     $attributes = $db->Execute("select products_options_id1484                                                 from " . TABLE_ORDERS_PRODUCTS_ATTRIBUTES . "1485                                                 where orders_id = '" . $orders->fields['orders_id'] . "' and products_options_id ='5'");1486                     if(!empty($attributes->fields)){1487                         $orders->MoveNext();1488                         continue;1489                     }1490                     1491                     $order_products = $db->Execute("select products_total_quantity1492                                                     from ". TABLE_ORDERS_PRODUCTS ."1493                                                     where orders_id=" .$orders->fields['orders_id'] . " AND products_total_quantity < 0 ORDER BY products_total_quantity ");1494                     if($order_products->fields) {1495                         $orders->MoveNext();1496                         continue;1497                     }1498                 }1499                 1500                 $onclick = 'onclick="document.location.href=\'' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID')) . 'oID=' . $orders->fields['orders_id'], 'NONSSL') . '\'"';1501                 1502                 if(empty($show_difference)) $p='&nbsp&nbsp&nbsp&nbsp';1503                 else $p='';1504 ?>1505                 <td class="dataTableContent" align="left" <?php echo $onclick; ?> ><?php echo $show_difference.$p.$orders->fields['orders_num']; ?></td>1506                 <td class="dataTableContent" align="left" width="50" <?php echo $onclick; ?> ><?php echo $show_payment_type; ?></td>1507                 <td class="dataTableContent" <?php echo $onclick; ?> ><?php echo '<a href="' . zen_href_link(FILENAME_CUSTOMERS, 'cID=' . $orders->fields['customers_id'], 'NONSSL') . '">' . zen_image(DIR_WS_ICONS . 'preview.gif', ICON_PREVIEW . ' ' . TABLE_HEADING_CUSTOMERS) . '</a>&nbsp;' . $orders->fields['customers_name'] . ($orders->fields['customers_company'] != '' ? '<br />' . $orders->fields['customers_company'] : ''); ?></td>1508                 <td class="dataTableContent" align="right" <?php echo $onclick; ?> ><?php echo strip_tags($orders->fields['order_total']); ?></td>1509                 <td class="dataTableContent" align="center" <?php echo $onclick; ?> ><?php echo zen_datetime_short($orders->fields['date_purchased']); ?></td>1510                 <td class="dataTableContent" align="right" <?php echo $onclick; ?> ><?php echo $orders->fields['orders_status_name']; ?></td>1511                 <td class="dataTableContent" align="center" <?php echo $onclick; ?> ><?php echo (zen_get_orders_comments($orders->fields['orders_id']) == '' ? '' : zen_image(DIR_WS_IMAGES . 'icon_yellow_on.gif', TEXT_COMMENTS_YES, 16, 16)); ?><?php echo (!empty($attributes->fields) ? zen_image(DIR_WS_IMAGES . 'icon_green_on.gif', IMAGE_ICON_STATUS_ON):''); ?><?php echo (!empty($order_products->fields) ? zen_image(DIR_WS_IMAGES . 'icon_red_on.gif', ICON_EDIT) : ""); ?></td>1512                 <td class="dataTableContent" align="center"><input type="checkbox" name="order_id[]" value="<?php echo $orders->fields['orders_id']; ?>"></td>1513                 <td class="dataTableContent" align="right" <?php echo $onclick; ?> ><?php echo '<a href="' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')) . 'oID=' . $orders->fields['orders_id'] . '&action=edit', 'NONSSL') . '">' . zen_image(DIR_WS_IMAGES . 'icon_edit.gif', ICON_EDIT) . '</a>'; ?><?php if (isset($oInfo) && is_object($oInfo) && ($orders->fields['orders_id'] == $oInfo->orders_id)) { echo zen_image(DIR_WS_IMAGES . 'icon_arrow_right.gif', ''); } else { echo '<a href="' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID')) . 'oID=' . $orders->fields['orders_id'], 'NONSSL') . '">' . zen_image(DIR_WS_IMAGES . 'icon_info.gif', IMAGE_ICON_INFO) . '</a>'; } ?></td>1514             </tr>1515 <?php1516       $orders->MoveNext();1517     }1518 ?>1519               <tr>1520                 <td class="smallText" align="right"  colspan="8"><input type="submit" value="Export Orders"></form></td>1521               </tr>1522               <tr>1523                 <td colspan="5"><table border="0" width="100%" cellspacing="0" cellpadding="2">1524                   <tr>1525                     <td class="smallText" valign="top"><?php echo $orders_split->display_count($orders_query_numrows, MAX_DISPLAY_SEARCH_RESULTS_ORDERS, $_GET['page'], TEXT_DISPLAY_NUMBER_OF_ORDERS); ?></td>1526                     <td class="smallText" align="right"><?php echo $orders_split->display_links($orders_query_numrows, MAX_DISPLAY_SEARCH_RESULTS_ORDERS, MAX_DISPLAY_PAGE_LINKS, $_GET['page'], zen_get_all_get_params(array('page', 'oID', 'action'))); ?></td>1527                   </tr>1528 <?php1529   if (isset($_GET['search']) && zen_not_null($_GET['search'])) {1530 ?>1531                   <tr>1532                     <td class="smallText" align="right" colspan="2">1533                       <?php1534                         echo '<a href="' . zen_href_link(FILENAME_ORDERS, '', 'NONSSL') . '">' . zen_image_button('button_reset.gif', IMAGE_RESET) . '</a>';1535                         if (isset($_GET['search']) && zen_not_null($_GET['search'])) {1536                           $keywords = zen_db_input(zen_db_prepare_input($_GET['search']));1537                           echo '<br/ >' . TEXT_INFO_SEARCH_DETAIL_FILTER . $keywords;1538                         }1539                       ?>1540                     </td>1541                   </tr>1542 <?php1543   }1544 ?>1545                 </table></td>1546               </tr>1547             </table></td>1548 <?php1549   $heading = array();1550   $contents = array();1551 1552   switch ($action) {1553     case 'delete':1554       $heading[] = array('text' => '<strong>' . TEXT_INFO_HEADING_DELETE_ORDER . '</strong>');1555 1556       $contents = array('form' => zen_draw_form('orders', FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')) . 'oID=' . $oInfo->orders_id . '&action=deleteconfirm', 'post', '', true));1557 //      $contents[] = array('text' => TEXT_INFO_DELETE_INTRO . '<br /><br /><strong>' . $cInfo->customers_firstname . ' ' . $cInfo->customers_lastname . '</strong>');1558       $contents[] = array('text' => TEXT_INFO_DELETE_INTRO . '<br /><br /><strong>' . ENTRY_ORDER_ID . $oInfo->orders_num . '<br />' . $oInfo->order_total . '<br />' . $oInfo->customers_name . ($oInfo->customers_company != '' ? '<br />' . $oInfo->customers_company : '') . '</strong>');1559       $contents[] = array('text' => '<br />' . zen_draw_checkbox_field('restock') . ' ' . TEXT_INFO_RESTOCK_PRODUCT_QUANTITY);1560       $contents[] = array('align' => 'center', 'text' => '<br />' . zen_image_submit('button_delete.gif', IMAGE_DELETE) . ' <a href="' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')) . 'oID=' . $oInfo->orders_id, 'NONSSL') . '">' . zen_image_button('button_cancel.gif', IMAGE_CANCEL) . '</a>');1561       break;1562     default:1563       if (isset($oInfo) && is_object($oInfo)) {1564         $heading[] = array('text' => '<strong>[' . $oInfo->orders_id . ']&nbsp;&nbsp;' . zen_datetime_short($oInfo->date_purchased) . '</strong>');1565 1566         $contents[] = array('align' => 'center', 'text' => '<a href="' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')) . 'oID=' . $oInfo->orders_id . '&action=edit', 'NONSSL') . '">' . zen_image_button('button_edit.gif', IMAGE_EDIT) . '</a> <a href="' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')) . 'oID=' . $oInfo->orders_id . '&action=delete', 'NONSSL') . '">' . zen_image_button('button_delete.gif', IMAGE_DELETE) . '</a>');1567         $contents[] = array('align' => 'center', 'text' => '<a href="' . zen_href_link(FILENAME_ORDERS_INVOICE, 'oID=' . $oInfo->orders_id) . '" TARGET="_blank">' . zen_image_button('button_invoice.gif', IMAGE_ORDERS_INVOICE) . '</a> <a href="' . zen_href_link(FILENAME_ORDERS_PACKINGSLIP, 'oID=' . $oInfo->orders_id) . '" TARGET="_blank">' . zen_image_button('button_packingslip.gif', IMAGE_ORDERS_PACKINGSLIP) . '</a>');1568         $contents[] = array('align' => 'center', 'text' => '<a href="' . zen_href_link(FILENAME_ORDERS, 'cID=' . $oInfo->customers_id) . '" ">' . zen_image_button('button_allroder.gif', "All order") . '</a>');1569         $contents[] = array('text' => '<br />' . TEXT_DATE_ORDER_CREATED . ' ' . zen_date_short($oInfo->date_purchased));1570         $contents[] = array('text' => '<br />' . $oInfo->customers_email_address);1571         $contents[] = array('text' => TEXT_INFO_IP_ADDRESS . ' ' . $oInfo->ip_address);1572         if (zen_not_null($oInfo->last_modified)) $contents[] = array('text' => TEXT_DATE_ORDER_LAST_MODIFIED . ' ' . zen_date_short($oInfo->last_modified));1573         $contents[] = array('text' => '<br />' . TEXT_INFO_PAYMENT_METHOD . ' '  . $oInfo->payment_method);1574         $contents[] = array('text' => '<br />' . ENTRY_SHIPPING . ' '  . $oInfo->shipping_method);1575 1576 // check if order has open gv1577         $gv_check = $db->Execute("select order_id, unique_id1578                                   from " . TABLE_COUPON_GV_QUEUE ."1579                                   where order_id = '" . $oInfo->orders_id . "' and release_flag='N' limit 1");1580         if ($gv_check->RecordCount() > 0) {1581           $goto_gv = '<a href="' . zen_href_link(FILENAME_GV_QUEUE, 'order=' . $oInfo->orders_id) . '">' . zen_image_button('button_gift_queue.gif',IMAGE_GIFT_QUEUE) . '</a>';1582           $contents[] = array('text' => '<br />' . zen_image(DIR_WS_IMAGES . 'pixel_black.gif','','100%','3'));1583           $contents[] = array('align' => 'center', 'text' => $goto_gv);1584         }1585       }1586 1587 // indicate if comments exist1588       $orders_history_query = $db->Execute("select orders_status_id, date_added, customer_notified, comments from " . TABLE_ORDERS_STATUS_HISTORY . " where orders_id = '" . $oInfo->orders_id . "' and comments !='" . "'" );1589       if ($orders_history_query->RecordCount() > 0) {1590         $contents[] = array('align' => 'left', 'text' => '<br />' . TABLE_HEADING_COMMENTS);1591       }1592 1593       $contents[] = array('text' => '<br />' . zen_image(DIR_WS_IMAGES . 'pixel_black.gif','','100%','3'));1594       $order = new order($oInfo->orders_id);1595       $contents[] = array('text' => 'Products Ordered: ' . sizeof($order->products) );1596       for ($i=0; $i<sizeof($order->products); $i++) {1597         $contents[] = array('text' => $order->products[$i]['qty'] . '&nbsp;x&nbsp;' . $order->products[$i]['name']);1598 1599         if (sizeof($order->products[$i]['attributes']) > 0) {1600           for ($j=0; $j<sizeof($order->products[$i]['attributes']); $j++) {1601             $contents[] = array('text' => '&nbsp;<i> - ' . $order->products[$i]['attributes'][$j]['option'] . ': ' . nl2br(zen_output_string_protected($order->products[$i]['attributes'][$j]['value'])) . '</i></nobr>' );1602           }1603         }1604         if ($i > MAX_DISPLAY_RESULTS_ORDERS_DETAILS_LISTING and MAX_DISPLAY_RESULTS_ORDERS_DETAILS_LISTING != 0) {1605           $contents[] = array('align' => 'left', 'text' => TEXT_MORE);1606           break;1607         }1608       }1609 1610       if (sizeof($order->products) > 0) {1611         $contents[] = array('align' => 'center', 'text' => '<a href="' . zen_href_link(FILENAME_ORDERS, zen_get_all_get_params(array('oID', 'action')) . 'oID=' . $oInfo->orders_id . '&action=edit', 'NONSSL') . '">' . zen_image_button('button_edit.gif', IMAGE_EDIT) . '</a>');1612       }1613       break;1614   }1615 1616   if ( (zen_not_null($heading)) && (zen_not_null($contents)) ) {1617     echo '            <td width="25%" valign="top">' . "\n";1618 1619     $box = new box;1620     echo $box->infoBox($heading, $contents);1621 1622     echo '            </td>' . "\n";1623   }1624 ?>1625           </tr>1626         </table></td>1627       </tr>1628 <?php1629   }1630 ?>1631     </table></td>1632 <!-- body_text_eof //-->1633   </tr>1634 </table>1635 <!-- body_eof //-->1636 1637 <!-- footer //-->1638 <div class="footer-area">1639 <?php require(DIR_WS_INCLUDES . 'footer.php'); ?>1640 </div>1641 <!-- footer_eof //-->1642 <br />1643 </body>1644 </html>1645 <?php require(DIR_WS_INCLUDES . 'application_bottom.php'); ?>
View Code

 

10. 修改付款后,给客户发送邮件的问题。注销 includes/modules/checkout_process.php 文件的 $order->send_order_email($insert_id, 2);  这是生成订单的时候发送订单邮件,不是付款成功时发送邮件,所以需要注销掉,当然你也可以自己写邮件,当订单生成后,可以发送提示邮件给客户。付款成功后发送邮件功能调用在 ipn_main_handler.php 文件中。发送邮件函数是在 includes/classes/order.php 文件的 send_order_email($zf_insert_id, $zf_mode) 函数,代码修改如下:

  1   function send_order_email($zf_insert_id, $zf_mode) {  2     global $currencies, $order_totals;  3     if( !empty($this->totals) ){  4         $order_totals = $this->totals;  5     }  6     if ($this->email_low_stock != '' and SEND_LOWSTOCK_EMAIL=='1') {  7       // send an email  8       $email_low_stock = SEND_EXTRA_LOW_STOCK_EMAIL_TITLE . "\n\n" . $this->email_low_stock;  9       zen_mail('', SEND_EXTRA_LOW_STOCK_EMAILS_TO, EMAIL_TEXT_SUBJECT_LOWSTOCK, $email_low_stock, STORE_OWNER, EMAIL_FROM, array('EMAIL_MESSAGE_HTML' => nl2br($email_low_stock)),'low_stock'); 10     } 11  12     // lets start with the email confirmation 13     // make an array to store the html version 14     $html_msg=array(); 15  16     //intro area 17     $email_order = EMAIL_TEXT_HEADER . EMAIL_TEXT_FROM . STORE_NAME . "\n\n" . 18     $this->customer['firstname'] . ' ' . $this->customer['lastname'] . "\n\n" . 19     EMAIL_THANKS_FOR_SHOPPING . "\n" . EMAIL_DETAILS_FOLLOW . "\n" . 20     EMAIL_SEPARATOR . "\n" . 21     EMAIL_TEXT_ORDER_NUMBER . ' ' . zen_get_order_orders_number($zf_insert_id) . "\n" . 22     EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "\n" . 23     EMAIL_TEXT_INVOICE_URL . ' ' . zen_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $zf_insert_id, 'SSL', false) . "\n\n"; 24     $html_msg['EMAIL_TEXT_HEADER']     = EMAIL_TEXT_HEADER; 25     $html_msg['EMAIL_TEXT_FROM']       = EMAIL_TEXT_FROM; 26     $html_msg['INTRO_STORE_NAME']      = STORE_NAME; 27     $html_msg['EMAIL_THANKS_FOR_SHOPPING'] = EMAIL_THANKS_FOR_SHOPPING; 28     $html_msg['EMAIL_DETAILS_FOLLOW']  = EMAIL_DETAILS_FOLLOW; 29     $html_msg['INTRO_ORDER_NUM_TITLE'] = EMAIL_TEXT_ORDER_NUMBER; 30     $html_msg['INTRO_ORDER_NUMBER']    = zen_get_order_orders_number($zf_insert_id); 31     $html_msg['INTRO_DATE_TITLE']      = EMAIL_TEXT_DATE_ORDERED; 32     $html_msg['INTRO_DATE_ORDERED']    = strftime(DATE_FORMAT_LONG); 33     $html_msg['INTRO_URL_TEXT']        = EMAIL_TEXT_INVOICE_URL_CLICK; 34     $html_msg['INTRO_URL_VALUE']       = zen_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $zf_insert_id, 'SSL', false); 35  36     //comments area 37     if ($this->info['comments']) { 38       $email_order .= zen_db_output($this->info['comments']) . "\n\n"; 39       $html_msg['ORDER_COMMENTS'] = nl2br(zen_db_output($this->info['comments'])); 40     } else { 41       $html_msg['ORDER_COMMENTS'] = ''; 42     } 43  44     //products area 45     $email_order .= EMAIL_TEXT_PRODUCTS . "\n" . 46     EMAIL_SEPARATOR . "\n" . 47     $this->products_ordered . 48     EMAIL_SEPARATOR . "\n"; 49     $html_msg['PRODUCTS_TITLE'] = EMAIL_TEXT_PRODUCTS; 50     $html_msg['PRODUCTS_DETAIL']='<table class="product-details" border="0" width="100%" cellspacing="0" cellpadding="2">' . $this->products_ordered_html . '</table>'; 51  52     //order totals area 53     $html_ot .= '<td class="order-totals-text" align="right" width="100%">' . '&nbsp;' . '</td> ' . "\n" . '<td class="order-totals-num" align="right" nowrap="nowrap">' . '---------' .'</td> </tr>' . "\n" . '<tr>'; 54     for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) { 55       $email_order .= strip_tags($order_totals[$i]['title']) . ' ' . strip_tags($order_totals[$i]['text']) . "\n"; 56       $html_ot .= '<td class="order-totals-text" align="right" width="100%">' . $order_totals[$i]['title'] . '</td> ' . "\n" . '<td class="order-totals-num" align="right" nowrap="nowrap">' .($order_totals[$i]['text']) .'</td> </tr>' . "\n" . '<tr>'; 57     } 58     $html_msg['ORDER_TOTALS'] = '<table border="0" width="100%" cellspacing="0" cellpadding="2"> ' . $html_ot . ' </table>'; 59  60     //addresses area: Delivery 61     $html_msg['HEADING_ADDRESS_INFORMATION']= HEADING_ADDRESS_INFORMATION; 62     $html_msg['ADDRESS_DELIVERY_TITLE']     = EMAIL_TEXT_DELIVERY_ADDRESS; 63     if(empty($this->delivery)){ 64         $html_msg['ADDRESS_DELIVERY_DETAIL']    = ($this->content_type != 'virtual') ? zen_address_label($_SESSION['customer_id'], $_SESSION['sendto'], true, '', "<br />") : 'n/a'; 65     }else{ 66         $delivery = $this->delivery; 67         $html_msg['ADDRESS_DELIVERY_DETAIL'] = $delivery['company'] . "<br />" . $delivery['name'] . "<br />" . $delivery['suburb'] . " " . $delivery['street_address'] . "<br />" .  $delivery['city'] . ", " . $delivery['postcode'] . "<br />" . $delivery['state'] . ", " . $delivery['country']; 68     } 69     $html_msg['SHIPPING_METHOD_TITLE']      = HEADING_SHIPPING_METHOD; 70     $html_msg['SHIPPING_METHOD_DETAIL']     = (zen_not_null($this->info['shipping_method'])) ? $this->info['shipping_method'] : 'n/a'; 71  72     if ($this->content_type != 'virtual') { 73       $email_order .= "\n" . EMAIL_TEXT_DELIVERY_ADDRESS . "\n" . 74       EMAIL_SEPARATOR . "\n" . 75       zen_address_label($_SESSION['customer_id'], $_SESSION['sendto'], 0, '', "\n") . "\n"; 76     } 77  78     //addresses area: Billing 79     $email_order .= "\n" . EMAIL_TEXT_BILLING_ADDRESS . "\n" . 80     EMAIL_SEPARATOR . "\n" . 81     zen_address_label($_SESSION['customer_id'], $_SESSION['billto'], 0, '', "\n") . "\n\n"; 82     $html_msg['ADDRESS_BILLING_TITLE']   = EMAIL_TEXT_BILLING_ADDRESS; 83     if(empty($this->billing)){ 84         $html_msg['ADDRESS_BILLING_DETAIL']  = zen_address_label($_SESSION['customer_id'], $_SESSION['billto'], true, '', "<br />"); 85     }else{ 86         $billing = $this->billing; 87         $html_msg['ADDRESS_BILLING_DETAIL'] = $billing['company'] . "<br />" . $billing['name'] . "<br />" . $billing['suburb'] . " " . $billing['street_address'] . "<br />" .  $billing['city'] . ", " . $billing['postcode'] . "<br />" . $billing['state'] . ", " . $billing['country']; 88     } 89  90     if (is_object($GLOBALS[$_SESSION['payment']])) { 91       $cc_num_display = (isset($this->info['cc_number']) && $this->info['cc_number'] != '') ? /*substr($this->info['cc_number'], 0, 4) . */ str_repeat('X', (strlen($this->info['cc_number']) - 8)) . substr($this->info['cc_number'], -4) . "\n\n" : ''; 92       $email_order .= EMAIL_TEXT_PAYMENT_METHOD . "\n" . 93       EMAIL_SEPARATOR . "\n"; 94       $payment_class = $_SESSION['payment']; 95       $email_order .= $GLOBALS[$payment_class]->title . "\n\n"; 96       $email_order .= (isset($this->info['cc_type']) && $this->info['cc_type'] != '') ? $this->info['cc_type'] . ' ' . $cc_num_display . "\n\n" : ''; 97       $email_order .= ($GLOBALS[$payment_class]->email_footer) ? $GLOBALS[$payment_class]->email_footer . "\n\n" : ''; 98     } else { 99       $email_order .= EMAIL_TEXT_PAYMENT_METHOD . "\n" .100       EMAIL_SEPARATOR . "\n";101       $email_order .= PAYMENT_METHOD_GV . "\n\n";102     }103     $html_msg['PAYMENT_METHOD_TITLE']  = EMAIL_TEXT_PAYMENT_METHOD;104     $html_msg['PAYMENT_METHOD_DETAIL'] = (is_object($GLOBALS[$_SESSION['payment']]) ? $GLOBALS[$payment_class]->title : PAYMENT_METHOD_GV );105     $html_msg['PAYMENT_METHOD_FOOTER'] = (is_object($GLOBALS[$_SESSION['payment']]) && $GLOBALS[$payment_class]->email_footer != '') ? nl2br($GLOBALS[$payment_class]->email_footer) : (isset($this->info['cc_type']) && $this->info['cc_type'] != '' ? $this->info['cc_type'] . ' ' . $cc_num_display . "\n\n" : '');106 107     // include disclaimer108     if (defined('EMAIL_DISCLAIMER') && EMAIL_DISCLAIMER != '') $email_order .= "\n-----\n" . sprintf(EMAIL_DISCLAIMER, STORE_OWNER_EMAIL_ADDRESS) . "\n\n";109     // include copyright110     if (defined('EMAIL_FOOTER_COPYRIGHT')) $email_order .= "\n-----\n" . EMAIL_FOOTER_COPYRIGHT . "\n\n";111 112     while (strstr($email_order, '&nbsp;')) $email_order = str_replace('&nbsp;', ' ', $email_order);113 114     if(!empty($this->customer['firstname'])){115         $html_msg['EMAIL_FIRST_NAME'] = $this->customer['firstname'];116         $html_msg['EMAIL_LAST_NAME'] = $this->customer['lastname'];117     }elseif($this->customer['name']){118         $html_msg['EMAIL_FIRST_NAME'] = $this->customer['name'];119         $html_msg['EMAIL_LAST_NAME'] = '';120     }121     //  $html_msg['EMAIL_TEXT_HEADER'] = EMAIL_TEXT_HEADER;122     $html_msg['EXTRA_INFO'] = '';123     $this->notify('NOTIFY_ORDER_INVOICE_CONTENT_READY_TO_SEND', array('zf_insert_id' => $zf_insert_id, 'text_email' => $email_order, 'html_email' => $html_msg));124     zen_mail($this->customer['firstname'] . ' ' . $this->customer['lastname'], $this->customer['email_address'], EMAIL_TEXT_SUBJECT . EMAIL_ORDER_NUMBER_SUBJECT . zen_get_order_orders_number($zf_insert_id), $email_order, STORE_NAME, EMAIL_FROM, $html_msg, 'checkout', $this->attachArray);125 126     // send additional emails127     if (SEND_EXTRA_ORDER_EMAILS_TO != '') {128       $extra_info=email_collect_extra_info('','', $this->customer['firstname'] . ' ' . $this->customer['lastname'], $this->customer['email_address'], $this->customer['telephone']);129       $html_msg['EXTRA_INFO'] = $extra_info['HTML'];130 131       // include authcode and transaction id in admin-copy of email132       if ($GLOBALS[$_SESSION['payment']]->auth_code || $GLOBALS[$_SESSION['payment']]->transaction_id) {133         $pmt_details = ($GLOBALS[$_SESSION['payment']]->auth_code != '' ? 'AuthCode: ' . $GLOBALS[$_SESSION['payment']]->auth_code . '  ' : '') . ($GLOBALS[$_SESSION['payment']]->transaction_id != '' ?  'TransID: ' . $GLOBALS[$_SESSION['payment']]->transaction_id : '') . "\n\n";134         $email_order = $pmt_details . $email_order;135         $html_msg['EMAIL_TEXT_HEADER'] = nl2br($pmt_details) . $html_msg['EMAIL_TEXT_HEADER'];136       }137 138       zen_mail('', SEND_EXTRA_ORDER_EMAILS_TO, SEND_EXTRA_NEW_ORDERS_EMAILS_TO_SUBJECT . ' ' . EMAIL_TEXT_SUBJECT . EMAIL_ORDER_NUMBER_SUBJECT . zen_get_order_orders_number($zf_insert_id),139       $email_order . $extra_info['TEXT'], STORE_NAME, EMAIL_FROM, $html_msg, 'checkout_extra', $this->attachArray);140     }141     $this->notify('NOTIFY_ORDER_AFTER_SEND_ORDER_EMAIL', array($zf_insert_id, $email_order, $extra_info, $html_msg));142   }143 144 }

 

11. 未付款订单不需要永久保存,我们规定未付款订单超过三天自动删除,而且未付款订单在生成半小时后,或距离删除时间还有12小时的时候,都会自动发送一封邮件给客户,提醒他及时付款,以及订单将被删除。现在需要在订单表 orders 中增加 payment_reminder, delete_reminder两个字段,类型为TINYINT,用0或1表示发送和未发送,在 includes/init_includes 中增加一个文件,或者在 includes/init_includes 目录下的某个文件中添加代码都可以。我是在 init_special_funcs.php 这个文件末尾增加代码,因为当网站被点击一次,这些代码将会被执行一次,其实完全没必要,所以使用了 if(rand(1,10) == 5) 这个方法来限制代码执行次数,如果你的PV量越大,随机数设置就要相应的大些即可。代码如下:

 1 if(rand(1,10) == 5){ 2     $unpaid_order = "select orders_id, orders_num, customers_name, customers_email_address, payment_reminder, delete_reminder, date_purchased from " . TABLE_ORDERS . " where orders_status = 11"; 3     $unpaid_order = $db->Execute($unpaid_order); 4     while (!$unpaid_order->EOF) { 5         $now=date("Y-m-d H:i:s"); 6         $delete_order = date("Y-m-d H:i:s",strtotime("+3days",strtotime($unpaid_order->fields['date_purchased']))); 7         $payment_reminder = date("Y-m-d H:i:s",strtotime("+5Minute",strtotime($unpaid_order->fields['date_purchased']))); 8         $delete_reminder = date("Y-m-d H:i:s",strtotime("+60Hour",strtotime($unpaid_order->fields['date_purchased']))); 9         10         if($now > $delete_order){11                 $db->Execute("delete from " . TABLE_ORDERS . " where orders_id = '" . (int)$unpaid_order->fields['orders_id'] . "'");12                 $db->Execute("delete from " . TABLE_ORDERS_PRODUCTS . "13                               where orders_id = '" . (int)$unpaid_order->fields['orders_id'] . "'");14             15                 $db->Execute("delete from " . TABLE_ORDERS_PRODUCTS_ATTRIBUTES . "16                               where orders_id = '" . (int)$unpaid_order->fields['orders_id'] . "'");17             18                 $db->Execute("delete from " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . "19                               where orders_id = '" . (int)$unpaid_order->fields['orders_id'] . "'");20             21                 $db->Execute("delete from " . TABLE_ORDERS_STATUS_HISTORY . "22                               where orders_id = '" . (int)$unpaid_order->fields['orders_id'] . "'");23             24                 $db->Execute("delete from " . TABLE_ORDERS_TOTAL . "25                               where orders_id = '" . (int)$unpaid_order->fields['orders_id'] . "'");26         }27         28         if($unpaid_order->fields['payment_reminder'] == 0 && $now > $payment_reminder){29             $to_name = $unpaid_order->fields['customers_name'];30             $to_address = $unpaid_order->fields['customers_email_address'];31             $email_subject="Your Pending Order No: " . $unpaid_order->fields['orders_num'];32             $email_text='<p>Dear '.$unpaid_order->fields['customers_name'].',<br /></p>33                          <p>Thanks for choosing Geeetech, your order has been generated, however, we are still waiting for your payment, please finish the payment timely.</p>34                          <p>We will keep your order  for 3 days, during that time, you can continue to pay at my order on www.geeetech.com.</p>35                          <p>If you do not pay in 3 days, your order will be deleted automatically, If there is any problem during the payment, please let us know as soon as possible.</p>36                          <p>37                          <a href="'.zen_href_link(FILENAME_ACCOUNT_HISTORY).'" style="height:30px; line-height:30px; border:1px #000 solid; display:block; width:100px; text-align:center; background:#ccc;">Check My Order</a>38                          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;39                          <a href="'.zen_href_link(FILENAME_ACCOUNT_HISTORY_INFO,"order_id=".$unpaid_order->fields["orders_id"]).'" style="height:30px; line-height:30px; border:1px #000 solid; display:block; width:100px; text-align:center; background:#ccc;">Pay Now</a>40                          </p>41                         ';42             $block=array("EMAIL_MESSAGE_HTML" => $email_text);43             zen_mail($to_name, $to_address, $email_subject, $email_text, STORE_NAME, EMAIL_FROM, $block);44             $db->Execute("update " . TABLE_ORDERS . "45                           set payment_reminder = 1 46                           where orders_id = '" . (int)$unpaid_order->fields['orders_id'] . "'");47         }48         49         if($unpaid_order->fields['delete_reminder'] == 0 && $now > $delete_reminder){50             $to_name = $unpaid_order->fields['customers_name'];51             $to_address = $unpaid_order->fields['customers_email_address'];52             $email_subject="Your Pending Order No: " . $unpaid_order->fields['orders_num'];53             $email_text='<p>Dear '.$unpaid_order->fields['customers_name'].',<br /></p>54                          <p>You have placed an order at Geeetech on ' . strftime(DATE_TIME_FORMAT,strtotime($unpaid_order->fields['date_purchased'])) .' [-0600GMT], however, we are still waiting for your payment. </p>55                          <p>Your order will be deleted automatically in 12 hours,  please finish the payment timely. If there is any problem during the payment, please let us know as soon as possible. </p>56                          </p>57                          <a href="'.zen_href_link(FILENAME_ACCOUNT_HISTORY).'" style="height:30px; line-height:30px; border:1px #000 solid; display:block; width:100px; text-align:center; background:#ccc;">Check My Order</a>58                          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;59                          <a href="'.zen_href_link(FILENAME_ACCOUNT_HISTORY_INFO,"order_id=".$unpaid_order->fields["orders_id"]).'" style="height:30px; line-height:30px; border:1px #000 solid; display:block; width:100px; text-align:center; background:#ccc;">Pay Now</a>60                          </p>61                         ';62             $block=array("EMAIL_MESSAGE_HTML" => $email_text);63             zen_mail($to_name, $to_address, $email_subject, $email_text, STORE_NAME, EMAIL_FROM, $block);64             $db->Execute("update " . TABLE_ORDERS . "65                           set delete_reminder = 166                           where orders_id = '" . (int)$unpaid_order->fields['orders_id'] . "'");67         }68         69         $unpaid_order->MoveNext();70     }71     72     $special_count = "select specials_id, specials_date_available from " . TABLE_SPECIALS . " where specials_date_available > '" . date('Y-m-d') . "' and counter > 0";73     $special_count = $db->Execute($special_count);74     while(!$special_count->EOF){75         $update_specials = "update " . TABLE_SPECIALS . " set counter = 0 where specials_id = ". $special_count->fields['specials_id'];76         $db->Execute($update_specials);77         $special_count->MoveNext();78     }79 }

 

经过上面的修改,我们的流程如下:

1. 购物车(shopping cart)

2. [货运方式(delivery method)]

3. 支付方式(payment method)

4. 订单确认(confirmation)  

5. 订单处理(checkout process)

6. 下单成功(checkout success)

7. [第三方网站支付] 

因为从订单确认到订单处理,都是在我们自己的网站完成的,并且进入支付网站之前,订单已经存在了,这样就不会出现漏单的情况了。

在测试过程中,我们不可能直接使用自己的Paypal去测试订单,这样手续费都要扣很大部分,Paypal为了给IT人员测试接口,开发了虚拟Paypal帐号,可以通过Paypal虚拟帐号测试功能。具体申请使用教程链接如下:http://blog.sina.com.cn/s/blog_7285f5d30101fq05.html

总结:

以上修改,完成了网站四个新功能。

1. 快速支付功能

2. 先生成订单后付款功能

3. 按指定时间自动删除未付款订单以及自动发送提示邮件功能

4. 实现和淘宝一样,后台修改未付款订单价格功能

最后:可能还有些代码细节没有一一说到,但是上传的这些代码里面都有体现,需要自己仔细看。有什么问题可以给我留言!

1楼miketwais
zencart 代码看起来怕怕的这代码。