When going legal… you need proof. Accepting the “Terms and Conditions” on the checkout is required in order to place an order – but how can you, WooCommerce store admin, “prove” that the Terms and Conditions were actually ticked by the customer?
One of the solutions might be to save such acceptance in the database and print the acceptance on the order admin (and maybe on the customer invoice as well). So, here’s a quick PHP snippet you can simply copy and paste in your child theme’s functions.php file in order to (1) save and (2) print the choice on the Single Order Admin page. Enjoy!

PHP Snippet: Save “Terms & Conditions” Customer Acceptance @ WooCommerce Checkout
/**
* @snippet Save "Terms and Conditions" @ Checkout - WooCommerce
* @how-to businessbloomer.com/woocommerce-customization
* @author Rodolfo Melogli, Business Bloomer
* @compatible WooCommerce 6
* @community https://businessbloomer.com/club/
*/
// 1. Save T&C as Order Meta
add_action( 'woocommerce_checkout_update_order_meta', 'bbloomer_save_terms_conditions_acceptance' );
function bbloomer_save_terms_conditions_acceptance( $order_id ) {
if ( $_POST['terms-field'] ) update_post_meta( $order_id, '_terms_accepted', esc_attr( $_POST['terms-field'] ) );
}
// 2. Display T&C @ Single Order Page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'bbloomer_display_terms_conditions_acceptance' );
function bbloomer_display_terms_conditions_acceptance( $order ) {
if ( get_post_meta( $order->get_id(), '_terms_accepted', true ) == 1 ) {
echo '<p><strong>Terms & Conditions: </strong>accepted</p>';
} else echo '<p><strong>Terms & Conditions: </strong>N/A</p>';
}
Hi Rodolfo,
Great site, I love the snippets and tutorials.
I have created a new HPOS compatible version using the “sanitised” data that Woocommerce captures from the form.
https://gist.github.com/diegomox/f3df8fa17fe8f330403d7369e6968237
Nice, well done
Works great. Thank you
Awesome
I use Code Snippets for stuff like this instead of using the functions.php file. I found that you have to select “Run Everywhere” before enabling the snippet. If not you’ll get a N/A where it should say accepted.
Might be good to point that out!
Cheers!
Thank you
Hi Rodolfo,
Given the last 2 comments since Feb 2022 I’m wondering if the order printing is the same for all?
I have checked database and it does appear that the value is being saved in postmeta table as meta_key = terms , meta_value = 1, however I an only getting display as N/A printed in the Order Details.
Regards
Tom
Sorry Thomas, try with this new version please
Hello Rodolfo,
I’ve used your other tutorial to add custom acceptance boxes for the checkout page.
I’ve added privacy policy, terms, and 2 other (last two are not required but I need to have the information if it have been checked or not)
Checkboxes are working just fine, but when I try to save the state of the checkbox (accepted or not) the values I’m getting in order are always N/A.
My code is copied from you, I’ve changed only some names
Hi Lukasz, maybe just change “on” to 1. I will edit my snippet as well. Let me know
Hi Rodolfo,
I love this snippet but sometime between Feb 8th and March 8th it stopped working. I don’t know if it’s because of a Word Press update, but could you please look into it?
The field is created in the order meta, but it is not recording acceptance. The Terms and Conditions are a required field and will not let you proceed with order if not selected, however, the plugin is not recording the “accepted” – it always returns “N/A”
Thank you in advance for your help!
And after March 8th it came back to work? What happened on Feb 8th on your website?
How to “default Checkbox makes as a marked ” on the checkout page?
Hello Dial, 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!
where can i find the proof of acceptance in database? like copy of the proof
It’s saved into the order custom field “terms”
You should give credit to Remi Corson. The code here was obviously copied from his blog post which he wrote in 2014. It’s not cool to copy someone’s codes without crediting them.
Thanks for your feedback Joe!
Hi Rodolfo, thanks for the code.
When i export the orders , it write “on”. IS it possibile to change it with “accepted”?
Thanks
Michele
Hi Michele, 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!
Perfect snippet! thanks! But is it allso possible to print the Terms & Conditions Acceptance on the invoice ?
Ingo, 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!
Appears to add N/A to all past orders, any ideas?
Correct Neil, that’s what the second part of the snippet does. You can remove the “else” bit completely and that won’t happen. Hope this helps
Hi
This code is terrific and just what i needed I am trying to export all of the orders using a plugin called. WooCommerce Customer / Order CSV Export
I need to be able to assign an ID to this function how would I do that.
Many thanks
Nick
Hey Nick, 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. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R
Below is my code.
I’m trying to add a non-required checkbox to my checkout, and return this result in the order page.
Every time, I get N/A.
Any insight to why?
Apologies for my multiple comments.
[php]
/**
*Add Signature opt-out policy tick box at checkout
*/
add_action( ‘woocommerce_review_order_before_submit’, ‘bbloomer_add_checkout_sign_optout_policy’, 9 );
function bbloomer_add_checkout_sign_optout_policy() {
woocommerce_form_field( ‘sign_optout_policy’, array(
‘type’ => ‘checkbox’,
‘class’ => array(‘form-row signoptout’),
‘label_class’ => array(‘woocommerce-form__label woocommerce-form__label-for-checkbox checkbox’),
‘input_class’ => array(‘woocommerce-form__input woocommerce-form__input-checkbox input-checkbox’),
‘required’ => false,
‘label’ => ‘I Opt-Out of Signature Upon Delivery and understand all Terms.’,
));
}
/**
* Save “Terms and Conditions” Acceptance Upon Checkout – WooCommerce
*/
// 1. Save T&C as Order Meta
add_action( ‘woocommerce_checkout_update_order_meta’, ‘bbloomer_save_terms_conditions_acceptance’ );
function bbloomer_save_terms_conditions_acceptance( $order_id ) {
if ( $_POST[‘sign_optout_policy’] ) update_post_meta( $order_id, ‘sign_optout_policy’, esc_attr( $_POST[‘sign_optout_policy’] ) );
}
// 2. Display T&C @ Single Order Page
add_action( ‘woocommerce_admin_order_data_after_billing_address’, ‘bbloomer_display_terms_conditions_acceptance’ );
function bbloomer_display_terms_conditions_acceptance( $order ) {
if ( get_post_meta( $order->get_id(), ‘sign_optout_policy’, true ) == ‘on’ ) {
echo ‘Terms & Conditions: accepted’;
} else echo ‘Terms & Conditions: N/A’;
}
[\php]
Sorry Ryan, I can’t help with custom coding/troubleshooting here via the comments. Thanks for your understanding 🙂
Hi, how to add privacy policy on this principle?
The condition works privacy_policy I always have n / a.
[PHP]
/**
* @snippet Save “Terms and Conditions” Acceptance Upon Checkout – WooCommerce
* @how-to businessbloomer.com/woocommerce-customization
* @source https://businessbloomer.com/?p=74053
* @author Rodolfo Melogli, Business Bloomer
* @compatible Woo 3.3.4
*/
// 1. Save T&C as Order Meta
add_action( ‘woocommerce_checkout_update_order_meta’, ‘bbloomer_save_terms_conditions_acceptance’ );
function bbloomer_save_terms_conditions_acceptance( $order_id ) {
if ( $_POST[‘terms’] ) update_post_meta( $order_id, ‘terms’, esc_attr( $_POST[‘terms’] ) );
}
add_action( ‘woocommerce_admin_order_data_after_billing_address’, ‘bbloomer_display_terms_conditions_acceptance’ );
function bbloomer_display_terms_conditions_acceptance( $order ) {
if ( get_post_meta( $order->get_id(), ‘terms’, true ) == ‘on’ ) {
echo ‘Regulamin: zaakceptowany’;
} else echo ‘Regulamin: N/A’;
}
add_action( ‘woocommerce_checkout_update_order_meta’, ‘bbloomer_save_privacy_policy_acceptance’ );
function bbloomer_save_privacy_policy_acceptance( $order_id ) {
if ( $_POST[‘polityka’] ) update_post_meta( $order_id, ‘polityka’, esc_attr( $_POST[‘polityka’] ) );
}
add_action( ‘woocommerce_admin_order_data_after_billing_address’, ‘bbloomer_display_privacy_policy_acceptance’ );
function bbloomer_display_privacy_policy_acceptance( $order ) {
if ( get_post_meta( $order->get_id(), ‘polityka’, true ) == ‘on’ ) {
echo ‘Polityka prywatności: zaakceptowany’;
} else echo ‘Polityka prywatności: N/A’;
}
[/PHP]
Hey Bartek, thanks so much for your comment! Do you have a checkbox field with name=politika on the checkout page? 🙂
I too am seeing N/A every time. The checkbox field name I set is present on the page.
Not sure what I am missing.
This is really a great code, but it is not to get GDPR complaint (in my opinion). Since you pay for a service, you will give your data under the contractual or legal basis. I am not an expert about it, but I have read a lot about GDPR over the last week so I wanted to share my opinion. This is however very good to confirm that customers are not minor!
Anwyhow, I do loooove all the work you’re sharing with use!!!
Yes Raluca, I totally agree 🙂 Thank you!
Hi Rodolfo,
Great site, I love the snippets and tutorials. For this one there is an error in the code which cause the error ‘id was called incorrectly. order properties should not be accessed directly’ cause by part 2:
Your Snippet
The following correction $order->get_id() will solve the error.
Chris, excellent stuff! Thank you 🙂
Since the checkout can’t be completed without checking the terms (which is the default behaviour of WooCommerce if a terms page is set) this shouldn’t be needed for GDPR compliance.
Yep, I agree Sven, thanks for that 🙂 This might apply to specific businesses that need proof however, but for different reasons than GDPR.
Did it!! Thanks for this snippet, Rodolfo, it worked perfectly 😀
In my case it’s a good idea since parents need to share some of their children info.
Now that I’m reading the GDPR article you wrote I realized that maybe it would be interesting to do the same with the acceptance of privacy policy (since it need to be in the checkout page), would it be possible to know what changes should I make to this code??
Thanks again!!
Excellent Monica 🙂 You can simply duplicate the snippet and change it slightly to target the privacy policy input field “name” and that should save as well. Have fun!
Thankyou Rodolfo!
🙂
Great job !!!
I alreay follow your steps for GDPR in order to make my shop « legal ».
Keep the good work 😉
Great! Thanks for your feedback Stan 🙂
Hi Rodolfo, another great post!! thank you!! do you think we can put that line in the order confirmation email? can you suggest the code snippet?
thank you
Angelo
Hello Angelo, thanks a million for your comment! This tutorial might help: https://businessbloomer.com/woocommerce-add-extra-content-order-email/
Hi Rodolfo,
isn’t the fact that T&C is required field enough of the proof? How can somebody not agree to a required checkbox? Is this really necessary?
Best regards.
Canagon, thanks so much for your comment! In my view, the T&C acceptance should also be printed in the customer email as well, so that both parties are aware of that. This is not required for all businesses, but some might need this extra care 🙂