Minimum Quantity Enforcement

The PromoSync Pricing Engine embed block is shared with Volume Pricing. If you already enabled it for tier pricing, minimum quantity enforcement is included — just verify the checkbox is on.

This guide explains how to enable automatic minimum order quantity enforcement on product pages using the PromoSync app extension — with zero theme code changes.


Background

PromoSync stores a per-product minimum order quantity in the psrestful.minimum_quantity metafield (populated during supplier import). Previously, enforcing this minimum required ~200 lines of custom code across 7+ theme files (global.js, product-info.js, main-product.liquid, cart templates, etc.).

This feature moves all enforcement logic into the PromoSync app extension so it works on any Dawn-compatible theme out of the box.


How It Works

The feature has two parts:

1. Quantity Input Enforcement (Embed Block)

The PromoSync Pricing Engine embed block (target: "body") injects:

  • A <script type="application/json" data-promo-min-quantity> tag on product pages containing the minimum quantity and product ID from psrestful.minimum_quantity
  • A MinQuantityHandler in promo-pricing.js that:
    • Sets the HTML5 min attribute on quantity inputs (so the browser’s native stepper respects it)
    • Sets data-min for themes that read it
    • Sets the initial value to the minimum if it’s currently below
    • Adds change and blur listeners that snap typed values back to the minimum (values of 0 are allowed for themes that use 0 as a reset)
    • Calls validateQtyRules() on Dawn’s <quantity-input> custom element if available (updates +/- button states)
    • Uses a MutationObserver to re-apply after Section Rendering API re-renders (e.g., variant changes)

2. Minimum Quantity Notice (App Block)

The Min Quantity Notice app block (target: "section") renders a styled notice: “Minimum order: N units”. Merchants drag it into any product page section via Theme Customizer.


Enforcement Scope

⚠️

Enforcement is client-side only. There is no Shopify Function or cart validation backing this feature. A determined buyer with developer tools, a custom cart implementation, or direct Storefront API calls can submit a quantity below the minimum and Shopify will accept the order.

This is a deliberate trade-off, not a missing feature. The minimum-quantity enforcement runs entirely in promo-pricing.js in the shopper’s browser, by clamping the <input> value, setting the HTML5 min attribute, and listening for change events. That is enough to stop every normal buyer from placing an under-minimum order through the product page, the cart drawer, or the cart template.

Compare with Volume Pricing, which is enforced server-side by a Shopify Function that runs at checkout. If you need server-side rejection of under-minimum orders for compliance or revenue-protection reasons, the current options are:

  • Use Shopify Flow to flag orders that fall below psrestful.minimum_quantity and route them for manual review.
  • Build your own Cart Validation Function that reads the same metafield. PromoSync does not ship one today.
  • For B2B accounts, use Shopify’s built-in order minimum settings on a B2B catalog.

For most distributors the client-side enforcement is sufficient: a real buyer who clicks “Add to Cart” through the product page never sees the quantity drop below the minimum, and the Min Quantity Notice block makes the requirement obvious before they try.


Setup Instructions

Step 1: Enable the Embed Block

  1. Go to Online Store > Themes > Customize
  2. Click App embeds (left sidebar, puzzle piece icon)
  3. Toggle PromoSync Pricing Engine to ON (if not already enabled for tier pricing)
  4. The “Enforce minimum order quantity” checkbox is ON by default

That’s it for enforcement. Quantity inputs on product pages will now respect the minimum.

Step 2 (Optional): Add the Notice Block

To show a visible “Minimum order: N units” message on product pages:

  1. In Theme Customizer, navigate to a product page template
  2. Click Add block in the product section
  3. Select Min Quantity Notice (under the PromoSync app)
  4. Drag it to your preferred position (e.g., below the quantity selector)
  5. Save

The notice only renders on products that have a psrestful.minimum_quantity metafield with a value greater than 0.


Settings Reference

PromoSync Pricing Engine (Embed Block)

SettingDefaultDescription
Enforce minimum order quantityONSet quantity input minimum and initial value on product pages using the psrestful.minimum_quantity metafield

Min Quantity Notice (App Block)

No additional settings. The block reads psrestful.minimum_quantity directly and uses the promo.min_quantity.notice translation key.


Behavior Details

What the enforcement does

ScenarioBehavior
Page load (min=5)Quantity input starts at 5, min attribute set to 5
User types “2”, tabs awayValue snaps back to 5
User clicks minus buttonStops at 5 (Dawn’s built-in stepDown() respects min)
User types “0”Allowed (some themes use 0 as remove/reset)
User types “10”Allowed (above minimum)
Variant changes re-render formMutationObserver re-applies enforcement
Product has no minimum metafieldNo enforcement, quantity input behaves normally
Minimum is 0 or 1No enforcement (minimum of 1 is the default)

Supported quantity input selectors

The handler finds inputs via these selectors, covering Dawn and compatible themes:

product-info quantity-input input.quantity__input
.product-form quantity-input input.quantity__input
form[action*="/cart/add"] input[name="quantity"]

Metafield Reference

MetafieldNamespaceKeyTypeSet By
Minimum quantitypsrestfulminimum_quantitynumber_integerPromoSync product import

The metafield is populated automatically when products are imported from PromoStandards suppliers. No manual setup is required.


Files Involved

FileTypePurpose
blocks/promo-pricing-engine.liquidEmbed blockSerializes min quantity JSON on product pages
assets/promo-pricing.jsJavaScriptMinQuantityHandler class (~65 lines)
blocks/min-quantity-notice.liquidApp blockDrag-and-drop “Minimum order: N units” notice
assets/promo-pricing.cssStylesheet.promo-min-quantity styles (already existed)
snippets/min-quantity.liquidSnippetLegacy snippet, kept for backward compatibility
locales/en.default.jsonTranslationspromo.min_quantity.notice key (already existed)

Customization

CSS

Override the notice styles using CSS custom properties:

:root {
  --promo-bg-alt: #f0f0f0;       /* Notice background */
  --promo-primary: #2c6ecb;       /* Left border color */
  --promo-text: #1a1a1a;          /* Text color */
  --promo-font-size-sm: 0.8125rem; /* Font size */
  --promo-spacing-sm: 0.5rem;      /* Padding */
  --promo-radius-sm: 0.25rem;      /* Border radius */
}

Translations

Edit locales/en.default.json to customize the notice text:

{
  "promo": {
    "min_quantity": {
      "notice": "Minimum order: {{ quantity }} units",
      "notice_short": "Min: {{ quantity }}"
    }
  }
}

Verification Checklist

  1. Open a product page with psrestful.minimum_quantity set (e.g., min=5)
  2. Quantity input starts at 5, not 1
  3. min and data-min attributes are set to 5 (inspect the input element)
  4. Type “2” in the input, tab away — snaps back to 5
  5. Click minus button — stops at 5
  6. Change variant — enforcement still active after re-render
  7. Add “Min Quantity Notice” block via Theme Customizer — renders correctly
  8. Open a product with no minimum quantity metafield — no enforcement, no notice
  9. Cart page — enforcement does not interfere with cart quantity inputs

Migrating from Theme-Level Enforcement

If you previously added minimum quantity enforcement directly in your theme code, you can safely remove:

  • enforceMinimum() from global.js or QuantityInput class overrides
  • setQuantityBoundries() / data-min logic from product-info.js
  • Metafield reads and min/data-min/value attributes from main-product.liquid
  • data-min plumbing from cart drawer/page templates

The app extension handles all of this automatically.