WooCommerce: Per-Product Terms & Conditions @ Checkout

A freelance client sells two distinct products on the same website: a membership and an online course. Two different audiences, different formats and… different Terms & Conditions.

The goal was therefore to display the “Terms & Conditions” checkbox on the Checkout page based on the product in the cart. Once again, we’re going to use Conditional Logic. With that, the snippet is pretty easy to code!

WooCommerce: Conditional Terms & Conditions @ Checkout

PHP Snippet: Terms & Conditions by Product – WooCommerce Checkout

/**
 * @snippet       Terms & Conditions by Product - WooCommerce Checkout
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 3.6.5
 * @community     https://businessbloomer.com/club/
 */
  
add_action( 'woocommerce_review_order_before_submit', 'bbloomer_add_checkout_per_product_terms', 9 );
   
function bbloomer_add_checkout_per_product_terms() {
 
// Show Terms 1
$product_id_1 = 522;
$product_cart_id_1 = WC()->cart->generate_cart_id( $product_id_1 );
$in_cart_1 = WC()->cart->find_product_in_cart( $product_cart_id_1 );
 
if ( $in_cart_1 ) {
      
?>
  
<p class="form-row terms wc-terms-and-conditions">
<label class="woocommerce-form__label woocommerce-form__label-for-checkbox checkbox">
<input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox" name="terms-1" <?php checked( apply_filters( 'woocommerce_terms_is_checked_default', isset( $_POST['terms-1'] ) ), true ); ?> id="terms-1"> <span>I agree to <a href="___" target="_blank">terms-1</a></span> <span class="required">*</span>
</label>
<input type="hidden" name="terms-1-field" value="true">
</p>
  
<?php
 
}
 
// Show Terms 2
$product_id_2 = 2152;
$product_cart_id_2 = WC()->cart->generate_cart_id( $product_id_2 );
$in_cart_2 = WC()->cart->find_product_in_cart( $product_cart_id_2 );
 
if ( $in_cart_2 ) {
      
?>
 
<p class="form-row terms wc-terms-and-conditions">
<label class="woocommerce-form__label woocommerce-form__label-for-checkbox checkbox">
<input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox" name="terms-2" <?php checked( apply_filters( 'woocommerce_terms_is_checked_default', isset( $_POST['terms-2'] ) ), true ); ?> id="terms-2"> <span>I agree to <a href="____" target="_blank">terms-2</a></span> <span class="required">*</span>
</label>
<input type="hidden" name="terms-2-field" value="true">
</p>
  
<?php
 
}
 
}
  
// Show notice if customer does not tick either terms
 
add_action( 'woocommerce_checkout_process', 'bbloomer_not_approved_terms_1' );
add_action( 'woocommerce_checkout_process', 'bbloomer_not_approved_terms_2' );
  
function bbloomer_not_approved_terms_1() {
    if ( $_POST['terms-1-field'] == true ) {
      if ( empty( $_POST['terms-1'] ) ) {
           wc_add_notice( __( 'Please agree to terms-1' ), 'error' );         
      }
   }
}
 
function bbloomer_not_approved_terms_2() {
   if ( $_POST['terms-2-field'] == true ) {
      if ( empty( $_POST['terms-2'] ) ) {
         wc_add_notice( __( 'Please agree to terms-2' ), 'error' );         
      }
   }
}

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

  • WooCommerce: Cart and Checkout on the Same Page
    This is your ultimate guide – complete with shortcodes, snippets and workarounds – to completely skip the Cart page and have both cart table and checkout form on the same (Checkout) page. But first… why’d you want to do this? Well, if you sell high ticket products (i.e. on average, you sell no more than […]
  • WooCommerce: Disable Payment Method If Product Category @ Cart
    Today we take a look at the WooCommerce Checkout and specifically at how to disable a payment gateway (e.g. PayPal) if a specific product category is in the Cart. There are two tasks to code in this case: (1) based on all the products in the Cart, calculate the list of product categories in the […]
  • WooCommerce: Add Privacy Policy Checkbox @ Checkout
    Here’s a snippet regarding the checkout page. If you’ve been affected by GDPR, you will know you now need users to give you Privacy Policy consent. Or, you might need customer to acknowledge special shipping requirements for example. So, how do we display an additional tick box on the Checkout page (together with the existing […]
  • WooCommerce: Redirect to Custom Thank you Page
    How can you redirect customers to a beautifully looking, custom, thank you page? Thankfully you can add some PHP code to your functions.php or install a simple plugin and define a redirect to a custom WordPress page (as opposed to the default order-received endpoint). This is a great way for you to add specific up-sells, […]
  • WooCommerce: Disable Payment Gateway by Country
    You might want to disable PayPal for non-local customers or enable a specific gateway for only one country… Either way, this is a very common requirement for all of those who trade internationally. Here’s a simple snippet you can further customize to achieve your objective. Simply pick the payment gateway “slug” you want to disable/enable […]

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

37 thoughts on “WooCommerce: Per-Product Terms & Conditions @ Checkout

  1. Hi there, is it possible to adjust this so that it shows for all products in a category as opposed to just products by ID?

    1. Hello Gina thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  2. Hi, would it be difficult to change the condition based on value in the cart ?
    I want to display or not the text on checkout based on the amount in the basket.
    For example if amount in the basket is < 100 $ than it shows text "Free delivery from 200 $"
    If in the basket is more than 200 $ then the text disepear.

  3. HI there,

    How would I add multiple products to any 1 terms? E.g. every time Product A, B and F are in basket, terms 2 should show.

    Thanks in advance, think this is the workaround we’ve been searching for!

    1. Hello Adriana, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  4. hi, can i ask beginner question, now terms-1 and terms-2 are the WP pages title?
    THANK U in advance

    1. No problem. No, you find an A HREF tag inside the snippet where you can enter the URL of each page

  5. Does this code work with WC 4 ?

    1. Sure, why not?

  6. Just tried this, and it doesn’t appear to be doing anything. Maybe it doesn’t work with bookable product IDs (woocommerce bookings)?

    1. Should work for any product type. Try to disable theme and all plugins but Woo and Woo Bookings and see if it works

  7. Seems to work great. thanks for posting this!

    1. Nice!

  8. Hi Rodolfo, thank you so much for making this code freely accessible for us! I was wondering if there is a way to apply specific terms & conditions to products that are downloadable? So ‘if a product is downloadable, show these terms’. I understand if you can’t answer such specific questions, but my knowledge of PHP is too limited to assess the level of complexity of my question. ^^

    1. Hi Nanieke, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

      1. You can use the “is_downloadable” logic.

        Example:

        if ($product->is_downloadable('yes')) {
            // Your Logic.
        }else{
            // Your Logic.
        }
  9. It appears that this only works if both checkboxes are visible and checked. So if a customer is buying only one product, and the checkout page shows only one checkbox, the form won’t submit because it wants the missing 2nd checkbox to be checked. This is the expected behavior?

    1. You’re right Arp ๐Ÿ™‚ Snippet has now been revised.

  10. In the last part where you show a notice if user doesn’t check the box:

    add_action(‘woocommerce_checkout_process’, ‘bbloomer_not_approved_terms_1’);

    … it is checking for that value every time a user goes to Checkout.
    If user didn’t add these items to their Cart, it shouldn’t tell them they didn’t tick the box.

    We need to add the product checking logic into this function as well, or else the Checkout will always be looking for the field values.

    Would you recommend writing a reusable function which will check if the product is in the cart? I’m thinking it would return true if product is in there. Then we could write an if() statement call to it from both actions. Is that correct?

    1. Something like this:

      function tc_product_is_in_cart( $product_id ){
      
      	$product_cart_id = WC()->cart->generate_cart_id( $product_id );
      	$in_cart = WC()->cart->find_product_in_cart( $product_cart_id );
      
      	if ( $in_cart ) {
      		return true;
      	}
      
      	return false;
      }
      
      function bbloomer_add_checkout_tickbox() {
      	if ( tc_product_is_in_cart(522) ) {
      	?>
      	(terms-1 html code goes here)
      	<?php
      	}
      
      	if ( tc_product_is_in_cart(2152) ) {
      	?>
      	(terms-2 html code goes here)
      	<?php
      	}
      }
      
      function bbloomer_not_approved_terms() {
      	if ( tc_product_is_in_cart(522) ) {
      		if ( empty( $_POST['terms-1'] ) ) {
              		wc_add_notice( __( 'Please agree to terms-1' ), 'error' );
      		}
      	}
      
      	if ( tc_product_is_in_cart(2152) ) {
      		if ( empty( $_POST['terms-2'] ) ) {
              		wc_add_notice( __( 'Please agree to terms-2' ), 'error' );
      		}
      	}
      }
      

      ???

      1. Alex, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

    2. I’m seeing this too. I set it up two different products, like the demo. If one is in the cart, the function is still checking to see if BOTH checkboxes are checked.

      So this solution only works if both products are in the cart.

  11. Hi Rodolfo,
    Your articles have been incredibly helpful – thank you! On the above, the second set of terms only worked for me when I removed the “a” from “if ( $in_cart_2a )”
    Thanks again!

    1. Thank you Heather! Typo has now been removed, you’re a star ๐Ÿ™‚

  12. Hi Rodolfo —

    Thank you so much for this code! It’s working great with my simple products. I also have a variable product that I’d like to setup. How would I specify that product ID? When I set the $product_id_2 = 6833 (the variation ID), it does not work. Is there additional code to accommodate a variable product?

    Thanks,
    Kari

    1. Hey Kari, thanks so much for your comment! Each variation has a common parent ID, you should use that ๐Ÿ™‚

      1. Hello,
        Unfortunately, I couldn’t run what Kari said on products with variations. I used common ID and variation ID but it still didn’t work. Do you have any advice?
        Thank you.

    2. Hi Rodolfo — I should have mentioned that I tried using the parent product and that also did not work. It seems like when you’re checking what’s in the cart, you’d have to specify not only the parent product ID, but also the variation ID?

      Thanks,
      Kari

      1. Uhm, maybe the find_product_in_cart only works with simple product? You can check if a product is in the cart with a foreach alternatively, like I did here: https://businessbloomer.com/woocommerce-apply-coupon-programmatically-product-cart/

  13. Hi Rodolfo,
    Thank you very much.
    I love your Visual Guides.
    About this snippet, I am a newbie in PHP, and I don’t understand 100% the line:
    if ( ! empty( $_POST[‘terms-2’] ) && empty( $_POST[‘terms-2’] ) )

    I think is like “If not terms-2 is empty and terms-2 is empty” You can help me with that? How I must interpret it?

    Regards,
    Urano

    1. Oops, you’re right Urano – snippet updated ๐Ÿ™‚ Thank you!

  14. Please help i have tried to use it in storefront theme but it isnt working for me

    1. Pankaj, thanks so much for your comment! Unfortunately this is custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~R

    2. Hi, maybe you have problem because there are conditions only for products with id 522 and 2152

      $product_id_2 = 2152;
      $product_id_1 = 522;

      Just delete the whole condition ๐Ÿ™‚

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 *