B2B & Wholesale Guide
Shopify B2B Catalog Visibility for AI Shopping Agents
Shopify B2B (formerly Handshake) uses authenticated price lists that AI crawlers cannot see. Here's how to structure your wholesale catalog so AI-powered procurement tools discover your products — without exposing your wholesale pricing to retail buyers.
eligibleQuantity and eligibleTransactionVolume JSON-LD on product pages. Procurement AI tools like Perplexity's business search and Google's AI Mode for business buyers can then surface your products with wholesale context.
Why B2B Catalog Visibility Is Different
Consumer AI shopping agents (ChatGPT Shopping, Perplexity Shopping, Google AI Mode) primarily serve retail queries — "best running shoes under $100." Procurement AI tools — used by purchasing managers, category buyers, and supply chain teams — serve different queries: "minimum order quantity for SKU X", "net terms for supplier Y", "approved vendor for category Z."
Shopify B2B creates a fundamental crawlability problem: authenticated product pages return a login redirect for any unauthenticated request, including AI crawlers. This means:
| Catalog area | Shopify B2B default | AI crawler sees |
|---|---|---|
| Product catalog (B2B price list applied) | Gated — requires login | 302 redirect to login; no product data |
| Retail storefront | Public | Retail prices only; no MOQ, no terms |
| Wholesale landing page (if exists) | Usually generic ("contact us") | No product context; unindexable |
| PDF price sheets | Manual send or downloadable | Usually not linked from public pages; invisible |
The opportunity: most competitors have the same visibility gap. Building a publicly-indexable B2B discovery layer puts your products in front of procurement AI tools before competitors even know there's a distribution channel to optimize.
The Two-Layer B2B Visibility Strategy
Layer 1: Public B2B discovery pages
Create a /wholesale/ section on your Shopify store with pages that rank for procurement queries. These pages live outside the authenticated B2B portal and are publicly crawlable. Each page should:
- Name the product category and your position in it ("wholesale organic cotton hoodies, US manufacturer")
- State a representative price range ("from $18/unit at 100+ MOQ") without exposing your exact B2B price list
- List minimum order quantities, lead times, and available payment terms
- Include a clear CTA to the B2B portal or a net terms application form
- Contain JSON-LD
Productmarkup witheligibleQuantityand B2B-appropriate availability signals
Layer 2: B2B-aware JSON-LD on retail product pages
Your retail product pages are publicly indexed. You can add a second Offer block to the existing JSON-LD that represents the wholesale offer without revealing exact wholesale prices — just the minimum quantity threshold and a "contact for pricing" signal that procurement tools understand:
"offers": [
{
"@type": "Offer",
"priceCurrency": "USD",
"price": "{{ product.price | money_without_currency }}",
"availability": "https://schema.org/InStock",
"priceValidUntil": "{{ 'now' | date: '%s' | plus: 2592000 | date: '%Y-%m-%d' }}",
"description": "Retail price — single unit"
},
{
"@type": "Offer",
"priceCurrency": "USD",
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": 24,
"unitCode": "C62"
},
"eligibleTransactionVolume": {
"@type": "PriceSpecification",
"minPrice": 500,
"priceCurrency": "USD"
},
"availability": "https://schema.org/InStock",
"description": "Wholesale pricing available. Minimum order: 24 units ($500 minimum). Net 30 available for approved accounts.",
"url": "{{ shop.url }}/pages/wholesale"
}
]
The wholesale Offer block tells procurement AI tools that a wholesale tier exists, what the minimum threshold is, and where to learn more — without revealing the unit wholesale price.
B2B Product Page JSON-LD Patterns
Minimum order quantity (MOQ) with eligibleQuantity
{
"@type": "Offer",
"eligibleQuantity": {
"@type": "QuantitativeValue",
"minValue": 12,
"maxValue": 999,
"unitCode": "C62",
"unitText": "pieces"
},
"price": "18.50",
"priceCurrency": "USD",
"description": "Case pack price. MOQ 12 units."
}
Tiered pricing with multiple Offer blocks
For stores with 2–3 wholesale tiers (e.g., distributor vs. retailer vs. direct brand), use separate Offer blocks per tier:
"offers": [
{
"@type": "Offer",
"name": "Retailer tier",
"eligibleQuantity": { "@type": "QuantitativeValue", "minValue": 12, "unitCode": "C62" },
"price": "22.00",
"priceCurrency": "USD"
},
{
"@type": "Offer",
"name": "Distributor tier",
"eligibleQuantity": { "@type": "QuantitativeValue", "minValue": 144, "unitCode": "C62" },
"price": "17.50",
"priceCurrency": "USD"
}
]
Net payment terms in structured data
schema.org lacks a native NetTerms type. Use Offer's paymentAccepted and a plain-text description for maximum compatibility with procurement AI parsing:
{
"@type": "Offer",
"paymentAccepted": "Invoice, ACH, Credit Card",
"description": "Net 30 payment terms available for approved wholesale accounts. Apply at /pages/wholesale-application."
}
Catalog Segmentation for AI Indexing
| Segmentation approach | AI indexing outcome | Recommended? |
|---|---|---|
| All B2B behind login, retail public | Only retail prices indexed; wholesale invisible to AI | Avoid |
| Public wholesale landing pages + authenticated portal | Category-level B2B discovery indexed; exact pricing gated | Best |
| Dual Offer blocks on retail product pages | Wholesale MOQ/terms indexed alongside retail; no price exposure | Good |
| Separate B2B subdomain (b2b.yourstore.com) | Requires separate robots.txt, sitemap, link equity — high maintenance | Caution |
| PDF price sheets only | AI agents cannot parse PDF price data from static files | Avoid |
B2B Catalog AI Visibility Checklist
| # | Check | Priority |
|---|---|---|
| 1 | Public /wholesale/ or /pages/wholesale page exists and is indexed |
Critical |
| 2 | Wholesale page states representative price range, MOQ, and lead time | Critical |
| 3 | Dual Offer blocks on product pages: retail Offer + wholesale Offer with eligibleQuantity |
High |
| 4 | Net payment terms stated in Offer description field | High |
| 5 | B2B gated pages return 401/403 (not 200 with redirect meta-tag) for unauthenticated requests | High |
| 6 | B2B gated URLs excluded from sitemap.xml and robots.txt disallow | Medium |
| 7 | Wholesale product categories have dedicated landing pages with category-level JSON-LD | Medium |
| 8 | Lead time and minimum shipment weight/volume expressed in QuantitativeValue blocks |
Medium |
Related Resources
- Shopify B2B Wholesale AI Agent Visibility — deeper dive into portal authentication patterns and their effect on AI crawlers.
- Shopify Metafields for AI Agents — using metafields to store and expose B2B-specific product attributes (MOQ, lead time, case pack).
- Shopify B2C Wholesale Pricing for AI Agents — managing dual DTC/wholesale pricing signals without cannibalizing retail visibility.
- AI Shopping Agent Product Ranking Factors — how B2B-specific signals factor into the 18-signal CatalogScan scoring model.
Frequently Asked Questions
Can AI shopping agents see Shopify B2B catalog prices?
Not directly. Shopify B2B price lists require authenticated login — AI agents crawling as anonymous visitors see retail prices or no prices at all. To give B2B buyers AI-assisted price discovery, you need either a publicly-indexed wholesale landing page with representative price ranges, or B2B-specific JSON-LD on product pages that includes a UnitPriceSpecification block with eligibleQuantity and eligibleTransactionVolume fields.
How do I mark minimum order quantities in structured data for AI agents?
Use the schema.org Offer's eligibleQuantity property with a QuantitativeValue. Set minValue to your minimum order quantity and unitCode to the appropriate UN/CEFACT unit (e.g., C62 for each/piece, KGM for kilogram). This tells AI shopping agents the listed price only applies above a quantity threshold.
What schema.org types work best for net payment terms?
schema.org does not have a dedicated NetTerms type. Use the Offer's paymentAccepted field for accepted payment methods and encode net terms context in the offer's description field: "Net 30 terms available for approved accounts." Procurement AI tools that parse offer text will surface this.
Should Shopify B2B and DTC catalogs have separate sitemaps?
Ideally yes, if your B2B catalog has a publicly-indexable subset. A dedicated /sitemap-b2b.xml lets AI crawlers process your B2B catalog independently. If your B2B product pages are fully behind login, they should not appear in any sitemap — submitting gated URLs that return 302 redirects to login pages harms your crawl budget and trust score.
Audit Your B2B Catalog's AI Visibility
CatalogScan checks whether your store's wholesale context is accessible to AI crawlers — including dual Offer block detection, eligibleQuantity presence, and whether gated URLs are leaking into your public sitemap.