I created a custom minicart with a shipping calculator with country select, postcode input and shipping method selection. The purpose is to show product subtotal, shipping method and subtotal, and the order total on the minicart.

Shop user may enter one's location to the calculator, which triggers an ajax call to refresh the minicart to show available shipping methods (list of radio buttons). The ajax call updates customer's billing/shipping country and postcode data.

This code is based on an answer I found in some thread here in SE/SO.

ajax_function_for_minicart_setup() {
$country = wc_clean( $_POST['country'] );
$postcode = wc_clean( $_POST['postalCode'] );

$customer_session = WC()->session->get( 'customer' );
$customer_session['country'] = $country;
$customer_session['shipping_country'] = $country;
$customer_session['billing_country'] = $country;
$customer_session['postcode'] = $postcode;
$customer_session['shipping_postcode'] = $postcode;
$customer_session['billing_postcode'] = $postcode;
$customer_session = WC()->session->set( 'customer', $customer_session );

WC()->customer->set_billing_country( $country );
WC()->customer->set_shipping_country( $country );

WC()->customer->set_billing_postcode( $postcode );
WC()->customer->set_shipping_postcode( $postcode );

if ( ! empty( $_POST['shippingMethod'] ) ) {

    WC()->session->set( 'chosen_shipping_methods', array( wc_clean( $_POST['shippingMethod'] ) ) );

echo wc_get_template( 'cart/mini-cart.php' );

(I added the if-statement in case the visitor changes the postcode)

User may then choose any of the shipping methods, which triggers another ajax call to refresh the minicart with recalculated order total (products + shipping). This ajax call updates the WooC session chosen shipping method data.

ajax_function_recalculate_shipping() {
WC()->session->set( 'chosen_shipping_methods', array( wc_clean( $_POST['shippingMethod'] ) ) );

echo wc_get_template( 'cart/mini-cart.php' );


On the checkout order review table the shipping method is the same one selected on the mini cart. But when the WooCommerce's default ajax update_shipping_method call runs, it wipes the previously selected shipping method and sets it to first method on the list.

This means that the user has to manually reselect the correct shipping method after the update_shipping_method ajax call. If the user doesn't notice that the shipping method has changed and don't reselect it, s/he'll get a nasty suprise in the form of wrong shipping method and I think that's bad user experience.


I'm clearly doing something wrong or missing something, but after hours of debugging and browsing Google and SE I still can't figure out what.

Any suggestion on how should I change the code so that the shipping method set on the minicart wouldn't get wiped on the checkout page?


I know this is an off-topic question, but previously I haven't had much luck when asking this kind of questions on the wordpress.org forums. I thought SE would be more appropriate forum for my question.

Browse other questions tagged or ask your own question.