Hi @icecappacino,
It is great that you have already managed to restore the guest shipping details and are digging into how WooCommerce handles sessions during checkout. Restoring chosen shipping methods can indeed be tricky since WooCommerce recalculates and sanitizes the chosen method during checkout refreshes, which often overrides any manual session value you set. I can see the determination behind your approach, and I am glad to help you move this forward.
In this case, the behaviour you are seeing usually comes from the checkout update process where WooCommerce triggers shipping rate recalculation and validation. Even if the session has the method stored, the checkout refresh can override it if the method is not yet registered with the customer’s current address or if the method is being set too early in the load order.
A few things to keep in mind:
- WooCommerce overwrites
chosen_shipping_methods after woocommerce_checkout_update_order_review, so any restoration has to happen after this point.
- Setting the
$_POST['shipping_method'] value alone may not hold if the checkout fragments refresh again after login.
- If the method you are restoring is not available for the newly logged-in user’s address, WooCommerce will always fall back to the default shipping method.
If you want to control when the method gets restored reliably, testing the snippet inside woocommerce_checkout_update_order_review or even later, such as during woocommerce_after_calculate_totals, may offer better persistence.
We have a helpful guide on how WooCommerce handles shipping methods that may support your testing, including how the selection is stored and validated: https://woocommerce.com/document/shipping-methods/.
@lovingbro ,
Thanks for the feedback. Did some extensive digging and it seems that the *chosen_shipping_method* gets overridden somewhere between “woocommerce_cart_loaded_from_session” and before the “woocommerce_shipping_method_chosen” hook. This is because indeed it seems that recalculations maybe triggered and the chosen_method is not available at the time which is weird( it appears the method in question rates disappeared despite explicitly restoring it at “woocommerce_restored_session_data”) as I assume after restoring the customer’s shipping infor( which is successful) the method should have been available.
My code…
add_filter( 'woocommerce_restored_session_data', function( $session_data ) {
if ( ! is_user_logged_in() ) {
return $session_data;
}
$user_id = get_current_user_id();
$cached = get_transient( "session_data_{$user_id}" );
if ( empty( $cached ) ) {
return $session_data;
}
$session_data = maybe_unserialize($session_data);
$cached = maybe_unserialize($cached);
/*
|----------------------------------------------------------------------
| Restore shipping fields
|----------------------------------------------------------------------
*/
if ( ! empty( $cached['customer'] ) ) {
$session_customer = $session_data['customer'] ;
$cached_customer = $cached['customer'];
$shipping_keys = [
'shipping_first_name',
'shipping_last_name',
'shipping_company',
'shipping_address_1',
'shipping_address_2',
'shipping_city',
'shipping_state',
'shipping_postcode',
'shipping_country',
];
foreach ( $shipping_keys as $key ) {
if ( isset( $cached_customer[ $key ] ) && !empty($cached_customer[ $key ] ) ) {
$session_customer[ $key ] = $cached_customer[ $key ];
}
}
}
/*
|----------------------------------------------------------------------
| Restore chosen shipping methods
|----------------------------------------------------------------------
*/
if ( ! empty( $cached['chosen_shipping_methods'] ) ) {
$session_data['chosen_shipping_methods'] = $shipping_methods = $cached['chosen_shipping_methods'];
if ( ! empty( $shipping_methods ) ) {
// Force WooCommerce to acknowledge the restored method
WC()->session->set( 'chosen_shipping_methods', $shipping_methods );
// Needed to prevent WC from overriding your rate during refresh
$_POST['shipping_method'] = $shipping_methods;
}
}
/*
|----------------------------------------------------------------------
| NEW: Restore shipping_for_package_* values
|----------------------------------------------------------------------
*/
foreach ( $cached as $key => $value ) {
// match keys like shipping_for_package_0, shipping_for_package_1, etc.
if ( stristr( $key, 'shipping_for_package_' ) ) {
// Also update WC()->session live
$unserialized = maybe_unserialize( $value );
$session_data[ $key ] = $unserialized;
WC()->session->set( $key, $unserialized );
}
}
return maybe_serialize($session_data);
}, 10, 1 );
I will look into your suggestion but I think even before those hooks you mentioned it still seems to be happening.
Hi there!
Thanks for sharing the detailed explanation and the code snippet — I can understand how frustrating it can be when the chosen shipping method doesn’t persist correctly.
From what you’ve described, this issue appears to be related to custom code overriding or conflicting with WooCommerce’s default session handling, especially around the woocommerce_cart_loaded_from_session and recalculation stages. WooCommerce can trigger multiple cart refreshes depending on the customer data and extensions involved, which may explain why the chosen_shipping_method is getting replaced.
However, since this involves custom PHP code and session manipulation, it goes beyond the scope of the support we provide here in the forums. We’re only able to help with core WooCommerce functionality, and we’re not able to debug, adjust, or test custom-coded solutions.
If you need more in-depth support or want to consider professional assistance for customization, I can recommend WooExperts and Codeable.io as options for getting professional help.
Alternatively, you can also ask your development questions in the WooCommerce Community Slack as custom code falls outside our usual scope of support.
shahzeen(woo-hc)
The reason for the custom code was not intentional and sort to ensure that the guest session was properly migrated. I was of the notion that on login on the checkout page that any settings on the checkout form would have been restored. But woocommerce attempts to “RESET” and override this which is what I needed to prevent( at least from shipping info standpoint)
If i removed this “custom code” then how exactly does woocommerce migrate the guest session data to the returning custom session to retain whatever previous shipping info( address, shipping options etc.) before login?
Hi there!
I understand why you added the custom code, and I can see what you were trying to achieve. However, since this involves custom session-handling logic, it falls outside the scope of the support we can provide in this public forum. We can explain how core WooCommerce works, but we aren’t able to review or modify custom code.
By defualt, when a guest logs in during checkout, WooCommerce automatically:
- Merges the guest cart with the customer’s session/cart
- Loads the customer’s saved address data from their account
- Triggers a fresh shipping calculation using the logged-in customer’s stored or entered address
- Re-runs shipping methods and totals based on the new customer context
This means WooCommerce does not attempt to restore the guest shipping address or chosen shipping method after login. Instead, it refreshes the checkout based on the authenticated customer’s actual saved address and available shipping rates.
Thank you for cooperation and understanding.
@shahzeenfarooq
Thanks for the feedback.