WooCommerce: Allow adding multiple products to the cart via the add-to-cart query string

If you’re not familiar, WooCommerce offers a way to link to the checkout/cart page and automatically add a product to the cart (h/t Justin). You can create a link like so:

$product_id = 55;
$url = esc_url_raw( add_query_arg( 'add-to-cart', $product_id, wc_get_checkout_url() ) );

I recently (somewhat annoyingly) discovered that while that works fairly well, there was no way to do this for multiple products. So I’ve created a snippet that will allow you to do so by adding a comma-separated list of products ids:

function woocommerce_maybe_add_multiple_products_to_cart( $url = false ) {
    // Make sure WC is installed, and add-to-cart qauery arg exists, and contains at least one comma.
    if ( ! class_exists( 'WC_Form_Handler' ) || empty( $_REQUEST['add-to-cart'] ) || false === strpos( $_REQUEST['add-to-cart'], ',' ) ) {
        return;
    }

    // Remove WooCommerce's hook, as it's useless (doesn't handle multiple products).
    remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 );

    $product_ids = explode( ',', $_REQUEST['add-to-cart'] );
    $count       = count( $product_ids );
    $number      = 0;

    foreach ( $product_ids as $id_and_quantity ) {
        // Check for quantities defined in curie notation (<product_id>:<product_quantity>)
        // https://dsgnwrks.pro/snippets/woocommerce-allow-adding-multiple-products-to-the-cart-via-the-add-to-cart-query-string/#comment-12236
        $id_and_quantity = explode( ':', $id_and_quantity );
        $product_id = $id_and_quantity[0];

        $_REQUEST['quantity'] = ! empty( $id_and_quantity[1] ) ? absint( $id_and_quantity[1] ) : 1;

        if ( ++$number === $count ) {
            // Ok, final item, let's send it back to woocommerce's add_to_cart_action method for handling.
            $_REQUEST['add-to-cart'] = $product_id;

            return WC_Form_Handler::add_to_cart_action( $url );
        }

        $product_id        = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $product_id ) );
        $was_added_to_cart = false;
        $adding_to_cart    = wc_get_product( $product_id );

        if ( ! $adding_to_cart ) {
            continue;
        }

        $add_to_cart_handler = apply_filters( 'woocommerce_add_to_cart_handler', $adding_to_cart->get_type(), $adding_to_cart );

        // Variable product handling
        if ( 'variable' === $add_to_cart_handler ) {
            woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_variable', $product_id );

        // Grouped Products
        } elseif ( 'grouped' === $add_to_cart_handler ) {
            woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_grouped', $product_id );

        // Custom Handler
        } elseif ( has_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler ) ){
            do_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler, $url );

        // Simple Products
        } else {
            woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_simple', $product_id );
        }
    }
}

// Fire before the WC_Form_Handler::add_to_cart_action callback.
add_action( 'wp_loaded', 'woocommerce_maybe_add_multiple_products_to_cart', 15 );


/**
 * Invoke class private method
 *
 * @since   0.1.0
 *
 * @param   string $class_name
 * @param   string $methodName
 *
 * @return  mixed
 */
function woo_hack_invoke_private_method( $class_name, $methodName ) {
    if ( version_compare( phpversion(), '5.3', '<' ) ) {
        throw new Exception( 'PHP version does not support ReflectionClass::setAccessible()', __LINE__ );
    }

    $args = func_get_args();
    unset( $args[0], $args[1] );
    $reflection = new ReflectionClass( $class_name );
    $method = $reflection->getMethod( $methodName );
    $method->setAccessible( true );

    $args = array_merge( array( $class_name ), $args );
    return call_user_func_array( array( $method, 'invoke' ), $args );
}

Now you can add items to the cart via the following URLs:

// Multiple products, multiple quantities per product.
$product_ids = '63833:2,221916:4';
$add_to_cart_url = esc_url_raw( add_query_arg( 'add-to-cart', $product_ids, wc_get_checkout_url() ) );

// Multiple products (default quantity of 1)
$product_ids = '63833,221916';
$add_to_cart_url = esc_url_raw( add_query_arg( 'add-to-cart', $product_ids, wc_get_checkout_url() ) );

// Normal add-to-cart URL
$product_ids = '63833';
$add_to_cart_url = esc_url_raw( add_query_arg( 'add-to-cart', $product_ids, wc_get_checkout_url() ) );
UPDATE 04-21-17: I have updated the snippet to work with non-simple product types. (See the MARKDOWN_HASHd8969cc70401fc7e3d75a74096dbd31dMARKDOWN_HASH function). As indicated by the function name, this is a hack to get access to WooCommerce protected/private methods. Your milage may vary when using this snippet.
UPDATE 07-08-17: Thanks to Peder in the comments, I have updated the snippet to allow specifying different quantities per-product.

29 Comments on “WooCommerce: Allow adding multiple products to the cart via the add-to-cart query string

  1. Hi, Thanks for the code. Can you please share a code for variable products also? Thanks

  2. Like this: 3072&variation_id=3083&attribute_pa_yuzukolcusu=09&quantity=3,3072&variation_id=3082&attribute_pa_yuzukolcusu=11&quantity=3

  3. I didn’t get where to put this piece of code:
    $product_ids = implode( ‘,’, array( 1, 2, 55 ) );
    $url = esc_url_raw( add_query_arg( ‘add-to-cart’, $product_ids, wc_get_checkout_url() ) );
    Within the snippet?

    • That is highly contextual to your project. You would use it wherever you need to output a url that adds multiple products to the cart. (where 1, 2, 55 equals the product ids you want to be added)

  4. Ok, but… should I put that piece of code within your snippet? Outside?

  5. Thanks JT for your reply! I assumed it was so… An example, please?

  6. What good code, but how do I for the quantity of several products?

    • Hi Wladimick Diaz,
      Did you find a way to achieve this (multiple products with quantities for each)? I’m struggling with this :-/
      Thanks!!

      • I found a solution, see further down the thread.

  7. Thanks for updating the snippet to handle multiple variable products! Legendary!

    Have you considered making an Admin facing UI to allow creating these URLs by selecting products? This would make a nice plugin.

    Cheers,
    Jason

  8. Hi,

    When i use your code it adds two of each product i want to add to the cart.

    Can you explain why?

    • I already figured it out.

      I am using jQuery to create the add-to-cart link, and i was redirecting to the wrong page.

  9. Thanks! I needed to be able to add more than one item of each product.

    To fix this I added this code as the first thing after:
    foreach ( $product_ids as $product_id ) { //line 14

    $id_and_quantity = explode( ':', $product_id );
    $product_id = $id_and_quantity[0];
    if ( count( $id_and_quantity ) > 1 ) {
    $_REQUEST['quantity'] = $id_and_quantity[1];
    } else {
    $_REQUEST['quantity'] = 1;
    }

    Then I can add products with optional amounts using this structure (product_id:quantity):
    $product_ids = implode( ',', array( '1:2', '2:5', '55:3' ) );

    Note: The quantity is not needed. E.g. $product_ids = implode( ',', array( '1:2', '2', '55:3' ) ); will only add one item to the cart for product id 2 (second array element).

      • Hey there, this is really awesome. I’ve just built my own quote form in JS and was wondering how I could create a single URL to add in up to 3 products each with its own quantity.
        I have a question, I’m a bit of a novice at the moment and I’m learning through trial and error!!
        When I copied and pasted the code into my functions.php it does allow me to add multiple products with one URL but I don’t understand how you’re meant to specify the quantity for the product. Is it along the lines of ‘.com/?add-to-cart=77:3,103:6’ or ‘.com/?add-to-cart=77,103&quantity=3,6’?
        Neither works. Would love some help. I’ve opened a question on StackEx as well to try and get some help. The URL is stackexchange /questions/45224362/add-multiple-products-to-cart-woocommerce where I’ve linked this awesome post!!

    • Hi, I’m new to the scene and was wondering if I could get some help. The code works really well, but for some reason it will always add at least one of the products, even if i put the quantity to 0. So ?add-to-cart=2001:0,2018:0,2020,1 will still add one of each product to the cart. Is there a way to fix that?

  10. Pingback: Add multiple products to cart - WooCommerce - Das Web Developer

  11. This is great code, but I have a question, how can i add all the products in my wishlist (Im using YITH plugin for this) to the cart with one click of a button.

  12. Hi There,

    I would like to know if I can use your code to add multiple products to a cart from within a product page.

    I sell flowers online and am looking for a solution to the following:

    I have a product page where customers can pick the size of the bouquet. I would like to add a selection box ‘add a vase to cart’ so customers can add a vase along with the bouquet.

    When the customer pushes the add to cart button on the product page and the ‘add a vase’ checkbox is checked, two items are added to the cart.

    Would this be possible with your query string?

  13. Hi guys, before i have done and success using this code for my shop. Now I have trouble after updating woocommerce and change my theme.

    When i’m trying to run com/cart/?add-to-cart=70:3,80:2:90:1 the result is only “90:1” on my page cart. I need “70:3,80:2:90:1” added also on my page cart.

    Can someone help me with this? Thank you before.

  14. Hi,

    This is very helpful article. Can you please help me to add multiple variation product.

    Thanks

Comment

Fast, secure WordPress hosting is provided by WP Engine.
%d bloggers like this: