Skip shopping cart in WooCommerce

My beautiful wife put together a great WordPress blog, and installed the WooCommerce plugin in order to sell some items on her site. However, she didn’t like the conversion flow for end users; users had to add an item to the cart, confirm the quantities and subtotal, then enter payment information. Because my wife only had one SKU (product), and customers could only buy one at a time, she wanted to skip the shopping cart verification step, and allow customers to go straight from the product page to entering payment information after hitting a big red button.

Seems like a reasonable request. However, after much googling, I determined there was no out-of-the-box setting to enable users to skip the cart page after adding an item to the cart. Furthermore, although the WooCommerce plugin app does expose some AJAX endpoints, those endpoints do not provide the ability to reliably add one and only item of a given product to a cart before redirecting a user to the checkout page.

Luckily my beautiful wife is married to an ace programmer. It’s been several years since I’ve done any coding in PHP, but I went ahead and threw down a little modification for the WooCommerce plugin to enable her special use case. I’m releasing the code here into the public domain.

/** * Set cart item quantity action *
 * Only works for simple products (with integer IDs, no colors etc) *
 * @access public
 * @return void */
function woocommerce_set_cart_qty_action() { 
  global $woocommerce;
  foreach ($_REQUEST as $key => $quantity) {
    // only allow integer quantities
    if (! is_numeric($quantity)) continue;

    // attempt to extract product ID from query string key
    $update_directive_bits = preg_split('/^set-cart-qty_/', $key);
    if (count($update_directive_bits) >= 2 and is_numeric($update_directive_bits[1])) {
      $product_id = (int) $update_directive_bits[1]; 
      $cart_id = $woocommerce->cart->generate_cart_id($product_id);
      // See if this product and its options is already in the cart
      $cart_item_key = $woocommerce->cart->find_product_in_cart( $cart_id ); 
      // If cart_item_key is set, the item is already in the cart
      if ( $cart_item_key ) {
        $woocommerce->cart->set_quantity($cart_item_key, $quantity);
      } else {
        // Add the product to the cart 
        $woocommerce->cart->add_to_cart($product_id, $quantity);
      }
    }
  }
}

add_action( 'init', 'woocommerce_set_cart_qty_action' );

Please be aware this code has been tested, but is intended for hobbyist use. No warranty is implied. Your mileage may vary. Offer void where prohibited.

Installation instructions:
Copy and paste the code in your theme’s functions.php file.

Usage instructions:
Create a hyperlink with a query string argument like so:
<url>?set-cart-qty_<product ID>=<quantity>
Where <product ID> is the numerical ID of your product (something like “167”) and <quantity> is the quantity you want set in the user’s shopping cart (most likely this will just be “1”).

Example URL to send user to checkout with exactly one item of product with ID “167” in cart:

http://my.website.com/checkout?set-cart-qty_167=1

In my wife’s case the URL was set to the checkout page, so that she could set up a shiny red button that linked the user to checkout with the appropriate product already set in the cart, ready to check out.

Feel free to use it for your own site; it should be useful for any situation where you want to ensure a single product exists in the cart at a set quantity.

31 thoughts on “Skip shopping cart in WooCommerce

  1. Hey. This is cool! Except – when it goes to checkout, it shows the product, the quantity (1) and a total ($9.00, for example); then (next line) a cart subtotal ($9.00), then (next line) ‘Order Total’ – which is $0.00.

    Am I missing something, or maybe there’s something in WC config?

    Thanks.

  2. Hello. I’ve put this in place in Woocommerce, and it works great except on presenting the screen, the last field – order total – is zero. So the user accepts the terms, clicks submit, and gets an error – … and the order total appears, and is correct. Now the user clicks submit and everythings working fine.

    I’m drilling around in the code and your change, but do you have any idea what would cause that behavior?

    Thanks.

  3. Hi Phil,

    Sorry for missing your question – yours is the first comment that hasn’t been spam. I haven’t seen the behavior you described. Are you seeing this on the checkout page or the shopping cart page?

    Thanks
    Sam

  4. Hi, thanks for the link and code. That looks like it could be useful in some situations, but I should note that it is not the same as the code snippet I posted above. The code snippet I originally posted sets the cart quantity to a specific amount (allowing the implementer to limit quantity to 1, for example), while your code snippet would allow users to add more than one item to the cart. Still, it looks like it could be useful in some situations where you don’t need to have an exact quantity of an item at checkout. Thanks for sharing.

  5. Sam,

    When using this code, somehow my cart still shows (with the correct quantity and correct product)

    i’m using the url: href=”/checkout?set-cart-qty_19113=1″

    ..and like I said; it takes me to the cart still 🙁

    please advise on what I can do to make this work as I have been struggling at this for days now.

    Best Regards,

    SS

  6. Hi Steven,

    Thanks for reaching out. It sounds like the code is not being executed, as the checkout will redirect back to the cart page if the shopping cart is empty.

    What versions of WooCommerce and WordPress are you using? I set this up on WordPress 3.5.1 and WooCommerce 1.6.6 FWIW. Are you sure you’re inserting the code in the correct file?

    You may also want to check it in a browser with a cleared cache (like an Incognito window in Google Chrome). Sometimes browsers can gather old cookies and get in a funky state, especially if you are using the same session that you use in the admin menu.

    Good luck!
    Sam

  7. Dude, you’re awesome man. Thanks for the code. I’ve been trying to implement this myself but no luck until i find your post.

    Thanks again man..

  8. Thanks for the snippets dude! This is exactly what I’m looking for. Though I need one more thing, I need the cart to be emptied after a 10 minutes session. Can we do this?

  9. Hi Michael,

    I think the best way to clear items after ten minutes would be to add some extra processing to shopping cart-related requests. In the extra processing you would have to pull the current shopping cart items, examine the age of the items (if that is available), and clear any older than ten minutes. You could also simplify and get a slight performance benefit from storing the shopping cart items and their expiration date in a cookie rather than doing the cart lookup on every request. It’s been a while since I’ve looked at the WordPress code so I’m not sure where would be the best place to insert that extra processing – you might try asking around on a WordPress developer’s forum. Good luck and feel free to post back if you get stuck.

  10. This is great- thanks so much for posting this. It took a couple of attempts until I got the URL syntax in correctly, but then it worked perfectly.

  11. Hi Chris, thanks for the feedback. I went ahead and added an example to the post so it should be a little more clear now how the syntax is structured.

  12. Hi Sam,

    I just thought I’d let you know that you’re piece of code works great for a site I’ve been working on. I just needed one more thing which was to only allow one item in the cart a a time.

    For those interested, if they want to make it so only one item can ever be in the cart at a time, all you need to do is add the following line

    $woocommerce->cart->empty_cart();

    Above

    $woocommerce->cart->add_to_cart($product_id, $quantity);

    In the code snippet you provided in your post.

    Thanks again.

    – Jamie.

  13. Thanks for the feedback Jamie. I’m glad you were able to modify the code to make it fit your needs. I’m sure someone else will find your modification useful too.

  14. Hi,

    Can we have a system like anyone can download a free product/file from products page without going to cart/checkout pages. Not even entering any billing email etc. But we want to have php protection for files to avoid hotlinking. Could you please guide me on it.

    Thanks in advance!
    Sampat Sharma

  15. Hi Sampat,

    What you are asking is pretty well outside the scope of this modification to WooCommerce, however, I believe you could implement something very simple without having to use WooCommerce WordPress at all. You could simply put your static files in an accessible directory on your webserver, and require simple HTTP authentication to access those files (if you are using Apache, you could use the Apache AuthBasicProvider directive.

    This proposal is not perfect for your needs, because it is technically possible to construct a link which includes HTTP authentication information in the URL, and that might allow for “hotlinking” of your resources. However, depending on your target users, this may not be much of a concern for you. Another alternative might be a simple file hosting site that supports password-controlled access.

    In either case, after hosting your files in a location with some sort of access-control in place, you would then simply make an HTML listing of the available files, which could live in WordPress or in a standalone HTML file.

    Good Luck
    Sam

  16. Hi Peter, functions.php is a text file which exists in your WordPress installation directory on your host server. This may be different depending on what version of WordPress you are using, but for me this is at “wp-content/themes//functions.php”, where “” is the name of the theme you are using (e.g., “Canvas”).

    I highly recommend you make a backup copy of this file before editing it.

    Once you find the functions.php file, you will have to edit the file using a text editor. You can download the file over FTP, edit on your computer using your OS’s built-in text editor (e.g., notepad, gedit, or textedit) and then sync the file back over FTP to your host server. Or if you are comfortable with the command line, you can edit the file directly on the server in an SSH session, using your preferred command line text editor.

    Good Luck
    Sam

  17. I had several developers try to create this functionality and all failed. I just got it done in 5 minutes with your script. THANKS!!

    One question: is there a way to also force a coupon so that I can specify the product and quantity AND have a specific coupon automatically applied?

    Another question: is there a way to specify the quantity=0 for all products EXCEPT the one being added? To insure the product added is the only one getting paid for? I can repeat the query with quantity=0 for other products, but with more than 2 it gets tedious.

  18. Hi Alex, sorry for the late reply. I’m glad my post was able to help you.

    As far as customization goes, it will take a bit of programming but I think you can tinker with what is already here to accomplish what you want. You can copy the block of code I posted and create additional actions, e.g., “woocommerce_set_coupon_action” or “woocommerce_clear_cart_action”, which can each look through any URL followed on your site and make whatever changes are necessary.

    You’ll probably need to consult a reference on the WooCommerce PHP API. I couldn’t immediately find a good source of documentation, but one might exist somewhere. I think when I originally wrote this I just consulted the source code. The relevant source code for the shopping cart class (which is what you would interact with to do things like “empty the shopping cart of all items exist this one”) is at https://github.com/woothemes/woocommerce/blob/master/includes/class-wc-cart.php. The rest of the source code is at https://github.com/woothemes/woocommerce.

    Feel free to follow up if you run into problems, or comment with an update if you want to share your coupon modification.

    Good luck!

    Update: One of the commenters already posted how to ensure that only one item is ever in the cart (i.e., emptying the cart of other items before adding items):

    For those interested, if they want to make it so only one item can ever be in the cart at a time, all you need to do is add the following line

    $woocommerce->cart->empty_cart();

    Above

    $woocommerce->cart->add_to_cart($product_id, $quantity);

    (Props to Jamie in the comments for that one)

  19. hi! great post, great solution.
    here my problem, i hope you can help me!
    i would like to bypass woocommerce cart and checkout (complitely) and link the “add to cart” button to an url maked “ad hoc” with the variables of my variable products.
    is it possible? how? does exists plugins or extensions that do it? can you give-me some examples of code that do it?
    thanks for the attention.
    regards

  20. Hi Mario, I would like to help you but I am not sure what you are trying to accomplish. Could you please give an example of what you are trying to achieve?

    Thanks
    Sam

  21. Thanks for sharing this Jack. I think there is a good deal of interest in this functionality and your plugin should find a good audience.

    Thanks
    Sam

  22. Do you know if this version will work with WooCommerce 2.3.5? I had this working with an older version but when I updated and moved the code back in place it seems to constantly redirect over and over again. I added some error logging and you can see that below. This happened every-time I hit the URL and caused the server to close the connection.

    [Wed Mar 04 21:02:52.272782 2015] [:error] [pid 27565] [client 71.181.125.154:60832] adding the product with quantity of 1
    [Wed Mar 04 21:02:55.957171 2015] [:error] [pid 27553] [client 71.181.125.154:60835] adding the product with quantity of 1, referer: http://jcrawford.heytix.com/?tribe_events=test-event-3
    [Wed Mar 04 21:02:58.297061 2015] [:error] [pid 27574] [client 71.181.125.154:60836] adding the product with quantity of 1, referer: http://jcrawford.heytix.com/?tribe_events=test-event-3
    [Wed Mar 04 21:03:00.726557 2015] [:error] [pid 27561] [client 71.181.125.154:60837] adding the product with quantity of 1, referer: http://jcrawford.heytix.com/?tribe_events=test-event-3
    [Wed Mar 04 21:03:03.019158 2015] [:error] [pid 27564] [client 71.181.125.154:60838] adding the product with quantity of 1, referer: http://jcrawford.heytix.com/?tribe_events=test-event-3
    [Wed Mar 04 21:03:05.180067 2015] [:error] [pid 27552] [client 71.181.125.154:60847] adding the product with quantity of 1, referer: http://jcrawford.heytix.com/?tribe_events=test-event-3

  23. I have this implemented on 2.3.5 and I have an issue. When my cart is empty then woocommerce goes into an endless loop until apache kills the connection and provides a no data received error message. However if I have even 1 item in my cart then this works without a problem adding the product to the cart.

    Any ideas why this would happen? I have more information which can be found here https://wordpress.org/support/topic/add-item-to-cart?replies=3

  24. Hi Joseph,

    Sorry for the delayed reply. It looks like this snippet I shared is not compatible with the latest version of WooCommerce. I don’t have any plans at the moment to update it for future versions. I made it several years ago when working on a personal project that I no longer actively maintain. If you decide to take that project on I can try to answer any questions you have along the way.

    Sam

  25. Hi Joseph, see my post above about 2.3.5 support. I believe the simplest explanation is that WooCommerce must have changed their internal API behavior sometime between when I first developed this snippet and when the 2.3.5 version was released. Your best bet would be to find a plugin or other feature that meets your needs, or find a contractor who can develop the functionality you desire (ODesk may be a good place to start for that).

    Good luck
    Sam

Leave a Reply

Your email address will not be published. Required fields are marked *