Zen Cart 中非 PayPal 支付方式在 checkout_confirmation 頁即生成訂單,但 PayPal 需從 paypal.com 返回 checkout_process 才生成訂單。若用戶支付後關閉瀏覽器、網絡中斷,將導致**後台無訂單記錄**(雖 PayPal 後台有流水),造成對賬困難。
在頁面輸出結束前插入:
// 防漏單: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']) 判斷,同一會話確認頁刷新不會重複生成訂單。
文件: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; // 已創建,不重複處理
}
}
checkout_process 提前到 checkout_confirmation 或 paypal::confirmation()$_SESSION['order_number_created'] 防重複checkout_payment 階段 unset 允許重新創建2 (Pending) 而非完成狀態$zco_notifier 事件觸發,兼容觀察者模式插件