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

WooCommerce如何在结账页仅展示最终选定的配送选项?

解决WooCommerce结账页仅展示已选配送方式的问题

我完全理解你想要简化结账流程的需求——让用户只在购物车页选择配送方式,结账页仅展示已选项,避免流程混乱。结合你已经梳理的核心文件,我给你两个落地性强的方案:

方案一:模板重载(直观可控)

你已经发现wc_cart_totals_shipping_html()会调用cart/cart-shipping.php模板,我们可以通过模板重载修改这个文件,让它在结账页只渲染已选配送方式:

  1. 复制WooCommerce默认模板:wp-content/plugins/woocommerce/templates/cart/cart-shipping.php
  2. 粘贴到你的主题目录:wp-content/你的主题名/woocommerce/cart/cart-shipping.php(目录不存在就新建)
  3. 修改文件逻辑,判断当前是否在结账页,只显示已选内容:
<?php
/**
 * Cart Shipping
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/cart/cart-shipping.php.
 *
 * @see     https://docs.woocommerce.com/document/template-structure/
 * @package WooCommerce\Templates
 * @version 4.6.0
 */

defined( 'ABSPATH' ) || exit;

?>
<tr class="shipping">
	<th><?php echo wp_kses_post( $package_name ); ?></th>
	<td data-title="<?php echo esc_attr( $package_name ); ?>">
		<?php if ( is_checkout() ) : ?>
			<?php
			// 结账页仅渲染已选配送方式
			if ( ! empty( $chosen_method ) && isset( $available_methods[ $chosen_method ] ) ) {
				$selected_method = $available_methods[ $chosen_method ];
				// 显示配送方式名称和价格
				echo wp_kses_post( wc_cart_totals_shipping_method_label( $selected_method ) );
				echo ' ' . wc_price( $selected_method->cost );
				
				// 显示配送方式的额外元数据(比如自提点信息)
				if ( $selected_method->get_meta_data() ) {
					foreach ( $selected_method->get_meta_data() as $meta ) {
						echo '<br><small>' . wp_kses_post( $meta->value ) . '</small>';
					}
				}
			} else {
				echo esc_html__( '未选择配送方式', 'woocommerce' );
			}
			?>
		<?php else : ?>
			<!-- 保留购物车页原有的配送选择逻辑 -->
			<?php if ( ! empty( $available_methods ) ) : ?>
				<ul id="shipping_method" class="shipping_methods">
					<?php foreach ( $available_methods as $method ) : ?>
						<li>
							<?php
							if ( 1 === count( $available_methods ) ) {
								printf( '<input type="radio" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" checked="checked" class="shipping_method" />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ) ); // WPCS: XSS ok.
							} else {
								printf( '<input type="radio" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" %4$s class="shipping_method" />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ), checked( $method->id, $chosen_method, false ) ); // WPCS: XSS ok.
							}
							printf( '<label for="shipping_method_%1$d_%2$s">%3$s</label>', $index, esc_attr( sanitize_title( $method->id ) ), wp_kses_post( wc_cart_totals_shipping_method_label( $method ) ) ); // WPCS: XSS ok.
							do_action( 'woocommerce_after_shipping_rate', $method, $index );
							?>
						</li>
					<?php endforeach; ?>
				</ul>
				<?php if ( is_cart() ) : ?>
					<p class="woocommerce-shipping-destination">
						<?php
						if ( $show_package_details ) {
							echo wp_kses_post( sprintf( __( '配送至 %s. ', 'woocommerce' ), '<strong>' . $package_details . '</strong>' ) );
							$calculator_text = __( '修改地址', 'woocommerce' );
						} else {
							echo wp_kses_post( sprintf( __( '配送至 %s. ', 'woocommerce' ), '<strong>' . wc_get_formatted_shipping_address( $package['destination'] ) . '</strong>' ) );
							$calculator_text = __( '修改地址', 'woocommerce' );
						}

						printf( '<a href="#" class="shipping-calculator-button">%s</a>', esc_html( $calculator_text ) );
						?>
					</p>
				<?php endif; ?>
			<?php elseif ( ! is_cart() ) : ?>
				<?php echo wp_kses_post( apply_filters( 'woocommerce_no_shipping_available_html', __( '未找到可用配送方式.', 'woocommerce' ) ) ); ?>
			<?php else : ?>
				<?php echo wp_kses_post( apply_filters( 'woocommerce_cart_no_shipping_available_html', __( '未找到配送选项.', 'woocommerce' ) ) ); ?>
				<?php
				$calculator_text = __( '输入地址查看配送选项', 'woocommerce' );
				printf( '<a href="#" class="shipping-calculator-button">%s</a>', esc_html( $calculator_text ) );
				?>
			<?php endif; ?>
		<?php endif; ?>
		<?php wc_cart_totals_shipping_package_html( $package ); ?>
	</td>
</tr>

修改后,结账页只会展示用户在购物车页选定的配送方式、价格及额外信息,不会出现可交互的选择控件。

方案二:钩子过滤(无需修改模板)

如果你不想改动模板,可以通过woocommerce_package_rates钩子,在结账页过滤掉未选中的配送方式:

将以下代码添加到主题的functions.php文件中:

add_filter( 'woocommerce_package_rates', 'keep_only_chosen_shipping_method_on_checkout', 10, 2 );
function keep_only_chosen_shipping_method_on_checkout( $rates, $package ) {
    // 仅在结账页执行过滤
    if ( ! is_checkout() ) {
        return $rates;
    }

    // 获取当前已选的配送方式ID
    $chosen_method = WC()->session->get( 'chosen_shipping_methods' )[ $package['index'] ] ?? '';

    // 仅保留已选的配送方式
    if ( ! empty( $chosen_method ) && isset( $rates[ $chosen_method ] ) ) {
        $rates = array( $chosen_method => $rates[ $chosen_method ] );
    }

    return $rates;
}

WooCommerce默认模板在只有一个配送方式时,会自动隐藏单选框,只显示方式名称和价格,完美匹配你的需求。

额外优化:隐藏结账页地址修改入口(可选)

如果想彻底避免用户在结账页修改地址导致配送方式变化,可以添加CSS隐藏修改链接:

.woocommerce-checkout .woocommerce-shipping-destination a.shipping-calculator-button {
    display: none !important;
}

或者用钩子移除:

add_filter( 'woocommerce_shipping_package_details_array', 'remove_shipping_calculator_on_checkout', 10, 2 );
function remove_shipping_calculator_on_checkout( $product_names, $package ) {
    if ( is_checkout() ) {
        remove_action( 'woocommerce_after_shipping_rate', 'woocommerce_shipping_calculator_enable' );
    }
    return $product_names;
}

这样用户就只能回到购物车页修改配送方式和地址了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:33:26