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

如何在WooCommerce结账页动态更新自定义内容(随国家变更)

问题

现有PHP代码如下,需要实现:结账页订单详情后显示指定HTML片段,且随配送国家变更动态更新内容。当前遇到的矛盾点是:

  • woocommerce_review_order_before_payment 钩子能在正确位置渲染HTML,但只有页面刷新时才会生效
  • woocommerce_cart_calculate_fees 钩子能响应配送国家变更的AJAX事件,但没法把HTML输出到正确位置

原代码:

class CheckoutTax{
    public function __construct(){
        // add a note after the order details, when a tax is charged and country changes 
        // the html snippet is shown after the order details on a page refresh
        add_action('woocommerce_review_order_before_payment', array($this, 'checkout_note_tax'));
        // the action is called when the country changes
        // but it does not show the html snippet at the correct place
        add_action('woocommerce_cart_calculate_fees', array($this, 'checkout_note_tax'));
        // how to combine
        // - show HTML snippet after the order details
        // - act on a country change
    }

    /**
     * Show checkout note, tax paid
     *
     * @return void
     */
    function checkout_note_tax() {
        if (is_admin() && !defined('DOING_AJAX')) return;
        if (!is_checkout()) return;
        global $WOOCS;
        $total_tax = WC()->cart->get_totals()['total_tax'];
        $shipping_country = WC()->customer->get_shipping_country();
        error_log( $total_tax );
        error_log( $shipping_country );
        if( $total_tax > 0 && $shipping_country != 'CH') {
            ?><h3>VAT / Custom Duties</h3><?php
        }
    }
}
解决方案

要兼顾正确位置渲染和动态更新,需要结合后端钩子输出和前端AJAX事件处理,具体实现如下:

修改后的完整代码

class CheckoutTax {
    public function __construct() {
        // 页面初始加载时,在指定位置渲染内容
        add_action('woocommerce_review_order_before_payment', array($this, 'render_tax_note'));
        
        // 响应配送国家变更的AJAX事件,更新内容到会话
        add_action('woocommerce_cart_calculate_fees', array($this, 'update_tax_note_via_ajax'));
        
        // 加载前端JS,处理动态更新逻辑
        add_action('wp_footer', array($this, 'load_checkout_update_script'));
    }

    /**
     * 生成税费提示的HTML内容
     * @return string
     */
    private function get_tax_note_html() {
        if (is_admin() && !defined('DOING_AJAX')) return '';
        if (!is_checkout()) return '';

        $total_tax = WC()->cart->get_totals()['total_tax'];
        $shipping_country = WC()->customer->get_shipping_country();

        // 满足条件时返回HTML,否则返回空字符串
        return ($total_tax > 0 && $shipping_country != 'CH') ? '<h3>VAT / Custom Duties</h3>' : '';
    }

    // 初始渲染内容到页面
    public function render_tax_note() {
        echo $this->get_tax_note_html();
    }

    // AJAX触发时,把最新内容存入WC会话
    public function update_tax_note_via_ajax() {
        if (defined('DOING_AJAX') && DOING_AJAX) {
            WC()->session->set('dynamic_tax_note', $this->get_tax_note_html());
        }
    }

    // 输出前端JS,监听结账页更新事件并替换内容
    public function load_checkout_update_script() {
        if (!is_checkout()) return;
        ?>
        <script>
            jQuery(document).ready(function($) {
                // 监听WC结账页AJAX更新完成的事件
                $(document.body).on('updated_checkout', function() {
                    // 从WC全局参数获取最新的提示内容
                    var noteContent = wc_cart_params.dynamic_tax_note || '';
                    // 找到订单详情后的位置,替换内容(可根据实际布局调整选择器)
                    if (!$('.dynamic-tax-note').length) {
                        $('#review-order').after('<div class="dynamic-tax-note"></div>');
                    }
                    $('.dynamic-tax-note').html(noteContent);
                });
            });
        </script>
        <?php
        // 把会话中的内容传递给前端JS
        wc_enqueue_js('wc_cart_params.dynamic_tax_note = "' . addslashes(WC()->session->get('dynamic_tax_note')) . '";');
    }
}

// 初始化类
new CheckoutTax();

关键逻辑说明

  1. 拆分内容生成逻辑:把判断条件和HTML生成放在get_tax_note_html私有方法中,避免代码重复,方便维护。
  2. 初始渲染:用woocommerce_review_order_before_payment钩子在页面第一次加载时,把内容输出到正确位置。
  3. AJAX响应:配送国家变更会触发woocommerce_cart_calculate_fees钩子的AJAX请求,此时把最新的内容存入WooCommerce会话中。
  4. 前端动态更新:监听WC结账页自带的updated_checkout事件(AJAX更新完成后触发),从全局参数中获取最新内容,插入到订单详情后的DOM位置。

可选调整

  • 如果你的结账页布局不同,可以修改JS中的DOM选择器(比如$('#review-order').after()),确保内容插入到你需要的位置。
  • 可以给HTML片段添加自定义类名,方便后续添加样式。

内容的提问来源于stack exchange,提问作者Fritz Herbers

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:36:03