Case study, Ready2HangArt

Wholesale portal Shopify build, one catalog, three price levels

A wholesale portal Shopify build: three price tiers on one catalog, a $500 order floor, invoice checkout, without the $2,300/month Plus plan. See it.

Let’s talk

This wholesale portal Shopify build gives Ready2HangArt one catalog that shows three different prices, retail, trade and wholesale, to three different kinds of buyer, in the same store.

It runs on a standard Shopify plan. The Shopify Plus licence it would otherwise have needed starts at $2,300/month, roughly $27,600/year before a single app.

$27,600
annual Shopify Plus licence the build avoids
3 × 5
customer tiers against product types in the pricing matrix
$500
wholesale order floor enforced in the cart
Ready2HangArt wholesale portal on Shopify: the same artwork priced for retail, trade and wholesale
The same product handle, the same artwork, three sessions: untagged, trade and wholesale.

One price per product, three kinds of buyer

Shopify applies one price per product. Ready2HangArt sells to three audiences at once: retail consumers at full price, interior designers and decorators at a middle discount, and resellers at a deep discount with a purchase minimum.

Every Shopify B2B setup that hits this wall takes one of three exits, and all three are expensive:

  • Separate catalogs or separate stores: the catalog gets duplicated, and so does every future edit to it
  • A wholesale app: a monthly fee forever, with order caps and per-product price editing
  • Pricing handled outside the store: email, spreadsheets and manual invoices, which is where the errors live

The documented consequence of all three: more operating cost, more mistakes, and a worse experience for the professional buyer, who is the one spending the most.

What native B2B gives you, and where it stops

Shopify’s native B2B does work below Plus, and for a simple wholesale operation it is the right answer. It is a floor, not a dead end.

What you get: up to three catalogs, assigned through Shopify Markets. If you have three tidy customer groups and one price list each, stop reading and use it.

Where it stops, precisely:

  • Every customer inside a catalog sees the same price. Two customers in the same market cannot have different prices.
  • The catalog attaches to a market, not to a company
  • No custom cart, no custom checkout
  • No rules per product family, no line you can block from wholesale, no line you can protect from discounting

Shopify Plus removes the per-customer pricing limit. It does not remove the build: the custom cart and the per-product-type rules are still development work. Plus enables it; it does not deliver it built. That is the part the pricing page does not say, and it is why the licence alone, $2,300/month on a three-year contract, around $27,600/year: is not the end of the invoice.

Ready2HangArt Shopify admin plan page showing a standard plan, not Shopify Plus

What was built

Changing the discount policy means editing one table. Not five thousand products.

The engine crosses two axes: three customer tiers (retail, trade, wholesale) against five product types (mass market, premium, Pictufy, originals, Fresenius). The discount depth is set per cell, and the depths in production are:

Mass marketPictufyPremium
Trade−25%−33%−39%
Wholesale~−51%~−64%~−71%

Two rules sit outside the grid: originals are blocked for wholesale entirely, and the Fresenius line is never discounted. Both are enforced by flags, wholesale_blocked, never_discount, retail_checkout_only: not by anyone remembering.

How it holds together:

  • customer.tags is the source of truth. A Liquid layer reads the tag and publishes window.B2B_Config so the front end knows who is looking
  • The product engine crosses customer tier against product tags and exposes window.R2H_Context, which carries the multiplier and whether this customer may buy this line at all
  • One MSRP lives in Shopify. Every discount is calculated from it at render time, on three surfaces: collection grid, product page and cart, so nothing can drift out of sync
  • Onboarding a B2B customer is one tag. There is no account limit and no order limit

This is theme-level engineering rather than an app install, which is the reason it survives a theme update. It is the Shopify infrastructure engineering line, on a real store.

The hard part: a B2B checkout Shopify does not do natively

Shopify does not apply per-customer wholesale prices in the standard checkout. That is the wall every non-Plus B2B build hits, and it is where most of them give up and go back to emailing invoices.

The wholesale path solves it without the buyer ever noticing. The button calls window.r2hCheckout(), which reads /cart.js, pulls each product’s tags from /products/{handle}.js, and POSTs { tier, cartItems } to a serverless function on Netlify. The function builds a Shopify draft order carrying the correct wholesale prices, and the buyer lands in a checkout that looks and behaves like any other, except every line shows its wholesale discount, and the summary shows what the order saved in total. No second site, no separate portal, no invoice arriving by email a day later. Retail checkout stays native, with the SKU injected as a line-item property on the way out.

Underneath it, a floor: the wholesale minimum is $500. Below it the checkout button is disabled and the cart shows how much is missing, so small unprofitable B2B orders never reach production.

Ready2HangArt wholesale checkout showing per-line discounts and total savings
Ready2HangArt wholesale cart with tier pricing applied and checkout blocked below the $500 minimum

Lead capture built into the grid

Every retail visitor browsing the catalog is a possible wholesale account, and the grid asks them.

Where a trade customer sees a discounted price, a non-B2B visitor sees a locked tile and the CTA “Unlock Wholesale Pricing”, pointing at the wholesale programme page. Dealer recruitment stops being a trade-show activity and becomes a property of the storefront itself: no second site, no gated microsite, no separate funnel to maintain.

Locked price tile with the Unlock Wholesale Pricing button in the Ready2HangArt collection grid

What it replaced, and what it costs to run

The app route is cheaper than Plus and it has a ceiling written into the pricing page.

  • Wholesale Gorilla: $34.95 to $149.95/month. Net terms and wholesale application forms only exist on the top plan
  • SparkLayer: $49 / $149 / $299/month, with hard caps of 50 / 100 / 150 monthly orders. Cancelled and refunded orders count against the cap. Above it, Enterprise starts at $499/month
  • Neither gives a custom cart or per-product-type rules, and both charge for as long as the store exists

What was built runs on a serverless function. No app subscription, no order cap, no account cap, no jump to Plus, the recurring cost is close to zero, and the automation behind the order flow is part of the same build rather than a second vendor.

Frequently asked questions

Do I need Shopify Plus to give each customer their own price?

No. Per-customer pricing can be built on a standard Shopify plan using customer tags and a pricing matrix applied at render time. Shopify Plus removes the native limit, but the custom cart and the per-product rules are development work either way.

How many B2B catalogs can I have without Shopify Plus?

Three. Shopify's native B2B below Plus allows up to three catalogs, assigned through Shopify Markets. Every customer inside a catalog sees the same price, so two customers in the same market cannot be priced differently without a custom build.

What happens to my retail customers when wholesale tiers are added?

Nothing changes for them. Retail visitors keep the standard price and the native Shopify checkout; the tier logic only activates for customers carrying a wholesale or trade tag. Untagged visitors see a locked price and an invitation to apply.

Can a wholesale customer check out at their own prices, not retail?

Yes. The wholesale cart builds a Shopify draft order carrying the correct tier prices, and the buyer completes it in a checkout that looks like any other, every line showing its wholesale discount and the total savings on the order. No separate portal, no invoice by email.

Bring your own price structure

If you can describe your discount policy in a table, it can be built as one.

Send your pricing rules, customer types, product families, and the lines that must never be discounted.

This is one of the builds behind the automation service.

See the automation service