How to add Affiliate Links to Woocommerce Variations

Posted by & filed under Tutorials, Uncategorized, Web Design Tutorials, Wordpress.

Recently we had a request from someone who wanted to add affiliate links to Woocommerce variations so we thought we would put together this quick tutorial to show you how to do that.

First, we need to have a way to input our links in the Woocommerce admin panel when the product type is “variable”. The best way I thought to achieve this would be to add a custom meta box to each variation box when the variations were set. Luckily someone had already done some leg work on this so we were able to use some of their code found here.

So in order to create our custom meta boxes for variations we need to start working with our themes functions.php file and start by adding some actions that will handle our magic, like so:

// Display Fields
add_action( 'woocommerce_product_after_variable_attributes', 'variable_fields', 10, 2 );
//JS to add fields for new variations
add_action( 'woocommerce_product_after_variable_attributes_js', 'variable_fields_js' );
// Save Fields
add_action( 'woocommerce_process_product_meta_variable', 'variable_fields_process', 10, 1 );

Great! We have plugged into the hooks that are going to handle our data handling, now we just need to create the functions that are going to assist that. So right below where we just added the hooks in our functions file, lets go ahead and create those functions.

function variable_fields( $loop, $variation_data ) {

}

function variable_fields_js() {

}

function variable_fields_process( $post_id ) {

}

Note: Notice the parameters we are passing through those functions. ie $loop, $variation_data, $post_id.

Now that we have our functions set we need to setup what is going to be inside of each one. Let’s start by creating our meta box, in this case I am going to use ‘_my_affiliate_url’ as the meta value, and of course the meta key would be the variation id (we will get into that more later).

So looking at the first two functions we created, we are going to place our code inside those two functions so it looks like this:

function variable_fields( $loop, $variation_data ) {
?>	
	<tr>
		<td>
			<div>
					<label><?php _e( 'Affiliate URL', 'woocommerce' ); ?></label>
					<input type="text" size="5" name="my_affiliate_url[<?php echo $loop; ?>]" value="<?php echo $variation_data['_my_affiliate_url'][0]; ?>"/>

			</div>
		</td>
	</tr>
<?php
}

function variable_fields_js() {
?>
<tr>
		<td>
			<div>
					<label><?php _e( 'My Custom Field', 'woocommerce' ); ?></label>
					<input type="text" size="5" name="my_affiliate_url[' + loop + ']" />
			</div>
		</td>
	</tr>
<?php
}

All this does is create our custom meta boxes for each Woocommerce variation. Login to the backend of your site and look at a variable product (click on Variations and expand each one) and you will see our new meta box. Except when you put info in there, it doesnt do anything, so we need to setup our function “variable_fields_process” so that it can save the data we enter in there.

Let’s do that now:

function variable_fields_process( $post_id ) {
	if (isset( $_POST['variable_sku'] ) ) :
		$variable_sku = $_POST['variable_sku'];
		$variable_post_id = $_POST['variable_post_id'];
		$variable_custom_field = $_POST['my_affiliate_url'];
		for ( $i = 0; $i < sizeof( $variable_sku ); $i++ ) :
			$variation_id = (int) $variable_post_id[$i];
			if ( isset( $variable_custom_field[$i] ) ) {
				update_post_meta( $variation_id, '_my_affiliate_url', stripslashes( $variable_custom_field[$i] ) );
			}
		endfor;
	endif;
}

Now we can enter our info in there and once the page refreshes we see that the info does save and show in the meta boxes.

Now we need to know how to show that info on the front-end of the website or in our case pass the info into our “Add to Cart” button so it will take the user to the appropriate affiliate link.

*If you dont plan on using affiliate links or are using these meta boxes for some other info that you need to display on the front – end of your website you can simply use this to get the meta_value for each variation:

$variations = $product->get_available_variations();
		foreach ($variations as $key => $value) {
			echo get_post_meta($value['variation_id'], '_my_affiliate_url', true);
		}

So what if we are using these for Affiliate links for variations? Well the best way I thought to do that would be to remove the default select box Woocommerce uses to house its variations and instead show them in a table format so each add to cart link is easy to view and handled appropriately. So finally, let’s set that up so that we can create that table and have each add to cart button link to each variations affiliate url.

To do this we need to add this last piece of code to our functions.php file underneath where we have been working:

//front-end variations
function woocommerce_variable_add_to_cart() {
		global $product, $post;
		$variations = $product->get_available_variations();
		foreach ($variations as $key => $value) {
		?>
		<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>"method="post" enctype='multipart/form-data'>
			<input type="hidden" name="variation_id" value="<?php echo $value['variation_id']?>" />
			<input type="hidden" name="product_id" value="<?php echo esc_attr( $post->ID ); ?>" />
			<?php
			if(!empty($value['attributes'])){
				foreach ($value['attributes'] as $attr_key => $attr_value) {
				?>
				<input type="hidden" name="<?php echo $attr_key?>" value="<?php echo $attr_value?>">
				<?php
				}
			}
			?>
			<table>
				<tbody>
					<tr>
						<td>
							<b><?php echo implode('/', $value['attributes']);?></b>
						</td>
						<td>
							<?php echo $value['price_html'];?>
						</td>
						<td>
							<a class="single_add_to_cart_button button alt" target="_blank" href="<?php echo get_post_meta($value['variation_id'], '_my_affiliate_url', true); ?>" ><?php echo apply_filters('single_add_to_cart_text', __( 'Add to cart', 'woocommerce' ), $product->product_type); ?></a>
						</td>
					</tr>
				</tbody>
			</table>
		</form>
		<?php
		}
}

So in the above code you will notice that we have completely removed the actual button[type="submit"] that Woocommerce uses but replace it with a basic anchor link while keeping the classes in tact so that it looks like the default Woocommerce Add to Cart button. We have assigned the href to grab our meta_value for EACH variation, and open it in a new tab.

When you have done all of this your completed code in your functions.php file should look like this:

// Display Fields
add_action( 'woocommerce_product_after_variable_attributes', 'variable_fields', 10, 2 );
//JS to add fields for new variations
add_action( 'woocommerce_product_after_variable_attributes_js', 'variable_fields_js' );
// Save Fields
add_action( 'woocommerce_process_product_meta_variable', 'variable_fields_process', 10, 1 );

function variable_fields( $loop, $variation_data ) {
?>	
	<tr>
		<td>
			<div>
					<label><?php _e( 'Affiliate URL', 'woocommerce' ); ?></label>
					<input type="text" size="5" name="my_affiliate_url[<?php echo $loop; ?>]" value="<?php echo $variation_data['_my_affiliate_url'][0]; ?>"/>

			</div>
		</td>
	</tr>
<?php
}

function variable_fields_js() {
?>
<tr>
		<td>
			<div>
					<label><?php _e( 'My Custom Field', 'woocommerce' ); ?></label>
					<input type="text" size="5" name="my_affiliate_url[' + loop + ']" />
			</div>
		</td>
	</tr>
<?php
}

function variable_fields_process( $post_id ) {
	if (isset( $_POST['variable_sku'] ) ) :
		$variable_sku = $_POST['variable_sku'];
		$variable_post_id = $_POST['variable_post_id'];
		$variable_custom_field = $_POST['my_affiliate_url'];
		for ( $i = 0; $i < sizeof( $variable_sku ); $i++ ) :
			$variation_id = (int) $variable_post_id[$i];
			if ( isset( $variable_custom_field[$i] ) ) {
				update_post_meta( $variation_id, '_my_affiliate_url', stripslashes( $variable_custom_field[$i] ) );
			}
		endfor;
	endif;
}

//front-end variations
function woocommerce_variable_add_to_cart() {
		global $product, $post;
		$variations = $product->get_available_variations();
		foreach ($variations as $key => $value) {
		?>
		<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>"method="post" enctype='multipart/form-data'>
			<input type="hidden" name="variation_id" value="<?php echo $value['variation_id']?>" />
			<input type="hidden" name="product_id" value="<?php echo esc_attr( $post->ID ); ?>" />
			<?php
			if(!empty($value['attributes'])){
				foreach ($value['attributes'] as $attr_key => $attr_value) {
				?>
				<input type="hidden" name="<?php echo $attr_key?>" value="<?php echo $attr_value?>">
				<?php
				}
			}
			?>
			<table>
				<tbody>
					<tr>
						<td>
							<b><?php echo implode('/', $value['attributes']);?></b>
						</td>
						<td>
							<?php echo $value['price_html'];?>
						</td>
						<td>
							<a class="single_add_to_cart_button button alt" target="_blank" href="<?php echo get_post_meta($value['variation_id'], '_my_affiliate_url', true); ?>" ><?php echo apply_filters('single_add_to_cart_text', __( 'Add to cart', 'woocommerce' ), $product->product_type); ?></a>
						</td>
					</tr>
				</tbody>
			</table>
		</form>
		<?php
		}
}

There you go, hope that helps you with understanding how custom meta fields work in Woocommerce and how to apply them to your shop. Happy theming :-)

Additional Resources:
Custom Fields in WordPress
get_post_meta – Codex
update_post_meta – Codex

Like this? Share it with your friends!
Facebook Twitter Linkedin Email

10 Responses to “How to add Affiliate Links to Woocommerce Variations”

  1. Samantha

    Hi Derek,
    Thanks so much for this! I will implement and let you know how it goes. Thanks for investigating and coming up with a great solution!
    regards, Sam

    Reply
  2. Samantha

    Hi Derek,
    Just implemented this on my test site and it works! I am so thrilled!
    Only thing I found was that it would only work for creating a new product, doesn’t (on my site anyway) display on front end after editing an already existing product. This was easily fixed for me, I just deleted and re-imported all my products and now works as expected.
    I am truly grateful for you very generously sharing your knowledge :)
    Thanks so much Derek – you are a star!
    regards,
    Sam

    Reply
  3. Leanne

    Do you have any suggestions for how you could do this to add custom fields for color swatches? I have searched everywhere for some answers and tried so many different things (including something with the Github code you started with!) but I haven’t yet made it happen. This tutorial seems the most comprehensive for what you are trying to accomplish and the first thing that actually made some sense!!!!

    Basically I just want the ability to specify the available colors via a custom fields box and have them show as a swatch for each color. It could be an image swatch if that is easier of even better a hex code. Also ideally they would be clickable so that the main product image would change to show the product in that color. They do not have to function for selecting the variables and adding to cart, just for visual purposes only.

    I purchased the color swatches plugin through woocommerce but unfortunately it changes the drop down selection box to show the colors which I didn’t want. I want my customers to select from a list that contains the text description (I hope that makes sense). In the long run I am hoping to call these swatches and display them on the product catalogue pages.

    Any suggestions or would you know of where to point me? I appreciate this may or may not be within the scope of what this tutorial covers.

    Any insight is much appreciated!

    Reply
    • Derek Schmidt

      Hi Leanne, sorry for the late response.. busy week. So to make sure I understand, you want to add color hex codes in the back end of your woo commerce shop for each product. Then on the front end you just want those swatches to show through as clickable images which when clicked show the color swatch (or image) in the main image for that product? Am I correct?

      Reply
      • Leanne

        Hi Derek,

        Actually your reply is pretty speedy so no apologies necessary!

        Yes you are absolutely correct – the only thing extra was that I also wanted to be able to display the color swatches on the catalogue pages. Once they are available on the front end I know it isn’t too hard to call them to the catalogue pages but if they will be clickable there (ie. click the color and change the image) then just on the catalogue pages they would need to change the image on the catalogue page instead of opening the single product page (I hope that makes sense).

        Really appreciate your help and thanks again for your speedy reply :)

        Reply
        • Derek Schmidt

          Makes perfect sense. So you will be adding echoing the custom field(s) (so they are seen on the front end) on your single-product page and also on your shop page within the loop. Then you just need to use jquery to handle switching out the images when users click each swatch. It will probably be the .replace event or .append, you may even look into the .attribute src for jQuery.

          I wish I could offer you more but right now is a tough time due to work but if I get some free time I will try to hack something up for you to start working with. Hopefully you have enough info here to get started.

          Reply
  4. Johan Vergeer

    Hi Derek,

    I have been looking for weeks for this solution. Thank you so much.
    Now when I am in the front end of a variable product it is not looking too nice. It has all the variations with a lot of buttons.
    eg: http://pervadi.com/product/cars-bermuda/

    Do you know how to solve this so I get one order button and the dropdowns there usually are in the variable products.

    Would be great if you could help me out with this.

    Johan

    Reply

Leave a Reply