# How prices are shown

URL: https://docs.sparklayer.io/help/pricing/pricing-display

Control how B2B prices appear on your store: RRP (MSRP), quantity price break tables, savings, price labels, unit costs, RRP-only mode and tax-inclusive prices.

> **Quick summary**
>
> - Change how prices appear to signed-in B2B customers: show an RRP (MSRP), price break tables and savings, tax-inclusive prices, custom price labels, a unit cost and an RRP-only mode.
> - Without code: show an **RRP** by filling in a field (a metafield) on each product variant, show **quantity price breaks** (they appear automatically), and turn on **Tax-inclusive prices** at **Settings > Configurations > Pricing and cart** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/configuration/settings/general)), or **SparkLayer Wholesale > Settings > Configurations > Pricing and cart** in the Shopify app. Wix doesn't support metafields, so RRP and unit cost display aren't available on Wix.
> - Savings and RRP options are switches at **Storefront > Options > Pricing and display** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/storefront/options)), or **SparkLayer Wholesale > Storefront > Options > Pricing and display** in the Shopify app: **Base savings on RRP**, **RRP toggle**, **Savings on price breaks** and **Round price break percentages**.
> - Everything else is a change to your SparkLayer **Core Script** or your theme, so it's usually done by your developer or agency. See [Customise how prices look](#customise-how-prices-look).

## How it works

Once your price lists are set up, SparkLayer's [frontend interfaces](https://docs.sparklayer.io/help/storefront/interfaces.md) show B2B prices on your store. You change what they show in 4 ways:

| Method | Use it for | How | Who usually does it |
| --- | --- | --- | --- |
| **Metafields** | Data stored per product variant, such as an RRP or a pack size | Set on the product in your eCommerce platform. See [Shopify metafields and data mapping](https://docs.sparklayer.io/help/platforms/shopify/metafields.md). | You, in your store admin |
| **Storefront options** | Switches for savings, the RRP toggle and price break percentages | Turn them on at **Storefront > Options > Pricing and display** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/storefront/options)), or **SparkLayer Wholesale > Storefront > Options > Pricing and display** in the Shopify app, then click **Save and publish**. See [Storefront options](https://docs.sparklayer.io/help/storefront/storefront-options.md). | You, in SparkLayer |
| **Core Script settings** | Display options (in `display`) and text (in `translations`) | Add code to your [Core Script](https://docs.sparklayer.io/help/storefront/storefront-options.md#add-a-core-script-setting). See [Languages and international](https://docs.sparklayer.io/help/storefront/languages-and-international.md) for changing text. | Your developer or agency |
| **CSS** | Colours and styling | Add CSS overrides. See [Customising the design](https://docs.sparklayer.io/help/storefront/customising-design.md). | Your developer or agency |

## Show an RRP (MSRP) price

Show the RRP (recommended retail price, also called MSRP) next to a customer's B2B price, so signed-in customers see what retail customers pay and how much they save. For example, a product page might show "£6.75" with "RRP: £29.99" beside it. Each variant row shows its own RRP under its price.

Each variant's RRP is stored in a field called `rrp` (a metafield). SparkLayer adds the field for you, then you fill it in.

> **Filling in RRPs for your whole catalogue?**
>
> Follow [Show RRPs to your trade customers](https://docs.sparklayer.io/help/guides/show-rrp.md). It copies your Shopify prices with a ready-made Shopify Flow, or fills in every variant from a spreadsheet, so you don't type RRPs product by product.

To set an RRP on one product:

1. Set up the RRP field once. On Shopify, go to **Integrations > Platform > Metafields** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/configuration/integrations/platform)), or **SparkLayer Wholesale > Integrations > Platform > Metafields** in the Shopify app and click **Configure** next to **SparkLayer metafields**. On other platforms, see the field details below.
2. In the form, enter the RRP and its currency, for example `15.99` and `usd`. Add a row for each currency you sell in. It writes the value for you.
3. Click **Copy**, open the variant in your store admin, paste the value into the `rrp` field and save.

The RRP is set on each variant, as a decimal amount such as `9.00` (not in pence or cents), with one entry per currency: `[{"value":9.00,"currency_code":"gbp"}]`.

On a product with several variants, the RRP in the product summary is the RRP of the first variant, in your platform's variant order. It doesn't change when the customer picks another variant, and it can't show a range yet. Each variant's own RRP shows in the variant table.

**Field details**

| Setting | Value |
| --- | --- |
| **Custom data type** | Variants. On Shopify, at **Settings > Custom data > Variants** ([open in the Shopify admin](https://admin.shopify.com/settings/custom_data/productvariant/metafields)) |
| **Metafield type** | `JSON` |
| **Namespace** | `sparklayer` |
| **Key** | `rrp` |
| **Value** | `[{"value":15.99,"currency_code":"usd"}]`, where `value` is the retail price and `currency_code` is the currency code (for example `usd`, `gbp` or `eur`). For more currencies, add more entries: `[{"value":15.99,"currency_code":"usd"},{"value":10.99,"currency_code":"gbp"}]` |

## Show the quantity pricing table

If you've set up [quantity pricing](https://docs.sparklayer.io/help/pricing/quantity-pricing.md), SparkLayer shows the price breaks in the [Product Detail Interface](https://docs.sparklayer.io/help/storefront/interfaces/product-detail.md) by default, as a table with **Qty**, **Price** and **Savings** columns.

Customers also see a **Qty discount pricing** table, and the price per unit, when they add items to the [My Cart Interface](https://docs.sparklayer.io/help/storefront/interfaces/my-cart.md).

To show an extra price breaks table anywhere on your product page, make a small change to your theme's product page code:

**Theme code for your developer**

Add this to the source code of your product pages:

```html
<spark-variant-price-breaks
  variant-sku="{{ product.selected_or_first_available_variant.sku }}"
  parent-id="{{ product.id }}"
>
</spark-variant-price-breaks>
```

For minimum quantities, pack sizes and other quantity settings, see [Quantity rules](https://docs.sparklayer.io/help/storefront/quantity-rules.md).

## Show tax-inclusive prices

Tax-inclusive price display shows your B2B prices with tax included, labelled "inc. tax" so buyers know what they're seeing. It's designed for markets where buyers expect gross prices, which is common in Australia and in trade sectors that sell to smaller businesses.

> **Tax-inclusive display changes presentation only**
>
> Your prices are still stored, uploaded and charged net. The tax your buyer pays is still calculated by your store's checkout at the point of purchase, using the rules or third-party integration set up in your eCommerce platform.

If your store's own prices include tax and you use automatic price lists, that's a different setting: see [If your store's prices include tax](https://docs.sparklayer.io/help/pricing/managing-pricing.md#tax-inclusive-prices).

How it works:

- **It shows gross prices** to buyers who think in tax-inclusive terms, without changing how you upload or charge for your pricing.
- **It works per price list.** Turn it on for the price lists that need it and leave the rest showing net prices, so you can serve different markets from one store.
- **It uses your own rate per product.** You supply a display tax rate per SKU, so reduced-rate and zero-rated products show correctly next to standard-rate ones.
- **It labels prices.** Key pricing areas add an "inc. tax" label, so it's clear which basis a buyer is seeing.

### Turn on tax-inclusive display

Buyers only see gross prices once all 3 parts are in place.

1. **Turn it on for your store.** Go to **Settings > Configurations > Pricing and cart** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/configuration/settings/general)), or **SparkLayer Wholesale > Settings > Configurations > Pricing and cart** in the Shopify app, turn on **Tax-inclusive prices** and click **Save**.
2. **Turn it on for each price list.** Each price list has its own **Tax Inclusive Display** setting. Turn it on for the price lists whose customers should see gross prices. Customers on other price lists keep seeing net prices.
3. **Add a display tax rate to your products.** Add a `display_tax_rate` column to your [price CSV](https://docs.sparklayer.io/help/pricing/csv-upload.md): the percentage used to work out the gross price from your net price, from 0 to 100. Use the same rate on every row for a SKU. For the columns and an example file, see [CSV columns](https://docs.sparklayer.io/help/pricing/csv-upload.md#csv-columns).

```csv
sku,price,display_tax_rate
ABC-123,10.00,20
```

A product on a tax-inclusive price list with **no rate, or a rate of 0**, still shows the "inc. tax" label, at 0%. This is deliberate, so a zero-rated product can't be confused with one whose rate hasn't been uploaded yet.

### Where buyers see tax-inclusive prices

Once it's on, gross prices and the "inc. tax" label appear at every step of buying.

| Area | What buyers see |
| --- | --- |
| **Product pages and product cards** | The gross price, with the label next to key pricing information. The label isn't repeated for every price in pricing tables. Where a product has several prices, the "from" price follows whichever price applies. |
| **Cart** | Each line shows its gross line total, and the cart subtotal and total show gross with the label. The shipping message reads "Prices include tax. Shipping costs calculated during checkout" instead of the standard net wording. |
| **Checkout** | The order total on the checkout review step shows gross with the label. Minimum and maximum order value rules are checked against the gross total, so buyers are measured against the total they can see. |
| **Order history** | In the customer's account area, order lines and the order total show on the same basis, so a past order looks the way the buyer bought it. |

### Limitations of tax-inclusive display

Tax-inclusive display only suits stores with simple tax setups, where you can always provide a tax rate for each SKU on a tax-inclusive price list. Read these limits before you turn it on.

| Limitation | What it means |
| --- | --- |
| **Your store's checkout decides the tax charged** | The display tax rate you upload is only used for display; the actual tax is calculated by your store's checkout. If the two differ, your buyer sees one figure in the cart and pays another. Keep your uploaded rates in line with your store's tax setup. |
| **Tax-exempt customers always see net prices** | If a customer is marked as tax exempt, SparkLayer shows them net prices with no label, whatever the price list setting, because a gross price would be wrong for them. |
| **Mixed carts show net totals** | If a cart has both tax-inclusive and tax-exclusive products, the cart totals show net and drop the label. Each line still shows on its own basis. A single gross total across both would understate the tax on the tax-exclusive lines. |
| **Custom items and unpriced products affect cart totals** | Custom line items have no display tax rate. A cart containing a product with no price but a manually quoted price shows net totals. |
| **Quoted prices are always net** | When a sales agent edits a quoted unit price, it's entered and stored net. The editor is labelled "(excluding tax)" when the prices around it are shown gross. |
| **RRP prices are never adjusted for tax** | RRPs show exactly as you upload them. On a tax-inclusive price list, a gross B2B price sits next to a net RRP, and any savings percentage based on the RRP compares the two. If you show both, upload RRPs on the same basis as your display prices. |
| **Display can vary within a product** | Variants of the same product can use different price lists, so one variant may be tax-inclusive and another not. Set up your price lists and customer groups so customers only see either tax-inclusive or tax-exclusive prices. |

## Show B2B prices in other apps

Wishlist, quick view, search and upsell apps show your platform's own price: the retail price, with tax included if your store shows it that way. They don't know about SparkLayer, so they can't show B2B prices on their own.

To show a B2B customer their price inside one of these apps, your developer embeds a SparkLayer interface in the app's template, if the app lets you edit it:

| To show | Use |
| --- | --- |
| **The price only** | `spark-product-price` (and `spark-product-rrp` for the RRP). See [Product price](https://docs.sparklayer.io/help/storefront/interfaces/product-price.md). |
| **The price with a quantity box and an add button** | `spark-product-card`, or `spark-product-card mode-quick-buy` for a quick buy row. See [Product card](https://docs.sparklayer.io/help/storefront/interfaces/product-card.md) and [quick buy mode](https://docs.sparklayer.io/help/storefront/product-display.md#turn-on-quick-buy-mode). |

The app's own quantity selectors and add-to-cart buttons don't add to the SparkLayer cart, so hide them for B2B customers. If you'd like us to set this up for you, [contact our support team](https://docs.sparklayer.io/help/support.md).

## Discounts and promotions

To show discounts and promotions in the cart, set them up in [Discounts](https://docs.sparklayer.io/help/pricing/discounts.md) (Growth plan). They apply automatically, or with a coupon code during checkout.

## Customise how prices look

Change what the price labels say, how the RRP and savings look, and what shows when a product has no price. Several of these are switches at **Storefront > Options > Pricing and display** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/storefront/options)), or **SparkLayer Wholesale > Storefront > Options > Pricing and display** in the Shopify app, which need no code. The rest are made in your SparkLayer [Core Script](https://docs.sparklayer.io/help/storefront/storefront-options.md#add-a-core-script-setting), your CSS overrides or your theme's code, usually by your developer or agency. For how language strings (`translations`) work, see [Languages and international](https://docs.sparklayer.io/help/storefront/languages-and-international.md).

### Change the RRP label

To change the "RRP" label, for example to "MSRP", add this to your [Core Script](https://docs.sparklayer.io/help/storefront/storefront-options.md#add-a-core-script-setting):

```javascript title="Core Script"
translations: {
  en: {
    "pdp.price.rrp": "MSRP: ",
    "product-card.price.rrp": "MSRP: ",
    "cart.price.rrp": "MSRP: ",
  }
},  
```

### Style the RRP

To change how the RRP looks, for example to strike it through in red, add this CSS to your [CSS overrides](https://docs.sparklayer.io/help/storefront/customising-design.md) and adjust it as needed:

```html
<style>
:root {
   --spark-pricing-rrp-decoration: line-through;
   --spark-pricing-rrp-color: red;
}
</style>
```

### Change how savings are shown

You can change the **Savings** column in quantity pricing tables at **Storefront > Options > Pricing and display** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/storefront/options)), or **SparkLayer Wholesale > Storefront > Options > Pricing and display** in the Shopify app, then click **Save and publish**:

| Switch | What it does |
| --- | --- |
| **Savings on price breaks** | Shows the amount saved next to each quantity break. On by default. |
| **Round price break percentages** | Shows savings as whole-number percentages, for example 9% off instead of 9.45% off. On by default. |

**The same settings in the Core Script**

```javascript title="Core Script"
display: {
  roundPriceBreakPercentages: true,
  showPriceBreakSavings: false,
}
```

`showPriceBreakSavings: false` hides the savings.

### Base savings on the RRP

By default, the savings in a quantity pricing table are calculated from the **single unit price** of the product or variant. For example, if the single unit price is $2.00 and the price drops to $1.00 for 5 or more, the savings show as `-50%`.

To calculate savings from the product's **RRP** (retail price) instead, turn on **Base savings on RRP** at **Storefront > Options > Pricing and display** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/storefront/options)), or **SparkLayer Wholesale > Storefront > Options > Pricing and display** in the Shopify app and click **Save and publish**. For example, with an RRP of $21.95 and a price of $16.66, the savings show as -24% from the first price break.

**The same setting in the Core Script**

```javascript title="Core Script"
display: {
  savingsUseRrp: true,
}
```

### Change the price labels

You can add text before the price on a product page, such as "Your price", so it reads "Your Price, from: £2.91". Add this to your [Core Script](https://docs.sparklayer.io/help/storefront/storefront-options.md#add-a-core-script-setting):

```javascript title="Core Script"
translations: {
  en: {
    "pdp.price.from-prefix": "Your Price:"
  }
},
```

You can also change any of the default pricing text with these language strings:

```javascript title="Core Script"
translations: {
  en: {
    "pdp.price.from": "From:",
    "pdp.price.rrp": "RRP:",
    "pdp.price.pack-size": "Pack ({packSize}): {price}",
    "product-card.price.from": "From:",
    "product-card.price.rrp": "RRP:"
  }
},
```

### Show a unit cost price

If you sell products made up of several units, you can show a unit price on your product pages, worked out automatically. For example, a product sold in packs of 10 could show "This product comes in packs of 10. Unit cost $0.31". Or, for products sold by weight, you could show a price per kg.

To set it up, add a `case_size` metafield to each product variant.

**Shopify:**

See [Shopify metafields and data mapping](https://docs.sparklayer.io/help/platforms/shopify/metafields.md) for how to set up metafields on Shopify.

| Setting | Value |
| --- | --- |
| **Custom data type** | Variants, at **Settings > Custom data > Variants** ([open in the Shopify admin](https://admin.shopify.com/settings/custom_data/productvariant/metafields)) |
| **Metafield type** | `integer` |
| **Namespace** | `sparklayer` |
| **Key** | `case_size` |
| **Value** | A whole number, for example `1`, `2` or `3` |

Then add this code to your product page template and change it as needed:

**View code sample**

```javascript
{%- if customer.metafields.sparklayer.authentication -%}

  {% if product.metafields.sparklayer.case_size %}
  <span data-custom-spark-case-size="{{ product.metafields.sparklayer.case_size }}" data-product-id="{{ product.id }}"></span>

  <script>
      document.addEventListener('DOMContentLoaded', function(event) {
        setTimeout(() => {
        document.querySelectorAll('[data-custom-spark-case-size]').forEach(async (el) => {
          var caseSize = Number(el.dataset.customSparkCaseSize);
          if (!caseSize) {
             return;
          }
          var productId = el.dataset.productId;
          try {
            priceData = await window.spark.getPriceForProduct (productId);
          } catch (e) {
            console.error(e);
            return;
          }
          const formatter =	new Intl.NumberFormat([], {
            style: 'currency',
            currency: priceData.currencyCode ?? 'usd',
          });
          el.textContent = `This product comes in packs of ${caseSize}. Unit price ${formatter.format(priceData.fromPrice / Number(caseSize))}`;
        });
        }, 500);
      });
  </script>

  {% endif %}

{% endif %}
```

**Use Shopify's unit price feature**

If you use Shopify's built-in unit price (in the product's pricing, tick **Show unit price for this product** and set the **Total product measurement** and **Base measure**, such as 400 g and 1 kg), you can show the reference unit, such as kg, lb or ml. In the code sample above, change `el.textContent` to:

```javascript
el.textContent = `Unit price per {{ item.unit_price_measurement.reference_unit }}:  ${formatter.format(priceData.fromPrice / Number(caseSize))}`;
```

To customise how this works further, we recommend working with a Shopify expert.

**Other platforms:**

| Setting | Value |
| --- | --- |
| **Custom data type** | Variant level (products) |
| **Metafield type** | `integer` |
| **Namespace** | `sparklayer` |
| **Key** | `case_size` |
| **Value** | A whole number, for example `1`, `2` or `3` |

For more information, see the [SparkLayer developer docs](https://docs.sparklayer.io/developers.md).

### Change the "Unavailable" message

When a product has no B2B price, the [Product Card Interface](https://docs.sparklayer.io/help/storefront/interfaces/product-card.md) and [Product Detail Interface](https://docs.sparklayer.io/help/storefront/interfaces/product-detail.md) show "Unavailable", so B2B customers know they can't buy it. To show a different message, such as "Price on application", add a translation override for each key below at **Storefront > Options > Translation overrides** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/storefront/options)), or **SparkLayer Wholesale > Storefront > Options > Translation overrides** in the Shopify app. No code is needed. For the full recipe, see [Show "price on application"](https://docs.sparklayer.io/help/pricing/managing-pricing.md#price-on-application).

| Key | Default text |
| --- | --- |
| `pdp.messaging.un-sellable` | Unavailable |
| `product-card.messaging.un-sellable` | Unavailable |
| `product-card.messaging.select-option` | Unavailable, please select another option |

A developer can set the same text in your [Core Script](https://docs.sparklayer.io/help/storefront/storefront-options.md#add-a-core-script-setting) instead:

```javascript title="Core Script"
translations: {
  en: {
    "pdp.messaging.un-sellable": "Unavailable",
    "product-card.messaging.un-sellable": "Unavailable",
    "product-card.messaging.select-option": "Unavailable, please select another option"
  }
},
```

### Show RRP prices only

If you take orders with customers in person, for example in a shop, you can make the SparkLayer [frontend interfaces](https://docs.sparklayer.io/help/storefront/interfaces.md) show only the RRP (MSRP) while browsing and adding items to an order. This hides your B2B prices from view.

Use cases include:

- In-store customer visits, where an order needs to be placed and the customer must only see retail (RRP) prices.
- Sales teams placing orders on behalf of customers (for example on the road), where only retail (RRP) prices must be seen.

This is for display only. The order is still created with the B2B prices of the signed-in customer.

To turn it on for every B2B customer who signs in, turn on **RRP toggle** ("Buyers can switch between the RRP and their own prices.") at **Storefront > Options > Pricing and display** in the SparkLayer Dashboard ([open](https://app.sparklayer.io/storefront/options)), or **SparkLayer Wholesale > Storefront > Options > Pricing and display** in the Shopify app and click **Save and publish**. Or add this to the `display` section of your [Core Script](https://docs.sparklayer.io/help/storefront/storefront-options.md#add-a-core-script-setting):

```javascript title="Core Script"
display: {
  showRrpToggle: true,
}
```

**Shopify only:**

To turn it on only for some customers, check their tags (Shopify Liquid):

```javascript title="Core Script"
display: {
{% for tag in customer.tags %}
 {% if tag == "b2b-group-1" %}
  showRrpToggle: true,
 {% elsif tag == "b2b-group-2" %}
  showRrpToggle: true,
 {% endif %}  
{% endfor %}

}
```

## FAQs

**Does tax-inclusive display change the prices I upload or the amount my customer is charged?**

No. Prices are stored and charged net exactly as before, and your checkout calculates tax as it always has. Only the figure shown on your store changes.

**Can I show tax-inclusive prices to some customers and not others?**

Yes. Tax-inclusive display is set per price list, so you can show gross prices to the customer groups on one price list and net prices to everyone else.

**What happens if I don't upload a display tax rate?**

Products on a tax-inclusive price list with no rate show their net price, still labelled "inc. tax", at an effective 0%. Upload rates for every product on a tax-inclusive price list so buyers see accurate gross prices.

**Why does my cart total show net when my product prices show gross?**

The cart most likely contains a mix of tax-inclusive and tax-exclusive products, a custom item, or a product with a quoted price and no uploaded price. In these cases the cart totals show net rather than a gross figure that would understate the tax due. Set up your price lists and customer groups so a customer sees only tax-inclusive or only tax-exclusive price lists, not a mixture.

**Will my buyers see gross prices at card checkout?**

The SparkLayer cart and checkout review show gross prices with the label. Once a buyer moves into your store platform's own checkout, that platform's tax display rules apply.

**Why don't RRP or unit cost prices show on my Wix store?**

**Wix only:**

Both rely on product metafields, which can't be set up in Wix. See [Wix limitations](https://docs.sparklayer.io/help/platforms/wix/limitations.md).
