WooCommerce: “Buy One Get One” (BOGO)

Case scenario: if you add a product ID to cart with a specific, you want another product automatically added to cart (Buy One Get One, or “BOGO”).

This second product should have price = 0 if you wish to completely give it away, or maybe a set sale price. It should also be set to “hidden” because maybe you want to hide this free product from the shop and only gift it when the first one is added to Cart.

Also, if you remove product 1, the gifted product should go away from the Cart too. So here follows the PHP snippet of course!

WooCommerce: add free gift to cart if product is added to cart

PHP Snippet: Add Another Product To Cart If A Given Product Is Added To Cart (BOGO)

/**
 * @snippet       Buy 1 Get 1 - WooCommerce
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    Woo 8
 * @community     https://businessbloomer.com/club/
 */

add_action( 'template_redirect', 'bbloomer_add_gift_if_id_in_cart' );

function bbloomer_add_gift_if_id_in_cart() {

	if ( is_admin() ) return;
	if ( WC()->cart->is_empty() ) return;

	$product_bought_id = 32;
	$product_gifted_id = 57;

	// see if product id in cart
	$product_bought_cart_id = WC()->cart->generate_cart_id( $product_bought_id );
	$product_bought_in_cart = WC()->cart->find_product_in_cart( $product_bought_cart_id );

	// see if gift id in cart
	$product_gifted_cart_id = WC()->cart->generate_cart_id( $product_gifted_id );
	$product_gifted_in_cart = WC()->cart->find_product_in_cart( $product_gifted_cart_id );

	// if not in cart remove gift, else add gift
	if ( ! $product_bought_in_cart ) {
		if ( $product_gifted_in_cart ) WC()->cart->remove_cart_item( $product_gifted_in_cart );
	} else {
		if ( ! $product_gifted_in_cart ) WC()->cart->add_to_cart( $product_gifted_id );
	}
}

Advanced Plugin: WooCommerce Discount Manager

If you’re not comfortable with editing code, then I have found that you can achieve a similar result with the WooCommerce Discount Manager plugin by Barn2.

This well-written plugin lets you create flexible Buy One Get One Free deals, with whatever logic you like. You can choose which products it applies to, schedule the sale, and make it available to certain user roles or guests only.

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

  • WooCommerce: How to Fix the “Cart is Empty” Issue
    For some reason, sometimes you add products to cart but the cart page stays empty (even if you can clearly see the cart widget has products in it for example). But don’t worry – it may just be a simple cache issue (and if you don’t know what cache is that’s no problem either) or […]
  • WooCommerce: “You Only Need $$$ to Get Free Shipping!” @ Cart
    This is a very cool snippet that many of you should use to increase your average order value. Ecommerce customers who are near the “free shipping” threshold will try to add more products to the cart in order to qualify for free shipping. It’s pure psychology. Here’s how we show a simple message on the […]
  • WooCommerce: Cart and Checkout on the Same Page
    This is your ultimate guide – complete with shortcodes, snippets and workarounds – to completely skip the Cart page and have both cart table and checkout form on the same (Checkout) page. But first… why’d you want to do this? Well, if you sell high ticket products (i.e. on average, you sell no more than […]
  • WooCommerce: Weight-Based Shipping Methods
    With WooCommerce you get 3 default shipping methods: Flat Rate, Free Shipping, Local Pickup. For each one you can define a cost, however there is no way to set up some “weight” restrictions. So, what if you want to display a rate for orders below 10 kg, and another shipping rate for orders above that […]
  • WooCommerce: Hide Shipping Method If Shipping Class Is In The Cart
    Our goal is to check if a Product with a specific Shipping Class is in the Cart, and consequently disabling a shipping rate such as Free Shipping if this is true. This is super useful when there are multiple items in the cart and you don’t want to give free shipping for certain orders for […]

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

46 thoughts on “WooCommerce: “Buy One Get One” (BOGO)

  1. Hi, looking for solution where every third product added to the cart will be discounted 100% (for free). I would like woocommerce to filter the cheapest products in the cart and apply 100% discount to every 3rd product (so if I have 3 products in my cart, the cheapest one will be for free; if I have 6 product – two cheapest will be for free; etc.) Haven’t found the solution. Any tips?

    1. Hi Aleksander, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  2. is there a way to make this work for product categories?

    Would love for a customer to get two product in same categories after making a purchase for one.

    So it’s more like buy one get two free, would really appreciate the support.

    1. Hi Victor, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  3. Good Evening, I am hoping you can help. I copied a code online for a buy 3 get 1 free promotion I am working on, and am getting an error when testing that ends in “/home2/shineboutiqueonl/public_html/wp-content/plugins/code-snippets/php/snippet-ops.php(446) : eval()’d code on line 20”.

    Assuming that means the error in on line 20 of the code which is

            if (get_field('buy_3_get_1_coupon', $coupon->ID)) {

    . Does anything seem off here?

    Thank you.
    Melanie Fuller
    Shine Boutique

    1. That’s not my code, sorry

  4. Works like a charm: 14/9/2020 thank you very much

    1. Thanks!

  5. How should I modify the snippet, to have multiple product ID-s that the free gift should apply to? So the free gift is added to the cart if either product X or Y is in the cart.

    1. Hi Szabolcs, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  6. Hello,

    The code above works very well for one product, but here is a tested scenario that opens an unwanted door and some other issue (described in Scenario 2):

    Scenario 1: let’s say the visitor adds to cart product A, which is the main one, and gets his cart automatically filled with product A + product B (which is the “gift” product). Now, the user clicks several times on the “+” button for product B (the “gift”). What happens is that the discount is applied automatically to all the B products (“gifts”), such that in the end, the buyer gets 1 main product (A) and indefinitely many “gifts”.

    Scenario 2: Another issue with this code is that if the client buys 3 products A (the main ones), he only gets one product B (the “gift”). He has to adjust manually the quantity of “gifts”, but then we return to Scenario 1, where he can empty the stock of “gifts”.

    1. Hi Vladimir, thanks for your feedback. You could force the gift to be purchased “only once per order” to fix Scenario 1 (from its settings). This will of course go against Scenario 2, but you have to make a choice. Coding a “sync” between product A and product B is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

      1. Hello, Rodolpho, and thanks a lot for your reply.

        Eventually, I have managed to code it, thanks to your magnificent tutorials here.
        My problem was the following: I have to build a conference website where there is a connected event (a workshop after the conference). Whoever buys a ticket for the workshop, he gets one ticket free for the conference. The same goes for multiple purchases — N workshop tickets will get the buyer N free conference tickets.
        I had also to implement reductions for multiple purchases (3 — 5%, 4-10 — 10%, >11 — 15%) for both workshop and conference tickets, and also make sure that if a buyer gets N workshops and N + m conferences, he will have to pay for the additional m conference tickets in his cart (according to the reduction rules imposed by my customer).
        Thanks to your wonderful tutorials, I have managed to get the job done (and also managed to start understanding how the Woocommerce plugin is coded).
        Mille grazie for the inspiration found on your website here!

        Vladimir.

        1. Excellent!

  7. Can’t seem to find this tutorial which is inside the snippet: https://businessbloomer.com/?p=19055
    Where can I find the tutorial now?

    1. Sorry about that Paul – should work now. Let me know

  8. Thank you so much!
    I appreciate you helping us out with this useful tip.
    I modified a bit so where you have:

    $giftsku = ('Product X');

    I changed it to

    $giftsku = array('Product X','Product Y','Product Z'); 

    The problem I’m having is that the discount is still applied when the product that gives the gift is removed from the cart. What modification would I need to use in order to fix that? Thanks!

    1. Hey Chris, thanks so much for your comment! Yes, this is possible – unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R

  9. Hi,

    This doesn’t seem to be working on your own sample site at present, so won’t even try to implement!

    Let us know when it’s fixed…

    Cheers

    1. Ahah good point Matt! I’m just not using it anymore, however the snippet still works πŸ™‚

  10. Hello & thanks for a great piece of code!
    See I have kind of trouble after implementing this code in my site I’ve got a woocommerce error message “Sorry this product cannot be purchased!” and it diesn’t appear in a Cart.

    I tried to use Grouped product or Single product (to be added in cart), with or without prices but no luck!

    1. Hey Dime πŸ™‚ Did you make sure to change all the SKUs and coupon codes inside the snippet?

  11. How do i apply the gift to ALL products in my website not only those SKU in $skuswithgift ?

    1. Avi, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  12. Hello ,

    I applied above code in my functions.php file. And i am able to manage to add another product in the cart. But my coupon is not working. My another product get added in the cart, but it’s price does not get discount to Zero, please help me out of this/

    1. Hey Divya, thanks so much for your comment! I just retested this on the latest version of WooCommerce and it still works. Unfortunately this looks like custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~R

  13. Hi

    I have added the code. So I also need to add a coupon that has 100% discount applied to the Free Gift right?

    Many Thanks

    1. Correct Dave! Or give the Gift a zero price πŸ™‚

  14. Hi Rodolfo,
    thanks for your snippet.

    Is there a way to flush the gift if the products that activate it will be removed from cart?

    Thanks in advance for your reply.

    1. Alessandro, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  15. Hi Rodolfo,
    Thank you for this great snippet. Its working only for simple product. How do i make it work for variable product.
    when someone buy particular variation, i tried to add variation sku, but its not adding free product to cart, Thanks in advance

    1. Hello Sunny, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  16. Hi , i just want a code for my website,
    if a person buy 3 item same 1 item free
    if its 6 then 2 free
    if its 10, 3 free

    can you help me on that

    thanks

    1. Raj, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  17. Hi,

    Is it possible to have this kind of concept… buy 1 product then after successfully shared to facebook, customer can able to choose another 1 product for free..

    Thanks

    1. Hey Marvin, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here on the blog. Thanks a lot for your understanding! ~R

    2. hi,

      thanks for the reply, i just played some codes to get what i want.. but i have one problem.

      Just want to ask if there’s anyway to change the add_to_cart button text for a certain product category..

      I already change the global product add to cart text into +show OFFER,. here’s the code

      function add_cart_button_replace() {
      global $product;
       $link = $product->get_permalink();
       echo do_shortcode('<a href="'.$link.'" rel="nofollow">+show OFFER</a>');
      }
      

      but what i want is to change the certain product category like “free-products”. when i open the archive of that certain category, it should be +choose me(with cart link) not the +show OFFER..

      Is that possible? thank you so much for the help..

      1. Marvin, yes, it is possible – but as I said I cannot help with custom work here in the blog comments. Thank you πŸ™‚

  18. How do I change this code to add to cart automatically if the price is more than $ 50 for example?

    1. How do I change this code to add to cart a gift automatically if the price is more than $ 50 for example?

  19. Can this be changed to add product x for any product added to cart?

  20. Hi,
    It’s great but if the first product (the one that gives the gift) is removed from the cart, the gift is still there and free that might be a problem.

    1. Julia, thanks for your comment, and spot on! Maybe this could help: https://gist.github.com/yojance/042350679b5222fcf16e

    2. Hi, I am having this same issue, did you ever get it fixed?

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

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