skip to Main Content

I’m encountering an issue while trying to implement a "Buy on Amazon" button on my WooCommerce product pages. The problem is that for variable products, the button consistently links to the first variation, and it doesn’t update when switching between variations. This issue is hampering the functionality of my online store, and I’m seeking a solution or alternative methods to address this challenge effectively.

I’m facing a challenge while attempting to add a "Buy on Amazon" button to the product page of my WooCommerce online store. This button should work seamlessly for both regular and variable products.

Here’s what I’ve tried:

Step 1: I created a custom field for the product using the following code:

// Add a custom field "Buy on Amazon Link" to variable product variations
add_action('woocommerce_product_after_variable_attributes', 'add_amazon_link_field_to_variations', 10, 3);
function add_amazon_link_field_to_variations($loop, $variation_data, $variation) {
    woocommerce_wp_text_input(array(
        'id'            => '_buy_on_amazon[' . $loop . ']',
        'class'         => 'short',
        'label'         => __('Buy on Amazon Link', 'woocommerce'),
        'value'         => get_post_meta($variation->ID, '_buy_on_amazon', true)
    ));
}

// Save the custom field for variations
add_action('woocommerce_save_product_variation', 'save_amazon_link_field_from_variations', 10, 2);
function save_amazon_link_field_from_variations($variation_id, $i) {
    $amazon_link = $_POST['_buy_on_amazon'][$i];
    if (isset($amazon_link)) {
        update_post_meta($variation_id, '_buy_on_amazon', esc_attr($amazon_link));
    }
}

// Add a custom field to regular products
add_action('woocommerce_product_options_general_product_data', 'add_amazon_link_field_to_products');
function add_amazon_link_field_to_products() {
    woocommerce_wp_text_input(array(
        'id'            => '_buy_on_amazon',
        'class'         => 'short',
        'label'         => __('Buy on Amazon Link', 'woocommerce'),
        'desc_tip'      => true,
        'description'   => __('This field will be used for the Amazon product links', 'woocommerce'),
        'value'         => get_post_meta(get_the_ID(), '_buy_on_amazon', true)
    ));
}

// Save the custom field for regular products
add_action('woocommerce_process_product_meta', 'save_amazon_link_field_from_products');
function save_amazon_link_field_from_products($post_id) {
    $amazon_link = $_POST['_buy_on_amazon'];
    if (isset($amazon_link)) {
        update_post_meta($post_id, '_buy_on_amazon', esc_attr($amazon_link));
    }
}

Step 2: Subsequently, I attempted to display the "Buy on Amazon" button on the product page using this code:

// Add the Buy on Amazon button next to the Add to Cart button
add_action('woocommerce_single_product_summary', 'add_amazon_button', 15);
function add_amazon_button() {
    global $product;

    // Check if the product is variable
    if ($product->is_type('variable')) {
        // Get the selected variation
        $variation_id = $product->get_available_variations()[0]['variation_id'];

        // Get the Amazon link for the selected variation
        $amazon_link = get_post_meta($variation_id, '_buy_on_amazon', true);

        // If the Amazon link exists, output the button
        if ($amazon_link) {
            echo '<a href="' . esc_url($amazon_link) . '" class="amazon-button" target="_blank">Buy on Amazon</a>';
        }
    } else {
        // For regular products, use the parent product's link
        $amazon_link = get_post_meta($product->get_id(), '_buy_on_amazon', true);

        // If the Amazon link exists, output the button
        if ($amazon_link) {
            echo '<a href="' . esc_url($amazon_link) . '" class="amazon-button" target="_blank">Buy on Amazon</a>';
        }
    }
}

For regular products, the button displays correctly. However, for variable products, the button consistently links to the first variation. In other words, when switching between different variations on the site, the link doesn’t update accordingly.

I’m reaching out to the Stack Overflow community for insights on how to resolve this issue or for suggestions on alternative methods to achieve this.

Your expertise and guidance would be greatly appreciated.

2

Answers


  1. I have revised your code using more recent hooks and WooCommerce methods, that will be compatible with future upcoming WooCommerce updates, as WooCommerce is progressively migrating to custom tables, for performances enhancements…

    // Add a custom field to simple products
    add_action('woocommerce_product_options_general_product_data', 'add_amazon_link_field_to_products');
    function add_amazon_link_field_to_products() {
        // Not on variable products
        echo '<div class="hide_if_variable">';
    
        woocommerce_wp_text_input(array(
            'id'            => '_buy_on_amazon',
            'class'         => 'short',
            'label'         => __('Buy on Amazon Link', 'woocommerce'),
            'description'   => __('This field will be used for the Amazon product links', 'woocommerce'),
            'desc_tip'      => true,
        ));
        echo '</div>';
    }
    
    // Save the custom field for simple products
    add_action('woocommerce_admin_process_product_object', 'save_amazon_link_field_from_products');
    function save_amazon_link_field_from_products( $product ) {
        if (isset($_POST['_buy_on_amazon'])) {
            $product->update_meta_data('_buy_on_amazon', sanitize_url($_POST['_buy_on_amazon']));
        }
    }
    
    
    // Add a custom field "Buy on Amazon Link" to product variations
    add_action('woocommerce_product_after_variable_attributes', 'add_amazon_link_field_to_variations', 10, 3);
    function add_amazon_link_field_to_variations($loop, $variation_data, $variation) {
        $variation_obj = wc_get_product($variation->ID);
    
        woocommerce_wp_text_input( array(
            'id'            => '_buy_on_amazon[' . $loop . ']',
            'class'         => 'short',
            'label'         => __('Buy on Amazon Link', 'woocommerce'),
            'value'         => $variation_obj->get_meta('_buy_on_amazon'),
        ) );
    }
    
    // Save the custom field for product variations
    add_action('woocommerce_admin_process_variation_object', 'save_amazon_link_field_from_variations', 10, 2 );
    function save_amazon_link_field_from_variations($variation, $i) {
        if ( isset($_POST['_buy_on_amazon'][$i]) ) {
            $variation->update_meta_data('_buy_on_amazon', sanitize_url($_POST['_buy_on_amazon'][$i]));
        }
    }
    

    In the following, for your variable products, we add the custom Amazon link for each variation, to the variable form data, and we use jQuery to set the correct Amazon link when selecting a variation:

    // Display the Buy on Amazon button next to the Add to Cart button
    add_action('woocommerce_single_product_summary', 'display_product_amazon_button_html', 15 );
    function display_product_amazon_button_html() {
        global $product;
    
        // For variable products
        if ( $product->is_type('variable') ) {
            printf( '<a class="amazon button">%s</a>', __('Buy on Amazon') );
        } 
        // For other products
        elseif ( $amazon_link = $product->get_meta('_buy_on_amazon')) {
            printf( '<a href="%s" class="amazon button" target="_blank">%s</a>', esc_url($amazon_link), __('Buy on Amazon') );
        }
    }
    
    // Add variation amazon link to the variable product data form
    add_action( 'woocommerce_available_variation', 'add_variations_amazon_links_to_variable_product_form', 10, 3 );
    function add_variations_amazon_links_to_variable_product_form( $variation_data, $product, $variation ) {
        if ( $amazon_link = $variation->get_meta('_buy_on_amazon') ) {
            $variation_data['amazon_link'] = esc_url($amazon_link);
        }
        return  $variation_data;
    }
    
    // Set the selected variation amazon link to the button
    add_action('woocommerce_after_add_to_cart_form', 'set_variation_amazon_link_js', 15 );
    function set_variation_amazon_link_js() {
        global $product;
        if ( $product->is_type('variable') ) : ?>
            <script>
            jQuery( function($){
                $('form.cart').on('show_variation', function(event, data) {
                    if ( $('.amazon.button').hasClass('disabled') && data.amazon_link !== undefined ) {
                        $('.amazon.button').removeClass('disabled').attr({'target': '_blank', 'href': data.amazon_link})
                    } else if  ( ! $('.amazon.button').hasClass('disabled') && data.amazon_link === undefined ) {
                        $('.amazon.button').addClass('disabled').removeAttr('href').removeAttr('target');
                    }
                }).on('hide_variation', function(){
                    if  ( ! $('.amazon.button').hasClass('disabled') ) {
                        $('.amazon.button').addClass('disabled').removeAttr('href').removeAttr('target');
                    }
                });
            });
        </script>
        <?php endif;
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works.

    Login or Signup to reply.
  2. Works like a charm 🙂 I tried it on my website theyayacafe.com to redirect users to exact listing on amazon and it works perfectly!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search