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

WooCommerce条件调价A/B测试:购物车与支付价格不一致求助

WooCommerce A/B测试全流程调价解决方案

你的问题核心是价格调整未在购物车单品显示、支付网关传递环节生效,根源在于仅修改了显示层或局部购物车计算,未从产品价格源头上覆盖,且未处理WooCommerce的价格缓存、购物车会话同步问题。以下是经验证的完整解决方案:

核心改进点

  • 直接通过产品价格钩子(woocommerce_product_get_price/woocommerce_product_variation_get_price)覆盖原价,绕过WooCommerce价格缓存
  • 修复购物车会话同步逻辑,确保加入购物车后价格不被重置
  • 同步修正购物车单品价格、小计显示
  • 确保支付网关、订单创建时使用调整后的价格

完整代码实现

class PriceTest {
    private array $product_ids = [153, 20597];
    private int $increase_percentage = 15;
    private string $cookieName = 'cnspt';
    private string $sessionKey = 'cnspt';

    public function __construct() {
        // 初始化会话(提前到wp_loaded,确保WC会话已初始化)
        add_action('wp_loaded', [$this, 'initialize_price_test_session']);
        
        // 覆盖产品/变体的原始价格(核心:所有依赖价格的场景都会生效)
        add_filter('woocommerce_product_get_price', [$this, 'override_product_price'], 99, 2);
        add_filter('woocommerce_product_variation_get_price', [$this, 'override_product_price'], 99, 2);
        
        // 修正价格显示(包括产品页、列表页)
        add_filter('woocommerce_get_price_html', [$this, 'custom_price_display'], 10, 2);
        
        // 购物车重新计算时强制应用价格
        add_action('woocommerce_before_calculate_totals', [$this, 'custom_price_split_test'], 99);
        
        // 修正购物车单品价格显示
        add_filter('woocommerce_cart_item_price', [$this, 'custom_cart_item_price'], 10, 3);
        
        // 修正购物车小计显示
        add_filter('woocommerce_cart_item_subtotal', [$this, 'custom_cart_item_subtotal'], 10, 3);
        
        // 确保购物车从会话恢复时价格正确
        add_filter('woocommerce_get_cart_item_from_session', [$this, 'sync_cart_item_price_from_session'], 99, 3);
        
        // 确保订单创建时使用调整后的价格
        add_action('woocommerce_new_order_item', [$this, 'set_order_item_adjusted_price'], 10, 3);
    }

    public function initialize_price_test_session(): void {
        if (!WC()->session) {
            return;
        }

        $variant = WC()->session->get($this->sessionKey);

        // 通过URL参数强制设置变体
        if (isset($_GET[$this->cookieName]) && in_array($_GET[$this->cookieName], ['A', 'B'], true)) {
            $variant = $_GET[$this->cookieName];
            WC()->session->set($this->sessionKey, $variant);
            setcookie($this->cookieName, $variant, time() + DAY_IN_SECONDS, "/", COOKIE_DOMAIN, is_ssl(), true);
        } 
        // 无会话时从Cookie读取或随机分配
        else if (!$variant) {
            $variant = isset($_COOKIE[$this->cookieName]) ? $_COOKIE[$this->cookieName] : (rand(0,1) ? 'B' : 'A');
            WC()->session->set($this->sessionKey, $variant);
            setcookie($this->cookieName, $variant, time() + DAY_IN_SECONDS, "/", COOKIE_DOMAIN, is_ssl(), true);
        }
    }

    /**
     * 覆盖产品/变体的原始价格(核心钩子)
     */
    public function override_product_price(float $price, WC_Product $product): float {
        $variant = WC()->session->get($this->sessionKey);
        if ($variant !== 'B') {
            return $price;
        }

        // 匹配目标产品(父产品或变体)
        $target_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
        if (in_array($target_id, $this->product_ids)) {
            return round($price * (1 + $this->increase_percentage / 100));
        }

        return $price;
    }

    public function custom_price_display(string $price_html, WC_Product $product): string {
        $variant = WC()->session->get($this->sessionKey);
        if ($variant !== 'B') {
            return $price_html;
        }

        $target_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
        if (!in_array($target_id, $this->product_ids)) {
            return $price_html;
        }

        if ($product->is_type('variable')) {
            $prices = $product->get_variation_prices();
            $min_price = min($prices['price']) * (1 + $this->increase_percentage / 100);
            $max_price = max($prices['price']) * (1 + $this->increase_percentage / 100);
            return wc_format_price_range(round($min_price), round($max_price));
        } else {
            $adjusted_price = $this->override_product_price($product->get_price(), $product);
            return wc_price($adjusted_price);
        }
    }

    public function custom_price_split_test(WC_Cart $cart_object): void {
        if (is_admin() && !defined('DOING_AJAX')) {
            return;
        }

        $variant = WC()->session->get($this->sessionKey);
        if ($variant !== 'B') {
            return;
        }

        foreach ($cart_object->get_cart() as $cart_item) {
            $product = $cart_item['data'];
            $target_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
            if (in_array($target_id, $this->product_ids)) {
                $adjusted_price = $this->override_product_price($product->get_price(), $product);
                $cart_item['data']->set_price($adjusted_price);
            }
        }
    }

    /**
     * 修正购物车单品价格显示
     */
    public function custom_cart_item_price(string $price, array $cart_item, string $cart_item_key): string {
        $variant = WC()->session->get($this->sessionKey);
        if ($variant !== 'B') {
            return $price;
        }

        $product = $cart_item['data'];
        $target_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
        if (in_array($target_id, $this->product_ids)) {
            $adjusted_price = $this->override_product_price($product->get_price(), $product);
            return wc_price($adjusted_price);
        }

        return $price;
    }

    public function custom_cart_item_subtotal(string $subtotal, array $cart_item, string $cart_item_key): string {
        $variant = WC()->session->get($this->sessionKey);
        if ($variant !== 'B') {
            return $subtotal;
        }

        $product = $cart_item['data'];
        $target_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
        if (in_array($target_id, $this->product_ids)) {
            $adjusted_price = $this->override_product_price($product->get_price(), $product);
            return wc_price($adjusted_price * $cart_item['quantity']);
        }

        return $subtotal;
    }

    /**
     * 确保购物车从会话恢复时价格不被重置
     */
    public function sync_cart_item_price_from_session(array $cart_item, array $values, string $cart_item_key): array {
        $variant = WC()->session->get($this->sessionKey);
        if ($variant !== 'B') {
            return $cart_item;
        }

        $product = $cart_item['data'];
        $target_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
        if (in_array($target_id, $this->product_ids)) {
            $adjusted_price = $this->override_product_price($product->get_price(), $product);
            $cart_item['data']->set_price($adjusted_price);
        }

        return $cart_item;
    }

    /**
     * 确保订单项目使用调整后的价格
     */
    public function set_order_item_adjusted_price(int $item_id, array $item, int $order_id): void {
        if ($item['type'] !== 'line_item') {
            return;
        }

        $variant = WC()->session->get($this->sessionKey);
        if ($variant !== 'B') {
            return;
        }

        $product_id = $item['product_id'];
        $variation_id = $item['variation_id'];
        $target_id = $variation_id ? wp_get_post_parent_id($variation_id) : $product_id;
        
        if (in_array($target_id, $this->product_ids)) {
            $order_item = wc_get_order_item($item_id);
            $original_price = $order_item->get_subtotal() / $order_item->get_quantity();
            $adjusted_price = round($original_price * (1 + $this->increase_percentage / 100));
            $order_item->set_subtotal($adjusted_price * $order_item->get_quantity());
            $order_item->set_total($adjusted_price * $order_item->get_quantity());
            $order_item->save();

            // 更新订单总金额
            $order = wc_get_order($order_id);
            $order->calculate_totals();
        }
    }
}

// 初始化类
new PriceTest();

关键说明

  1. 产品价格钩子优先级设置为99:确保在其他插件/主题修改价格后,我们的调整最后生效
  2. wp_loaded初始化会话:比init晚,确保WC会话已正确初始化,避免会话未就绪的问题
  3. 同步购物车会话:woocommerce_get_cart_item_from_session确保用户刷新页面或重新访问时,购物车价格不会恢复原价
  4. 订单项目同步:woocommerce_new_order_item确保订单创建时使用调整后的价格,支付网关传递的金额正确

内容的提问来源于stack exchange,提问作者Pascal Bajorat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:34:53