Add Custom Checkout fields to Woocommerce

Here are a couple sample fields you can add to your theme’s functions file to create some Custom Fields on checkout for Woocommerce.

First, add the fields to checkout. There is also a conditional Birthday field…

/**
 * Add the field to the checkout
 */
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );

function my_custom_checkout_field( $checkout ) {

	// Student Name
    echo '<div id="my_custom_checkout_field"><h2>' . __('Student Name / Student Teacher') . '</h2>';

    woocommerce_form_field( 'student_name', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Student Name'),
        'placeholder'   => __('Student Name'),
		'required'      => true,
        ), $checkout->get_value( 'student_name' ));

   // Teacher Name

    woocommerce_form_field( 'student_teacher', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Student Teacher'),
        'placeholder'   => __('Student Teacher'),
		'required'      => true,
        ), $checkout->get_value( 'student_teacher' ));
	
	// Grade
		
		 woocommerce_form_field( 'grade', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Grade'),
        'placeholder'   => __('Grade'),
		'required'      => true,
        ), $checkout->get_value( 'grade' ));

    echo '</div>';
	
	
		// If in Birthday Book Category...	
		//Check if Book in Cart (UPDATE WITH YOUR PRODUCT ID)
		$book_in_cart = wordimpress_is_conditional_product_in_cart( 3702 );
		
		if ( $book_in_cart === true ) {
		  	woocommerce_form_field( 'child_birthday', array(
				'type'          => 'text',
				'class'         => array('my-field-class form-row-wide'),
				'label'         => __('Child\'s Birthday'),
				'placeholder'   => __('mm/dd/yyyy'),
				'required'      => true,
				), $checkout->get_value( 'child_birthday' ));
		} 

}

For the Birthday, check to see if it’s in the cart…

/**
 * Check if Conditional Product is In cart
 *
 * @param $product_id
 *
 * @return bool
 */
function wordimpress_is_conditional_product_in_cart( $product_id ) {
	//Check to see if user has product in cart
	global $woocommerce;
 
	//flag no book in cart
	$book_in_cart = false;
 
	foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
		$_product = $values['data'];
 
		if ( $_product->id === $product_id ) {
			//book is in cart!
			$book_in_cart = true;
 
		}
	}
 
	return $book_in_cart;
 
}

Process the checkout…

/**
 * Process the checkout
 */
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');

function my_custom_checkout_field_process() {
    // Check if set, if its not set add an error.
    if ( ! $_POST['student_name'] )
        wc_add_notice( __( '<strong>Student\'s name</strong> is a required field.' ), 'error' );
	if ( ! $_POST['student_teacher'] )
        wc_add_notice( __( '<strong>Teachers\'s name</strong> is a required field.' ), 'error' );
	if ( ! $_POST['grade'] )
        wc_add_notice( __( '<strong>Grade</strong> is a required field.' ), 'error' );
}

Save those fields!

/**
 * Save the fields
 */
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );

function my_custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['student_name'] ) ) {
        update_post_meta( $order_id, 'Student Name', sanitize_text_field( $_POST['student_name'] ) );
    }
	if ( ! empty( $_POST['student_teacher'] ) ) {
        update_post_meta( $order_id, 'Student Teacher', sanitize_text_field( $_POST['student_teacher'] ) );
    }
	if ( ! empty( $_POST['grade'] ) ) {
        update_post_meta( $order_id, 'Grade', sanitize_text_field( $_POST['grade'] ) );
    }
	if ( ! empty( $_POST['child_birthday'] ) ) {
        update_post_meta( $order_id, 'Child Birthday', sanitize_text_field( $_POST['child_birthday'] ) );
    }
}

Finally, display those fields on the order backend edit page…

/**
 * Display field value on the order edit page
 */
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );

function my_custom_checkout_field_display_admin_order_meta($order){
    echo '<p><strong>'.__('Student Name').':</strong> ' . get_post_meta( $order->id, 'Student Name', true ) . '</p>';
	echo '<p><strong>'.__('Student Teacher').':</strong> ' . get_post_meta( $order->id, 'Student Teacher', true ) . '</p>';
	echo '<p><strong>'.__('Grade').':</strong> ' . get_post_meta( $order->id, 'Grade', true ) . '</p>';
	echo '<p><strong>'.__('Child Birthday').':</strong> ' . get_post_meta( $order->id, 'Child Birthday', true ) . '</p>';
}

Bonus: Add those fields that go out in the email to the store owner…

In “admin-new-order.php” in the Woocommerce email template file, and after the do_action(‘woocommerce_email_customer_details’)

<p><strong><?php _e( 'Student\'s Name:', 'woocommerce' ); ?></strong> <?php echo get_post_meta( $order->id, 'Student Name', true ) ?></p>
<p><strong><?php _e( 'Teacher\'s Name:', 'woocommerce' ); ?></strong> <?php echo get_post_meta( $order->id, 'Teacher Name', true ) ?></p>
<p><strong><?php _e( 'Grade:', 'woocommerce' ); ?></strong> <?php echo get_post_meta( $order->id, 'Grade', true ) ?></p>

<?php if ( $order->child_birthday ) : ?>
	<p><strong><?php _e( 'Child Birthday:', 'woocommerce' ); ?></strong> <?php echo $order->child_birthday; ?></p>
<?php endif; ?>