You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce令牌折扣在IE中添加商品到购物车后失效问题

问题描述

我在为WooCommerce商店做基于令牌的折扣系统,Chrome、Firefox、Edge这些主流浏览器都能正常跑,但到了Internet Explorer(IE)就出问题:带令牌的URL能让商品页、店铺页正常显示折扣价,可点「Add to Cart」把商品加进购物车后,价格直接变回原价。

预期实现目标

  • 用户点开带?token=AX4HN参数的链接时,自动设置有效期1小时的cookie存折扣令牌
  • 不管用户浏览页面还是加购商品,这个令牌折扣得全程生效

现存问题

  • IE里首次通过带令牌的链接进商品页,折扣显示正常;但一点「Add to Cart」,购物车就显示原价
  • 只有IE会出这问题,其他浏览器都符合预期

当前实现代码

步骤1:URL里有令牌时设置Cookie

function set_token_cookie() {
    if (isset($_GET['token']) && $_GET['token'] === 'AX4HN') {
        setcookie('discount_token', 'AX4HN', time() + 3600, '/'); // Cookie有效期1小时
        $_COOKIE['discount_token'] = 'AX4HN'; // 让当前请求立即生效
    }
}
add_action('init', 'set_token_cookie');

步骤2:验证令牌是否有效

function has_valid_token() {
    return (isset($_GET['token']) && $_GET['token'] === 'AX4HN') || 
           (isset($_COOKIE['discount_token']) && $_COOKIE['discount_token'] === 'AX4HN');
}

步骤3:令牌有效时应用折扣

add_filter('woocommerce_product_get_price', 'custom_price_discount', 20, 2);
function custom_price_discount($price, $product) {
    $discount_rate = 0.8; // 打8折
    if (has_valid_token() && !$product->is_on_sale()) {
        return floatval($price) * $discount_rate;
    }
    return $price;
}

观察结果

  • IE里商品页能正确显示折扣价
  • 加购后购物车页面显示原价
  • 推测IE离开初始页面后没法正确读取Cookie

解决方案

针对IE Cookie读取问题的修复

IE对Cookie的处理有特殊限制,尤其是跨请求(比如加购的POST请求)场景,得把Cookie属性设置得更兼容:

  1. 完善Cookie属性设置
    IE要求显式声明SameSite属性,HTTPS站点还要注意secure属性。修改set_token_cookie函数:
function set_token_cookie() {
    if (isset($_GET['token']) && $_GET['token'] === 'AX4HN') {
        $expire = time() + 3600;
        $path = '/';
        $domain = $_SERVER['HTTP_HOST'];
        $secure = is_ssl();
        $httponly = true;
        $samesite = 'Lax';

        // IE不支持SameSite属性,单独处理
        if (isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Trident/') !== false)) {
            setcookie('discount_token', 'AX4HN', $expire, $path, $domain, $secure, $httponly);
        } else {
            setcookie('discount_token', 'AX4HN', [
                'expires' => $expire,
                'path' => $path,
                'domain' => $domain,
                'secure' => $secure,
                'httponly' => $httponly,
                'samesite' => $samesite
            ]);
        }
        $_COOKIE['discount_token'] = 'AX4HN';
    }
}
add_action('init', 'set_token_cookie');
  1. 覆盖购物车价格计算逻辑
    WooCommerce加购可能用AJAX或POST请求,IE里这类请求可能不自动带Cookie。除了商品页的折扣钩子,还要加购物车总价计算的钩子:
// 购物车项目价格重新计算
add_action('woocommerce_before_calculate_totals', 'custom_cart_price_discount', 20);
function custom_cart_price_discount($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    if (has_valid_token()) {
        $discount_rate = 0.8;
        foreach ($cart->get_cart() as $cart_item) {
            $product = $cart_item['data'];
            if (!$product->is_on_sale()) {
                $original_price = $product->get_regular_price();
                $cart_item['data']->set_price(floatval($original_price) * $discount_rate);
            }
        }
    }
}

更兼容IE的全站令牌折扣实现方案

  1. 结合Session存储令牌
    除了Cookie,同时用Session存令牌,绕开IE的Cookie读取问题:
function set_token_session_and_cookie() {
    if (isset($_GET['token']) && $_GET['token'] === 'AX4HN') {
        // 启动Session并存令牌
        session_start();
        $_SESSION['discount_token'] = 'AX4HN';
        // 设置兼容IE的Cookie
        $expire = time() + 3600;
        setcookie('discount_token', 'AX4HN', $expire, '/', $_SERVER['HTTP_HOST'], is_ssl(), true);
        $_COOKIE['discount_token'] = 'AX4HN';
    }
}
add_action('init', 'set_token_session_and_cookie');

// 更新令牌验证函数,加入Session判断
function has_valid_token() {
    session_start();
    return (isset($_GET['token']) && $_GET['token'] === 'AX4HN') || 
           (isset($_COOKIE['discount_token']) && $_COOKIE['discount_token'] === 'AX4HN') ||
           (isset($_SESSION['discount_token']) && $_SESSION['discount_token'] === 'AX4HN');
}
  1. 覆盖所有价格相关钩子
    WooCommerce有多个价格计算钩子,要确保折扣在商品页、购物车、结算页都生效:
  • woocommerce_product_get_price:商品页显示价格
  • woocommerce_product_get_regular_price:商品常规价格
  • woocommerce_before_calculate_totals:购物车总价计算
  • woocommerce_cart_item_price:购物车单个商品价格显示

内容的提问来源于stack exchange,提问作者thecodedeveloper.com

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:02:02