Zencart先生成订单后付款,类似淘宝后台修改订单价格 - 阿癫

时间:2024-02-21 07:30:48

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 use
107    * (Number, Owner, and CVV Lengths)
108    *
109    * @return string
110     */
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 Page
116    *
117    * @return array
118     */
119   function selection() {
120     return array(\'id\' => $this->code,
121                  \'module\' => MODULE_PAYMENT_PAYPAL_TEXT_CATALOG_LOGO,
122                  \'icon\' => MODULE_PAYMENT_PAYPAL_TEXT_CATALOG_LOGO
123                  );
124   }
125   /**
126    * Normally evaluates the Credit Card Type for acceptance and the validity of the Credit Card Number & Expiration Date
127    * Since paypal module is not collecting info, it simply skips this step.
128    *
129    * @return boolean
130    */
131   function pre_confirmation_check() {
132     return false;
133   }
134   /**
135    * Display Credit Card Information on the Checkout Confirmation Page
136    * Since none is collected for paypal before forwarding to paypal site, this is skipped
137    *
138    * @return boolean
139     */
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 string
149     */
150   function process_button() {
151     return false;
152   }
153   /**
154    * Determine the language to use when visiting the PayPal site
155    */
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 gateway
174    */
175   function before_process() {
176     return false;
177   }
178   /**
179     * Checks referrer
180     *
181     * @param string $zf_domain
182     * @return boolean
183     */
184   function check_referrer($zf_domain) {
185     return true;
186   }
187   /**
188     * Build admin-page components
189     *
190     * @param int $zf_order_id
191     * @return string
192     */
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 activities
203    * When the order returns from the processor, if PDT was successful, this stores the results in order-status-history and logs data for subsequent reference
204    *
205    * @return boolean
206     */
207   function after_process() {
208     return false;
209   }
210   /**
211    * Used to display error message details
212    *
213    * @return boolean
214     */
215   function output_error() {
216     return false;
217   }
218   /**
219    * Check to see whether module is installed
220    *
221    * @return boolean
222     */
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 settings
237     *
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/webscr
265     $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 here
267     $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 settings
274     *
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 module
283    *
284    * @return array
285     */
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 data
320     $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_reason
346                 FROM " . TABLE_PAYPAL . "
347                 WHERE txn_id = :transactionID OR parent_txn_id = :transactionID
348                 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 checkup
377           } 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 release
388       $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 session
430       $_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 optional
489       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 possible
510       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 mode
520           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 submission
548       $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 fields
552       foreach ($options as $name => $value) {
553           // remove quotation marks
554           $value = str_replace(\'"\', \'\', $value);
555           // check for invalid chars
556           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 modules
11       $payment_modules->after_process();
12       
13       $_SESSION[\'cart\']->reset(true);
14       
15       // unregister session variables used during checkout
16       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 SYSTEM
22       
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 transaction
104    */
105   $isECtransaction = ((isset($_POST[\'txn_type\']) && $_POST[\'txn_type\']==\'express_checkout\') || (isset($_POST[\'custom\']) && in_array(substr($_POST[\'custom\'], 0, 3), array(\'EC-\', \'DP-\', \'WPP\')))); /*|| $_POST[\'txn_type\']==\'cart\'*/
106   $isDPtransaction = (isset($_POST[\'custom\']) && in_array(substr($_POST[\'custom\'], 0, 3), array(\'DP-\', \'WPP\')));
107   /**
108    * set paypal-specific application_top parameters
109    */
110   $current_page_base = \'paypalipn\';
111   $loaderPrefix = \'paypal_ipn\';
112   $show_all_errors = FALSE;
113   require(\'includes/application_top.php\');
114 
115   $extraDebug = (defined(\'IPN_EXTRA_DEBUG_DETAILS\') && IPN_EXTRA_DEBUG_DETAILS == \'All\');
116 
117   if (  (defined(\'MODULE_PAYMENT_PAYPALWPP_DEBUGGING\') && strstr(MODULE_PAYMENT_PAYPALWPP_DEBUGGING, \'Log\')) ||
118       (defined(\'MODULE_PAYMENT_PAYPAL_IPN_DEBUG\') && strstr(MODULE_PAYMENT_PAYPAL_IPN_DEBUG, \'Log\')) ||
119       ($_REQUEST[\'ppdebug\'] == \'on\' && strstr(EXCLUDE_ADMIN_IP_FOR_MAINTENANCE, $_SERVER[\'REMOTE_ADDR\'])) || $extraDebug  ) {
120     $show_all_errors = true;
121     $debug_logfile_path = ipn_debug_email(\'Breakpoint: 0 - Initializing debugging.\');
122     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 use
133    */
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, etc
140    */
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 updates
173    */
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 processing
202    */
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 requirements
213    */
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 transactions
220       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 payments
225       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 yet
231       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 needed
250         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 -- housekeeping
276        */
277       $db->Execute("delete from " . TABLE_PAYPAL_SESSION . " where session_id = \'" . zen_db_input(str_replace(\'zenid=\', \'\', $_POST[\'custom\'])) . "\'");
278       /**
279        * require shipping class
280        */
281       require(DIR_WS_CLASSES . \'shipping.php\');
282       /**
283        * require payment class
284        */
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 class
290        */
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 class
300        */
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\' => 0
350             );
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\' => 0
365             );
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\' => 0
435                                     );
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=Voided
514           $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 failed
521           $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-cleared
528           $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 authorization
533           $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 now
537         case (substr($txn_type,0,8) == \'pending-\'):
538           // pending anything
539           $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 information
543       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 only
556   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 <?php
1035     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 <?php
1053 }
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 <?php
1070     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 <?php
1110     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 <?php
1123   // show downloads
1124   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 <?php
1139     $orders_history = $db->Execute("select orders_status_id, date_added, customer_notified, comments
1140                                     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 <?php
1205 // check if order has open gv
1206         $gv_check = $db->Execute("select order_id, unique_id
1207                                   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 <?php
1219   } 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                   <?php
1233                     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 <?php
1255 // Sort Listing
1256           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 <?php
1294 // Only one or the other search
1295 // create search_orders_products filter
1296   $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 <?php
1312 // create search filter
1313   $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_products
1328     $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 <?php
1331       if (isset($_GET[\'cID\'])) {
1332             $cID = zen_db_prepare_input($_GET[\'cID\']);
1333           //add code
1334           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 code
1381       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 Page
1416 // reset page when page is unknown
1417 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 total
1435     $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 <?php
1471                 if(!empty($_GET[\'cID\']) || !empty($_GET[\'search\']) || !empty($_GET[\'orders_num\']) || !empty($_GET[\'search_orders_products\'])){
1472                     
1473                     $attributes = $db->Execute("select products_options_id
1474                                                 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_quantity
1478                                                     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_id
1484                                                 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_quantity
1492                                                     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 <?php
1516       $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 <?php
1529   if (isset($_GET[\'search\']) && zen_not_null($_GET[\'search\'])) {
1530 ?>
1531                   <tr>
1532                     <td class="smallText" align="right" colspan="2">
1533                       <?php
1534                         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 <?php
1543   }
1544 ?>
1545                 </table></td>
1546               </tr>
1547             </table></td>
1548 <?php
1549   $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 gv
1577         $gv_check = $db->Execute("select order_id, unique_id
1578                                   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 exist
1588       $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 <?php
1629   }
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 disclaimer
108     if (defined(\'EMAIL_DISCLAIMER\') && EMAIL_DISCLAIMER != \'\') $email_order .= "\n-----\n" . sprintf(EMAIL_DISCLAIMER, STORE_OWNER_EMAIL_ADDRESS) . "\n\n";
109     // include copyright
110     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 emails
127     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 email
132       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 = 1
66                           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. 实现和淘宝一样,后台修改未付款订单价格功能

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