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

如何通过AJAX调用WooCommerce自定义配送类的calculate_shipping方法?

解决方案

错误原因

你直接在AJAX的action参数里指定类方法,这不符合WordPress AJAX的工作机制——WordPress要求必须通过注册wp_ajax_{action}和wp_ajax_nopriv_{action}钩子来处理请求,不能直接调用类方法,这是400错误的核心原因。


1. 修改插件PHP代码,添加AJAX处理逻辑

在你的插件代码中补充自定义AJAX动作钩子和处理函数:

if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {

    function your_shipping_method_init() {
        if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {
            class WC_Your_Shipping_Method extends WC_Shipping_Method {
                /**
                 * Constructor for your shipping class
                 *
                 * @access public
                 * @return void
                 */
                public function __construct() {
                    $this->id                 = 'your_shipping_method';
                    $this->title              = '自定义配送方式'; // 初始化标题,避免calculate_shipping中$this->title为空
                    $this->method_title       = '自定义配送方式';
                    $this->method_description = '通过AJAX调用的自定义配送计算';
                    $this->enabled            = 'yes';
                    $this->init();
                }

                public function init() {
                    // 初始化设置(按需添加)
                    $this->init_form_fields();
                    $this->init_settings();
                    add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
                }

                public function calculate_shipping( $package = array() ) {
                    $rate = array(
                        'label' => $this->title,
                        'cost' => '10.99',
                        'calc_tax' => 'per_item'
                    );

                    // 注册费率
                    $this->add_rate( $rate );
                }
            }
        }
    }

    add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' );

    function add_your_shipping_method( $methods ) {
        $methods['your_shipping_method'] = 'WC_Your_Shipping_Method';
        return $methods;
    }

    add_filter( 'woocommerce_shipping_methods', 'add_your_shipping_method' );

    // 注册AJAX处理钩子(登录用户)
    add_action( 'wp_ajax_calculate_custom_shipping', 'calculate_custom_shipping_ajax_handler' );
    // 注册AJAX处理钩子(未登录用户)
    add_action( 'wp_ajax_nopriv_calculate_custom_shipping', 'calculate_custom_shipping_ajax_handler' );

    function calculate_custom_shipping_ajax_handler() {
        // 验证请求合法性(推荐添加)
        check_ajax_referer( 'custom_shipping_nonce', 'security' );

        // 获取当前购物车的配送包裹数据
        $package = WC()->cart->get_shipping_packages()[0];

        // 实例化配送类并调用计算方法
        $shipping_method = new WC_Your_Shipping_Method();
        $shipping_method->calculate_shipping( $package );

        // 获取计算后的费率并返回
        $rates = $shipping_method->get_rates();
        wp_send_json_success( $rates );
    }

}

2. 修改前端AJAX代码,添加安全验证和正确action

更新JS代码,使用自定义action名称并添加WordPress安全nonce验证:

<script type='text/javascript'>
    jQuery(document).ready(function() { 
        jQuery('select[name="shipping_delivery_method"]').change(function () {
            jQuery.ajax({
                type: "POST",
                url: '<?php echo admin_url('admin-ajax.php'); ?>', // 动态获取AJAX地址,避免硬编码
                data: {
                    action: 'calculate_custom_shipping',
                    security: '<?php echo wp_create_nonce("custom_shipping_nonce"); ?>' // 安全验证nonce
                },
                success: function (response) {
                    if (response.success) {
                        console.log('计算后的配送费率:', response.data);
                        // 可在此添加更新前端配送信息的逻辑,比如替换页面上的配送价格
                    } else {
                        console.log('请求失败:', response.data);
                    }
                },
                error: function(error) {
                    console.log('AJAX错误:', error);
                }
            });
        });
    });
</script>

关键注意事项

  • 构造函数初始化:必须在构造函数中初始化id、title等核心属性,否则WooCommerce无法正确识别配送方式,calculate_shipping中的$this->title也会为空。
  • 安全验证:添加check_ajax_referer和前端nonce是WordPress的安全规范,可有效防止恶意请求。
  • 购物车Package:通过WC()->cart->get_shipping_packages()获取实际购物车数据,确保计算逻辑符合当前用户的购物车状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:20:58