WooCommerce: Add Custom Field on Checkout Based on Product Quantity in Cart

In this tutorial, I will show you how to add dynamic checkout fields based on cart quantity on WooCommerce checkout page. The custom field will be multiply by product quantity, that means if a customer has 3 quantity in the cart then your custom field will repeat 3 times and display 3 fields on the checkout page.

Let’s say you have a booking system on your WooCommerce store and you want to capture the additional information at checkout if someone books for more than one quantity. For e.g., if you have Events/Workshops site and want to capture Name, Email, phone, and Address of everyone who attended your Event/Workshop and someone books for 3 quantity on your website then you need additional dynamic custom fields to capture the details of other 2 attendees. So if someone adds 3 quantity to the cart then the checkout page adds additional fields for other 2 attendees if 4 quantity added to the cart then it adds fields for other 3 attendees.

Within the following function, we will check how many quantities the user has in their cart and adds the additional fields to the checkout page if the quantity is more than 1. And save the field values to display it in the order in admin side.

Go to your functions.php file and add the following code at the end of the file or you can create your own plugin to add this function.

//Custom WooCommerce Checkout Fields based on Quantity
add_action( 'woocommerce_before_order_notes', 'person_details' );
function person_details($checkout) {
global $woocommerce;
$count = $woocommerce->cart->cart_contents_count;
$i = 1;
for($k=2; $k<= $count; $k++) {
$i++;
print ('<h3>Please enter details of attendee '.$i.'</h3>');
woocommerce_form_field( 'cstm_full_name'.$i, array(
'type'          => 'text',
'class'         => array('my-field-class form-row-wide'),
'label'         => __('Full name'),
'placeholder'   => __('Enter full name'),
),
$checkout->get_value( 'cstm_full_name'.$i ));
echo '<div class="clear"></div>';
woocommerce_form_field( 'cstm_phone'.$i, array(
'type'          => 'text',
'class'         => array('my-field-class form-row-first'),
'label'         => __('Phone'),
'placeholder'   => __('Enter phone number'),
),
$checkout->get_value( 'cstm_phone'.$i ));
woocommerce_form_field( 'cstm_email'.$i, array(
'type'          => 'email',
'class'         => array('my-field-class form-row-last'),
'label'         => __('Email address'),
'placeholder'   => __('Enter email address'),
),
$checkout->get_value( 'cstm_email'.$i ));
echo '<div class="clear"></div>';
woocommerce_form_field( 'cstm_address'.$i, array(
'type'          => 'textarea',
'class'         => array('my-field-class form-row-wide'),
'label'         => __('Full address'),
'placeholder'   => __('Enter full address'),
),
$checkout->get_value( 'cstm_address'.$i ));
}
}
/**
* Save value of fields
*/
add_action('woocommerce_checkout_update_order_meta', 'customise_checkout_field_update_order_meta');
function customise_checkout_field_update_order_meta($order_id) {
global $woocommerce;
$count = $woocommerce->cart->cart_contents_count;
$i = 1;
for($k=2; $k<= $count; $k++) {
$i++;
if (!empty($_POST['cstm_full_name'.$i])) {
update_post_meta($order_id, 'Name of Attendee'.$i, sanitize_text_field($_POST['cstm_full_name'.$i]));
}
if (!empty($_POST['cstm_phone'.$i])) {
update_post_meta($order_id, 'Phone of Attendee'.$i, sanitize_text_field($_POST['cstm_phone'.$i]));
}
if (!empty($_POST['cstm_email'.$i])) {
update_post_meta($order_id, 'Email of Attendee'.$i, sanitize_text_field($_POST['cstm_email'.$i]));
}
if (!empty($_POST['cstm_address'.$i])) {
update_post_meta($order_id, 'Address of Attendee'.$i, sanitize_text_field($_POST['cstm_address'.$i]));
}
}
}
/**
* Add fields to order emails
**/
add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys');
function my_custom_checkout_field_order_meta_keys( $keys ) {
$i = 1;
for($k=2; $k<= 50; $k++) {
$i++;
$keys[] = 'Name of Attendee'.$i;
$keys[] = 'Phone of Attendee'.$i;
$keys[] = 'Email of Attendee'.$i;
$keys[] = 'Email of Participant '.$i;
$keys[] = 'Address of Attendee'.$i;
}	
return $keys;
}

Dynamic custom fields on checkout page

Dynamic Custom Field on Checkout Based on Product Quantity 1

Custom Fields value on order page in admin

23 thoughts on “WooCommerce: Add Custom Field on Checkout Based on Product Quantity in Cart

  • July 24, 2018 at 6:56 am
    Permalink

    Hi Wasim, how are you?

    I used you code from post WooCommerce: Add Dynamic Custom Field on Checkout Based on Product Quantity in Cart and it works perfectly. However, how do i change the field from optional to required?

    Thank you in advance!

    Reply
    • July 29, 2018 at 9:58 am
      Permalink

      Dear Wan,

      Just add ‘required’ => true, to make a field required.

      For Example:

      woocommerce_form_field( 'cstm_full_name'.$i, array(
      'type'          => 'text',
      'class'         => array('my-field-class form-row-wide'),
      'label'         => __('Full name'),
      'placeholder'   => __('Enter full name'),
      'required' => true,
      ),
      $checkout->get_value( 'cstm_last_name'.$i ));
      
      Reply
      • July 31, 2018 at 4:19 am
        Permalink

        Hi Wasim,

        Thank you so much for helping me! Will get back to you if there is anything. Wish you all the best in anything you do!

        Wan Ahmad

        Reply
  • February 8, 2019 at 5:47 pm
    Permalink

    This is great, how can this be altered for the Woocommerce Bookings extension?

    Reply
    • February 28, 2019 at 1:58 pm
      Permalink

      Hey Max,

      This plugin can’t be altered for Woocommerce Booking extension as it has many other features. This snippet is only getting other peoples details if there are multiple quantities in the cart.

      Reply
  • February 10, 2019 at 2:32 am
    Permalink

    Hey Wasim,
    Thanks so much for your post, that’s exactly what I am trying to do.
    I copied your code in functions.php but it didn’t work for me.
    I am just starting with Woocommerce, so I appreciate any help you can give me on how I can make this work.
    Do I need to add anything else for this to work?
    Regards,
    Leon

    Reply
  • June 4, 2019 at 1:11 pm
    Permalink

    Hi Wasim

    We’ve added the code above to our functions.php. Now we want to display the fields in the confirmation e-mail. How can we do this?

    Thanks for your feedback and greetings
    Larissa

    Reply
    • June 4, 2019 at 6:55 pm
      Permalink

      Hello Larissa,

      Please use the following snippet to add fields in the order notification email.

      /**
      * Add the field to order emails
      **/
      add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys');
      function my_custom_checkout_field_order_meta_keys( $keys ) {
      $i = 1;
      for($k=2; $k<= 50; $k++) {
      $i++;
      $keys[] = 'Name of Attendee'.$i;
      $keys[] = 'Phone of Attendee'.$i;
      $keys[] = 'Email of Attendee'.$i;
      $keys[] = 'Email of Participant '.$i;
      $keys[] = 'Address of Attendee'.$i;
      }	
      return $keys;
      }
      

      I also have added this snippet in the post. Please check complete code in the post above.

      Reply
      • June 5, 2019 at 1:28 pm
        Permalink

        Hi Wasim

        Thank’s for your feedback.
        I’ve added the snippet like this:
        _____________________________________

        get_formatted_billing_full_name() ); ?>
        <?php

        /*
        * @hooked WC_Emails::order_details() Shows the order details table.
        * @hooked WC_Structured_Data::generate_order_data() Generates structured data.
        * @hooked WC_Structured_Data::output_structured_data() Outputs structured data.
        * @since 2.5.0
        */
        do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );

        /*
        * @hooked WC_Emails::order_meta() Shows order meta data.
        */
        do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );

        /*
        * @hooked WC_Emails::customer_details() Shows customer details
        * @hooked WC_Emails::email_address() Shows email address
        */
        do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );

        /*
        * @hooked WC_Emails::email_footer() Output the email footer
        */
        do_action( 'woocommerce_email_footer', $email );

        add_filter(‘woocommerce_email_order_meta_keys’, ‘my_custom_checkout_field_order_meta_keys’);
        function my_custom_checkout_field_order_meta_keys( $keys ) {
        $i = 1;
        for($k=2; $k<= 50; $k++) { $i++; $keys[] = 'Name of Attendee'.$i; $keys[] = 'Phone of Attendee'.$i; $keys[] = 'Email of Attendee'.$i; $keys[] = 'Email of Participant '.$i; $keys[] = 'Address of Attendee'.$i; } return $keys; }
        _____________________________________

        But unfortunately doesn't work.

        Thank's for your help and greetings
        Larissa

        Reply
        • June 6, 2019 at 5:50 pm
          Permalink

          Hello Larissa,

          It Looks Like you added the snippet in Woocommerce email template. You need to add this snippet in function file where you added other code to display fields on the checkout. Also, replace ‘Name of Attendee’, ‘Phone of Attendee’, ‘Email of Attendee’, ‘Email of Participant ‘, ‘Address of Attendee’ with your field names.

          Reply
  • June 8, 2019 at 12:38 am
    Permalink

    Hi Wasim, thanks for sharing this code snippet for custom repeater field. I used it slightly modified (i=0, k=1) as the person booking the event will be a parent and booking for their children so i need to collect names, age for all children. your code has been very helpful.

    Now, how would you display this on the order page? I know how to display for one person, not in loop.. Can you help pls?

    Reply
  • June 8, 2019 at 2:38 am
    Permalink

    Hi Wasim, not sure if my previous msg went through..Thanks for sharing this code, very helpful! I’d like to see these fields i nhe order form as well, how can I do that?

    Reply
  • June 8, 2019 at 8:44 am
    Permalink

    One more question, IS this how you would add a drop down in this repeater field?

    woocommerce_form_field( ‘participant_gender’.$i, array(
    ‘type’ => ‘select’,
    ‘class’ => array(‘my-field-class form-row-last’),
    ‘label’ => __(‘Gender’),
    ‘options’ = array(
    ” => __( ‘Select’ ),
    ‘Male’ => ‘Male’,
    ‘Female’ => ‘Female’),
    ),
    $checkout->get_value( ‘participant_gender’.$i ));

    Reply
  • June 14, 2019 at 11:50 pm
    Permalink

    Hi there. This works so very well except that although highlighting the fields in the additional inforamtion section after adding the required = true, it will still let the user skip through to checkout. Any reason why that you can think of?

    Reply
    • June 15, 2019 at 1:35 pm
      Permalink

      You need to add validation for the required field.

      For Example:

      function person_details($checkout) {
      global $woocommerce;
      $count = $woocommerce->cart->cart_contents_count;
      $i = 1;
      for($k=2; $k<= $count; $k++) {
      $i++;
      print ('Please enter details of attendee '.$i);
      woocommerce_form_field( 'cstm_full_name'.$i, array(
      'type'          => 'text',
      'class'         => array('my-field-class form-row-wide'),
      'label'         => __('Full name'),
      'placeholder'   => __('Enter full name'),
      'required' => true,
      ),
      $checkout->get_value( 'cstm_full_name'.$i ));
      }
      }
      /**
      * For data validation of the custom field.
      */
      add_action('woocommerce_checkout_process', 'customise_checkout_field_process');
      function customise_checkout_field_process() {
      global $woocommerce;
      $count = $woocommerce->cart->cart_contents_count;
      $i = 1;
      for($k=2; $k<= $count; $k++) {
      $i++;
      // if the field is set, if not then show an error message.
      if (!$_POST['cstm_full_name'.$i]) wc_add_notice(__('Full name of ATTENDEE '.$i.' is a required field.') , 'error');
      }	
      }
      
      Reply
  • July 15, 2019 at 12:20 pm
    Permalink

    Thank you for this code, it helped me a lot!
    But for some reason I have encountered an issue showing the data in admin order details page, is there something missing in the code?

    Thanks!

    Reply
  • July 22, 2019 at 1:35 am
    Permalink

    Hello Wasim, thanks for your great blog post. Is it possible to limit limit this function to particular items in the cart? E.g. I’d like to add this custom field for some product IDs, but not other product IDs. Thanks

    Reply
  • September 10, 2019 at 2:05 pm
    Permalink

    Hi there. This is exactly what I was looking for, thanks so much for sharing.
    All working as expected apart from the additional fields are not showing on the order admin page. They show on the checkout and emails, just not inside the order detail page. Any ideas why this may be the case?
    Thanks again,

    Reply
  • January 31, 2020 at 3:31 pm
    Permalink

    Hi Wasim,
    thank you for your work, I was looking for this kind of code for a long time.
    I have a little problem, I receive informations on emails, it’s perfect but I can’t retrieve the informations on admin order. I don’t have any informations about this fields.
    If you can help me with that.
    I really thank you.

    Reply
    • March 11, 2020 at 2:49 pm
      Permalink

      Got the exact same issue, would be super nice if you could help with that part !
      Thank you

      Reply

Leave a Reply

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

More in WooCommerce
checkout
How to Hide Fields on Checkout Page for specific Product in the Cart in Woocommerce

Today one of our client wanted to hide the specific field on the checkout page for a specific product contained

Close