---
title: "Creating a Custom Volume Pricing Block"
description: "Use the app’s metafield data to design your own volume pricing display or custom component."
url: https://help.mnmlapps.com/en/articles/6-creating-a-custom-volume-pricing-block
collection: "Code Examples"
updated: 2026-10-28
language: en
---

# Creating a Custom Volume Pricing Block

Use the app’s metafield data to design your own volume pricing display or custom component.

### Overview

The MNML Volume Pricing app stores all tier data in **Shopify metafields**, allowing you to build your own layouts or theme components using the same information shown by the widget.

-   On the **Standard Plan**, metafields are created **at the product level**.
    
-   On the **Pro Plan**, metafields are also available **at the variant level**, giving full control when each variant has its own pricing structure.
    

You can access this data through **Liquid**, the **Storefront API**, or **GraphQL**, and display it anywhere on your product page.

* * *

### Metafield Details

<table data-id="14360b5a-558c-4a49-91d8-9b55b64992cd" style="min-width: 50px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p data-id="3009e7e4-3592-4bbc-998e-16269d6f3840"><strong>Field</strong></p></td><td colspan="1" rowspan="1"><p data-id="68981870-0d48-41e2-aff0-9e495e55626c"><strong>Value</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p data-id="2ef2bc55-49e0-4a0b-93f8-18a4bac1c390"><strong>Namespace</strong></p></td><td colspan="1" rowspan="1"><p data-id="2cde2a5b-1f5d-4c34-952c-dd11985d2a52"><code>mnml</code></p></td></tr><tr><td colspan="1" rowspan="1"><p data-id="a4cae9c3-8232-4979-9528-96bc1d538b64"><strong>Key</strong></p></td><td colspan="1" rowspan="1"><p data-id="2ce9335b-ccc8-4998-a53c-8bb6787c63f5"><code>volume_pricing_tiers</code></p></td></tr><tr><td colspan="1" rowspan="1"><p data-id="228ef0fa-9d8c-4a0c-a76f-9f5f373c7691"><strong>Type</strong></p></td><td colspan="1" rowspan="1"><p data-id="b0edc4d9-df47-4be9-9e1f-4811d8d21a01"><code>JSON</code></p></td></tr><tr><td colspan="1" rowspan="1"><p data-id="1e5075c3-bdf4-4beb-a8c7-4992b8149584"><strong>Scope</strong></p></td><td colspan="1" rowspan="1"><p data-id="eab17027-3474-4301-86df-54d310d2d103">Product (Standard Plan) / Variant (Pro Plan)</p></td></tr></tbody></table>

Each metafield contains an array of tier objects representing quantity thresholds, prices, and optional labels.

### Tier Object Fields

<table data-id="57233d16-bff6-437f-9161-38bfe7369c14" style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p data-id="56606104-2aa3-479a-ad74-32bfc41b8cd9"><strong>Field</strong></p></td><td colspan="1" rowspan="1"><p data-id="1171186e-0f96-442b-b441-372801c34de8"><strong>Type</strong></p></td><td colspan="1" rowspan="1"><p data-id="52fa142d-d1c3-4fab-a00e-19fc791874ff"><strong>Description</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p data-id="d1429bf6-8f42-40d2-853c-3003252dfd43"><code>qty</code></p></td><td colspan="1" rowspan="1"><p data-id="fca2a274-5f63-481c-869d-47357a3e8d71">Integer</p></td><td colspan="1" rowspan="1"><p data-id="3984d181-793b-4df7-bf4d-040d7640c13a">Minimum quantity to trigger this tier</p></td></tr><tr><td colspan="1" rowspan="1"><p data-id="3679f259-1cac-4be6-82d2-37f96d96e24f"><code>price</code></p></td><td colspan="1" rowspan="1"><p data-id="ade01ec5-a071-4a5e-9481-28a3db728db3">Number</p></td><td colspan="1" rowspan="1"><p data-id="1f88e728-41c4-4c5d-9e4e-8254c2cd0e05">Discount value (see note below)</p></td></tr><tr><td colspan="1" rowspan="1"><p data-id="b9d1b0e0-04fb-4bfe-a73f-894d455e4cf8"><code>type</code></p></td><td colspan="1" rowspan="1"><p data-id="b80c5da7-2de8-45b8-8bc1-6827a3314357">String</p></td><td colspan="1" rowspan="1"><p data-id="a19afc41-e56b-470a-8492-cafa23fc7d2b">Either <code>"amount"</code> or <code>"percentage"</code></p></td></tr><tr><td colspan="1" rowspan="1"><p data-id="540e93a3-61e7-462e-9c26-a602c30f3604"><code>badge</code></p></td><td colspan="1" rowspan="1"><p data-id="f27f93d4-d364-4cd6-80b5-2f3c09dbbdc8">String</p></td><td colspan="1" rowspan="1"><p data-id="b2df65a5-0d28-4713-957c-6c7dc986b2e1">Optional label (e.g., "Best Value")</p></td></tr></tbody></table>

**Price values:**

-   For `"amount"` type: stored in **cents** (e.g., `500` = $5.00 off per unit)
    
-   For `"percentage"` type: stored as the **percentage value** (e.g., `10` = 10% off)
    

**Combine Variant Quantities:** When `combineVariantQuantities` is `true`, quantities of all variants are counted together toward tier thresholds.

* * *

### Example JSON (Fixed Price Example)

```javascript
{
  "combineVariantQuantities": true,
  "tiers": [
    { "qty": 10, "price": 500, "type": "amount", "badge": "" },
    { "qty": 25, "price": 800, "type": "amount", "badge": "" },
    { "qty": 50, "price": 1200, "type": "amount", "badge": "Best Value" }
  ]
}
```

Prices are stored in **minor units** (e.g. `5000` = £50.00).

### Example JSON (Percentage Discount Example)

```javascript
{
  "combineVariantQuantities": false,
  "tiers": [
    { "qty": 5, "price": 5, "type": "percentage", "badge": "" },
    { "qty": 10, "price": 10, "type": "percentage", "badge": "10% Off" },
    { "qty": 25, "price": 15, "type": "percentage", "badge": "Best Deal" }
  ]
}
```

* * *

### Example Liquid Snippet (List)

```javascript
{% assign tiers = product.metafields.mnml.volume_pricing_tiers.value %}
{% if tiers %}
  <div class="custom-volume-pricing">
    <h4>Volume Discounts</h4>
    <ul>
      {% for tier in tiers %}
        <li>
          Buy {{ tier.qty }}+ — 
          {% if tier.type == 'percentage' %}
            {{ tier.price }}% off
          {% else %}
            {{ tier.price | divided_by: 100.0 | money }} off
          {% endif %}
          {% if tier.badge %}
            <span class="tier-badge">{{ tier.badge }}</span>
          {% endif %}
        </li>
      {% endfor %}
    </ul>
  </div>
{% endif %}
```

This example displays a simple list of pricing tiers. You can style or expand this however you wish, including highlighting the active tier or integrating it into your theme’s layout.

### Example Liquid Snippet (Table)

```javascript
{% assign tiers = product.metafields.mnml.volume_pricing_tiers.value %}
{% if tiers %}
  <div class="custom-volume-pricing">
    <h4>Volume Discounts</h4>
    <table class="volume-pricing-table">
      <thead>
        <tr>
          <th>Quantity</th>
          <th>Discount</th>
        </tr>
      </thead>
      <tbody>
        {% for tier in tiers %}
          <tr>
            <td>{{ tier.qty }}+</td>
            <td>
              {% if tier.type == 'percentage' %}
                {{ tier.price }}% off
              {% else %}
                {{ tier.price | divided_by: 100.0 | money }} off
              {% endif %}
              {% if tier.badge %}
                <span class="tier-badge">{{ tier.badge }}</span>
              {% endif %}
            </td>
          </tr>
        {% endfor %}
      </tbody>
    </table>
  </div>
{% endif %}
```

This example displays a pricing tiers table. You can style or expand this however you wish, including highlighting the active tier or integrating it into your theme’s layout.

* * *

### Working with Variant-Level Pricing

If you're using variant-level pricing (Pro Plan), you'll need to update your custom display when a customer selects a different variant.

#### Accessing Variant Metafields

To display variant-specific tiers, reference the variant metafield instead of the product metafield:

```liquid
{% assign current_variant = product.selected_or_first_available_variant %}
{% assign tiers = current_variant.metafields.mnml.volume_pricing_tiers.value %}

{% comment %} Fallback to product-level if no variant tiers exist {% endcomment %}
{% if tiers == blank %}
  {% assign tiers = product.metafields.mnml.volume_pricing_tiers.value %}
{% endif %}
```

#### Reloading on Variant Change

When a customer selects a different variant, your custom pricing table won't automatically update - it requires JavaScript to detect the variant change and reload the content.

This is an **advanced customisation** that varies depending on your theme. Each Shopify theme handles variant selection differently, so the JavaScript required to listen for changes and refresh your pricing display will be specific to your theme's implementation.

**Common approaches include:**

-   Listening for the theme's variant change event
    
-   Using Shopify's Section Rendering API to reload the block
    
-   Fetching variant metafield data via the Storefront API
    

**Need help?** If you're using variant-level pricing and need assistance setting up dynamic reloading for your custom block, reach out to our support team. We're happy to help you get it working with your specific theme.

* * *

### Notes

-   **Product-level metafields** are available to all users.
    
-   **Variant-level metafields** require the **Pro Plan**.
    
-   **Variant data** overrides product-level data when both are present.
    
-   Prices are stored as **integers in minor units**, so convert to your shop’s currency before displaying.
    
-   Any updates made through the MNML app automatically sync to these metafields.
