How to Display the Discount Percentage on the Sale Badge?

Be default Woocommerce sale badge shows only text (“Sale”) but there is no out-of-the-box option if you want the sale badge to show the discount percentage. For example, instead of saying ”Sale” you would like it to show “- 40%”.

Therefore, in this post I am going to show you how to display the discount percentage on the Woocommerce sale badge.

Video: How to Add the Discount Percentage on the Woocommerce Sale Badge?

How to Display the Discount Percentage on the Sale Badge (single products only)?

Step 1: Copy the code here below

Step 2: Add it to your functions.php file. Better option, install and add the code using Code snippets plugin

add_action( 'woocommerce_sale_flash', 'sale_badge_percentage', 25 );
 
function sale_badge_percentage() {
   global $product;
   if ( ! $product->is_on_sale() ) return;
   if ( $product->is_type( 'simple' ) ) {
      $max_percentage = ( ( $product->get_regular_price() - $product->get_sale_price() ) / $product->get_regular_price() ) * 100;
   } elseif ( $product->is_type( 'variable' ) ) {
      $max_percentage = 0;
      foreach ( $product->get_children() as $child_id ) {
         $variation = wc_get_product( $child_id );
         $price = $variation->get_regular_price();
         $sale = $variation->get_sale_price();
         if ( $price != 0 && ! empty( $sale ) ) $percentage = ( $price - $sale ) / $price * 100;
         if ( $percentage > $max_percentage ) {
            $max_percentage = $percentage;
         }
      }
   }
   if ( $max_percentage > 0 ) echo "<span class='onsale'>-" . round($max_percentage) . "%</span>"; // If you would like to show -40% off then add text after % sign
}

How to Display the Discount Percentage on the Sale Badge for variable products, single products and grouped products?

If you need to display the discount percentage on the sale badge for both variable products and sale products then use this code.

// Display the Woocommerce Discount Percentage on the Sale Badge for variable products and single products
add_filter( 'woocommerce_sale_flash', 'display_percentage_on_sale_badge', 20, 3 );
function display_percentage_on_sale_badge( $html, $post, $product ) {

  if( $product->is_type('variable')){
      $percentages = array();

      // This will get all the variation prices and loop throughout them
      $prices = $product->get_variation_prices();

      foreach( $prices['price'] as $key => $price ){
          // Only on sale variations
          if( $prices['regular_price'][$key] !== $price ){
              // Calculate and set in the array the percentage for each variation on sale
              $percentages[] = round( 100 - ( floatval($prices['sale_price'][$key]) / floatval($prices['regular_price'][$key]) * 100 ) );
          }
      }
      // Displays maximum discount value
      $percentage = max($percentages) . '%';

  } elseif( $product->is_type('grouped') ){
      $percentages = array();

     // This will get all the variation prices and loop throughout them
      $children_ids = $product->get_children();

      foreach( $children_ids as $child_id ){
          $child_product = wc_get_product($child_id);

          $regular_price = (float) $child_product->get_regular_price();
          $sale_price    = (float) $child_product->get_sale_price();

          if ( $sale_price != 0 || ! empty($sale_price) ) {
              // Calculate and set in the array the percentage for each child on sale
              $percentages[] = round(100 - ($sale_price / $regular_price * 100));
          }
      }
     // Displays maximum discount value
      $percentage = max($percentages) . '%';

  } else {
      $regular_price = (float) $product->get_regular_price();
      $sale_price    = (float) $product->get_sale_price();

      if ( $sale_price != 0 || ! empty($sale_price) ) {
          $percentage    = round(100 - ($sale_price / $regular_price * 100)) . '%';
      } else {
          return $html;
      }
  }
  return '<span class="onsale">' . esc_html__( 'up to -', 'woocommerce' ) . ' '. $percentage . '</span>'; // If needed then change or remove "up to -" text
}

How to Display the Discount Percentage on the Sale Badge for specific user roles?

You can use the code below to display the WooCommerce discount percentage on the sale badge for specific user roles. Pay special attention to line 37, where the user role “silver” is defined; feel free to modify it as needed and add your own user role.


// Add filter for single product pages
add_filter('woocommerce_sale_flash', 'display_percentage_on_sale_badge', 20, 3);

// Add filter for archive pages (shop, category, tag pages)
add_filter('woocommerce_before_shop_loop_item_title', 'display_archive_sale_badge', 10);

/**
 * Display sale badge on archive pages
 */
function display_archive_sale_badge() {
    global $product;
    if ($product->is_on_sale()) {
        echo calculate_sale_badge($product);
    }
}

/**
 * Display sale badge on single product pages
 */
function display_percentage_on_sale_badge($html, $post, $product) {
    return calculate_sale_badge($product);
}

/**
 * Calculate and format the sale badge HTML
 *
 * @param WC_Product $product
 * @return string
 */
function calculate_sale_badge($product) {
    // Check if user is logged in and has 'silver' role
    if (!is_user_logged_in()) {
        return ''; // Return empty string to hide badge for logged out users
    }

    $user = wp_get_current_user();
    if (!in_array('silver', (array) $user->roles)) {
        return ''; // Return empty string to hide badge for non-silver users
    }

    // Calculate discount percentage based on product type
    if ($product->is_type('variable')) {
        $percentages = array();
        // Get all variation prices
        $prices = $product->get_variation_prices();
        foreach ($prices['price'] as $key => $price) {
            // Only on sale variations
            if ($prices['regular_price'][$key] !== $price) {
                // Calculate percentage for each variation on sale
                $percentages[] = round(100 - (floatval($prices['sale_price'][$key]) / floatval($prices['regular_price'][$key]) * 100));
            }
        }
        // No sale variations found
        if (empty($percentages)) {
            return '';
        }
        $percentage = max($percentages) . '%';
    } elseif ($product->is_type('grouped')) {
        $percentages = array();
        // Get all children products
        $children_ids = $product->get_children();
        foreach ($children_ids as $child_id) {
            $child_product = wc_get_product($child_id);
            $regular_price = (float) $child_product->get_regular_price();
            $sale_price    = (float) $child_product->get_sale_price();
            if ($sale_price != 0 && !empty($sale_price)) {
                // Calculate percentage for each child on sale
                $percentages[] = round(100 - ($sale_price / $regular_price * 100));
            }
        }
        // No sale products found in group
        if (empty($percentages)) {
            return '';
        }
        $percentage = max($percentages) . '%';
    } else {
        $regular_price = (float) $product->get_regular_price();
        $sale_price    = (float) $product->get_sale_price();
        
        if ($sale_price == 0 || empty($sale_price)) {
            return '';
        }
        $percentage = round(100 - ($sale_price / $regular_price * 100)) . '%';
    }

    // Add a CSS class for archive pages to help with styling if needed
    $additional_class = (is_archive() || is_shop()) ? ' archive-sale-badge' : '';
    
    return sprintf(
        '<span class="onsale%s">%s %s</span>',
        esc_attr($additional_class),
        esc_html__('up to -', 'woocommerce'),
        esc_html($percentage)
    );
}

/**
 * Optional: Add custom CSS for archive page badges
 */
add_action('wp_head', 'add_sale_badge_css');
function add_sale_badge_css() {
    ?>
    <style>
        /* Adjust archive page badge positioning if needed */
        .archive-sale-badge {
            position: absolute;
            top: 0;
            right: 0;
            z-index: 9;
            background: #77a464;
            color: #fff;
            padding: 0.202em 0.6em;
            font-size: 0.857em;
            border-radius: 3px;
        }
    </style>
    <?php
}

Related Woocommerce hacks

Do you want to thank me and buy me a beer?

Every donation is entirely welcome but NEVER required. Enjoy my work for free but if you would like to thank me and buy me a beer or two then you can use this form here below.

Donation Form (#2)

Here are some of my favorite WordPress tools

Thanks for reading this article! I hope it's been useful as you work on your own websites and e-commerce sites. I wanted to share some tools I use as a WordPress developer, and I think you'll find them helpful too.

Just so you know, these are affiliate links. If you decide to use any of them, I'll earn a commission. This helps me create tutorials and YouTube videos. But honestly, I genuinely use and recommend these tools to my friends and family as well. Your support keeps me creating content that benefits everyone.

Themes: Over the past few years, I've consistently relied on two primary themes for all sorts of projects: the Blocksy theme and the Kadence Theme. If you explore this website and my YouTube channel, you'll come across numerous tutorials that delve into these themes. If you're interested in obtaining a 10% discount for both of these themes, then:

Code Snippets Manager: WPCodeBox allows you to add code snippets to your site. Not only that, but it also provides you with the capability to construct and oversee your WordPress Code Snippets library right in the cloud. You can grab it with the 20% discount here (SAVE 20% Coupon: WPSH20).

Contact forms: There are hundreds of contact forms out there but Fluent Forms is the one I like the most. If you need a 20% discount then use this link (save 20% coupon is WPSH20).

Gutenberg add-ons: If I need a good Gutenberg blocks add-on then Kadence Blocks is the one I have used the most. You’ll get a 10% discount with the coupon SIMPLEHACKS here.

Website migration: While building a website you probably need a good plugin that can help you with the migration, backups, restoration, and staging sites. Well, WpVivid is the one I have used for the last couple of years. If you use this link along with the WPSH20 coupon you’ll get a 20% discount.

Woocommerce extensions: There are a bunch of Woocommerce extensions that I like but the one that stands out is Advanced Dynamic Pricing. Once again, you’ll get a 20% discount if you use this link here (save 20% coupon is WPSH20)

Web Hosting: If you would like to have a really fast and easy-to-use managed cloud hosting, then I recommend Verpex Hosting (see my review here). By the way, this site is hosted in Verpex.)

To see all my most up-to-date recommendations, check out this resource that I made for you!

Janek T.
Janek T.

Improve this text: {CLIPBOARD}

- I have been passionate about Wordpress since 2011, creating websites and sharing valuable tips on using Wordpress and Woocommerce on my site.
- Be the first to receive notifications about new tutorials by subscribing to my Youtube channel .
- Follow me on Twitter here

Articles: 134