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
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */
  
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 this snippet?

You can place PHP snippets at the bottom of your child theme functions.php file (delete "?>" if you have it there). CSS, on the other hand, goes in your child theme style.css file. Make sure you know what you are doing when editing such files - if you need more guidance, please take a look at my free video tutorial "Where to Place WooCommerce Customization?"

Does this snippet (still) work?

Please let me know in the comments if everything worked as expected. I would be happy to revise the snippet if you report otherwise (please provide screenshots). I have tested this code with Storefront theme, the WooCommerce version listed above and a WordPress-friendly hosting on PHP 7.3.

If you think this code saved you time & money, feel free to join 14,000+ WooCommerce Weekly subscribers for blog post updates or 250+ Business Bloomer supporters for 365 days of WooCommerce benefits. Thank you in advance :)

Need Help with WooCommerce?

Check out these free video tutorials. You can learn how to customize WooCommerce without unnecessary plugins, how to properly configure the WooCommerce plugin settings and even how to master WooCommerce troubleshooting in case of a bug!

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.

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? Support? Leave your Comment Now!
_____

If you are writing code, please wrap it between shortcodes: [php]code_here[/php]. Failure to complying with this (as well as going off topic, not writing in English, etc.) will result in comment deletion. 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 BloomerArmada to get blog comment reply priority, ask me 1-to-1 WooCommerce questions and enjoy many more perks. Thank you :)

Your email address will not be published.