Posted on

WooCommerce: Display Product-Specific T&C @ 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        Watch tutorial @ https://businessbloomer.com/?p=19055
 * @sourcecode    https://businessbloomer.com/?p=72828
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 3.3.1
 */
 
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 code?

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

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.

If you think this code saved you time & money, please join other Business Bloomer supporters and avail of 365 days of WooCommerce benefits. Thank you in advance :)

Need Help with WooCommerce?

Check out these free videos, tutorials and tips!

  • how-to-edit-woocommerce-with-php-snippets
  • woocommerce-hooks-add_action-list-visual
  • woocommerce-customize-single-product-page-PHP
  • woocommerce-customize-shop-page-PHP
  • woocommerce-advanced-customization
  • how-to-edit-woocommerce-cart
  • woocommerce-customize-checkout-page-PHP
  • woocommerce-email-customization
  • woocommerce-conditional-logic

Rodolfo Melogli

Author, WooCommerce expert, WordCamp speaker and Internet marketer, Rodolfo Melogli has worked as a WooCommerce freelancer since 2011. He helps entrepreneurs and developers overcome their WooCommerce nightmares :) Rodolfo is the organiser of WordCamp Dublin, the Dublin WooCommerce Meetup, the Dublin Ecommerce Meetup and the Dublin WordPress Meetup. He enjoys interacting with people, travelling and chasing tennis & soccer balls. Of course, he loves pizza too.

18 thoughts on “WooCommerce: Display Product-Specific T&C @ Checkout

  1. 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.

  2. 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' );
      		}
      	}
      }
      

      ???

    2. 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

    3. 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.

  3. 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 ๐Ÿ™‚

  4. 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 ๐Ÿ™‚

    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

    3. 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/

  5. 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!

  6. 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're writing code, please wrap it between: [php] code_here [/php]

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.