首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Zen Cart 防漏單:PayPal 支付前在確認頁預先生成訂單

     編輯:PHP 相關知識

問題背景

Zen Cart 中非 PayPal 支付方式在 checkout_confirmation 頁即生成訂單,但 PayPal 需從 paypal.com 返回 checkout_process 才生成訂單。若用戶支付後關閉瀏覽器、網絡中斷,將導致**後台無訂單記錄**(雖 PayPal 後台有流水),造成對賬困難。

解決方案:在 checkout_confirmation 預創建訂單

文件:includes/modules/pages/checkout_confirmation/header_php.php (或同目錄主流程文件)

在頁面輸出結束前插入:

// 防漏單:PayPal 在確認頁預創建訂單
if ($_SESSION['payment'] == 'paypal' && !isset($_SESSION['order_number_created'])) {
    $insert_id = $order->create($order_totals, 2); // 2 = 訂單狀態:待支付
    
    $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_CREATE');
    $payment_modules->after_order_create($insert_id);
    $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_PAYMENT_MODULES_AFTER_ORDER_CREATE');
    
    $order->create_add_products($insert_id); // 寫入訂單商品明細
    $_SESSION['order_number_created'] = $insert_id; // 標記已創建
}

防止重複創建:清除標記

文件:includes/modules/pages/checkout_payment/header_php.php

// 返回修改購物車時重置標記,允許重新創建
unset($_SESSION['order_number_created']);

防止頁面刷新重複創建

上方代碼已包含 !isset($_SESSION['order_number_created']) 判斷,同一會話確認頁刷新不會重複生成訂單。

替代方案:在 PayPal 模塊 confirmation() 中創建

文件:includes/modules/payment/paypal.php

function confirmation() {
    global $order, $order_total_modules, $order_totals, $zco_notifier, $insert_id;
    
    if (!isset($_SESSION['order_number_created'])) {
        // ... 驗證用戶、購物車、訂單總計邏輯 ...
        
        $insert_id = $order->create($order_totals, 2);
        require(DIR_WS_LANGUAGES . 'english/email_extras.php');
        require(DIR_WS_LANGUAGES . 'english/checkout_process.php');
        
        $order->create_add_products($insert_id);
        $_SESSION['order_number_created'] = $insert_id;
        
        $zco_notifier->notify('NOTIFY_CHECKOUT_PROCESS_AFTER_ORDER_CREATE_ADD_PRODUCTS');
        $order->send_order_email($insert_id, 2); // 發送訂單郵件
        
        // 重置訂單總計模塊輸出
        if (is_array($order_total_modules->modules)) {
            reset($order_total_modules->modules);
            while (list(, $value) = each($order_total_modules->modules)) {
                $class = substr($value, 0, strrpos($value, '.'));
                if (!isset($GLOBALS[$class])) continue;
                $GLOBALS[$class]->output = null;
            }
        }
    } else {
        return false; // 已創建,不重複處理
    }
}

關鍵點總結

  1. 時機前移: 從 checkout_process 提前到 checkout_confirmation 或 paypal::confirmation()
  2. 狀態標記: $_SESSION['order_number_created'] 防重複
  3. 狀態重置: checkout_payment 階段 unset 允許重新創建
  4. 訂單狀態: 傳入 2 (Pending) 而非完成狀態
  5. 通知機制: 保持 $zco_notifier 事件觸發,兼容觀察者模式插件

相關專題

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved