I’ve been trying to update the manual shipping value in the order review table in the checkout page, when user a click a button in the billing details section that I have already created. I used a manual test value in this case. But the order review table isn’t updating that value in the order review table.
Updated
I declared a test value and assigned to the shipping label, and I’ve got that updated value through the Ajax response. But the order review table shipping value is not getting updated. (please see the PHP code)
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);
}
});
});
});
2
Answers
I recently created a custom checkout process that had to draw shipping costs from a separate database.
It uses the existing shipping methods in woocommerce and just adjusted their rates, meaning you don’t have to hide the existing shipping label.
I have adjusted your code to use the same method I used.
Your existing JS code should work fine.
You can find your shipping method id from 2 methods:
Method 1
If your shipping method is a Flat Rate method, you can inspect the ‘Edit’ button and just change the id number in the code to match.
Get Flat Rate shipping method ID
Method 2
At checkout, you can inspect the shipping method and then the value of the element is the full shipping method id, so in this instance you will need to replace ‘flat_rate:31’ with ‘local_pickup:28’
Get all shipping method ID
There are multiple mistakes and missing things in your codeā¦
I have commented/disabled the following code line, as you don’t provide distancecal.php file:
Also, you should not use WooCommerce existing Ajax actions, so I changed your action name from
update_checkout
toshipping_cost_update
.Then there was some missing mandatory hooked functions (see this thread)
Try the following revised main php code:
And for distancecal-scripts.js JavaScript file:
PHP: Missing mandatory code (Refresh shipping methods cache):
Add the code (both functions) to your main plugin file.
Optional code: Reset/remove the WC Session variable if customer goes other pages.
Add optionally this code functions to your main plugin file.
Tested and works, Updating the shipping cost.
Important note: Don’t forget to empty your cart to refresh shipping method caches on first start.
Related: