Zencart 使用 Paypal 付款,會出現(xiàn)漏單的情況,即 paypal 已經(jīng)收到客戶的付款,但是網(wǎng)站后臺沒有客戶的訂單。導(dǎo)致 paypal 漏單的原因大致會是當(dāng)客戶跳轉(zhuǎn)到Paypal 網(wǎng)站付款完畢之后,直接關(guān)閉了窗口,或者網(wǎng)絡(luò)不穩(wěn)定,沒有正常跳轉(zhuǎn)到網(wǎng)站。
解決 Paypal 漏單問題的方案有好幾種:
一. 開啟 Detailed Line Items in Cart 選項。
原理:在 zencart 后臺 Module --> Payment --> PayPal Website Payments Standard - ipN 開啟 Detailed Line Items in Cart 選項。這個選項會把你所有的訂單物品信息傳給 paypal,當(dāng)客戶付款成功而后臺未能成功生成訂單時,也可以通過 paypal 帳號交易信息看到客戶購買了哪些物品。

二. 使用 Paypal sessions Viewer 插件找回 Paypal 漏掉的訂單。
原理:zencart 購物車的物品,通過 paypal 方式付款,會在 paypal_session 表中保存此次付款的所有記錄,如果付款成功后,從 paypal 網(wǎng)站跳轉(zhuǎn)到購物網(wǎng)站并生成了訂單時,zencart系統(tǒng)會自動刪除這條 paypal_session 記錄,如果沒有成功跳轉(zhuǎn)到購物網(wǎng)站,沒有成功生成訂單,那這條付款記錄數(shù)據(jù)就會一直保存在數(shù)據(jù)庫,當(dāng)使用 Paypal Session Viewer 插件,就能查看這條記錄的所有數(shù)據(jù),包括客戶信息,購物時間,商品信息,如果你確定已收到款,就可以把這條 paypal_session 信息轉(zhuǎn)移到訂單中,生成一個訂單。
插件下載地址:http://www.zen-cart.cn/english-version-modules/admin-tools/paypal-sessions-viewer

三. 修改付款流程,先生成訂單后付款。
原理:用過zen-cart的人都知道,zen-cart中下單步驟是下面這樣的(其中[]中的表示不是必須的):
1. 購物車(shopping cart)
2. [貨運方式(delivery method)]
3. 支付方式(payment method)
4. 訂單確認(confirmation)
5. [第三方網(wǎng)站支付]
6. 訂單處理(checkout PRocess)——這一步比較重要,因為會在這里將購物車中的信息寫入訂單
7. 下單成功(checkout success)
這樣的流程在正常情況下是沒有任何問題的。但是,從第5步到第6部的過程中,用戶可能以為付款成功就直接關(guān)閉掉網(wǎng)頁了,或者由于網(wǎng)絡(luò)原因造成不能正常跳轉(zhuǎn)到checkout_process頁面,這樣造成的后果是很嚴重的,因為訂單不能被正常的創(chuàng)建。基于上述的分析, 我們希望稍微地改變一下流程,即在支付之前訂單已經(jīng)創(chuàng)建好了,這樣就算在支付時不能從第三方支付網(wǎng)站跳轉(zhuǎn)回來,我們也不會存在用戶付款成功卻在后臺沒有訂單的情況了。
本人是參照東國先生的這篇修改zen-cart下單和付款流程以防止漏單 教程去修改的,因為這個教程比較老,而且也沒有很全面,所以我根據(jù)自己的實際需求,把他做的更完善,更細節(jié)化。
經(jīng)過修改后的藍圖基本是下面這樣的:
1. 在checkour_confirmation頁面確認訂單后,都會直接proccess,并且進入 account_history_info 頁面,可以在這里進入付款頁面。如下圖所示:

2. 如果當(dāng)時客戶沒能付款,也可進入自己的后臺對歷史訂單進行付款。如下圖所示:

3. 未付款的訂單,可以在后臺修改價格,像淘寶一樣拍下寶貝后,店主給你修改價格后再付款一樣。如下圖所示:

下面我們來正式修改代碼,首先我列舉出所有要修改的文件:
1. includes/classes/payment.php
2. includes/modules/payment/paypal.php
3. includes/classes/order.php
4. includes/modules/pages/checkout_process/header_php.php
5. includes/modules/pages/account_history_info/header_php.php
6. includes/templates/你的模板目錄/templates/tpl_account_history_info_default.php
7. includes/templates/你的模板目錄/templates/tpl_account_history_default.php
8. ipn_main_handler.php
9. admin(后臺目錄)/orders.php
因為先生成訂單再付款,付款步驟就會比原來又多了一步,為了簡化付款流程,我安裝了 Fast And Easy Checkout For Zencart(快速支付) 插件,安裝此插件之前,需要安裝另外一個插件 CSS Js Loader For Zencart,這是快速支付插件的依賴插件。快速支付與先生成訂單后支付沒什么因果關(guān)系,所以如果你不想安裝的話完全可以不理。
按步驟修改上面列舉的文件:
1. 首先我們需要對現(xiàn)有的支付模塊進行一個改造。需要對支付方式的class增加一個字段paynow_action_url,用來表示進行支付的頁面 url,另外還需要增加一個函數(shù),paynow_button($order_id),來獲取支付表單的參數(shù)隱藏域代碼。
要增加 paynow_action_url 變量,請在類payment的構(gòu)造函數(shù)中最后加上下面的代碼:
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)函數(shù),請在payment類的最后一個函數(shù)之后加上如下的代碼:
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支付方式為例子,說明如何具體實現(xiàn)。這里直接修改 paypal.php 文件,注意備份此文件。代碼如下所示,可以看到,這里去掉了對 form_action_url 的指定,并給定了 paynow_action_url,因為我們希望用戶點擊“確認訂單”后直接進入checkout_process,所以如果不指定 form_action_url,那么確認訂單的表單就會直接提交到 checkout_process 頁面了,而 paynow_action_url 就是 以前的 form_action_url 的值。paynow_button 函數(shù)的實現(xiàn)也很簡單,這里只是將原先的 process_button() 函數(shù)的內(nèi)容剪切過來而已,只不過我們沒有使用全局的$order變量,而是使用 $order = new order($order_id),來重新構(gòu)造的一個對象,這樣做是為在歷史訂單中顯示pay now按鈕做準(zhǔn)備的。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_ZO
新聞熱點
疑難解答