Wordpress 如何在基于自定义字段的电子商务结帐中动态更改运费?

Wordpress 如何在基于自定义字段的电子商务结帐中动态更改运费?,wordpress,woocommerce,Wordpress,Woocommerce,如何通过Ajax请求更改Woocommerce中的运输成本? 我试过这个: add_action('wp_ajax_set_shipping_price', 'set_shipping_price'); add_action('wp_ajax_nopriv_set_shipping_price', 'set_shipping_price'); function set_shipping_price(){ $packages = WC()->cart->get_shipping

如何通过Ajax请求更改Woocommerce中的运输成本? 我试过这个:

add_action('wp_ajax_set_shipping_price', 'set_shipping_price');
add_action('wp_ajax_nopriv_set_shipping_price', 'set_shipping_price');
function set_shipping_price(){
    $packages = WC()->cart->get_shipping_packages();
    foreach ($packages as $package_key => $package){
        $session_key  = 'shipping_for_package_'.$package_key;
        $stored_rates = WC()->session->__unset( $session_key );
        $WC_Shipping = new WC_Shipping();
        $WC_Shipping->calculate_shipping_for_package( $package, $package_key = 0);
        WC()->cart->calculate_shipping();
        WC()->cart->calculate_totals();
    }
    wp_die();
}
以及:

hook
woocommerce\u-package\u-rates
在页面加载时工作,但ajax不起任何作用。请提供帮助。

是关于如何从Ajax调用中获取post数据的说明

此外,您可以在签出中的字段更改或被单击(而不是创建自定义Ajax调用)后,使用WooCommerce
update\u checkout
事件更新签出(从而重新计算运费)。你会发现一个完整的列表

因此,假设您希望在id为自定义装运价格(例如)的字段更改时重新计算装运成本,您可以使用以下脚本:

// updates the checkout (and shipping charge calculation) when the value of a field changes
add_action( 'wp_footer', 'update_checkout' );
function update_checkout() {

    // only in the checkout
    if ( ! is_checkout() ) {
        return;
    }

    ?>
    <script type="text/javascript">
    jQuery( document ).ready(function( $ ) {
        // when the value of the field with id "custom_shipping_price" changes it updates the checkout
        jQuery('#custom_shipping_price').change(function(){
            jQuery('body').trigger('update_checkout');
        });
    });
    </script>
    <?php
}

这两个代码都经过了测试,并且都能正常工作。将它们添加到活动主题的functions.php中。

这是否回答了您的问题?我看到了这个主题,并从中提取了部分代码。但这不是答案,因为我真的不明白为什么“woocommerce\u package\u rates”钩子不能通过ajax请求工作。你能说明你的目的吗?是否希望在字段值更改时更新签出?其目的是通过发送如下ajax请求来更新签出:jQuery.ajax({url:ajaxurl,方法:'POST',数据:{action:'set_shipping_price',cost:resultPrice})非常感谢,update_checkout event确实是我所需要的。它很有效。问题已经解决。@castetus当这个答案回答您的问题时,您可以请回答,如果您喜欢/想要,您也可以请回答,谢谢。
// updates the checkout (and shipping charge calculation) when the value of a field changes
add_action( 'wp_footer', 'update_checkout' );
function update_checkout() {

    // only in the checkout
    if ( ! is_checkout() ) {
        return;
    }

    ?>
    <script type="text/javascript">
    jQuery( document ).ready(function( $ ) {
        // when the value of the field with id "custom_shipping_price" changes it updates the checkout
        jQuery('#custom_shipping_price').change(function(){
            jQuery('body').trigger('update_checkout');
        });
    });
    </script>
    <?php
}
// update the shipping cost based on a custom field in the checkout
add_filter( 'woocommerce_package_rates', 'update_shipping_cost_based_on_custom_field', 10, 2 );
function update_shipping_cost_based_on_custom_field( $rates, $package ) {

    if ( ! $_POST || is_admin() || ! is_ajax() ) {
        return;
    }

    // gets the post serialized data sent with the Ajax call
    if ( isset( $_POST['post_data'] ) ) {
        parse_str( $_POST['post_data'], $post_data );
    } else {
        $post_data = $_POST;
    }
    
    // set the cost of shipping (if the custom field should be empty)
    $new_cost = 0;

    // if the field is set it gets the value
    if ( isset( $post_data['custom_shipping_price'] ) && ! empty( $post_data['custom_shipping_price'] ) ) {
        // forces conversion of value into number
        $new_cost = (float) str_replace( ',', '.', $post_data['custom_shipping_price'] );
    }
    // set the percentage of taxes (ex. 22%)
    $tax_rate = 0.22;

    foreach( $rates as $rate_key => $rate ) {
        if ( 'free_shipping' !== $rate->method_id ) {
            // set rate cost
            $rates[$rate_key]->cost = $new_cost;
            // set taxes rate cost (if enabled)
            $taxes = array();
            foreach ( $rates[$rate_key]->taxes as $key => $tax ) {
                if ( $rates[$rate_key]->taxes[$key] > 0 ) {
                    $taxes[$key] = $new_cost * $tax_rate;
                }
            }
            $rates[$rate_key]->taxes = $taxes;
        }
    }
    return $rates;
}