WooCommerce结账字段触发自定义费用函数问题求助
解决WooCommerce结账页选择特定选项时添加自定义费用的问题
我来帮你搞定这个需求——当用户在结账页选择值为1的选项时,才触发22%的费用计算。你的原代码缺少了判断用户选项值的关键逻辑,我给你补全并优化一下:
完整代码实现
// 第一步:添加结账页的自定义选项(如果还没加的话) add_action( 'woocommerce_after_order_notes', 'add_custom_checkout_option' ); function add_custom_checkout_option( $checkout ) { echo '<div id="custom_checkout_option"><h3>' . __('是否添加22%服务费?') . '</h3>'; woocommerce_form_field( 'custom_option', array( 'type' => 'radio', 'class' => array('form-row-wide'), 'label' => __('请选择'), 'options' => array( '0' => __('不需要'), '1' => __('需要,添加22%服务费') ), ), $checkout->get_value( 'custom_option' )); echo '</div>'; } // 第二步:条件判断并添加费用 add_action( 'woocommerce_cart_calculate_fees','conditional_add_fee' ); function conditional_add_fee() { // 后台环境且非AJAX请求时,不执行该函数 if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; // 获取用户在结账页选择的选项值 $selected_option = WC()->checkout->get_value( 'custom_option' ); // 仅当选项值为1时,计算并添加费用 if ( $selected_option === '1' ) { $subtotal = WC()->cart->subtotal; $fee_percentage = 0.22; // 22%比例 $fee_amount = round( $subtotal * $fee_percentage, 2 ); // 四舍五入保留两位小数 // 添加费用到购物车:参数分别是费用名称、金额、是否含税、税费类别 WC()->cart->add_fee( __('22%服务费'), $fee_amount, true, 'standard' ); } } // 第三步:保存用户选择到订单元数据(方便后续查看订单) add_action( 'woocommerce_checkout_update_order_meta', 'save_custom_option_to_order' ); function save_custom_option_to_order( $order_id ) { if ( ! empty( $_POST['custom_option'] ) ) { update_post_meta( $order_id, '_custom_option', sanitize_text_field( $_POST['custom_option'] ) ); } }
关键说明
- 自定义选项适配:如果你已经有了自己的结账选项(比如下拉框、其他单选组),只需要把代码里的
custom_option换成你的字段name属性即可,不用保留第一个添加字段的函数。 - 值判断逻辑:用
WC()->checkout->get_value()可以精准获取结账时的用户选择,包括AJAX实时更新的场景,比直接用$_POST更可靠。 - 费用细节调整:
- 如果你不想让费用含税,把
add_fee的第三个参数改成false - 税费类别
standard可以根据你的店铺税费设置调整成其他值
- 如果你不想让费用含税,把
- 订单记录:第三个函数会把用户的选择保存到订单的元数据里,在后台查看订单时可以看到用户是否选择了添加费用的选项。
特殊场景适配
如果你的“值为1的选项”是配送方式或支付方式,而不是自定义字段,那获取值的方式要改:
- 配送方式:
$selected_shipping = WC()->session->get('chosen_shipping_methods')[0];,然后判断这个ID是否等于你要的配送方式ID - 支付方式:
$selected_payment = WC()->session->get('chosen_payment_method');,判断是否等于目标支付方式的slug
内容的提问来源于stack exchange,提问作者robert
相关产品推荐
相关产品推荐

