Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WooCommerce: How to retain checkout info when client leaves then comes back?

Is there a simple way or a plugin to retain checkout information entered by the client after he/she leaves and comes back?

This plugin retains "fields information for customers when they navigate back and forth" however it has quite a lot of recent bad reviews so I don't think I'll use that for production. Any alternative suggestion?

like image 803
drake035 Avatar asked May 26 '16 11:05

drake035


1 Answers

---- Update ----

The code below is working, but only if data is submitted!

The only possible ways are javascript/jQuery form event detection on checkout fields and worpress Ajax:

  • Using ajax connected to some session transients function (as in code below).
  • Using (javascript) web Storage: localStorage, sessionStorage

I have found some real interesting code in this thread that is using sessions transients to store checkout data.

// this function sets the checkout form data as session transients whenever the checkout page validates
function set_persitent_checkout ( $a ) {
    $arr = array();
    foreach ( $a as $key => $value )
        if ( ! empty($value) )
            $arr[$key] = $value;

    WC()->session->set( 'form_data', $arr );
    return $a;
}
add_action( 'woocommerce_after_checkout_validation', 'set_persitent_checkout' );


// this function hooks into woocommerce_checkout_get_value to substitute standard values with session values if present
function get_persistent_checkout ( $value, $index ) {
    $data = WC()->session->get('form_data');
    if ( ! $data || empty($data[$index]) )
        return $value;
    return is_bool($data[$index]) ? (int) $data[$index] : $data[$index];
}
add_filter( 'woocommerce_checkout_get_value', 'get_persistent_checkout', 10, 2 );


// This is a fix for the ship_to_different_address field which gets it value differently if there is no POST data on the checkout
function get_persitent_ship_to_different ( $value ) {
    $data = WC()->session->get('form_data');
    if ( ! $data || empty($data['ship_to_different_address']) )
        return $value;

    return is_bool($data['ship_to_different_address']) ? (int) $data['ship_to_different_address'] : $data['ship_to_different_address'];
}
add_action( 'woocommerce_ship_to_different_address_checked', 'get_persitent_ship_to_different' );

Add this code to the functions.php file located in your active child theme or theme.

Explanations from the author:

1. Save the form data:

The first function set_persitent_checkout hooks into woocommerce_after_checkout_validation.

Whenever that hook is fired, any current form data is saved as a WordPress transient via the WC_Session_Handler class (which was recently updated in version 2.5 to be a lot more efficient).

2. Check the saved data on reload:

Next we hook woocommerce_checkout_get_value with get_persitent_checkout. As the name suggests, here we check the session transients and return any matches for the current field if found.

3. Make ship_to_different_address work:

The only difficult was the ship_to_different_address field, which gets its value through a different method.

To get around this the final function was added. This works exactly the same as the previous function, but hooks into woocommerce_ship_to_different_address_checked.

There you have it. It would be nice if the data was saved after every field update on checkout, but the woocommerce_after_checkout_validation hook fires enough to capture the data at all the important points.

like image 72
LoicTheAztec Avatar answered Sep 28 '22 00:09

LoicTheAztec