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.

81 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

    • Hi Everybody,

      I recently found these very interesting plugin developers in the WordPress repository: WPclever

      They have developed a lot of (free) plugins where you can add multiple products from the product page at once to the cart and delete the individual items from the cart later on. A few of the plugins I have tried:

      WPC Frequently Bought Together for WooCommerce
      WPC Grouped Product for WooCommerce
      WPC Force Sells for WooCommerce
      WPC Product Bundles for WooCommerce

      I hope one of these plugins can be usefull in your case.

  15. Thanks a lot for this perfect article.
    Just a small question: Is it possible to use it with Woocommerce Subscription Plugin? To add multiple Variable Subscription Products? I’m going crazy with this problem…
    Thanks and cheers
    jonas

  16. Thanks for that script – very helpful.

    I had an error and needed to fix the woo_hack_invoke_private_method function.

    This is what I ended up with:


    /**
    * 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()' );
    }
    $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( $reflection ), $args );
    return call_user_func_array( array( $method, 'invoke' ), $args );
    }

    I needed to change $class_name to $reflection in the last line before ‘return’.
    My error message said: ‘PHP Warning: ReflectionMethod::invoke() expects parameter 1 to be object, string given in …’

    After some research I thought the first parameter needs to be an real Class, not just the name of a class.
    That did the trick – but I don’t know much about the Reflection things. Please let me know if I have bad things worse …

    I am running on PHP 7.0

    Thanks a lot for share your code!

    • Works well! Though if anyone is copy/pasting the above please note this blog/site changes quotes to curly/special quotes int he code so you’ll have to change them back to code standard quotes (” ‘ etc).

      • If you hover over the snippet, there is a code copy button at the top right which should copy the snippet with proper quotes.

        • Oh, I realize you’re talking about the quote in the comment. Yah, that’s another matter. :)

  17. It looks like the woocommerce 3.2 update broke something so this snippet doesn’t work with adding multiple variable products now

    • the second products attribute doesn’t seem to pass in.

      I get the following error: “(product attribute) is a required field”

      The first variable product add correctly. Anything after that doesn’t.

  18. I’ve been following this thread since months.
    Not only it became awesome, not only I did not understand how to use it, but I also think that it should become a plugin. :)

    Now, is there anyone who can give an example of how to use it, please?

    Thanks!

  19. This code worked great. The only problem I have is that its listing the product prices including tax. I have WC set up to not include taxes per item, but to add it in at the bottom with shipping charges instead. I checked your code and don’t see where the tax inclusive parm is being set. Any ideas?

    Thanks for this excellent code.
    Roger

  20. I don’t think this codesnippet works any longer since woocommerce updated. Even though I add several variable products with quantity, only one product is added to the cart.

    I tested to change $class_name to $reflection as Sebastian Gärtner wrote earlier and then I got some parts to work. Now all the products I choose are added, but it seems like it’s an instance of the product. If I re-enter one of the products in the cart and add additional one of the same product, a new row will be created in the shopping cart. It should only increase the amount of that product.

    Does this make any sense?

    Anyone who has a solution to this?

    Thank you for a wonderful code.

    • Hi, Can i ask how did you output the url to add multiple products variable, i tried like using like “http://site.com/cart/?add-to-cart=162039,173167&variation_id=162040,173170&attribute_pa_event-session=early-bird&attribute_pa_select-size=m” but only one product and double the quantity is added.

  21. When I add click on the link url /? Add-to-cart = 1250,1260 or url /? Add-to-cart = 1250: 90,1260: 90 always double the amount. In the first case I get 2 as quantity ‘for each product and in the second case I get out 180.
    How could I solve.Thank you so much

    • Has anyone figured out this doubling problem? I have tried to use the link that i made, I have sent it to both the ‘cart’ and ‘checkout’ page. When it goes to cart it loads the right number, but then if you click to the checkout it doubles (it must fire once before the url is changed) and when i send it to the checkout page, it loads in doubled already.. Is there a way to have the add-to-cart action only fire once?

  22. Hello.
    Thank you for your help.
    But is ti possible somehow to use your code with Variable Products and with its Attributes and Variations?

  23. Has anyone had any luck with this script NOT forwarding to another page? I would love to get this working via AJAX like a traditional “Add to Cart” button (staying on the same page without refreshing page). Yes, my AJAX setting is enabled.

  24. Great bit of code.

    One thing to note, if you’re building your URL’s from hand note that this script won’t work for a individual item added to cart if your string doesn’t and in an ‘,’ (comma).

    The PHP script explodes the string based on the comma, and if you’re just doing:
    /?add-to-cart=8:1
    it will not work, it instead has to be:
    /?add-to-cart=8:1,

  25. Great code!
    Can you maybe tell me a way, how to check the url for ?clear-cart also and to clear the cart, if the string is found, before adding the items?

    I have tried

    add_action( ‘init’, ‘woocommerce_clear_cart_url’ );
    function woocommerce_clear_cart_url() {
    if ( isset( $_GET[‘clear-cart’] ) ) {
    global $woocommerce;
    $woocommerce->cart->empty_cart();
    }
    }

    but it is not compatible with your code.

    Regards Dominik

  26. Same here, only one product added to cart.
    Changed the last part and now works

    // Simple Products
    } else {
    // woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_simple', $product_id );
    WC()->cart->add_to_cart($product_id, $_REQUEST['quantity']);
    }

  27. Great piece of code! Unfortunately it doesnt work to add products to the cart if the products are assigned with attributes such as size or color. Is it possible to create a function to add the default attribut value to each post in the same way we declare quantity? The URL generated needs to look something like this: http://localhost/store/cart/?add-to-cart=&attribute_size=40 but the attribute data needs to be a variable so the value can be dynamic to the product

  28. Thank you so much. The code works perfectly. I am calling the add_to_cart_url via ajax. The products are being added, no problem here. The mini cart does not update though. How can I update the minicart here?

    Thank you

  29. Awesome code!

    Is there a way to add regular price override?

    This would be ideal:
    ::

    I tried adding after quantity:

    $_REQUEST[‘regular_price’] = ! empty( $id_and_quantity[2] ) ? floatval( $id_and_quantity[2] ) : 2;

    That didn’t work. I’d appreciate your help if it’s an easy change I can add?

    Thank you!

  30. Hi,
    I have 50 products of eye glasses, if someone buy 2 or more frames how to add in cart?

    I am using this link to add product in the cart

    <

    form method=”POST” action=”https://lamzglasses.co.uk/cart/?add-to-cart=”>

    Can you please tell me how to add multiple products or comma separated ids in URL? I have placed your code in functions.php but nothing happen. Please help me.

  31. It was working fine until recently it only adds the last item in the list. For example ?add-to-cart=1001:2,1002:2,1003,2

    it only adds two units of 2003.

    Additionally a new warning appeared “PHP Warning: ReflectionMethod::invoke() expects parameter 1 to be object, string given”.

    Any idea why guys?

    • Same issue here. This seems to be a PHP 7.2 issue. When I change PHP to V 7.0 it works. Hope there will be a fix for PHP 7.2

  32. @dssadmin1 I had the same issue. I changed the last function to:

    function woo_hack_invoke_private_method( $class_name, $method_name, $product_id ) {

    if ( version_compare( phpversion(), '5.3', '<' ) ) {
    throw new Exception( 'PHP version does not support ReflectionClass::setAccessible()', __LINE__ );
    }

    $reflection_method = new ReflectionMethod( $class_name, $method_name );
    $reflection_method->setAccessible( true );

    return $reflection_method->invoke( null, $product_id );

    }

    • I have the same problem as @dssadmin1. I also try Hernan Villanueva solution but I get error 500.

      I didn’t update Woocommerce for so long, so I think the problem maybe is last WordPress updates. Now I am with WordPress 5.1.

      • Its not a WP version. I have WP 4.9.10 and WC 3.2.6. Started with WC 3.6.0 and downgrade dont work. But WC version 3.2.6 is fine, I have another site with 3.2.6 and there is no problem with this. PHP 7.2.10.

  33. How can I get the Product id and quantity dynamically for multiple products.

  34. Has anyone figured out this doubling problem? I have tried to use the link that i made, I have sent it to both the ‘cart’ and ‘checkout’ page. When it goes to cart it loads the right number, but then if you click to the checkout it doubles (it must fire once before the url is changed) and when i send it to the checkout page, it loads in doubled already.. Is there a way to have the add-to-cart action only fire once?

    • It loops if the category url is not set. Try like this:

      /vare-kategori/krydderuter/?add-to-cart=96:10,101:1

      This should work

  35. Pingback: WooCommerce custom sales page – cookies and cart not saved – FeuTex – #ForAuthors

  36. hey greate plugin but it does not work when i put only one variable product with or without “,”!

    i have tried ?add-to-cart=338:3
    or
    ?add-to-cart=338:3,

    can anyone help please ?

    • Worked for me with a comma at the end. But I did also implement @diegobetto’s excellent update.

  37. Multiple simple products did not work without @diegobetto’s awesome change. Works for me, WordPress 5.2.2, php7.3

  38. Latest woocommerce and latest wordpress.
    The products are there on the checkout but there are two spinning wheels on the checkout page that stays.
    In the console log I receive the message : Timeout several times

  39. Hey. Can anyone help me please?

    I’m having a hard time to fix this issue Variable product isn’t working accurately. While the Simple Products perfecty working well.

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

    Please help me.

  40. This is not nooby-friendly at all. One cannot even tell where or how to use the code. Poor tutorial

  41. Pingback: Add Multiple Products to WooCommerce Cart using the fetch API - Insytful

Comment