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

WordPress单产品页自定义按钮控制COD支付网关显示问题排查

问题分析与代码修正

原代码的核心问题

  1. 结账页COD禁用逻辑失效:
    原代码通过$_POST['custom_field_name']判断是否隐藏COD,但结账页面是独立的HTTP请求,添加购物车时的POST数据不会保留到结账环节,导致该判断永远不成立。

  2. 自定义字段验证逻辑矛盾:
    validate_custom_field函数中的条件isset($_POST['custom_field_name']) && !empty($_POST['custom_field_name']) && empty(trim($_POST['custom_field_name']))存在逻辑冲突——!empty($_POST['custom_field_name'])和empty(trim($_POST['custom_field_name']))无法同时满足,导致字段为空时不会触发错误提示。

  3. 过时钩子兼容性问题:
    woocommerce_add_order_item_meta钩子已被WooCommerce弃用,继续使用可能导致订单项元数据无法正确保存。

  4. 后台订单显示参数错误:
    woocommerce_admin_order_data_after_order_details钩子的参数为$order,但原函数错误地接收$item_id, $item, $product,导致无法读取订单项的自定义元数据。


修正后的完整代码

// 显示自定义按钮和字段
function display_customize_button_and_field() {
    echo '<p id="customize-instruction" style="margin-bottom: 5px;">' . __('If you want to customize the product, click here:', 'woocommerce') . '</p>';
    echo '<button id="customize-button" type="button" style="margin-bottom: 10px;">' . __('Customize', 'woocommerce') . '</button>';
    echo '<div id="custom-field-container" style="display:none;">';
    woocommerce_form_field( 'custom_field_name', array(
        'type'        => 'textarea',
        'class'       => array('custom-field-class form-row-wide'),
        'label'       => __('Message', 'woocommerce'),
        'placeholder' => __('Write Details here', 'woocommerce'),
    ), '' );
    echo '</div>';
}
add_action( 'woocommerce_before_add_to_cart_button', 'display_customize_button_and_field' );

// 验证自定义字段(修正逻辑)
function validate_custom_field($passed, $product_id, $quantity) {
    // 当用户点击自定义并提交空内容时触发验证
    if ( isset($_POST['custom_field_name']) && empty(trim($_POST['custom_field_name'])) ) {
        wc_add_notice( __('Please enter a value for the custom field.'), 'error' );
        return false;
    }
    return $passed;
}
add_filter('woocommerce_add_to_cart_validation', 'validate_custom_field', 10, 3);

// 保存自定义字段到购物车项
function save_custom_field($cart_item_data, $product_id) {
    if (isset($_POST['custom_field_name']) && !empty(trim($_POST['custom_field_name']))) {
        $cart_item_data['custom_field_name'] = sanitize_textarea_field($_POST['custom_field_name']);
        // 添加唯一键确保购物车中相同商品的自定义项被视为独立条目
        $cart_item_data['unique_key'] = md5(microtime().rand());
    }
    return $cart_item_data;
}
add_filter('woocommerce_add_cart_item_data', 'save_custom_field', 10, 2);

// 在购物车页面显示自定义字段
function display_custom_field_in_cart($item_data, $cart_item) {
    if (isset($cart_item['custom_field_name'])) {
        $item_data[] = array(
            'name' => __('Custom Field'),
            'value' => $cart_item['custom_field_name']
        );
    }
    return $item_data;
}
add_filter('woocommerce_get_item_data', 'display_custom_field_in_cart', 10, 2);

// 保存自定义字段到订单项(使用新钩子)
function add_custom_field_to_order_meta($item, $cart_item_key, $values, $order) {
    if (isset($values['custom_field_name'])) {
        $item->add_meta_data(__('Custom Field'), $values['custom_field_name']);
    }
}
add_action('woocommerce_checkout_create_order_line_item', 'add_custom_field_to_order_meta', 10, 4);

// 在后台订单页面显示自定义字段(修正参数)
function display_custom_field_in_admin_order($order) {
    echo '<h3>' . __('Customized Products', 'woocommerce') . '</h3>';
    foreach ($order->get_items() as $item) {
        if ($custom_field_value = $item->get_meta(__('Custom Field'))) {
            echo '<p><strong>' . $item->get_name() . ':</strong> ' . $custom_field_value . '</p>';
        }
    }
}
add_action('woocommerce_admin_order_data_after_order_details', 'display_custom_field_in_admin_order', 10, 1);

// 加载自定义脚本
function enqueue_custom_script() {
    if ( is_product() ) {
        wp_enqueue_script( 'customize-product', get_template_directory_uri() . '/js/customize-product.js', array('jquery'), null, true );
    }
}
add_action( 'wp_enqueue_scripts', 'enqueue_custom_script' );

// 结账页禁用COD(修正判断逻辑)
function disable_cod_for_customized_product_on_checkout($available_gateways) {
    // 仅在结账页执行
    if ( !is_checkout() || is_wc_endpoint_url() ) return $available_gateways;

    // 遍历购物车项,检查是否有自定义字段
    foreach (WC()->cart->get_cart() as $cart_item) {
        if (isset($cart_item['custom_field_name']) && !empty($cart_item['custom_field_name'])) {
            // 存在自定义商品,隐藏COD
            unset($available_gateways['cod']);
            break; // 只要有一个自定义商品就停止遍历
        }
    }
    return $available_gateways;
}
add_filter('woocommerce_available_payment_gateways', 'disable_cod_for_customized_product_on_checkout');

关键修正说明

  1. COD禁用逻辑:改为遍历当前购物车的所有商品,检查是否存在custom_field_name字段,只要有一个自定义商品就隐藏COD。
  2. 字段验证:简化条件,当用户提交空的自定义字段时触发错误提示。
  3. 订单项元数据保存:使用woocommerce_checkout_create_order_line_item钩子替代过时的woocommerce_add_order_item_meta,确保元数据正确保存。
  4. 后台订单显示:修正钩子参数,遍历订单的所有订单项,显示每个商品的自定义内容。
  5. 购物车唯一键:添加unique_key确保相同商品的自定义版本在购物车中被视为独立条目,避免覆盖。

内容的提问来源于stack exchange,提问作者Muhammad zubair Ahmad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:42:14