Shopify Pricing + AI Visibility
Shopify B2C wholesale pricing
and AI shopping agents
How to encode volume discount tiers in schema.org so ChatGPT Shopping, Google AI Mode, and Perplexity can surface your "buy more, pay less" pricing — instead of showing only your retail price.
Offer objects with eligibleQuantity to expose each price tier. Do not set eligibleCustomerType: BusinessCustomer on public-facing B2C volume prices or AI agents will hide them from consumer queries.
The problem: AI agents see only your retail price
A merchant who sells candles at $18 retail, $14 when you buy 6, and $11 when you buy 12 has a genuine competitive advantage for bulk queries: "candles in bulk", "wedding favor candles wholesale", "cheap candles large quantities". But if their product page encodes only the $18 retail price in JSON-LD — which is what every Shopify theme does by default — every AI shopping agent quotes $18, making the merchant look expensive compared to competitors who might have worse bulk pricing but better structured data.
Volume pricing apps like Wholesale Gorilla, Orbit Wholesale, Bold Custom Pricing, and Quantity Breaks all inject their price tables via JavaScript or calculate prices client-side. None of them modify the server-rendered JSON-LD in the <head>. As a result, your volume pricing is completely invisible to GPTBot, PerplexityBot, and Bing's crawler.
What the default Shopify JSON-LD outputs for a product with volume pricing
{% comment %} Default Dawn theme output — only retail price, no tiers {% endcomment %}
{
"@type": "Product",
"offers": {
"@type": "Offer",
"price": "18.00", ← Only this is visible to AI agents
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
}
}
What you need to output
{
"@type": "Product",
"offers": [
{
"@type": "Offer",
"price": "18.00",
"priceCurrency": "USD",
"eligibleQuantity": { "@type": "QuantitativeValue", "minValue": 1, "maxValue": 5 },
"availability": "https://schema.org/InStock"
},
{
"@type": "Offer",
"price": "14.00",
"priceCurrency": "USD",
"eligibleQuantity": { "@type": "QuantitativeValue", "minValue": 6, "maxValue": 11 },
"availability": "https://schema.org/InStock"
},
{
"@type": "Offer",
"price": "11.00",
"priceCurrency": "USD",
"eligibleQuantity": { "@type": "QuantitativeValue", "minValue": 12 },
"availability": "https://schema.org/InStock"
}
]
}
AI agent behavior with tiered pricing structured data
| Agent | Without eligibleQuantity | With eligibleQuantity tiers | Query types benefited |
|---|---|---|---|
| Google AI Mode | Shows retail price only | "From $11 per unit (qty 12+)" | Bulk, wholesale, quantity queries |
| ChatGPT Shopping | Shows retail price only | Shows lowest available tier price | Price comparison, bulk queries |
| Perplexity Shopping | Shows retail price only | Mentions "tiered pricing available" | Research queries mentioning bulk |
| Bing Shopping AI | Shows retail price only | Shows retail; may note volume pricing | Limited benefit currently |
| Google Shopping | Shows retail price only | Passes Merchant Center price rules | Price accuracy validation |
Complete Liquid implementation with metafield-stored tiers
Step 1: Store volume tiers in a metafield
Create a metafield definition on products: namespace pricing, key volume_tiers, type json. Set the value for each product as a JSON array:
[
{ "min_qty": 1, "max_qty": 5, "price": "18.00" },
{ "min_qty": 6, "max_qty": 11, "price": "14.00" },
{ "min_qty": 12, "price": "11.00" }
]
Step 2: Liquid JSON-LD with tiered offers
{% assign tiers_raw = product.metafields.pricing.volume_tiers.value %}
{% assign variant = product.selected_or_first_available_variant %}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": {{ product.title | json }},
"description": {{ product.description | strip_html | truncate: 500 | json }},
"sku": {{ variant.sku | json }},
"brand": { "@type": "Brand", "name": {{ product.vendor | json }} },
"image": [{% for img in product.images limit: 3 %}{{ img.src | json }}{% unless forloop.last %},{% endunless %}{% endfor %}],
{% if product.metafields.custom.gtin.value != blank %}
"gtin": {{ product.metafields.custom.gtin.value | json }},
{% endif %}
"offers": [
{% if tiers_raw != blank %}
{% for tier in tiers_raw %}
{
"@type": "Offer",
"price": {{ tier.price | json }},
"priceCurrency": {{ shop.currency | json }},
"availability": {% if product.available %}"https://schema.org/InStock"{% else %}"https://schema.org/OutOfStock"{% endif %},
"url": "{{ shop.url }}{{ product.url }}",
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": {{ tier.min_qty }}
{% if tier.max_qty != blank %},"maxValue": {{ tier.max_qty }}{% endif %}
},
"priceValidUntil": "{{ 'now' | date: '%Y' | plus: 1 }}-12-31"
}{% unless forloop.last %},{% endunless %}
{% endfor %}
{% else %}
{
"@type": "Offer",
"price": {{ variant.price | divided_by: 100.0 | json }},
"priceCurrency": {{ shop.currency | json }},
"availability": {% if product.available %}"https://schema.org/InStock"{% else %}"https://schema.org/OutOfStock"{% endif %},
"url": "{{ shop.url }}{{ product.url }}",
"priceValidUntil": "{{ 'now' | date: '%Y' | plus: 1 }}-12-31"
}
{% endif %}
]
}
</script>
PriceSpecification for unit pricing (per-item vs. per-case)
For products sold in cases or multipacks where the displayed price is per-case but buyers think in per-unit terms, add a PriceSpecification with referenceQuantity to expose the per-unit economics:
{
"@type": "Offer",
"price": "66.00",
"priceCurrency": "USD",
"description": "Case of 6 bottles",
"eligibleQuantity": { "@type": "QuantitativeValue", "minValue": 1 },
"priceSpecification": {
"@type": "UnitPriceSpecification",
"price": "11.00",
"priceCurrency": "USD",
"referenceQuantity": {
"@type": "QuantitativeValue",
"value": 1,
"unitCode": "C62",
"valueReference": {
"@type": "QuantitativeValue",
"value": 6,
"unitCode": "C62"
}
}
}
}
eligibleCustomerType: when to use it (and when not to)
Schema.org's eligibleCustomerType accepts two values: EndUser (retail consumer) and BusinessCustomer (business buyer with a trade account). The distinction matters for AI agent behavior:
| Scenario | Use eligibleCustomerType? | Value | Effect on AI agents |
|---|---|---|---|
| Public volume pricing (anyone can buy in bulk) | No — omit it | — | All agents show the tiered prices |
| Shopify B2B account pricing (login required) | Yes | BusinessCustomer | Consumer-facing AI agents hide this price |
| Trade professional pricing (contractor, reseller) | Yes | BusinessCustomer | Hidden from consumer AI shopping results |
| Promotional pricing open to all (sale, clearance) | No — omit it | — | AI agents surface the sale price |
Wholesale pricing apps and structured data — the audit table
| App | Implementation method | Modifies JSON-LD? | AI agent visible? |
|---|---|---|---|
| Wholesale Gorilla | JavaScript price override | No | No |
| Orbit Wholesale | JavaScript price override | No | No |
| Bold Custom Pricing | JavaScript price calculation | No | No |
| Quantity Breaks & Discounts | JavaScript widget | No | No |
| Shopify B2B native (Plus) | Server-side price lists | No (hides from public) | Intentionally hidden |
| Custom Liquid metafield (this guide) | Server-side Liquid | Yes | Yes |
FAQ
Can AI shopping agents show volume discount pricing for Shopify products?
Yes, but only with explicit eligibleQuantity encoding in JSON-LD. AI agents do not infer volume pricing from JavaScript-calculated price tables. Google AI Mode renders "from $X per unit for orders of Y+" when it detects multiple Offer objects with different eligibleQuantity values. ChatGPT Shopping and Perplexity show the lowest qualifying unit price. Without structured data, all AI agents show only the default retail price.
What is the difference between B2B and B2C wholesale pricing in Shopify?
Shopify B2B (Plus-only) is for businesses under formal customer accounts with negotiated price lists — prices are hidden from public pages. B2C wholesale (volume pricing) is publicly visible tiered pricing for any consumer buying in quantity. B2C wholesale should be encoded in public-facing JSON-LD using eligibleQuantity. B2B account pricing is private and should not appear in public structured data.
How do I add volume pricing to Shopify without a third-party app?
Create a product metafield with namespace pricing, key volume_tiers, type json. Store tiers as a JSON array with min_qty, max_qty (optional), and price per tier. In your Liquid product template, loop through the tiers to render both the visible HTML price table and the JSON-LD Offer array. No app needed, and the result is server-rendered and AI-crawlable.
Does eligibleCustomerType matter for AI agent visibility of wholesale prices?
For B2C wholesale (publicly visible volume pricing), do not set eligibleCustomerType — leaving it unset signals any consumer can access the price. Setting it to BusinessCustomer causes ChatGPT Shopping and Perplexity to hide it from consumer queries. Only use BusinessCustomer for genuine B2B prices requiring a trade account.
Do volume pricing apps like Wholesale Gorilla modify my JSON-LD?
No. Every major Shopify wholesale and volume pricing app injects pricing via JavaScript or calculates prices client-side. None modify the server-rendered JSON-LD in the HTML head. This means all AI crawlers (GPTBot, PerplexityBot, Bing crawler) see only the default retail price, regardless of which app you use. The metafield + Liquid approach in this guide is the only reliable way to get volume pricing into AI-readable structured data.
Check if AI agents see your volume pricing
CatalogScan's free scan checks your product pages for the presence of multi-offer structured data, eligibleQuantity tiers, and pricing conflicts between JSON-LD and page content. Get a report on what ChatGPT Shopping and Google AI Mode actually see when they crawl your store.
Related: B2B wholesale AI visibility · Subscription pricing guide (blog) · Schema markup overview