Istiaq Nirab full stack + ai
← Writing
WooCommerce Dec 20, 2022

WooCommerce auto apply & remove coupon

Apply coupon in cart based on certain conditions

It’s very good idea to give your customer some discounts. You can increase your sales to give some discounts based on certain conditions.

These certain conditions can be something like :

  • If anyone has equal OR greater than X amount of items in carts Then give Y amount discount in checkout as coupons.
  • If anyone put X quantity of items in carts Then give Y quantity discount in checkout as coupons.
  • Apply automatic coupon when anyone get into site via specific custom url.
  • If Subtotal is greater than X then give Y discount.

and many more …

You can do this in two ways.

  1. Using third-party plugins

    Checkout Advance Coupons for Woocommerce plugin which can extends default WooCommerce coupon features.

  2. Write own solution Programmatically

Lets take an example:

If Subtotal is greater than X then give Y discount.

Here Y discount will be applied via Y Coupon. So the coupon must be created first in Marketing > Coupons. We only apply it from code, we don’t create it from code.

<?php

add_action('woocommerce_before_cart', 'auto_coupon');
add_action('woocommerce_before_checkout_form', 'auto_coupon');

function auto_coupon() {
   $coupon_code = 'over199'; // your existing coupon code
   $x_amount    = 199;

   $applied_coupons = WC()->cart->get_applied_coupons();
   $subtotal        = WC()->cart->get_subtotal();

   if (!in_array($coupon_code, $applied_coupons) && $subtotal > $x_amount) {
      WC()->cart->apply_coupon($coupon_code);
   }
}

woocommerce_before_cart covers the cart page and woocommerce_before_checkout_form covers the checkout page. Don’t use wp_head or init here, cart is not ready that early.

Now remove it

Apply is the easy half. The real problem starts when customer removes a product and subtotal goes down to 150, but the coupon is still sitting there. Customer gets the discount without the condition. So the same function have to remove it back :

<?php

add_action('woocommerce_before_cart', 'auto_coupon');
add_action('woocommerce_before_checkout_form', 'auto_coupon');

function auto_coupon() {
   $coupon_code = 'over199';
   $x_amount    = 199;

   $applied_coupons = WC()->cart->get_applied_coupons();
   $subtotal        = WC()->cart->get_subtotal();
   $has_coupon      = in_array($coupon_code, $applied_coupons);

   if ($subtotal > $x_amount) {
      if (!$has_coupon) {
         WC()->cart->apply_coupon($coupon_code);
      }
   } else {
      if ($has_coupon) {
         WC()->cart->remove_coupon($coupon_code);
      }
   }
}

One thing to keep in mind, remove_coupon() only removes the code you pass. Manually entered coupons of the customer stays untouched, which is what we want.

Same thing with quantity

If your condition is quantity instead of money, only the check part changes :

<?php

$count = WC()->cart->get_cart_contents_count();

if ($count >= 3) {
   // apply
} else {
   // remove
}

Some notes

Check the coupon really exists.

If somebody deletes the coupon from admin, apply_coupon() will throw a notice on every page load. A small guard saves you :

<?php

if (wc_get_coupon_id_by_code($coupon_code) == 0) return;

The notices.

WooCommerce prints “Coupon code applied successfully.” and “Coupon has been removed.” every time. Customer didn’t do anything, so it looks strange. You can clear them :

<?php

WC()->cart->apply_coupon($coupon_code);
wc_clear_notices();

Better way is to clear only the coupon ones and show your own message, but for most shops wc_clear_notices() after the apply is enough.

Individual use only.

If your auto coupon is marked as Individual use only, applying it will kick out the coupon customer typed by hand. Customer will not be happy. Keep the auto coupon normal unless you really need it.

Don’t do it inside woocommerce_before_calculate_totals.

Looks tempting because it runs everywhere, but get_subtotal() is not calculated yet at that point and applying a coupon there triggers the totals again. You get a loop. Stick with the cart & checkout hooks.

Thanks.

Discussion

Comments run on giscus, backed by GitHub Discussions — sign in with GitHub to reply.

More posts
LLM

Five steps from a business problem to an LLM that actually ships

Understand, prepare, select, customize, productionize. A working order of operations for picking a language model and getting it into production without burning a quarter.

2026-09-12
NLP

N-grams: the language model before language models

How N-grams turn text into countable sequences, how they predict the next word, and why counting eventually stopped being enough.

2026-09-11
Laravel

Setup vsCode for Laravel Development

The extensions and keyboard shortcuts that turn Visual Studio Code into a proper Laravel editor.

2023-09-22
ContactGMT+6

Have something that needs building, fixing, or finishing? Write one paragraph — that's usually enough.

open to new work
Local time--:--:--
Based inDhaka, BD
Experience6+ years