从 WC 会话变量更改 WooCommerce Checkout 运输方式成本

问题描述 投票:0回答:2

当用户单击我已创建的账单详细信息部分中的按钮时,我一直在尝试更新结帐页面中订单审核表中的手动运费值。在这种情况下我使用了手动测试值。但订单审核表不会更新订单审核表中的该值。

已更新 我声明了一个测试值并分配给发货标签,并且我通过 Ajax 响应获得了更新后的值。但订单审核表运费价值未更新。 (请查看PHP代码)

PHP

<?php
/*
Plugin Name: Change Shipping Value
Description: Customizations for WooCommerce.
Version: 1.0
Author: udd_ish
*/

function enqueue_custom_scripts() {
    // Enqueue the custom JS file
    wp_enqueue_script('jquery');
    wp_enqueue_script('distancecal-scripts', plugin_dir_url(__FILE__) . 'js/distancecal-scripts.js', array('jquery'), '1.0', true);
    wp_localize_script('distancecal-scripts', 'ajax_object', array('ajaxurl' => admin_url('admin-ajax.php')));
}

add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');

// Add a button after the billing form in WooCommerce checkout
add_action('woocommerce_after_checkout_billing_form', 'add_custom_button_after_billing_form');

function add_custom_button_after_billing_form() {
    include_once(plugin_dir_path(__FILE__) . 'distancecal.php'); // Include PHP functions file
    ?>
    <div id="custom-button-wrapper">
        <button type="button" id="custom-button" class="button alt">Calculate Delivery Fee</button>
    </div>
<?php
}


function modify_shipping_cost($shipping_cost) {
    if ( isset($shipping_cost) ){
        WC()->session->set('shipping_cost', $shipping_cost);
        return $shipping_cost;
    }
}


add_filter( 'woocommerce_package_rates', 'shipping_package_rates_filter_callback', 100, 2 );
function shipping_package_rates_filter_callback( $rates, $package ) {
    // The defined rate id
    $shipping_rate_id = 'flat_rate:4'; //Use your own shipping method id

    $tax_rate = 0.1; // 10%

    if( isset(WC()->session->get('shipping_cost') ) ) {
        $shipping_cost = WC()->session->get('shipping_cost' );
        $rates = array( $shipping_rate_id => $rates[ $shipping_rate_id ] );
        // Set rate cost
        $rates[$shipping_rate_id ]->cost = $shipping_cost;
        // Set taxes rate cost (if enabled)
        $taxes = array();
        foreach ($rates[$shipping_rate_id ]->taxes as $key => $tax){
            if( $rates[$shipping_rate_id ]->taxes[$key] > 0 )
                $taxes[$key] = $shipping_cost * $tax_rate;
        }
        $rates[$shipping_rate_id ]->taxes = $taxes;
    } else {
        unset( $rates[ $shipping_rate_id ] );
    }

    return $rates;
}


// AJAX handler for updating checkout
add_action('wp_ajax_update_checkout', 'update_checkout_callback');

function update_checkout_callback() {

    $testvalue = 100;

    // Update the shipping cost with the new test value
    $newvalue = modify_shipping_cost($testvalue);
    
    wp_send_json(array('updated_fee' => $newvalue));
    
    // Make sure to exit after handling the AJAX request
    wp_die();

} ?>

JS

jQuery(document).ready(function($) {
    // Add your custom JavaScript here
    $('#custom-button').on('click', function() {
        var streetAddress = $('#billing_address_1').val();
        $.ajax({
            type: 'POST',
            url: ajax_object.ajaxurl,
            data: {
                action: 'update_checkout',
                street_address: streetAddress
            },
            success: function(response) {
                console.log(response);
                $('body').trigger('update_checkout', { update_shipping_method: true });
                
            },
            error: function(error) {
                // Handle AJAX error if needed
                console.error('AJAX error:', error);
            }
        });
    });
});
php jquery ajax woocommerce shipping-method
2个回答
0
投票

您的代码中有多个错误和遗漏的内容......

我已注释/禁用以下代码行,因为您没有提供 distancecal.php 文件:

// include_once(plugin_dir_path(__FILE__) . 'distancecal.php'); // Include PHP functions file

此外,您不应该使用 WooCommerce 现有的 Ajax 操作,因此我将您的操作名称从

update_checkout
更改为
shipping_cost_update

然后缺少一些强制挂钩函数(请参阅此线程)

尝试以下修改后的主要 php 代码:

<?php
/**
 * Plugin Name: Woo Custom Shipping Value (Test)
 * Description: Customizations for WooCommerce.
 * Version: 1.0
 * Author: udd_ish
**/

defined( 'ABSPATH' ) or exit;

add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');
function enqueue_custom_scripts() {
    // Enqueue the custom JS file
    wp_enqueue_script('jquery');
    wp_enqueue_script('distancecal-scripts', plugin_dir_url(__FILE__) . 'js/distancecal-scripts.js', array('jquery'), '1.0', true);
    wp_localize_script('distancecal-scripts', 'ajax_object', array('ajaxurl' => admin_url('admin-ajax.php')));
}

function modify_shipping_cost($shipping_cost) {
    if ( isset($shipping_cost) ){
        WC()->session->set('shipping_cost', $shipping_cost);
    }
    return $shipping_cost;
}

// Add a button after the billing form in WooCommerce checkout
add_action('woocommerce_after_checkout_billing_form', 'add_custom_button_after_billing_form');
function add_custom_button_after_billing_form() {
    // include_once(plugin_dir_path(__FILE__) . 'distancecal.php'); // Include PHP functions file
    ?>
    <div id="custom-button-wrapper">
        <button type="button" id="custom-button" class="button alt"><?php _e('Calculate Delivery Fee'); ?></button>
    </div>
<?php
}

add_filter( 'woocommerce_package_rates', 'shipping_package_rates_filter_callback', 100, 2 );
function shipping_package_rates_filter_callback( $rates, $package ) {
    // HERE define your targeted rate id
    $targeted_rate_id = 'flat_rate:4'; 
    
    if ( ! array_key_exists($targeted_rate_id, $rates) ) 
        return $rates;

    // Customize the shipping method label name
    $rates[$targeted_rate_id]->label = __('New name', 'woocommerce'); // Set the new name

    $new_cost = WC()->session->get('shipping_cost'); // Get new cost from WC sessions

    if ( ! empty($new_cost) ) {
        $rate = $rates[$targeted_rate_id];
        $cost = $rate->cost; // Set the initial cost in a variable for taxes calculations
        $rates[$targeted_rate_id]->cost = $new_cost; // Set the new cost

        $has_taxes = false; // Initializing
        $taxes     = array(); // Initializing
        foreach ($rate->taxes as $key => $tax_cost){
            if( $tax_cost > 0 ) {
                $tax_rate    = $tax_cost / $cost; // Get the tax rate conversion
                $taxes[$key] = $new_cost * $tax_rate; // Set the new tax cost in taxes costs array
                $has_taxes   = true; // There are taxes (set it to true)
            }
        }
        if( $has_taxes ) {
            $rates[$targeted_rate_id]->taxes = $taxes; // Set taxes costs array
        }
    } else {
        unset($rates[$targeted_rate_id]);
    }
    return $rates;
}


// PHP WP AJAX handler
add_action('wp_ajax_shipping_cost_update', 'shipping_cost_update_callback');
add_action('wp_ajax_nopriv_shipping_cost_update', 'shipping_cost_update_callback');
function shipping_cost_update_callback() {
    $test_value = 100;

    wp_send_json( array( 'updated_shipping_cost' => modify_shipping_cost($test_value) ) );
    wp_die(); // Make sure to exit after handling the AJAX request
}

## Missing mandatory code:

// Refresh shipping methods
add_action('woocommerce_checkout_update_order_review', 'checkout_update_refresh_shipping_methods' );
function checkout_update_refresh_shipping_methods() {
    if ( WC()->session->__isset('shipping_cost') ) {
        $packages = WC()->cart->get_shipping_packages();
        foreach ($packages as $package_key => $package ) {
             WC()->session->set( 'shipping_for_package_' . $package_key, false ); // Or true
        }
    }
}

// Remove the WC session variable once the order is created
add_action('woocommerce_checkout_order_created', 'remove_wc_session_shipping_cost_variable', 10, 1);
function remove_wc_session_shipping_cost_variable( ) {
    if ( WC()->session->__isset('shipping_cost') ) {
        WC()->session->__unset('shipping_cost');
    }
}

// (optional) Remove the WC Session variable on other pages than checkout
add_action('template_redirect', 'wc_session_shipping_cost_variable_only_on_checkout', 10, 1);
function wc_session_shipping_cost_variable_only_on_checkout() {
    if ( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) {
        remove_wc_session_shipping_cost_variable();
    }
}

对于 distancecal-scripts.js JavaScript 文件:

jQuery( function($) {
    // Add your custom JavaScript here
    $(document.body).on('click', '#custom-button', function() {
        const streetAddress = $('#billing_address_1').val();

        if ( $('#billing_address_1').val() !== '' ) {
            $.ajax({
                type: 'POST',
                url: ajax_object.ajaxurl,
                data: {
                    action: 'shipping_cost_update',
                    street_address: streetAddress
                },
                success: function(response) {
                    console.log(response);
                    $(document.body).trigger('update_checkout', { update_shipping_method: true });
                    
                },
                error: function(error) {
                    // Handle AJAX error if needed
                    console.error('AJAX error:', error);
                }
            });
        }
    });
});

已测试并有效更新运费。

重要提示:不要忘记清空购物车以刷新运输方式缓存。


0
投票

我最近创建了一个自定义结帐流程,必须从单独的数据库中提取运费。

它使用 woocommerce 中现有的运输方式,只是调整了其费率,这意味着您不必隐藏现有的运输标签。

我已经调整了你的代码以使用与我使用的相同的方法。

function modify_shipping_cost($shipping_cost) {
    if ( isset($shipping_cost) ){
        WC()->session->set('shipping_cost', $shipping_cost);
        return $shipping_cost;
    }
}

add_filter( 'woocommerce_package_rates', 'shipping_package_rates_filter_callback', 100, 2 );
function shipping_package_rates_filter_callback( $rates, $package ) {
    // The defined rate id
    $shipping_rate_id = 'flat_rate:31'; //Use your own shipping method id

    $tax_rate = 0.1; // 10%

    if( isset(WC()->session->get('shipping_cost') ) ) {
        $shipping_cost = WC()->session->get('shipping_cost' );
        $rates = array( $shipping_rate_id => $rates[ $shipping_rate_id ] );
        // Set rate cost
        $rates[$shipping_rate_id ]->cost = $shipping_cost;
        // Set taxes rate cost (if enabled)
        $taxes = array();
        foreach ($rates[$shipping_rate_id ]->taxes as $key => $tax){
            if( $rates[$shipping_rate_id ]->taxes[$key] > 0 )
                $taxes[$key] = $shipping_cost * $tax_rate;
        }
        $rates[$shipping_rate_id ]->taxes = $taxes;
    } else {
        unset( $rates[ $shipping_rate_id ] );
    }

    return $rates;
}

add_action('wp_ajax_update_checkout', 'update_checkout_callback');
function update_checkout_callback() {

    $testvalue = 100;
    
    // Update the shipping cost with the new test value
    $newvalue = modify_shipping_cost($testvalue);
    
    wp_send_json(array('updated_fee' => $newvalue));

    // Make sure to exit after handling the AJAX request
    wp_die();

}

您现有的 JS 代码应该可以正常工作。

您可以通过 2 种方法找到您的运输方式 ID:

方法1 如果您的送货方式是统一费率方式,您可以检查“编辑”按钮,然后更改代码中的 ID 号以进行匹配。 Get Flat Rate shipping method ID

方法2 结帐时,您可以检查运输方式,然后该元素的值是完整的运输方式 ID,因此在这种情况下,您需要将 'flat_rate:31' 替换为 'local_pickup:28' Get all shipping method ID

© www.soinside.com 2019 - 2024. All rights reserved.