Add custom fields to WooCommerce product variations

Here's a simple way to add custom meta fields to WooCommerce Product Variations in PHP. Change your custom property per variant right from the native WooCommerce product editor.

There’s no end in sight for website owners’ desire to customize the behavior of their applications. Those who make WooCommerce their e-com platform of choice have plenty of flexibility to extend every nook and cranny of their site.

Today I’m looking to add a custom field to each WooCommerce product that will be utilized based on a condition at checkout, but the client needs the ability to modify the value at the variation level. I’m feeling very anti-plugin today, so we’re adding this functionality programmatically into the theme.

The end result will look like this:

Add the action hooks

The hooks required for this change are different than those used for adding the custom field to the parent product form, so follow along.

Copy these functions and filters into your functions.php or class file. In my case I’m adding a pricing discount field, so be sure to adjust any variable names to your situation.

/**
 * Add custom meta fields to the product view's pricing section
 */
public function add_product_pricing_meta_fields( $index, $variation_data, $variation ) {
	
	$discount_price = get_post_meta( $variation->ID, '_discount_price', true );
	
	$discount_price_args = array(
		'id' => '_discount_price['. $index .']',
		'class' => 'wc_input_discount_price',
		'wrapper_class' => 'form-row form-row-first',
		'label' => __('Discount Price', 'crafter'),
		'description' => ' ' . __( 'A discounted price that will be applied for qualified users.', 'crafter' ),
		'desc_tip' => true
	);
	
	if ( $discount_price >= 0 )
		$discount_price_args['value'] = $discount_price;
	
	woocommerce_wp_text_input( $discount_price_args );
}

/**
 * Save all product view custom meta fields
 *
 * @param $id int
 */
public function save_product_meta_fields( $variation_id, $index ) {
	
	$discount_price = ! empty( $_POST['_discount_price'] ) ? trim( $_POST['_discount_price'][$index] ) : '';
	
	update_post_meta( $variation_id, '_discount_price', $discount_price );
}

add_action( 
	'woocommerce_variation_options_pricing', 
	'add_product_pricing_meta_fields' ], 10, 3 
);
add_action( 
	'woocommerce_save_product_variation', 
	'save_product_meta_fields', 10, 2 
);

The actions specified here will add the field to the pricing section of each variation, but you can place your custom field into any of the other sections by altering the hook name.

Other variation option hooks:

woocommerce_variation_options_inventory
woocommerce_variation_options_dimensions
woocommerce_variation_options_tax
woocommerce_variation_options_download

Use the new custom field

To make use of your new custom variation field, just request it from the post_meta table like so:

$price = get_post_meta( $variation->get_id(), '_discount_price', true );

If you’re also implementing a price modifier like I was and need help with finding the right hooks to override pricing on the front-end, read my post on overriding a WooCommerce price.