I recently wrote about how to edit the existing WooCommerce checkout fields. That tutorial is useful if all you need to edit are the default fields that WooCommerce provides at checkout. If you are finding yourself requiring additional information from your customers, you may want to add a custom field to WooCommerce checkout process.
Note: This tutorial assumes that you have some knowledge of functions and actions. If you do not, it is not advisable to continue on your own.
All of the code provided below should be entered in your child theme’s functions.php file, or a site specific plugin. If you are using a theme’s functions.php, it is strongly suggested that you create a child theme first.
You can easily add custom fields to WooCommerce Checkout and edit existing fields with Conditional Woo Checkout Field Pro. Get Conditional Woo Checkout Field Pro
Add a Custom Checkout Field to WooCommerce
In the previous article about editing WooCommerce checkout fields, I highlighted the various properties that could be edited for each form field. Each of those properties can be used when adding a custom field to WooCommerce as well.
The first thing we need to do is add an action and function to the functions.php file. We can do this with the following code:
<?php /** * Add the field to the checkout page */ add_action( 'woocommerce_after_order_notes', 'some_custom_checkout_field' ); function some_custom_checkout_field( $checkout ) { echo '<div id="some_custom_checkout_field"><h2>' . __('My Field Header') . '</h2>'; woocommerce_form_field( 'some_field_name', array( 'type' => 'text', 'class' => array('my-field-class form-row-wide'), 'label' => __('My Field Label'), 'placeholder' => __('Some placeholder text to guide the customer'), 'required' => true, ), $checkout->get_value( 'some_field_name' )); echo '</div>'; } |
So this added a text field to the checkout page, which will look like this:
Since we set the field to be required, we’ll need to validate the field so that an error message is displayed if it is left blank.
<?php /** * Process the checkout */ add_action('woocommerce_checkout_process', 'some_custom_checkout_field_process'); function some_custom_checkout_field_process() { // Check if the field is set, if not then show an error message. if ( ! $_POST['some_field_name'] ) wc_add_notice( __( 'Please enter something here.' ), 'error' ); } ?> |
So far so good. We have added a custom field to WooCommerce checkout page, and we are checking to see if it is filled in before processing the order.
Now, the information that the customer enters into this field needs to be saved along with the rest of the order information when they check out. To do this, we will be using WordPress custom fields, which allows us to attach the custom information to this order.
<?php /** * Update the order meta with field value */ add_action( 'woocommerce_checkout_update_order_meta', 'some_custom_checkout_field_update_order_meta' ); function some_custom_checkout_field_update_order_meta( $order_id ) { if ( ! empty( $_POST['some_field_name'] ) ) { update_post_meta( $order_id, 'Some Field', sanitize_text_field( $_POST['some_field_name'] ) ); } } ?> |
The information will be saved as custom field Some Field, with whatever value the customer enters into that field. When you view the order details page, you will see this field like in the screenshot below.
Add a Custom Field to WooCommerce Order Emails
It would be nice to let your customer know that you received the information they ordered. Especially if it is critical to their order, as in the case of a customized product where the spelling of something might be important. You can do this by adding the custom information to the confirmation email that gets sent to them.
<?php /** * Add the field to order emails **/ add_filter( 'woocommerce_email_order_meta_keys', 'some_order_meta_keys' ); function some_order_meta_keys() { if (get_post_meta( get_the_ID(), 'Some Field')) { echo 'This is the custom information you entered in Some Field: ' . get_post_meta( get_the_ID(), 'Some Field', true) . '<br />'; } } ?> |
The following bit is somewhat redundant because we already made the form field required at checkout, so it will be filled out in this example.
if (get_post_meta( get_the_ID(), 'Some Field')) { |
However, if you decided not to make the field required, you could add this check to see if “Some Field” is filled in. If it is then the email will display the message with the field’s value. If it isn’t, then nothing extra will be displayed in the email.
You will also have to change ‘Some Field’ with whatever name you gave your custom field. Note that this should be the same value shown under the Name column in the Custom Field screenshot above.
Petra says
Nice tut! Maybe you have an answer to the following issue:
I want to display the billing data below the order table in checkout. But I have no clue how to reorder the checkout-page.
Kind regards!
Scott says
This would require editing the WooCommerce template files. Since you aren’t changing the functionality of anything you would only need to reorder the fields on the checkout page. I would caution you though that any changes made directly to the WooCommerce template files will be lost when the plugin is updated. If you are going to attempt this, there is a help guide that shows you how to not lose your changes here: http://docs.woothemes.com/document/template-structure/
If you need any help with this, I will be happy to discuss with you. Send an email over at http://surpriseazwebservices.com/contact if you would like some help.
Petra says
Thank you very much indeed!
Matthijs says
Hi, Thanx For the tutorial! it works great! exept one thing, i can’t get the new custom field in the ‘new order mail’ or any other e-mail to the customer. I paste the code in the function.php from my theme.
What do i do wrong? Maybe you can tell me?
Thanks in Advanced..
Scott says
Did you add the last block of code:
/**
* Add the field to order emails
**/
add_filter( 'woocommerce_email_order_meta_keys', 'some_order_meta_keys' );
function some_order_meta_keys() {
if (get_post_meta( get_the_ID(), 'Some Field')) {
echo 'This is the custom information you entered in Some Field: ' . get_post_meta( get_the_ID(), 'Some Field', true) . '
';
}
}
That should work for you. If not, try adding the code from this page instead: http://woodocs.wpengine.com/document/add-a-custom-field-in-an-order-to-the-emails/
/**
* Add the field to order emails
**/
add_filter('woocommerce_email_order_meta_keys', 'my_woocommerce_email_order_meta_keys');
function my_woocommerce_email_order_meta_keys( $keys ) {
$keys['How did you hear about us?'] = 'hear_about_us';
return $keys;
}
Adam Leis says
Great info, Scott. I wonder if you could help with my issue regarding this one. I have tried both versions to get the custom meta into the email (adding to the $key array, as well as directly getting the post meta via get_post_meta). I’ve made sure to use the correct key and value for the $key array, and I’ve been sending tests and checking variables used in the function. Your solution to use the get_post_meta uses the get_the_ID function, but no id is returning for me. Am I missing something? What variable(s) can I test for to get it working correctly.
Thanks very much!
Ego says
Thanks for the tutorial.
It works alright but how can I check if the custom field contains data and then add a fee if e.g. is filled ?
I tried some hooks like woocommerce_cart_calculate_fees
woocommerce_calculate_totals, woocommerce_review_order_after_shipping and woocommerce_checkout_process
but I need it to update totals before I click the confirm order button so the client can see the fee
Scott says
I haven’t tried to set a fee for a custom checkout field. These fields were set up to be more informational. For example, if someone wants to add engraving to a product the customer can enter the message to be engraved in this field. The field wouldn’t show up for any product in the cart because not all products are able to accept engraving.
I have seen some sites use this method by creating two products – one is the base product that is able to be engraved, and a second product, which is simply an up charge for engraving. The up charge for engraving product is the product that this conditional field would be applied to, so if someone purchases the product but doesn’t want it to be engraved, the up charge (and the conditional field) do not show up in the checkout.
Hope this helps.
Gabrielle says
Hi, is it possible to add 2 number input fields to :simple product, order pages(only values from inputs), and validate price on product page? After few weeks of fighting i added fields to product in my categories, but i can’t set price and save values ;/
Scott says
The methods discussed in this article specifically refer to adding a custom field to the checkout pages only – this doesn’t dive into adding a field to the product page.
However, if you are looking to have some inputs from customers only for certain products, you can try the Conditional Woo Checkout Field Plugin, which will display a field at checkout only if a particular product (or products) are in the customer’s cart.
This plugin doesn’t update the price of the order, however it will allow you to collect the information you require.
I hope this helps!
Inês Bessone says
How can I put two custom field to the checkout page.
Thanks
Scott says
You should be able to add a second field to the checkout page by simply duplicating the code in the functions above, and adjusting for the appropriate field name, message, etc.
If you would like, there is a plugin I sell that should be able to do what you’re looking for called Conditional Woo Checkout Field Pro. It’s relatively inexpensive, and might save you some headache.
This plugin will let you have up to five extra fields at checkout. The plugin does require you to specify which products it will display the fields for, so it can display both fields for only certain products, or if you enter in every product ID, you can have the fields display at checkout regardless of which products are being purchased.
Omer says
Thanks for your help, I have a problem that is
I use checkout by amazon or by paypal express, when user clicks on amazon or on pay pal , when control comes back on my site i have no checkout field, infect all form is gone just the order summary is listed, how can i show my extra created field?
Alezandr says
HI, I’m trying to display my custom field which i’ve created in product page, and i need it to show after customer made payment, in order details page.
I’ve trying to using hook, but nothing happened, can’t understand why, when i’m trying to var_dump or print_r variables i don’t get my custom code.
Here is the code….
add_action( ‘woocommerce_order_details_after_order_table’, ‘code_activation’, 10, 2);
function code_activation($order_id){
$order = new WC_Order($order_id);
$items = $order->get_items();
foreach ($items as $item) {
$product_name = $item[‘name’];
$product_id = $item[‘product_id’];
$product_variation_id = $item[‘variation_id’];
}
echo ‘‘.__(‘Activation code’).’: ‘ . get_post_meta( $order_id->id, ‘activation_code’, true ). ”;
}
I’ll be really appreciate for any help…
Katrina says
You rock so much for this!
Scott says
Glad it helped!
Anup says
This tutorial is awesome it helped me .i have one question how i can add those fields in email and recipt also….for now i can see only those fields in order view in meta box from admin panel i want those fields to be there in customer order recipt to….
Scott says
The last section in this tutorial “Add a Custom Field to WooCommerce Order Emails” should help get what you’re looking for.
Eder says
Hi, how to add this field in a new colunm in the admin orders.
Thanks!
Scott says
You would need to hook into
woocommerce_admin_order_data_after_shipping_address
, and adjust the CSS that controls the display of that meta box.I haven’t really tested it, but something like this should work:
In functions.php/site specific plugin, add:
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_admin_order_meta', 10, 1 );
function display_admin_order_meta($order){
echo '
if (metadata_exists( 'post', $order->id, get_option('Some Field') )) {
echo '
' . get_option("Some Field') . ':
' . get_post_meta( $order->id, get_option('Some Field'), true );
}
}
}
Then you would have to add the style to the admin pages, so that the columns are more narrow (so they’ll all fit in the space). Something like this should work:
#order_data .order_data_column {
width: 23%;
}
Yavuz says
Thank you so much for this. Is it also possible to add this field to be available on the web service side of woocommerce?
Scott says
I’m not sure what you mean by that? Where are you trying to add them?
Schalk says
Hi,
In the pro plugin demo, is there a way to add custom fields based on product quantity fields?
In order to collect names of attendees when selling tickets.
Thank you,
Jaydeep Akbari says
how to display custom field in in order success page
Tanmoy says
or add a field to the checkout page and we need something like a license key generator,
so when the people buy from us and the payment is done, they should get a license key from a data-bank automatically to their email address.please help me some
Scott DeLuzio says
You can do this with an add-on plugin like WooCommerce’s Software Add-On. Or, you can replace $checkout->get_value( ‘some_field_name’ ) in the first code sample with a value that pulls from either a random license key generator function, or a pre-set list of keys.
rizwan says
hi sir i need few help i want to call me custom field value on the check out page
i want create i custom field on check out page now i wan to call on the place of 100 please guide me how i can call the code for this .i really appreciate for this help thank you
function woo_add_cart_fee() {
global $woocommerce;
$woocommerce->cart->add_fee( __(‘Postag’, ‘woocommerce’), 100);
}
add_action( ‘woocommerce_before_calculate_totals’, ‘woo_add_cart_fee’ );