Optimization Guide
Shopify Wholesale & B2B Pricing Schema — MOQ, Volume Tiers & Business Audience JSON-LD
AI procurement agents fielding queries like "wholesale supplier minimum 100 units custom mugs," "bulk hand sanitizer net 30 terms," or "distributor pricing for promotional pens 500 qty" need machine-readable minimum order quantities, volume pricing tiers, and business-audience signals — none of which Shopify's default Product JSON-LD outputs. B2B and wholesale commerce is the fastest-growing segment of AI-assisted purchasing, and structured data is the only way your catalog surfaces in procurement workflows.
eligibleCustomerType: "https://schema.org/BusinessAudience" on the Offer to signal B2B-only pricing. Use eligibleQuantity with QuantitativeValue minValue / maxValue for MOQ tiers. Express volume pricing as multiple Offer objects — one per tier — each with its own eligibleQuantity range and price. Set valueAddedTaxIncluded: false for net B2B prices. Use priceType: "https://schema.org/MinimumAdvertisedPrice" for MAP Offers. For dual D2C + wholesale pages, output two Offer objects: EndUserAudience retail + BusinessAudience wholesale.
Why B2B Catalogs Are Invisible to AI Procurement Queries
AI procurement agents operate fundamentally differently from consumer shopping agents. Where a consumer agent matches "best running shoe for wide feet," a procurement agent matches "supplier of nitrile gloves minimum 1,000 units FDA compliant net 30" — a query that requires four simultaneous structured data signals: product type, minimum order quantity, regulatory certification, and payment terms. None of these signals are present in Shopify's default Product JSON-LD.
The result is systematic exclusion from the procurement layer of AI commerce. Platforms like Faire, RangeMe, global Amazon Business procurement, and emerging AI-powered procurement tools all depend on machine-readable pricing tiers and eligibility conditions to surface the right supplier for a given buyer's requirements. Without structured data, your wholesale catalog is invisible to the fastest-growing purchasing channel in B2B commerce.
The schema.org Offer type has robust support for B2B pricing patterns — eligibleCustomerType, eligibleQuantity, valueAddedTaxIncluded, deliveryLeadTime, and priceType — but virtually no Shopify stores implement them because the default Liquid theme ignores the entire B2B surface area of the schema.org vocabulary.
B2B schema.org Offer properties reference
| Property | Type | B2B use case | Example value |
|---|---|---|---|
eligibleCustomerType |
URL (Audience subtype) | Signal B2B-only offer | https://schema.org/BusinessAudience |
eligibleQuantity |
QuantitativeValue | MOQ and tier range | minValue: 12, unitCode: "C62" |
priceType |
URL (PriceTypeEnumeration) | MAP, invoice, or sale price designation | https://schema.org/MinimumAdvertisedPrice |
valueAddedTaxIncluded |
Boolean | Net vs. gross pricing signal | false (net/ex-VAT for B2B) |
deliveryLeadTime |
QuantitativeValue | B2B production / fulfillment time | minValue: 5, maxValue: 10, unitCode: "DAY" |
hasMerchantReturnPolicy |
MerchantReturnPolicy | B2B return restrictions | Damage-only, 48hr claim window |
seller |
Organization | Vendor identity + tax ID for trust signals | vatID, taxID |
eligibleCustomerType: BusinessAudience vs EndUserAudience
The eligibleCustomerType property signals which buyer type an Offer is valid for. Schema.org defines two primary audience types for commerce:
https://schema.org/BusinessAudience— the Offer applies to business buyers: wholesalers, retailers, resellers, enterprise procurement teams, and organizational purchasers. This is the signal AI procurement agents use to identify B2B-eligible offers.https://schema.org/EndUserAudience— the Offer applies to individual consumers purchasing for personal use. This is the D2C retail audience.
For a dual-audience Shopify store (selling both retail and wholesale), output two Offer objects under the Product's offers array. The AI agent selects the appropriate Offer based on the buyer type context of the query.
{
"@type": "Offer",
"price": "8.50",
"priceCurrency": "USD"
// No eligibleCustomerType
// No eligibleQuantity
// AI agent cannot determine
// whether this is B2B or D2C
}
"offers": [
{
"@type": "Offer",
"price": "14.99",
"eligibleCustomerType":
"schema.org/EndUserAudience"
},
{
"@type": "Offer",
"price": "8.50",
"eligibleCustomerType":
"schema.org/BusinessAudience",
"eligibleQuantity": {
"minValue": 12
}
}
]
Volume Pricing Tiers: Multiple Offer Objects
Express volume pricing tiers as an array of Offer objects under the Product's offers key. Each Offer represents one pricing tier with its own eligibleQuantity range and price. AI procurement agents parse the full Offer array and apply the tier that matches the buyer's intended order quantity.
Volume tier Offer structure
| Tier | Quantity range | Unit price | eligibleQuantity values |
|---|---|---|---|
| Tier 1 — Case pack | 12–23 units | $8.50 | minValue: 12, maxValue: 23 |
| Tier 2 — Half pallet | 24–47 units | $7.25 | minValue: 24, maxValue: 47 |
| Tier 3 — Full pallet | 48+ units | $6.00 | minValue: 48 (open-ended) |
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Custom Printed Ceramic Coffee Mug — 11oz White — Logo Imprint",
"description": "11oz white ceramic coffee mug, dishwasher-safe, with full-color ceramic transfer imprint. Custom logo or artwork. Case pack minimum 12 units. Volume discounts for 24+ and 48+ unit orders.",
"url": "https://example.com/products/custom-mug-11oz-white",
"sku": "MUG-11OZ-WHT-CUSTOM",
"brand": { "@type": "Brand", "name": "PromoWorks" },
"offers": [
{
"@type": "Offer",
"name": "Retail single unit",
"price": "14.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"eligibleCustomerType": "https://schema.org/EndUserAudience",
"valueAddedTaxIncluded": true,
"url": "https://example.com/products/custom-mug-11oz-white"
},
{
"@type": "Offer",
"name": "Wholesale Tier 1 — Case Pack (12–23 units)",
"price": "8.50",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"eligibleCustomerType": "https://schema.org/BusinessAudience",
"valueAddedTaxIncluded": false,
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": 12,
"maxValue": 23,
"unitCode": "C62",
"unitText": "units"
},
"deliveryLeadTime": {
"@type": "QuantitativeValue",
"minValue": 7,
"maxValue": 10,
"unitCode": "DAY",
"unitText": "business days"
},
"url": "https://example.com/wholesale/custom-mug-11oz-white"
},
{
"@type": "Offer",
"name": "Wholesale Tier 2 — Half Pallet (24–47 units)",
"price": "7.25",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"eligibleCustomerType": "https://schema.org/BusinessAudience",
"valueAddedTaxIncluded": false,
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": 24,
"maxValue": 47,
"unitCode": "C62",
"unitText": "units"
},
"deliveryLeadTime": {
"@type": "QuantitativeValue",
"minValue": 7,
"maxValue": 12,
"unitCode": "DAY",
"unitText": "business days"
},
"url": "https://example.com/wholesale/custom-mug-11oz-white"
},
{
"@type": "Offer",
"name": "Wholesale Tier 3 — Full Pallet (48+ units)",
"price": "6.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"eligibleCustomerType": "https://schema.org/BusinessAudience",
"valueAddedTaxIncluded": false,
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": 48,
"unitCode": "C62",
"unitText": "units"
},
"deliveryLeadTime": {
"@type": "QuantitativeValue",
"minValue": 10,
"maxValue": 15,
"unitCode": "DAY",
"unitText": "business days"
},
"url": "https://example.com/wholesale/custom-mug-11oz-white"
}
]
}
</script>
MAP Pricing: priceType MinimumAdvertisedPrice
Minimum Advertised Price (MAP) policies protect brand equity and channel partner margins by setting a floor on the price at which authorized resellers may advertise a product. Encode MAP using a separate Offer object with priceType: "https://schema.org/MinimumAdvertisedPrice".
The MAP Offer signals to AI agents that this is the lowest price that should appear in product listings and price comparisons — not the actual transaction price. The actual net wholesale price (which may be lower, subject to account approval) is expressed in the BusinessAudience Offer with priceType: "https://schema.org/InvoicePrice".
| priceType URL | Meaning | When to use |
|---|---|---|
https://schema.org/MinimumAdvertisedPrice |
Floor price for public advertising — not the transaction price | MAP policy enforcement for channel partners |
https://schema.org/InvoicePrice |
Net price on invoice — actual transaction price ex-VAT | B2B net wholesale price (after account approval) |
https://schema.org/SalePrice |
Reduced price during a promotional event | Temporary promotional wholesale pricing |
https://schema.org/ListPrice |
Manufacturer's suggested retail price (MSRP) | MSRP reference shown alongside wholesale/MAP pricing |
// Full three-price structure: MSRP + MAP + B2B net
"offers": [
{
"@type": "Offer",
"name": "MSRP — Manufacturer Suggested Retail",
"price": "24.99",
"priceCurrency": "USD",
"priceType": "https://schema.org/ListPrice",
"eligibleCustomerType": "https://schema.org/EndUserAudience"
},
{
"@type": "Offer",
"name": "MAP — Minimum Advertised Price",
"price": "19.99",
"priceCurrency": "USD",
"priceType": "https://schema.org/MinimumAdvertisedPrice",
"eligibleCustomerType": "https://schema.org/BusinessAudience",
"description": "Authorized resellers may not advertise below $19.99"
},
{
"@type": "Offer",
"name": "Wholesale Net Price (48+ units)",
"price": "11.50",
"priceCurrency": "USD",
"priceType": "https://schema.org/InvoicePrice",
"eligibleCustomerType": "https://schema.org/BusinessAudience",
"valueAddedTaxIncluded": false,
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": 48,
"unitCode": "C62"
}
}
]
Seller Organization: vatID, taxID, and potentialAction
For B2B purchasers, seller identity and tax registration are trust signals that AI procurement agents use to evaluate supplier legitimacy. Add a seller object on the Offer with the selling Organization's VAT ID or EIN, and a potentialAction on the Organization linking to your wholesale application form.
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "PromoWorks Wholesale LLC",
"url": "https://example.com/wholesale",
"vatID": "US-12-3456789",
"taxID": "12-3456789",
"legalName": "PromoWorks Wholesale LLC",
"address": {
"@type": "PostalAddress",
"streetAddress": "500 Commerce Drive",
"addressLocality": "Chicago",
"addressRegion": "IL",
"postalCode": "60601",
"addressCountry": "US"
},
"potentialAction": [
{
"@type": "ApplyAction",
"name": "Apply for Wholesale Account",
"description": "Apply for a wholesale account to access B2B pricing, volume tiers, and net 30 payment terms.",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://example.com/wholesale/apply",
"actionPlatform": "https://schema.org/DesktopWebPlatform"
}
}
]
}
The vatID field signals that the seller is VAT-registered (relevant for EU B2B cross-border purchases under reverse charge). The taxID field (US EIN format) signals US business tax registration. AI procurement agents trained on supplier evaluation signals use these fields to distinguish verified business sellers from unverified individual sellers. For more on seller organization markup, see E-commerce Seller Organization Schema.
B2B Return Policy and Delivery Lead Time
B2B return policies are structurally different from D2C return policies. Wholesale and B2B orders typically allow returns only for manufacturing defects or shipping damage — and only within a narrow claim window (24–72 hours of delivery). Custom and special-order items are almost always non-returnable. These restrictions must be machine-readable for AI procurement agents to accurately answer "what is the return policy for bulk orders?"
{
"@type": "MerchantReturnPolicy",
"name": "B2B Wholesale Return Policy",
"applicableCountry": "US",
"returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
"merchantReturnDays": 2,
"returnMethod": "https://schema.org/ReturnByMail",
"returnFees": "https://schema.org/OriginalShippingFees",
"description": "Wholesale returns accepted only for manufacturing defects or shipping damage. Claims must be submitted within 48 hours of delivery with photographic documentation. Custom imprint orders are non-refundable. Standard stock returns accepted within 2 business days, unopened original packaging only.",
"customerRemorseReturnFees": "https://schema.org/ReturnFeesCustomerResponsibility",
"itemDefectReturnFees": "https://schema.org/FreeReturn"
}
For B2B delivery lead time (including production time for custom orders), use deliveryLeadTime on the Offer as a QuantitativeValue with unitCode: "DAY" for business days. Note that B2B lead times are often significantly longer than D2C lead times — custom imprint products may require 7–14 business days. Signal this distinction explicitly so procurement agents advising on project timelines surface accurate lead time data.
"deliveryLeadTime": {
"@type": "QuantitativeValue",
"minValue": 7,
"maxValue": 14,
"unitCode": "DAY",
"unitText": "business days",
"description": "Includes 5-7 business days production time for custom imprint plus 2-5 business days ground shipping."
}
Dual-Audience Pattern: Serving B2B and D2C from One Page
Many Shopify stores sell the same product to both retail customers and wholesale buyers from a single product page. The schema.org pattern for this is a Product with an offers array containing two (or more) Offer objects — one per audience type. AI agents filter by eligibleCustomerType to surface the Offer matching the buyer context.
In Shopify, the buyer's audience is determined by customer tags. A customer tagged "wholesale" or "b2b-approved" is a business buyer. The Liquid snippet below conditionally outputs the B2B Offer block only when the current customer has the appropriate tag — preventing wholesale pricing from appearing in the JSON-LD visible to unauthenticated (D2C) visitors.
{% comment %} b2b-schema.liquid — B2B wholesale offer JSON-LD, Shopify customer tag gated {% endcomment %}
{% assign is_wholesale_customer = false %}
{% if customer %}
{% for tag in customer.tags %}
{% if tag == 'wholesale' or tag == 'b2b-approved' or tag == 'trade-account' %}
{% assign is_wholesale_customer = true %}
{% endif %}
{% endfor %}
{% endif %}
{% assign w_tier1_price = product.metafields.wholesale.tier1_price %}
{% assign w_tier1_min = product.metafields.wholesale.tier1_min_qty %}
{% assign w_tier1_max = product.metafields.wholesale.tier1_max_qty %}
{% assign w_tier2_price = product.metafields.wholesale.tier2_price %}
{% assign w_tier2_min = product.metafields.wholesale.tier2_min_qty %}
{% assign w_tier2_max = product.metafields.wholesale.tier2_max_qty %}
{% assign w_tier3_price = product.metafields.wholesale.tier3_price %}
{% assign w_tier3_min = product.metafields.wholesale.tier3_min_qty %}
{% assign w_lead_min = product.metafields.wholesale.lead_time_min_days %}
{% assign w_lead_max = product.metafields.wholesale.lead_time_max_days %}
{% assign w_map_price = product.metafields.wholesale.map_price %}
Save as snippets/b2b-schema.liquid. Render from your product template: {% raw %}{% render 'b2b-schema' %}{% endraw %}. The snippet outputs the MAP Offer unconditionally (MAP pricing is public), but gates the InvoicePrice wholesale tier Offers behind customer tag authentication — protecting net pricing from public visibility while still making it available to logged-in approved wholesale customers.
Shopify Metafield Architecture for B2B Wholesale
| Metafield key | Type | Maps to | Example |
|---|---|---|---|
wholesale.map_price |
Decimal number | priceType MinimumAdvertisedPrice |
19.99 |
wholesale.tier1_price |
Decimal number | Offer price (InvoicePrice, Tier 1) | 8.50 |
wholesale.tier1_min_qty |
Integer | eligibleQuantity.minValue Tier 1 |
12 |
wholesale.tier1_max_qty |
Integer | eligibleQuantity.maxValue Tier 1 |
23 |
wholesale.tier2_price |
Decimal number | Offer price (InvoicePrice, Tier 2) | 7.25 |
wholesale.tier2_min_qty |
Integer | eligibleQuantity.minValue Tier 2 |
24 |
wholesale.tier2_max_qty |
Integer | eligibleQuantity.maxValue Tier 2 |
47 |
wholesale.tier3_price |
Decimal number | Offer price (InvoicePrice, Tier 3) | 6.00 |
wholesale.tier3_min_qty |
Integer | eligibleQuantity.minValue Tier 3 |
48 |
wholesale.lead_time_min_days |
Integer | deliveryLeadTime.minValue (DAY) |
7 |
wholesale.lead_time_max_days |
Integer | deliveryLeadTime.maxValue (DAY) |
14 |
5 Common B2B Wholesale Schema Mistakes
| # | Mistake | Impact | Fix |
|---|---|---|---|
| 1 | No eligibleCustomerType on any Offer |
AI procurement agents cannot distinguish B2B offers from D2C offers. Wholesale products appear as standard retail listings, with MOQ and net pricing invisible to procurement queries | Add eligibleCustomerType: "https://schema.org/BusinessAudience" to every wholesale Offer. For dual-audience pages, add EndUserAudience to the retail Offer simultaneously |
| 2 | Expressing MOQ only in product description text ("Minimum order: 12 units") | AI procurement agents cannot apply numeric comparison operators against free-text MOQ. Queries for "suppliers with minimum order under 50 units" exclude products whose MOQ is only in text | Add eligibleQuantity with QuantitativeValue minValue on the B2B Offer. Use UN/CEFACT unit code C62 for individual units |
| 3 | Single Offer for all volume tiers instead of multiple Offer objects | AI agents cannot determine the price at a given quantity without separate Offer objects for each tier. "What is the unit price for 100 units?" cannot be answered from a single Offer with tiered pricing in its description | Output one Offer per pricing tier, each with its own eligibleQuantity range (minValue + maxValue) and price |
| 4 | Missing valueAddedTaxIncluded: false on B2B net pricing |
AI agents surface B2B net prices as if they include VAT, inflating apparent cost by 10–25% for buyers comparing ex-VAT prices. EU B2B procurement agents expect net prices and flag gross prices as data quality issues | Set valueAddedTaxIncluded: false on all BusinessAudience Offers. For EU D2C Offers, set valueAddedTaxIncluded: true |
| 5 | Wholesale net pricing visible in JSON-LD to all visitors | Exposing invoice-level net pricing in page source to unauthenticated visitors violates most wholesale agreements and MAP policies. It also signals to public price comparison tools that your MAP floor is lower than it is | Gate InvoicePrice Offer output behind Shopify customer tag authentication in the Liquid snippet. MAP Offers are public by definition and can be rendered unconditionally |
Frequently Asked Questions
How does eligibleCustomerType tell AI agents a product is B2B-only?
Set eligibleCustomerType on the Offer to https://schema.org/BusinessAudience. This signals that the Offer is valid for business buyers. AI procurement agents filter by this signal when matching queries like "wholesale supplier minimum 100 units." Contrast with https://schema.org/EndUserAudience for D2C retail Offers. For dual-audience pages, output both Offer types in the offers array. For related member-exclusive product patterns, see Shopify Member-Exclusive Product Schema.
How do I express minimum order quantities (MOQ) in schema?
Use eligibleQuantity on the Offer object with a QuantitativeValue specifying minValue (and optionally maxValue for a tier range) and unitCode: "C62" (UN/CEFACT for individual unit). For a case pack of 12 units: minValue: 12. For a tier range 12–23 units: minValue: 12, maxValue: 23. For 48+ units (open-ended): minValue: 48 with no maxValue. AI agents use these numeric values to match procurement queries specifying quantity requirements.
How do I encode volume pricing tiers as multiple Offer objects?
Create one Offer object per pricing tier. For "12–23 @ $8.50, 24–47 @ $7.25, 48+ @ $6.00": Offer 1 has eligibleQuantity minValue: 12, maxValue: 23, price: 8.50; Offer 2 has minValue: 24, maxValue: 47, price: 7.25; Offer 3 has minValue: 48, price: 6.00 (no maxValue). Wrap all three in the Product's offers array. AI procurement agents parse the array and select the tier matching the buyer's order quantity context.
Should VAT be included in B2B wholesale prices?
No — set valueAddedTaxIncluded: false on B2B BusinessAudience Offers. B2B buyers are VAT-registered and reclaim input tax, so net (ex-VAT) prices are the standard for trade. For EU D2C consumer Offers on the same page, set valueAddedTaxIncluded: true. AI procurement agents use this flag to surface the correct price type in cost comparison workflows. For more on seller organization trust signals including vatID and taxID, see E-commerce Seller Organization Schema.
What is MAP pricing and how do I encode it in schema?
MAP (Minimum Advertised Price) is a brand's floor price policy for authorized resellers. Encode it as an Offer with priceType: "https://schema.org/MinimumAdvertisedPrice". The MAP Offer represents the lowest price that should appear in public advertising and AI price-comparison surfaces. The actual net wholesale transaction price (which may be lower) is a separate Offer with priceType: "https://schema.org/InvoicePrice", gated behind customer authentication. MAP Offers are public and do not require customer tag gating.
Are your wholesale pricing tiers invisible to AI procurement agents?
CatalogScan audits your Shopify store's structured data and identifies missing B2B audience signals, MOQ fields, volume tier Offer objects, and MAP pricing across your entire product catalog.
Run Free ScanRelated Resources
- E-commerce Seller Organization Schema — vatID, taxID & Trust Signals
- Shopify Member-Exclusive Product Schema — Gated Pricing & Access Signals
- Shopify B2B Wholesale AI Agent Visibility Guide
- E-commerce Installment Payment Schema — Net Terms & Payment Plans
- E-commerce Merchant Return Policy Schema
- CatalogScan Blog — AI Shopping Agent Optimization