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.

24 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!!

  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.

Comment

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