How to add a possibility for customers to provide their custom data to each product purchase. Example with names on T-Shirts

Product purchase

Please look on the screenshots below to understand what we are going to do step by step.

Step 1. The additional input field is added just before the Add to Cart button. A user can provide a name he would like on this T-shirt.

Step 2-3. The information provided by the user in the previous step will be displayed on the Cart and Checkout pages.

Step 3. It will be displayed on the Thank You page too.

Step 4. Finally, the order is published, shop managers will find the information on the Edit Order page near the associated order item.

Below is code

/*
 * Step 1. Add an input field just before the "Add to cart" button
 */
add_action( 'woocommerce_before_add_to_cart_button', 'misha_before_add_to_cart_field' );

function misha_before_add_to_cart_field() {
	global $product; // awesome - we have a global product object here

	// let's add the input field only for products in a specific category with "t-shirts" slug
	if ( !has_term('t-shirts', 'product_cat', $product->get_id() ) ) {
		return;
	}

	echo '<div class="misha-before-add-to-cart-field">
		<label for="name-on-t-shirt">Name on T-Shirt: </label>
		<input type="text" id="name-on-t-shirt" name="name-on-t-shirt" placeholder="Enter a name" maxlength="15">
	</div>';

}

/*
 * Step 2. Save the provided field value to the cart data
 */
add_filter( 'woocommerce_add_cart_item_data', 'misha_save_field_value_to_cart_data', 10, 3 );

function misha_save_field_value_to_cart_data( $cart_item_data, $product_id, $variation_id ) {

	if ( !empty( $_POST['name-on-t-shirt'] ) ) { // here could be another validation if you need
		$cart_item_data['name-on-t-shirt'] = sanitize_text_field( $_POST['name-on-t-shirt']);
	}

	return $cart_item_data;

}

/*
 * Step 3. Display "Name on T-shirt" on the pages: Cart, Checkout, Order Received
 */
add_filter( 'woocommerce_get_item_data', 'misha_display_field', 10, 2 );

function misha_display_field( $item_data, $cart_item ) {

	if ( !empty( $cart_item['name-on-t-shirt'] ) ) {
		$item_data[] = array(
			'key'     => 'Name on T-shirt',
			'value'   => $cart_item['name-on-t-shirt'],
			'display' => '', // in case you would like to display "value" in another way (for users)
		);
	}

	return $item_data;

}

/*
 * Step 4. Add the field value to the Order Item meta
 */
add_action( 'woocommerce_checkout_create_order_line_item', 'misha_add_order_item_meta', 10, 4 );

function misha_add_order_item_meta( $item, $cart_item_key, $values, $order ) {

	if ( !empty( $values['name-on-t-shirt'] ) ) {
		$item->add_meta_data( 'Name on a T-Shirt', $values['name-on-t-shirt'] );
	}

}