如何通过GET参数为WooCommerce商品设置差异化定价
基于GET参数实现WooCommerce商品差异化定价方案
我来帮你搞定这个需求——让带emailsale=true参数的访问者看到促销价,普通用户看常规价,结合你提供的代码,整理了一套完整的实现方案:
1. 先把折扣状态存在会话里
首先得把用户访问特殊URL的状态存起来,不然跳转页面后状态就丢了。把这段代码加到主题的functions.php里:
add_action('init', 'set_email_sale_session'); function set_email_sale_session() { if (isset($_GET['emailsale']) && $_GET['emailsale'] === 'true') { // 开启会话,确保状态能跨页面保留 if (!session_id()) { session_start(); } $_SESSION['emailsale_active'] = true; } }
2. 修改前端商品价格显示
用WooCommerce自带的钩子,根据会话状态切换价格显示样式,和原生样式保持一致:
add_filter('woocommerce_get_price_html', 'custom_price_html_based_on_session', 10, 2); function custom_price_html_based_on_session($price, $product) { // 检查用户是否处于折扣会话中 if (isset($_SESSION['emailsale_active']) && $_SESSION['emailsale_active']) { $regular_price = $product->get_regular_price(); $sale_price = $product->get_sale_price(); if (!empty($sale_price)) { // 显示带划线的促销价格式 $price = wc_format_sale_price(wc_price($regular_price), wc_price($sale_price)); } else { // 如果商品没设促销价,还是显示常规价 $price = wc_price($regular_price); } } return $price; }
3. 确保购物车/结算时用对价格
光前端显示不够,得让购物车和结算环节也同步用折扣价,避免“显示一套结算一套”的问题:
add_action('woocommerce_before_calculate_totals', 'custom_cart_price_based_on_session', 10, 1); function custom_cart_price_based_on_session($cart) { // 后台操作跳过,只处理前端和AJAX请求 if (is_admin() && !defined('DOING_AJAX')) { return; } // 非折扣会话直接返回 if (!isset($_SESSION['emailsale_active']) || !$_SESSION['emailsale_active']) { return; } // 遍历购物车商品,设置为促销价 foreach ($cart->get_cart() as $cart_item_key => $cart_item) { $product = $cart_item['data']; $sale_price = $product->get_sale_price(); if (!empty($sale_price)) { $cart_item['data']->set_price($sale_price); } } }
4. 优化你现有自定义订单代码
针对你提供的自定义购物车/订单创建代码,调整价格判断逻辑,确保和会话状态同步:
// 先确保会话已开启 if (!session_id()) { session_start(); } // 你的商品查询参数,根据实际需求调整 $args = array( 'post_type' => 'product', 'posts_per_page' => -1 ); $posts = get_posts($args); woocommerce_product_loop_start(); foreach ($posts as $post): setup_postdata($post); $product_id = get_the_ID(); $_SESSION['product_id'] = $product_id; $product = wc_get_product($product_id); // 根据会话状态渲染对应价格 if (isset($_SESSION['emailsale_active']) && $_SESSION['emailsale_active']) { $regular_price = round($product->get_regular_price()); $sale_price = round($product->get_sale_price()); $price_html = wc_format_sale_price(wc_price($regular_price), wc_price($sale_price)); } else { $regular_price = round($product->get_regular_price()); $price_html = wc_price($regular_price); } echo $price_html; endforeach; wp_reset_postdata(); woocommerce_product_loop_end(); // 创建订单并设置支付方式 $order = wc_create_order(); $order->set_customer_id(is_numeric($args['customer_id']) ? absint($args['customer_id']) : 0); // 根据会话状态添加对应价格的商品到订单 if (isset($_SESSION['emailsale_active']) && $_SESSION['emailsale_active']) { $product = wc_get_product($_SESSION['product_id']); $sale_price = $product->get_sale_price(); $order->add_product($product, 1, array('subtotal' => $sale_price)); } else { $product = wc_get_product($_SESSION['product_id']); $regular_price = $product->get_regular_price(); $order->add_product($product, 1, array('subtotal' => $regular_price)); } $order->calculate_totals(); update_post_meta($order->get_id(), '_payment_method', 'kassa-com'); update_post_meta($order->get_id(), '_payment_method_title', 'Kassa.com'); ?> <form method="GET" action="<?php echo $order->get_checkout_payment_url(); ?>"> <input type="submit" class="btn btn-pink right" value="Pay"> </form>
几个关键注意点
- 确保你的商品已经在WooCommerce后台正确设置了常规价格和促销价格,不然代码没法获取到对应价格值。
- 会话会在用户关闭浏览器或清除缓存后失效,用户需要重新访问带
emailsale=true的URL才能再次享受折扣。 - 代码建议放在子主题的
functions.php里,避免主题更新时丢失修改。
内容的提问来源于stack exchange,提问作者DarkAngel55
相关产品推荐
相关产品推荐

