Showing price after an automatic discount directly on the product page

armdgnthr
Shopify Partner
1 0 14

Hi there!

 

I wanted to test the automatic discounts for special events, for example the Summer Sales or whatever.

So the I created my automatic discount and selected the products I want to apply it on. On the cart, no problem the price displayed is the actual price minus the reduction.

 

Thing is, I'd like to change the price on the product page too. For the moment, the normal price is still displayed. If possible I would like to avoid setting the price manually for each variant of each product, I have a lot of them...

 

In fact, I'd like to have something exactly like when you I apply manually the discount in the 'Pricing' section of the product: the real price crossed and the discounted price showed. And with the sentence 'You saved $XX !" also.

 

I tried to modify the code by copying the code from the cart page to the product page but was unsuccessful. I can't manage to get the discounted price, the price showing is still the one before the discount.

 

Anyone has an idea how I can solve this ? Or an indication ?

 

Thanks a lot!

Replies 22 (22)

vianap
Visitor
2 0 5

This is exacly what I'm looking for and got nothing yet on google, I hope someone could help us.

C4r4m314ppl3s
Visitor
1 0 10
I’ve been looking for this! So, far I’ve asked 3 Shopify collaborators who have been no help and told me it only exists for the cart page. I feel like this is a necessity for online shops, yet Shopify lacks that major feature. I hope someone can solve this soon.

mozz
Visitor
1 0 3

I have the same issues, I am not able to find anything to help

BradSCJB
Explorer
81 0 157

Looking for a solution for this as well....

 

Shopify....? Are you listening?

bathroomvillage
Excursionist
12 0 15

Same here, would love to only have 1 price list, then everything else managed by "automatic discounting"

 

Have requested via live chat, so will wait to hear back

RGarcia
Visitor
2 0 12

I'm trying to do the same thing.  I had to go back to my products and change the pricing manually, and take off the automatic discount.  It was easy though with holding down shift key and clicking the bottom cell to be able to change all at once.  I agree - Shopify needs to add an option to the discount settings so that customers can see the discount reflect immediately.  

tkwinter
Visitor
1 0 8

I can't believe this isn't available yet - all the major retailers have slashed prices (especially on Cyber Monday) and you are way more apt to add something to your cart when you see the savings. Shopify - please hurry up!


Pardoc
Excursionist
13 1 0

After much research, I also did not find a solution on the internet. The main problem is that 'line_level_discount_allocations' is only available in a for loop which traverses the 'cart' object. I tinker with a functional solution for our shop, but I warn you I am a novice:

 

let pvfID = {{ product.variants.first.id }},
            newVal = 1,
            discounts= [],
            discountAllocation = function (type, title, value, valueType, allocationMethod, targetSelection, targetType, totalAllocatedAmount) {
              this.type = type;
              this.title = title;
              this.value = value;
              this.valueType = valueType;
              this.allocationMethod = allocationMethod;
              this.targetSelection = targetSelection;
              this.targetType = targetType;
              this.totalAllocatedAmount = totalAllocatedAmount;
            },
            pvfIDPOST = function() {
              jQuery.post('/cart/add.js', {quantity: 1, id: pvfID})
            },
            pvfIDREMOVE = function(newQty){
              jQuery.post('/cart/change.js', {quantity: newQty, id: pvfID})
            };
       
        $.when( pvfIDPOST() ).done(setTimeout (function() {        	
            jQuery.getJSON('/cart.js', function(cart) {      
              for(let i = 0; i < cart.items.length; i++){
                if(pvfID === cart.items[i].id){
                    let currentQty = cart.items[i].quantity;
                    if(cart.items[i].line_level_discount_allocations.length > 0){
                      for(let it = 0; it < cart.items[i].line_level_discount_allocations.length; it++){
                        let currentItem = cart.items[i].line_level_discount_allocations[it].discount_application;                        
                        discounts[it] = new discountAllocation(currentItem.type, currentItem.title, currentItem.value, currentItem.value_type, currentItem.allocation_method, currentItem.target_selection, currentItem.target_type, currentItem.total_allocated_amount);                                                
                      }
                      showDiscount();
                      pvfIDREMOVE(currentQty-1);
                    }else{
					  console.log('discount allocations not fount');
                      pvfIDREMOVE(currentQty-1);
                    }
                }
              }
            });
			Shopify.getCart(function(data){ console.log(data); })
        }, 2000 ));
        
        function showDiscount(){
          for(let i = 0; i < discounts.length; i++){
            
            console.log(discounts[i])
          }
        }

This javascript code uses the jquery library. it uses the shopify API to add the product from the product page consulted in the cart, extracts the automatic promotion and finally it removes the product from the cart. The content of the automatic promotion will be visible in the console. You still have to modify the current code to display the information that interests you on your template.

HouseofBestToys
Visitor
2 0 0

So where would you paste/copy this?

iwan
Visitor
2 0 1

did you found already a solution?

 

thanks

 

iwan

 

Pardoc
Excursionist
13 1 0

my system is not perfect but it works for me, but not on variant product

i use : 

 

{% assign prixTTC = product.price | times: 1.2 %}

{% if product.compare_at_price_max > 0 %}
     {% assign baseTTC = product.compare_at_price | times: 1.2 %}
     {% assign pourcentage = product.price | times: 1000 | divided_by: product.compare_at_price_max %}
     {% assign pourcentageReduction = 1000 | minus: pourcentage | divided_by: 10 %}
     {% assign eurosReduction = baseTTC | minus: prixTTC %}
{% endif %}

<script type="text/javascript">
      // Auto Discount
      let pvfID = {{ product.variants.first.id }},
          priceShopify = {{ product.price }},
          taxes = 1.2,
            totalValueTTC = 0,
            discounts= [],
            discountAllocation = function (type, title, value, valueType, allocationMethod, targetSelection, targetType, totalAllocatedAmount) {
            this.type = type;
            this.title = title;
            this.value = value;
            this.valueType = valueType;
            this.allocationMethod = allocationMethod;
            this.targetSelection = targetSelection;
            this.targetType = targetType;
            this.totalAllocatedAmount = totalAllocatedAmount;
          },
            pvfIDPOST = function() {
            jQuery.post('/cart/add.js', {quantity: 1, id: pvfID})
          },
            pvfIDREMOVE = function(newQty){
            jQuery.post('/cart/change.js', {quantity: newQty, id: pvfID})
          };
        
        // Check Auto Discount
        function checkAutoDiscount(){
          jQuery.getJSON('/cart.js', function(cart) {
            for(let i = 0; i < cart.items.length; i++){
              if(pvfID === cart.items[i].id){
                if(cart.items[i].variant_options.length >= 1 ){
                  let currentQty = cart.items[i].quantity;
                  if(cart.items[i].line_level_discount_allocations.length > 0){
                    for(let it = 0; it < cart.items[i].line_level_discount_allocations.length; it++){
                      let currentItem = cart.items[i].line_level_discount_allocations[it].discount_application;                        
                      discounts[it] = new discountAllocation(currentItem.type, currentItem.title, currentItem.value, currentItem.value_type, currentItem.allocation_method, currentItem.target_selection, currentItem.target_type, currentItem.total_allocated_amount);                                                
                    }
                    
                    showDiscount();
                    pvfIDREMOVE(currentQty-1);
                  }else{
                    console.log('automatic discount : no');
                    pvfIDREMOVE(currentQty-1);
                  }
                }
              }
            }
            
          });        
        }
        
        // YOU NEED CUSTOM THIS FOR YOUR THEM :
        function showDiscount(){
          $('.detail-price .price-sale').fadeOut();
          for(let i = 0; i < discounts.length; i++){
            let value = parseInt(discounts[i].value, 10);
            
            // Percent Discount
            if(discounts[i].valueType === 'percentage'){
              let valueTTC = (((priceShopify * value) / 10000)*taxes).toFixed(2);
              $('#product_v2_allDiscountBox').append(
                '<div class="product_v3_badge4">'+
                '<i class="demo-icon icon-electro-cart-icon"></i>'+
                ' '+discounts[i].title+' : -'+value+'%'+'  vous économisez : '+valueTTC+'€'+
                '</div>'
              );
              if($(window).width() < 457 ){
                
                  $('.detail-price').append(
                    '<div class="price-sale" style="color: #5bb300!important">'+
                    ((priceShopify / 100) * taxes - valueTTC).toFixed(2)+'€'+
                    '</div>'
                  );

                  // Product Discount
                  {% if product.compare_at_price_max > 0 %}
                    $('.product_v2_boxContent .product-price').append(
                      '<div class="product_v2_reductionValue" style="background-color: rgb(194, 222, 244);">'+
                      '<div class="sale-text">'+
                      'Remise sur le produit : <strong>-'+{{pourcentageReduction}}+'%</strong>'+
                      '</div>'+
                      '</div>'
                    )
                   {% endif %}

                  // Cart Discount
                  $('.product_v2_boxContent .product-price').append(
                    '<div class="product_v2_reductionValue" style="background-color: rgb(194, 222, 244);">'+
                      '<div class="sale-text">'+
                          'Offre spéciale : <strong>-'+value+'%</strong>'+
                      '</div>'+
                    '</div>'
                  )
                
              }else{
                $('.product_v2_reduction').append(                       
                  '<div class="product_v2_reductionValue">'+
                    '<div class="sale-text" style="background-color: #5bb300">'+
                      '-'+value+'%'+
                    '</div>'+
                  '</div>'
                );
                $('.detail-price').append(
                  '<div class="price-sale" style="color: #5bb300!important">'+
                      ((priceShopify / 100) * taxes - valueTTC).toFixed(2)+'€ TTC'+
                  '</div>'
                );
              }
              totalValueTTC += valueTTC;
              
            // Remise fixe
            }else{
              let valueTTC = (value * taxes).toFixed(2);
              $('#product_v2_allDiscountBox').append(                         
                '<div class="product_v3_badge4">'+
                '<i class="demo-icon icon-electro-cart-icon"></i>'+
                ' '+discounts[i].title+' : -'+valueTTC+'€ TTC'+
                '</div>'
              );
              if($(window).width() < 457 ){
                $('.detail-price').append(
                  '<div class="price-sale" style="color: #5bb300!important">'+
                  ((priceShopify / 100) * taxes - valueTTC).toFixed(2)+'€'+
                  '</div>'
                );
                // Product Discount
                {% if product.compare_at_price_max > 0 %}
                  $('.product_v2_boxContent .product-price').append(
                    '<div class="product_v2_reductionValue" style="background-color: rgb(194, 222, 244);">'+
                      '<div class="sale-text">'+
                      	'Remise sur le produit : <strong>-'+{{pourcentageReduction}}+'%</strong>'+
                      '</div>'+
                    '</div>'
                  )
                 {% endif %}
                // Cart Discount
                $('.product_v2_boxContent .product-price').append(
                  '<div class="product_v2_reductionValue" style="background-color: rgb(194, 222, 244);">'+
                  '<div class="sale-text" >'+
                  	'Offre spéciale : <strong>-'+value * taxes +'€ TTC</strong>'+
                  '</div>'+
                  '</div>'
                )
              }else{
                $('.product_v2_reduction').append(                       
                  '<div class="product_v2_reductionValue">'+
                  '<div class="sale-text" style="background-color: #5bb300">'+
                  '-'+value+'€'+
                  '</div>'+
                  '</div>'
                );
                $('.detail-price').append(
                  '<div class="price-sale" style="color: #5bb300!important">'+
                  ((priceShopify / 100) * taxes - valueTTC).toFixed(2)+'€ TTC'+
                  '</div>'
                );
              }

              totalValueTTC += valueTTC;
            }
            
            // Add style mobile
            if($(window).width() < 457 && {{product.compare_at_price_max}} != null ){
              for (let ite =0; ite < $('.product_v2_reduction').length; ite++){
                $('.detail-price').css('width','75%');
                $('.detail-price').css('margin','auto');
                $('.detail-price').css('flex-flow','row-reverse');
                $('.product_v2_reduction').css('margin','10px 0');
				$('.price-compare').css('flex','1');
                $('.price-compare s').css('margin','0 5px 3px 5px');
                $('.price-compare s').css('font-size','22px');
                $('.detail-price .product_v2_reductionValue').css('display','none');
                $('.price-sale').css('font-size','30px');
                $('.price-sale').css('flex','1');
              }
            }
          }
        }                                       
        
        // Start checkAutoDiscount if variant is not available
		{% unless variant.available %}
          $.when( pvfIDPOST() ).done(setTimeout (function() {        	
            checkAutoDiscount()
          }, 1000 ));
        {% endunless %}
</script>


I hope this will inspire you.

Steven_Amrhein
Shopify Partner
7 0 10

Hi, showing automatic discount prices on pages other than the cart is possible, but it requires you being comfortable editing your theme. This solution works on collection pages and product pages, and with variants. It does not work with automatic discounts that have minimum requirements other than a quantity of 1. This solution may have unintended consequences for analytics and page speed, because it involves adding and removing large numbers of products from the cart using the Ajax API. @Pardoc's method is on the right track. Because automatic discounts are only applied after products are added to the cart, on every page where a product price appears, we have to add those products to the cart temporarily using the Ajax API, check their discounted prices in the cart, update prices on the page with those discounted prices, then remove them from the cart.

I've listed instructions below which should work with most of Shopify's free sectioned themes. I've tested it with Simple, Boundless, Venture, Debut, and Supply. You can easily break your theme, so be sure to make a backup before editing any code. To make a backup, navigate to the themes page and next to your live theme click Actions > Download theme file.

  1. Open your theme's main JavaScript file in the code editor, usually Assets > theme.js or Assets > theme.js.liquid. At the very bottom, add this code, which provides the bulk of the discount price functionality:
    /*
    Update displayed product prices to reflect automatic discounts
    */
    //newly added product listing selector and theme's single product variant select element
    if($('[data-price-id], form[action="/cart/add"] select[name="id"]').length){
      displayAutoDiscounts();
    }
    
    //when variants are changed on a product page, update the displayed price
    var $new_price = $();
    $(document).on("change", ".single-option-selector", function(){
      $new_price.remove();
      //theme's single product price wrapper element
      var $price = $('[itemprop="price"]:not(meta), .product__price, #productPrice-product-template');
      $price.show();
      displayAutoDiscounts();
    });
    
    //add all products prices on this page to a data array including a unique item property so that they can be removed later
    function displayAutoDiscounts(){
      var items_to_add = [];
      var item_counter = 0;
      $('[data-price-id]').each(function( index ){
        items_to_add.push({
          quantity: 1,
          id: $(this).data('price-id'),
          properties: {
              'discount_check': 1
            }
        });
      });
      //theme's single product variant option element
      $('form[action="/cart/add"] select[name="id"] option').each(function( index ){
        items_to_add.push({
          quantity: 1,
          id: $(this).val(),
          properties: {
              'discount_check': 1
            }
        });
      });
      
      //add items to the cart
      if(items_to_add.length){
        $.ajax({
          type: 'POST', 
          url: '/cart/add.js',
          dataType: 'json', 
          data: { "items": items_to_add },
          success: itemsAdded
        });
      }
    }
      
    //check the items in the cart for automatic discounts, update the displayed price, then remove them from the cart
    function itemsAdded(response){
      var items_to_remove = {};
    
      //update displayed prices
      for (item of response.items) {
        items_to_remove[ item.key ] = 0;
        if(item.discounted_price < item.original_price && item.discounts.length > 0){
          //item has a discount, update the sale price
          var discount_dollars = item.discounted_price / 100;
          discount_dollars = discount_dollars.toLocaleString("en-US", {style:"currency", currency:"USD"});
          var regular_dollars = item.original_price / 100;
          regular_dollars = regular_dollars.toLocaleString("en-US", {style:"currency", currency:"USD"});
          var saved_dollars = (item.original_price - item.discounted_price) / 100;
          saved_dollars = saved_dollars.toLocaleString("en-US", {style:"currency", currency:"USD"});
          
          //get product listing price element
          var $price = $('[data-price-id="'+item.id+'"]');
          var is_single = false;
          
          if(!$price.length){
            //theme's single product variant option element
          	$price = $('form[action="/cart/add"] select[name="id"] option[value="'+item.id+'"]');
            is_single = true;
          }
                
          if($price.is(':selected')){
            //get single product price element
            //theme's single product price wrapper element
            $price = $('[itemprop="price"]:not(meta), .product__price, #productPrice-product-template');
            
          } else if( $price.is('option')){
            //price is for the unselected variant, skip
            continue;
          }
          
          /*
          adjust the following to match your theme's sale price display
          */
          if(is_single){
            //single product price display update
          	$price.hide();
            $new_price.remove();
          	$new_price = $(
              '<h4><span style="color:green">' + discount_dollars + '</span> \
    		  <s>' + regular_dollars + '</s>\
    		  <small style="display:inline-block; line-height: 1.2; padding: 0 0.2em; color:white; background: green;">SALE</small> \
    		  <small style="color:green;">You saved ' + saved_dollars + '!</small></h4>'
            );
            $price.after($new_price);
          } else {
            //product listing price display update
            $price.empty();
          	$price.append(
              '<span><span style="color:green">' + discount_dollars + '</span> \
              <s>' + regular_dollars + '</s></span>\
    		  <small style="display:inline-block; line-height: 1.2; padding: 0 0.2em; color:white; background: green;">SALE</small>'
          	);
          }
          /*
          END adjust the following to match your theme's price elements
          */
        }
      }
    
      //remove items from the cart
      $.ajax({
        type: 'POST', 
        url: '/cart/update.js',
        dataType: 'json', 
        data: {
          updates: items_to_remove
        }
      });
    }
      
    //in case the there are temp items still in the cart, remove them on the cart page
    if($('body').hasClass('template-cart')){
      cleanupCart();
    }
      
    function cleanupCart(){
      if($('[data-cart-item-property-name]:contains("discount_check")').length){
      
        $.getJSON('/cart.js', function(cart) {
    
          var items_to_remove = {};
    
          cart.items.forEach(function(item) {
            //only remove discount check items from cart based on item property
            if(typeof item.properties.discount_check !== 'undefined'){
              items_to_remove[item.key] = 0;
            }
          });
          
          //remove items from the cart and refresh the page
          var params = {
            url: '/cart/update.js',
            data: { updates: items_to_remove },
            dataType: 'json'
          };
          
    	  if( Object.keys(items_to_remove).length !== 0 ){
            $.post(params).always(
              function() {
                location.reload();
              }
            );
          } else {
          	location.reload();
          }
          
        });
      }
    }
    /*
    END Update displayed product prices to reflect automatic discounts
    */
  2. Next you'll need to modify the price that appears in product lists, such as on collection pages. Our script needs to know the product variant id of the product in the list. This is done by adding a variant id to a data attribute on the html element that wraps the product price. The location of the code that renders the product list items varies from theme to theme. Here are the file and html tags that you'll need to edit in each theme that I've tested:

    Simple - Snippets > product-grid-item.liquid - <div class="product__prices text-center">
    Boundless - Snippets > product-grid-item.liquid - <p class="product-item__price-wrapper">
    Venture - Snippets > product-cart.liquid - <div class="product-card__price">
    Debut - Snippets > product-price-listing.liquid - <dl class="price price--listing ... >
    Supply - Snippets > product-grid-item.liquid - <div class="product-item--price">

    Within the opening tag of the element that wraps the product price, add:
    {% if product.variants.first.available %}data-price-id="{{ product.variants.first.id }}"{% endif %}
    For example, with the Venture theme, that opening tag will now be:
    <div {% if product.variants.first.available %}data-price-id="{{ product.variants.first.id }}"{% endif %} class="product-card__price">
  3. Last step. Product recommendations in some themes are loaded via Ajax, so our script may run before these products appear. To update the prices on recommended products, you need to edit Sections > product-recommendations.liquid, if your theme contains this file. Just after the line:
    {%- if recommendations.products_count > 0 -%}
    add the line:
    <script>if (typeof displayAutoDiscounts === "function") { displayAutoDiscounts(); }</script>
    This re-runs the JavaScript function that updates the prices.

 

If these instructions don't work with your theme, check to make sure that you have included jQuery. Also, in theme.js you may need to replace the jQuery selector underneath

//theme's single product price wrapper element

with a jQuery selector for the html element that wraps the price on single product pages.

This solution is somewhat generic, so the discount price will need to be styled to match your theme. In theme.js, the html for the discount price can be found underneath

/*
adjust the following to match your theme's sale price display
*/

 

I've included different price discount html for the single product page and product listings.

 

This code can definitely be optimized, but hopefully it helps someone!

Steven_Amrhein
Shopify Partner
7 0 10

WARNING: I just confirmed that my above code adds a huge amount of Add-to-cart events to Shopify Analytics, Facebook, and Google Analytics. I'm not sure if there's a way to exclude them, so use it at your own risk.

jesssss
Visitor
1 0 0

Hi Steven_Amrhein,

Did you end up figuring out how to fix this issue? I did the same code as what was detailed in the above post, and I also realized random add to cart events. Does anyone know which part of the code is doing this? Otherwise everything outlined above worked but it is messing up the add to cart analytics. Anyway of fixing it? I did mine on the minimal theme. Please let me know. Thanks

NewZealand
New Member
4 0 0

Hi, 

I manually solved this be adding the following codes :

Shopify Automatic Discount : 25% on ALL products  except products with product type is NODISCOUNT (or whatever condition you have on your automatic discount)

On Product page:  snippets\product-price.liquid

Replace From :
    assign compare_at_price = variant.compare_at_price
    assign price = variant.price
 
To:
if  product.type == "NODISCOUNT"
     assign compare_at_price = variant.compare_at_price
     assign price = variant.price
else 
    assign compare_at_price = variant.price 
    assign price = variant.price | times: 0.75
endif
 
The above code will show the automatic percentage discounts on the product page (matching the cart page), However, the only issue here is that the discounted price will not be showing in Google. (Fact: When you set manual discount on product admin , i.e compare price/price fields , Google will show the discounted price   ) . Anyone suggests a solution for this google issue?
 
Regards
NewZealand
Arrchith
Visitor
2 0 1

This worked for me for the product page but in the home page in my bestselling products section it still shows without the discounted price. Can you tell me if there is a code for that too?

GRUB
Visitor
2 0 1

Still nothing yet?

I was expecting something like

{% if product.descount == true %}

This item have an automatic descount 

{% end if %}

But sadly that object do not exist. I have 500 products with variables, I don't want to do it manually

MvW
Visitor
2 0 2

Still waiting here also! Would be great if they found a solution looking at the upcoming holidays and black friday....

dram
Tourist
4 0 5

all this is inconceivable! Showing the discount only in the cart is against all usability rules. Please fix it

lpscleay
Excursionist
16 0 17

Like so many things shopify, it is just mad that this is not easily achievable. Like excluding products/collections from previously created discount codes, or setting region specific pricing, it's simply far easier and profitable for shopify to shovel the issue off to an app dev, and take a 30% cut for not solving anything.

There is zero incentive for shopify to fix any of the issues that repeatedly come up on here because they make more money forcing us to buy apps to plug holes in shopify functionality.

PatrickF1
Tourist
6 0 7

It is absolutely ridiculous that Shopify has not created this solution yet. You are 100% correct, they do not make any changes to their usability because they profit more from the apps, yet they are frustrating their customers to no end! I am so tired of not having simple features on my store because of Shopify's greed.  

Arrchith
Visitor
2 0 1

Any update on this question.