In WooCommerce, I am trying to adjust the specific product prices for A/B testing purposes. The price adjustment is based on a cookie value ('A' or 'B') that I set afterward in a WC session variable. If the cookie value is 'B', I want to increase the price by 15%.
I've attempted this by applying filters to the hooks that fetch product prices (woocommerce_product_variation_get_price, woocommerce_product_variation_get_regular_price, woocommerce_product_variation_get_sale_price, etc.). On the product page and shop overview, the price is correctly adjusted.
However, in the shopping cart, the individual product price is incorrect, although the subtotal for each item (price*quantity) is correctly calculated using the adjusted price. More importantly, the incorrect (unadjusted) price is transferred to the payment provider.
To attempt to correct the cart issue, I've applied a function on the woocommerce_before_calculate_totals action, which also attempts to adjust the product price if the cookie value is 'B'. But, it doesn't seem to affect the prices shown in the cart.
I suspect that WooCommerce is somehow storing or caching the original prices and using these stored values in the cart and during checkout.
Can anyone suggest the correct approach to adjusting the prices in WooCommerce so that the adjusted prices are consistently used throughout the shopping and checkout process, including when transferring the final price to the payment provider?
What hooks or filters should I be using, or is there another technique to achieve this?
Your help is highly appreciated.
This is my latest code version:
class PriceTest {
private array $product_ids = [153, 20597];
private int $increase_percentage = 15;
private string $cookieName = 'cnspt';
private string $sessionKey = 'cnspt';
public function __construct() {
add_action('init', [$this, 'initialize_price_test_session']);
add_filter('woocommerce_get_price_html', [$this, 'custom_price_display'], 10, 2);
add_action('woocommerce_before_calculate_totals', [$this, 'custom_price_split_test']);
add_filter('woocommerce_cart_item_subtotal', [$this, 'custom_cart_item_subtotal'], 10, 3);
}
public function initialize_price_test_session(): void {
$variant = null;
if (isset($_GET[$this->cookieName]) && in_array($_GET[$this->cookieName], ['A', 'B'], true)) {
$variant = $_GET[$this->cookieName];
WC()->session->set($this->sessionKey, $variant);
} else {
if (!WC()->session->get($this->sessionKey)) {
if (!isset($_COOKIE[$this->cookieName])) {
$variant = rand(0, 1) === 0 ? 'A' : 'B';
setcookie($this->cookieName, $variant, time() + DAY_IN_SECONDS, "/");
} else {
$variant = $_COOKIE[$this->cookieName];
}
WC()->session->set($this->sessionKey, $variant);
}
}
}
public function custom_price_split_test(\WC_Cart $cart_object): void {
$variant = WC()->session->get($this->sessionKey);
if ($variant === 'B') {
foreach ($cart_object->get_cart() as $cart_item) {
$product_id = $cart_item['data']->get_parent_id();
if (in_array($product_id, $this->product_ids)) {
$original_price = $cart_item['data']->get_price();
$new_price = round($original_price * (1 + $this->increase_percentage / 100));
$cart_item['data']->set_price($new_price);
}
}
}
}
public function custom_price_display(string $price_html, \WC_Product $product): string {
$variant = WC()->session->get($this->sessionKey);
if ($variant === 'B') {
$product_id = $product->get_parent_id() ?: $product->get_id();
if (in_array($product_id, $this->product_ids)) {
if ($product->is_type('variable')) {
// Show price range for variable products
$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);
$price_html = wc_format_price_range(round($min_price), round($max_price));
} else {
$original_price = $product->get_price();
$new_price = round($original_price * (1 + $this->increase_percentage / 100));
$price_html = wc_price($new_price);
}
}
}
return $price_html;
}
public function custom_cart_item_subtotal($subtotal, $cart_item, $cart_item_key) {
$variant = WC()->session->get($this->sessionKey);
if (is_cart() && $variant === 'B') {
$product_id = $cart_item['data']->get_parent_id();
if (in_array($product_id, $this->product_ids)) {
$quantity = $cart_item['quantity'];
$original_price = $cart_item['data']->get_price();
$new_price = round($original_price * (1 + $this->increase_percentage / 100));
$subtotal = wc_price($new_price * $quantity);
}
}
return $subtotal;
}
}