Back to Journal
storefronten

Quote-first cart for B2B: 18 months, 1,247 requests

1,247 quotes, 34% PO conversion, 8-day median. The quote-first cart is not a sales-team replacement — it is a multiplier.

The Netorigo Storefront cart is not always a cart. The moment any cart line carries CartLine.isOnlinePurchasable=false, the cart flips into RFQ (Request for Quote) mode. This article covers the design decisions, plus 18 months of live data across four storefronts.

The flag: isOnlinePurchasable

The product Prisma table has a boolean isOnlinePurchasable. When false, the PDP shows no "Add to cart" button — only an "Request quote" CTA. If someone forces it into a cart anyway (e.g., as part of a bundle, or via admin override), the cart line renders with an amber (--nrt-amber-500) "Quote-based" badge.

The flag is toggled in the admin at /admin/catalog/products/[id]. The default is true because the Storefront is primarily B2C; only industrial / project-grade items go RFQ.

Mode switching: the checkout itself

The moment at least one quote-only line is in the cart, the useCartPurchasability(items) hook returns a mode: 'quote' or mode: 'mixed' discriminator. The /checkout page branches on it:

  • mode: 'cart': classic payment checkout (Barion, Stripe, bank transfer).
  • mode: 'quote': RFQ form. Fields: company name, VAT number, purchasing contact name + phone, free-text note. Submit routes through the submitQuoteRequest MCP tool to the backend's quotes.create endpoint, which inserts a row into quote_request and notifies the sales-rep module.
  • mode: 'mixed': dual checkout. Purchasable lines go straight to payment, quote-only lines go to RFQ. The buyer receives two emails (order confirmation + quote request acknowledgement).

The mixed case is tricky. We had a long design debate: do we let the buyer split workflows, or force them to choose ("everything as RFQ" / "just the purchasable lines now")? The split workflow won, because most partner sales teams asked for it — "do not stall an online purchase on a long RFQ cycle."

The sales hand-over

The quote lands in the /admin/sales/quotes module. The module lists, ranks them by priority + value, and the sales rep authors a quote response there (PDF generated from the quote). The response comes back to the buyer carrying a 14-day-expiring quote-specific-pricing cookie: opening the quote URL shows the negotiated price (not the list price), so the buyer can self-serve completion.

18 months of numbers (n=1,247 quotes, 4 storefronts)

  • Total quotes: 1,247 (avg 69/month, November peak of 142)
  • PO conversion: 34% (424 completed orders)
  • Median quote-to-PO: 8 days (mean 11.4, p90 21)
  • Self-serve completion via the quote URL: 11% of POs (47 cases, only accurately measured since March 2025)
  • Average quote value: 1.2M HUF; average PO value from quote: 980k HUF (so the buyer-negotiated discount averages ~18%)
  • Expired quotes (14 days): 23% (the rest either flow into a new quote or quietly die)

The downside nobody talks about

The quote-first cart visibly degrades the cart-conversion metric (the classic "adds-to-cart / completes purchase" funnel), because you lose a cohort: the quote requesters. Do not measure the quote-driven revenue with the same KPI — the 8-day lag spreads the money out of the metric window. Run two parallel measurement tracks: the quote pipeline on the sales side, the cart conversion on the marketing side. Don't mix.