Posted on August 3, 2016
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.
Hi, Thanks for the code. Can you please share a code for variable products also? Thanks
Like this: 3072&variation_id=3083&attribute_pa_yuzukolcusu=09&quantity=3,3072&variation_id=3082&attribute_pa_yuzukolcusu=11&quantity=3
Hi thanks for the code…..can you please share the code with adding a multiple variation of multiple product?
if ( ‘simple’ !== $add_to_cart_handler ) {
continue;
}
You can share the code vor variable please
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)
Ok, but… should I put that piece of code within your snippet? Outside?
No, not within the snippet. Wherever you need it. Like
the_permalink()
, etc.Thanks JT for your reply! I assumed it was so… An example, please?
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.
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
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.
what did you do to fix the doubling problem?
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).Awesome, thank you! I have updated the post/snippet.
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!!
Try:
.com/cart/?add-to-cart=77:3,103:6
NICE! Works perfectly!
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?
Thanks man for this script and for sharing it!
Pingback: Add multiple products to cart - WooCommerce - Das Web Developer
You are a true American hero.
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.
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?
I recommend using composite plugin offered by woocommerce .. it’s awesome this is a demo
https://www.pistakkiofood.it/prodotto/box-amuni-fai-da-te-formato-1×6-pistakkiofood#scegli-il-formato-e-il-tipo-di-pasta
Hi Hos, thank you very much. The Woocommerce Composite Plugin is indeed just what I Needed! Thanks!
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.
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.
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
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. :)
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.
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!
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
For anyone following along, we have created an issue to get this functionality in WooCommerce core: https://github.com/woocommerce/woocommerce/issues/17477
As well as a pending pull request: https://github.com/woocommerce/woocommerce/pull/17855
Update: It looks like it will be available with the 3.4.0 release, though may get some modifications from its existing PR state before it’s “official”. This should make a bunch of you happy. :)
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.
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?
Hello.
Thank you for your help.
But is ti possible somehow to use your code with Variable Products and with its Attributes and Variations?
It is not quite a direct way but i used a workarround ( but works nicely)
first there is a SKU assigned to each possible variation (ACF)
with this code (http://www.remicorson.com/add-woocommerce-product-to-cart-from-url-using-products-sku/) you can use these SKU’s to add with the script from this side :)
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.
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,
That is not true. PHP’s explode creates an array whether the separator exists in the string or not. http://codepad.org/Jkbm42pA
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
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']);
}
thank you!
your codes saved my day!
you are welcome :)
You saved me <3
where should i place the above code?
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
Just what i need, thanks!
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
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!
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.
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
@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.
It
s not a WP version. I have WP 4.9.10 and WC 3.2.6. Started with WC 3.6.0 and downgrade don
t 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.I have just written few seconds ago because I had same problem as dssadmin1 but I solved with @diegobetto solution. Thanks!
https://dsgnwrks.pro/snippets/woocommerce-allow-adding-multiple-products-to-the-cart-via-the-add-to-cart-query-string/#comment-12289
How can I get the Product id and quantity dynamically for multiple products.
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
Pingback: WooCommerce custom sales page – cookies and cart not saved – FeuTex – #ForAuthors
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.
Multiple simple products did not work without @diegobetto’s awesome change. Works for me, WordPress 5.2.2, php7.3
without creating product page can i create multiple products and add to cart in woocomerce
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
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.
This is not nooby-friendly at all. One cannot even tell where or how to use the code. Poor tutorial
Hello – I made a plugin which uses this method. Thanks for sharing.
https://github.com/gerrgg/wc-frequently-purchased-together
Pingback: Add Multiple Products to WooCommerce Cart using the fetch API - Insytful