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 frompsrestful.minimum_quantity - A
MinQuantityHandlerinpromo-pricing.jsthat:- Sets the HTML5
minattribute on quantity inputs (so the browser’s native stepper respects it) - Sets
data-minfor themes that read it - Sets the initial value to the minimum if it’s currently below
- Adds
changeandblurlisteners 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
MutationObserverto re-apply after Section Rendering API re-renders (e.g., variant changes)
- Sets the HTML5
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_quantityand 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
- Go to Online Store > Themes > Customize
- Click App embeds (left sidebar, puzzle piece icon)
- Toggle PromoSync Pricing Engine to ON (if not already enabled for tier pricing)
- 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:
- In Theme Customizer, navigate to a product page template
- Click Add block in the product section
- Select Min Quantity Notice (under the PromoSync app)
- Drag it to your preferred position (e.g., below the quantity selector)
- 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)
| Setting | Default | Description |
|---|---|---|
| Enforce minimum order quantity | ON | Set 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
| Scenario | Behavior |
|---|---|
| Page load (min=5) | Quantity input starts at 5, min attribute set to 5 |
| User types “2”, tabs away | Value snaps back to 5 |
| User clicks minus button | Stops 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 form | MutationObserver re-applies enforcement |
| Product has no minimum metafield | No enforcement, quantity input behaves normally |
| Minimum is 0 or 1 | No 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
| Metafield | Namespace | Key | Type | Set By |
|---|---|---|---|---|
| Minimum quantity | psrestful | minimum_quantity | number_integer | PromoSync product import |
The metafield is populated automatically when products are imported from PromoStandards suppliers. No manual setup is required.
Files Involved
| File | Type | Purpose |
|---|---|---|
blocks/promo-pricing-engine.liquid | Embed block | Serializes min quantity JSON on product pages |
assets/promo-pricing.js | JavaScript | MinQuantityHandler class (~65 lines) |
blocks/min-quantity-notice.liquid | App block | Drag-and-drop “Minimum order: N units” notice |
assets/promo-pricing.css | Stylesheet | .promo-min-quantity styles (already existed) |
snippets/min-quantity.liquid | Snippet | Legacy snippet, kept for backward compatibility |
locales/en.default.json | Translations | promo.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
- Open a product page with
psrestful.minimum_quantityset (e.g., min=5) - Quantity input starts at 5, not 1
minanddata-minattributes are set to 5 (inspect the input element)- Type “2” in the input, tab away — snaps back to 5
- Click minus button — stops at 5
- Change variant — enforcement still active after re-render
- Add “Min Quantity Notice” block via Theme Customizer — renders correctly
- Open a product with no minimum quantity metafield — no enforcement, no notice
- 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()fromglobal.jsorQuantityInputclass overridessetQuantityBoundries()/data-minlogic fromproduct-info.js- Metafield reads and
min/data-min/valueattributes frommain-product.liquid data-minplumbing from cart drawer/page templates
The app extension handles all of this automatically.