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.
Leave a Reply