WooCommerce 2 Step Checkout

Right, new year (nepali), new tutorial.

We’re going to be taking a dive into a custom WooCommerce Multistep Checkout.

If you rather just see the code then here or here is good 😀

The Scenario:

So here’s what I want to do, create a 2 – step checkout.

First Step:

The User Fills in their user details

Second Step:

The User reviews their order and completes payment.

For simplicity sake, this tutorial won’t go beyond that. We won’t be covering, changing user details once they enter the second step because well that’s just too much to cover.

Modifying the template:

I’m using the default twenty seventeen theme

So first things first, we need to figure out all the elements we’re going to be changing.

So as you may know woocommerce offer us the ability to change templates and modify them to our needs. We will be doing that.

The template in question is /plugins/woocommerce/checkout/form-checkout.php/.

We copy this template into our child-theme into a /woocommerce/checkout/ folder.

So if you have a look at this template you see it’s already very well segmented.

What we are going to do now is add our own wrappers around each segment.

The step-1 div wrapper will go around customer-details

And the step-2 div wrapper will go around step-2. Now using some CSS we hide the second div.

The final result should look something like this.

Adding the Verify Details Button:

At this time, the billing and shipping fields (if shipping is enabled) and order notes should be visible and, order review and payment forms are hidden.

Now we add the button at the very end of customer-details div as well as a hidden field called, current_step. The intention here is that we want the user to be able to verify all their details and show any and all error before moving to step-2. For this a little bit of trickery is required.

The Problem:

Ok we’re got everything setup, now. The Steps have been divided, the button added and now all we need to do is hide and show the fields using some very simple jquery. Right ? WRONG.

The PROBLEM here is that if a user, goes from step-1 to step-2 , without filling out every field correctly. They will encounter an error in step-2.

So imaging having to go back and forth each time just to correct one error. Troublesome right.

The Solution:

Part 1: THE PHP

Luckily that’s where the hidden button comes in, as well as some diving into the woocommerce core files.

Let’s go into, the normal flow of the checkout.

A user goes to checkout click on make payment, via ajax the order is validated and if any errors occur the process is halted otherwise checkout is completed.

My goal here is to pause this process on the validation and prevent the checkout from happening.

That way, if there are errors the errors will be displayed. Else, the user goes to step-2 and continues the checkout process.

So to do that lets go into the /plugins/woocommerce/class-wc-checkout.php and the public function process_checkout() line no 895, this is where the magic happens.

On line no 920 I noticed. $this->validate_checkout() and in the function it has a action.

do_action( ‘woocommerce_after_checkout_validation’, $data, $errors );

So. What I am doing now is in my child themes functions.php file. I check if there are errors and which step the user is on, if there are errors then fine, woocommerce will handle it itself.

If there aren’t any errors and the user is on step-1 however I forcibly add my own error and prevent the checkout process from continuing any further.

This I do in my child themes functions.php file

add_action('woocommerce_after_checkout_validation', 'digthis_two_step_checkout_validate', 9999, 2);
function digthis_two_step_checkout_validate($data, $errors) {

$step = filter_input(INPUT_POST, ‘current_step’);

if( empty( $errors->errors ) && $step == ‘step-1’ ){
$errors->add( ‘digthis’, __( ‘<span id=”digthis-prevent-error”>Digthis Error</span>’, ‘woocommerce’ ) );
}

}

Now lets take a moment to stop here and take a look at our progress. What should be happening is.

If there are errors, errors should show. Otherwise, Digthis Error should show.

 

Part 2 : THE JS

Now comes the second part of our solutioin. After we’ve successfully validated the form fields and prevented auto checkout. We now need to go to step-2.

WooCommerce triggers  a ‘checkout_error’ event when an error occurs and this allows us to hook in and find if “digthis-prevent-error” div is present and move on to step-2.

Here is the complete files, for your convience in a zip format. Hope this helps someone out.

And if anyone has a better way to do this. I’m all ears.

 

9 thoughts on “WooCommerce 2 Step Checkout”

  1. Im so excited to see this as it is exactly what i am looking for . I set this up on my current theme but im running into an issue, After completing the first step and clicking verify it automatically completes the order and goes to the order completed details page . it is skipping the second step with order table and choice of shipping . I am using wordpress 4.6.5 and woocommerce 3.0 so im not sure if these versions have factors in this or if it is my theme .

    Any help or advice would be greatly appreciated

  2. I was trying to figure out a 2 step checkout process and I found this article from google, a very great solution! I’m definitely gonna use it.

  3. Hi Digamber Pradhan,

    sorry for my english. Congratulations to the solution. But i have a question, for a problem.
    I have add custom special field

    add_action(‘woocommerce_before_checkout_billing_form’, ‘customise_checkout_category_user’, 0);

    function customise_checkout_category_user($checkout) {

    woocommerce_form_field( ‘inscription_textbox_cf’, array(
    ‘type’ => ‘text’,
    ‘class’ => array( ‘inscription-text_cf form-row-wide’ ),
    ‘label’ => __( ‘Codice Fiscale’ ),
    ‘required’ => true,
    ), $checkout->get_value( ‘inscription_textbox_cf’ ) );

    woocommerce_form_field( ‘inscription_textbox_iva’, array(
    ‘type’ => ‘text’,
    ‘class’ => array( ‘inscription-text_iva form-row form-row-last’ ),
    ‘label’ => __( ‘Partita Iva’ ),
    ‘required’ => true,
    ), $checkout->get_value( ‘inscription_textbox_iva’ ) );

    }
    The validation of these fields takes place only at the end of the second step, when I click on the “finish order” button, after payment method choice’s.

    Thanks in advance.
    Francesco

    1. Hey Francesco,
      I haven’t had the chance to look into what you are saying yet. I will give it a go and come back to you as soon as i can

  4. Hello,
    I have tried your solution and it works. I played with code, but can’t reproduce “thank you” page look on your “review before payment” page. Besides that, I would like to include item price on first step (when filling out form) and on a second step I’d like to add contact info from step 1.

    Also, I use a delivery date plugin, which doesn’t get validated on step one, but does on step 2, so i would appriciate some help around that too 🙂
    Plugin link: https://wordpress.org/plugins/order-delivery-date-for-woocommerce/

    Hope you will answer soon 🙂 🙂

    Best regards, Tine

Leave a Reply

Your email address will not be published. Required fields are marked *