如何通过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
相关产品推荐
相关产品推荐

