WooCommerce: How to Customize Checkout For Conversions

I had the honor to speak at WCEU 2020 thanks to WooCommerce, who hosted me in their Sponsor track. It was a short and sweet lightning talk on the first day (Friday), called “Customizing The WooCommerce Checkout To Improve Conversions“, followed by a live coding session on Saturday.

Here’s the video recording of the lightning talk, as well as a few PHP and CSS snippets you can copy/paste to improve your WooCommerce Checkout and immediately expect an increase in conversion rate. So, enjoy the video and then go test the snippets you find below!

Video: Customizing The WooCommerce Checkout To Improve Conversions

The WooCommerce Checkout is the most important page of your website. Which means, you’ve got to optimize it.

In this presentation, I take a look at successful ecommerce B2C websites and see what they do. Maybe we can identify trends and weaknesses and get to work on that.

Please note there are subtitles available. Simply click on the “CC” button in the bottom right of the video player.

10 PHP & CSS WooCommerce Checkout Conversion Rate Optimization Snippets

In the follow-up session, I shared my screen and started live coding what we learned during the lightning talk. In a nutshell, we decided to take action on the following points:

  1. Remove header, sidebar, footer so there are no distractions and customer is fully focused on the only remaining call to action – the “PAY” button
  2. Move the order summary, shipping and payment method selection to the right hand side so it’s always visible
  3. Split the long layout made of billing, shipping, order notes, coupon form etc. in visual steps
  4. Move coupon form to the bottom to avoid coupon fraud
  5. Keep the shipping form always “open” as that’s the most important section for B2C
  6. Move the billing form below shipping form
  7. Remove unnecessary billing/shipping fields; the more fields the lower your conversion rate!
  8. Make the shipping method selection stand out more, because the default layout is quite poor
  9. Add an “edit cart” link so users can go back to the Cart page and edit their order
  10. Add security badges / phone / FAQs to let the customer trust your online business

But before coding, let’s take a look at the tools stack.

Theme: I used the official WooCommerce theme, Storefront. This already comes with some inbuilt CSS customization for the checkout. Another fav of mine could have been Shoptimizer, a theme built for WooCommerce speed and conversions. Anyhow, because one of the snippets is about removing header and footer from the checkout page, I therefore used my Storefront theme visual hook guide, so I know which hooks to use.

Hooks: on top of using my visual hook guide for Storefront, we also require to know all the WooCommerce Checkout hooks. My WooCommerce Visual Hook Guide for the Checkout Page is perfect for what we need.

Docs: WooCommerce has a nice document that explains how to customize checkout fields. In one of the snippets we will remove some of the billing/shipping fields, so this is a must-know reference.

1. PHP Snippet: Remove header, sidebar and footer @ WooCommerce Checkout Page

This snippet is valid for the Storefront theme only. You will need to adjust the code for your customized theme.

/**
 * @snippet       Storefront Theme Remove Header Footer @ Checkout
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @testedwith    WooCommerce 4.1
 * @community     https://businessbloomer.com/club/
 */

add_action( 'wp', 'bbloomer_unhook_storefront_functions' );

function bbloomer_unhook_storefront_functions() {
	if ( is_checkout() ) {
		remove_all_actions( 'storefront_header' );
		remove_action( 'storefront_before_content', 'woocommerce_breadcrumb', 10 );
		remove_action( 'storefront_sidebar', 'storefront_get_sidebar', 10 );
		remove_action( 'storefront_footer', 'storefront_footer_widgets', 10 );
	}
}

On Storefront, once you remove the sidebar with the above remove_action call, the layout won’t automatically adjust to full-width. The sidebar will go away but it’s “space” will remain there and push the checkout form to the left.

That means we also need a bit of CSS to fix that:

@media (min-width: 768px) {
	.woocommerce-checkout.right-sidebar .content-area {
		width: 100%;
		float: none;
		margin-right: 0;
	}
}

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

2. CSS Snippet: Move Order Review To Top Right @ WooCommerce Checkout Page

The Storefront theme already does that out of the box! So, it seems they studied ecommerce trends as well and decided that was the right choice.

Of course, most themes do not do that by default. For inspiration, you can try copying Storefront’s CSS (you may need to change some selectors):

@media (min-width: 768px) {

	/* Billing & Shipping @ Left */

	.col2-set {
		width: 52.9411764706%;
		float: left;
		margin-right: 5.8823529412%;
	}

	/* Order Review @ Right */

	#order_review_heading, #order_review {
		width: 41.1764705882%;
		float: right;
		margin-right: 0;
		clear: right;
	}

}

Now, I’d also like to make the whole Order Review “sticky”. Which means, once a user scrolls down to fill out checkout fields for example, the Order Review box (now on the top right) should stay visible and “fixed” to the top of the browser.

I’ve tried the following CSS but unfortunately it doesn’t seem to work (Storefront theme). Can you help maybe?

#order_review {
    position: sticky;
    top: 0;
}

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

3. PHP Snippet: Move coupon form to the bottom @ WooCommerce Checkout Page

We can use the Visual hook guide for the checkout for this. First, we remove it, then we readd it at the very bottom.

/**
 * @snippet       Move Coupon @ Checkout Bottom
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @testedwith    WooCommerce 4.1
 * @community     https://businessbloomer.com/club/
 */

remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );

add_action( 'woocommerce_after_checkout_form', 'woocommerce_checkout_coupon_form', 10 );

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

4. PHP Snippet: Keep the shipping form always “open” @ WooCommerce Checkout Page

Thankfully if you look at form-shipping.php template file, WooCommerce gives us a filter here:

apply_filters( 'woocommerce_ship_to_different_address_checked', 'shipping' === get_option( 'woocommerce_ship_to_destination' ) ? 1 : 0 )

Which means I can now code a simple PHP snippet to override that behavior:

/**
 * @snippet       Shipping Always Open @ Checkout
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @testedwith    WooCommerce 4.1
 * @community     https://businessbloomer.com/club/
 */

add_filter( 'woocommerce_ship_to_different_address_checked', 'bbloomer_open_shipping_checkout' );

function bbloomer_open_shipping_checkout() {
	return 1;
}

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

5. CSS Snippet: Move the billing form below shipping form @ WooCommerce Checkout Page

First of all, Billing and Shipping forms must be made full-width. Storefront theme already does that, so in case you’re using another theme, try with this:

.col2-set .col-1, .col2-set .col-2 {
	float:none;
	width: 100%
	margin: 0;
}

Once you have Billing and Shipping one above the other, we want now to feature the Shipping form first (top) and Billing form after (bottom). Doing this with PHP is possible, but there is a much neater way to accomplish it: CSS flex.

.col2-set {
    display: flex;
    flex-direction: column;
}

.col2-set > .col-1 {
	order: 2; 
}

.col2-set > .col-2 {
	order: 1; 
}

In a nutshell, I’m declaring that the customer details (Billing & Shipping forms wrapper) displays as “flex”. In this way, I can use the “order” property and switch the vertical order of the Billing and Shipping divs.

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

6. PHP Snippet: Split the long layout made of billing, shipping, order review into visual steps @ WooCommerce Checkout Page

Here we use once again the visual hook guide, and print 3 new divs in specific positions (above shipping, above billing, above order review).

/**
 * @snippet       Add Visual Steps @ Checkout
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @testedwith    WooCommerce 4.1
 * @community     https://businessbloomer.com/club/
 */

add_action( 'woocommerce_checkout_shipping', 'bbloomer_checkout_step1' );

function bbloomer_checkout_step1() {
	echo '<p class="steps">STEP1</p>';
}

add_action( 'woocommerce_checkout_billing', 'bbloomer_checkout_step2' );

function bbloomer_checkout_step2() {
	echo '<p class="steps">STEP2</p>';
}

add_action( 'woocommerce_checkout_before_order_review_heading', 'bbloomer_checkout_step3' );

function bbloomer_checkout_step3() {
	echo '<p class="steps">STEP3</p>';
}

Of course we also need some CSS:

.steps {
	background: black;
	color: white;
	display: inline-block;
	padding: 0.5em 2em;
}

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

7. PHP Snippet: Remove unnecessary billing/shipping fields @ WooCommerce Checkout Page

Here, the documentation reference I shared above comes to the rescue. The “woocommerce_checkout_fields” filter allows us to “unset” fields we don’t need.

/**
 * @snippet       Remove Ship/Bill Fields @ Checkout
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @testedwith    WooCommerce 4.1
 * @community     https://businessbloomer.com/club/
 */

add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );

function custom_override_checkout_fields( $fields ) {
	
     unset( 
		 $fields['order']['order_comments'], 
		 $fields['shipping']['shipping_company'],
		 $fields['shipping']['shipping_address_2'],
		 $fields['billing']['billing_company'],
		 $fields['billing']['billing_address_2'],
		 $fields['billing']['billing_postcode'],
		 $fields['billing']['billing_phone']
     );

     return $fields;
}

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

8. PHP Snippet (Idea): Make the shipping method selection stand out more @ WooCommerce Checkout Page

This is the most difficult snippet, and that’s because WooCommerce is not really flexible in this regard. To demonstrate that, we first need to find out how the shipping method form is generated.

In the checkout “order review” template we find this PHP:

<?php if ( WC()->cart->needs_shipping() && WC()->cart->show_shipping() ) : ?>

   <?php do_action( 'woocommerce_review_order_before_shipping' ); ?>

   <?php wc_cart_totals_shipping_html(); ?>

   <?php do_action( 'woocommerce_review_order_after_shipping' ); ?>

<?php endif; ?>

It’s evident that we need to study how wc_cart_totals_shipping_html() function works, to see if there are any filters that allow us to customize the output.

Unfortunately, that function simply calls the cart-shipping.php template file thanks to the wc_get_template() function; I say unfortunately because that same template is also used on the Cart page.

Now, this is getting more complicated than I though, but if we wish to take the shipping method form out of that order review table we basically need to write or own custom template (e.g. checkout-shipping.php), place it in the /woocommerce folder of our child theme, and then use the wc_get_template filter to load our alternative template on the checkout page only. Kinda complex, but doable – I’ll leave it up to you 😀

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

9. PHP Snippet: Add an “edit cart” link @ WooCommerce Checkout Page

Because we removed all links from the Checkout page, it’s fair to give the user a chance to get back to the Cart page in case they want to change quantities or remove products.

You can pick any WooCommerce Checkout hook, but in this case I selected the “woocommerce_checkout_before_order_review” one, which is positioned right below the “Your Order” heading.

/**
 * @snippet       Add edit cart link @ Checkout
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @testedwith    WooCommerce 4.1
 * @community     https://businessbloomer.com/club/
 */

add_action( 'woocommerce_checkout_before_order_review', 'bbloomer_edit_cart_checkout' );

function bbloomer_edit_cart_checkout() {
	echo '<a href="' . wc_get_cart_url() . '">Edit Cart</a>';
}

With a bit of CSS, you can also position this on the same line as “Your Order” and save some space.

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

10. PHP Snippet: Add phone number @ WooCommerce Checkout Page

You can add whatever content you wish to the Checkout page, mostly if it helps potential customers trust your business.

Usually you would add secure payment badges, FAQ or contact links, as well as an immediate way to get in touch with you (live chat and phone number).

So, this is how to add a phone number right below the “PLACE ORDER” button on the checkout page.

/**
 * @snippet       Phone Number @ Checkout
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @testedwith    WooCommerce 4.1
 * @community     https://businessbloomer.com/club/
 */

add_action( 'woocommerce_review_order_after_submit', 'bloomer_phone_checkout_page' );

function bloomer_phone_checkout_page() {
	?>
	<p>Need help? Give us a call at <a href="tel:1123456789">+1 123456789</a></p>
	<?php
}

Need a visual proof? Click here to view the WooCommerce Checkout page customization “before” and “after” screenshots.

WooCommerce Checkout Page Customization: “Before” and “After” Screenshots

Before

The WooCommerce Checkout page (Storefront theme) BEFORE applying snippets 1->10.

After

This is the WooCommerce Checkout Page AFTER applying snippets 1->10. As you can see we achieved a distraction-free, B2C focused, shipping-oriented, secure checkout layout.

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

15 thoughts on “WooCommerce: How to Customize Checkout For Conversions

  1. Any ideas how to align the ‘Edit Cart’ link right next to ‘Your Order’ heading? Been trying to figure that out for hours…

    1. You’ll need a bit of CSS for that

  2. Hello Rodolpho and congrats for the awesome job you are doing! I implemeted the codes for the three steps @ checkout, they work perfectly but the 3rd step is fullwidth not like step 1 and step 2, how can I make it like the other 2?

    1. You’d need a little CSS there

  3. Hi again,
    As i am using Astra theme, i would like to share the scripts i modified to make it work in Astra.
    To remove header and footer:

    add_action( 'wp', 'bbloomer_unhook_astra_functions' );
     
    function bbloomer_unhook_astra_functions() {
       if ( is_checkout() ) {
          remove_all_actions( 'astra_header' );
          remove_action( 'astra_before_content', 'woocommerce_breadcrumb', 10 );
          remove_action( 'astra_sidebar', 'astra_get_sidebar', 10 );
          remove_all_actions( 'astra_footer' );
       }
    }

    and for both the phone number and the edit cart link:

    add_action( 'woocommerce_review_order_after_payment', 'bloomer_phone_checkout_page' );
     
    function bloomer_phone_checkout_page() {
       ?>
       <img src="https://yoursite.com/badge.png">
       <p><center>Need checkout help? Live chat or give us a message at: <a href="tel:+1 2090000000">+1 2090000000</a></center></p>
       <?php
    }
    add_action( 'woocommerce_checkout_before_order_review', 'bbloomer_edit_cart_checkout' );
     
    function bbloomer_edit_cart_checkout() {
       echo '<a class="edit_cart_position" href="' . wc_get_cart_url() . '"><<< Edit Cart</a>';
    }

    And to make this work you have to do some styling, i did as what i like (i add it in the theme customizer additional css, but you can instead add a style.css file in your child theme):

    /*styling the edit cart link in checkout*/
    .edit_cart_position {
    	font-size: 16px;
    	color: white;
    	background: black;
      display: flex;
      padding: 0 0.5em;
    }
    /* for mobile or tablet*/
    @media(max-width:500px) {
    
    .edit_cart_position {
    	font-size: 16px;
    	color: white;
    	background: black;
      display: block;
      padding: 0 0.5em;
    }
    }
    /*End of styling the edit cart link in checkout*/

    I also used these codes: Moving coupon code below and visual steps without any problem.

    Thanks again Mr. Rodolfo for this amazing article and i hope you can help me achieve what i wrote in the previous comment 🙂

    1. Awesome!

      1. This works to keep the order review sticky with Astra.

        div#order_review.woocommerce-checkout-review-order {
          position: sticky !important;
          top: 0;
        }
        
        1. Cool

  4. Hi Mr. Rodolfo,
    Wow this is a great content thank you very much for sharing it.
    I tried most of them and it is working good, but yes couldn’t make the order_review sticky, and actually as i am using Astra theme i think i need to edit some actions..
    Question: Is it possible to add some text above the email form or address and such, i mean i am trying to do like shopify checkout page where for simplicity sake they write for example above the email form “Contact information” and above the address formS “Shipping address” ?? Maybe there are some hooks for that?!
    Thanks

    1. Sorry forgot to mention that i don’t want to use plugins, as they are breaking my payment gateways 🙂

      1. Sure, always use the Visual Hook Guide for the Checkout and you’ll find some hooks

  5. Wow. Much helpful article. Haven’t even thought about this. Great 🙂

    1. Awesome!

      1. Thanks, that is a great post

        The only thing that I am not convinced about is the always visible shipping address.
        In this case the User has to fill out two address forms. Usualy (if shipping and billing address is the same) he has only to fill out one.

        1. Sure, good idea. Everything shall be split-tested of course

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

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