程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> Zencart先生成訂單後付款,類似淘寶後台修改訂單價格,zencart生成訂單

Zencart先生成訂單後付款,類似淘寶後台修改訂單價格,zencart生成訂單

編輯:關於PHP編程

Zencart先生成訂單後付款,類似淘寶後台修改訂單價格,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 帳號交易信息看到客戶購買了哪些物品。

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> 966 <tr id="products_list_changes"> 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">$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>; 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">$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">$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).'">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"]).'">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).'">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"]).'">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. 實現和淘寶一樣,後台修改未付款訂單價格功能

最後:可能還有些代碼細節沒有一一說到,但是上傳的這些代碼裡面都有體現,需要自己仔細看。有什麼問題可以給我留言!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved