Skip to content

E-commerce / Case 05

Free-pair and BOGO rules without duplicate or unavailable gifts

A free-product promotion became an inventory problem, a pricing problem, and a cart-state problem at the same time.

ShopifyJavaScriptBOGOInventoryCart logic

What this solved for the business or user

The customer experience stayed simple: qualify, receive one free item, and continue to checkout. The implementation handled the difficult parts quietly, including exclusions, size selection, stock fallbacks, and duplicate prevention.

What was happening

One production promotion qualified an order after a spend threshold while excluding gift-card spend. Product groups that could help reach the threshold were not always valid gifts. The selected free variant also depended on size, product priority, and live availability. Separate category-level BOGO rules could create additional free quantities in the same cart.

Why the obvious solution was not enough

A free item still represents real inventory. The rule could not simply subtract money from the total and ignore which variant would be fulfilled. Repeated cart updates also had to remain idempotent so the same promotion could not create a second free line.

How the solution works

  1. Calculate qualifying spend from paid merchandise only and keep exclusions in one explicit rule set.
  2. Resolve the customer's preferred gift size from items already in the cart when possible instead of forcing another selection step.
  3. Store gift product and size priorities as configuration rather than scattering them through UI conditions.
  4. Check whether the preferred variant is sellable and available before choosing it. If not, walk the configured fallback list in a predictable order.
  5. Represent the gift as a real Shopify variant line so inventory continues to come from the actual product record.
  6. Separate paid and free quantities when a BOGO rule applies. The free quantity is calculated from the qualifying category count and sent as its own 100%-discounted line.
  7. Before checkout, detect whether the promotional gift already exists and enforce the one-gift rule again on the server.
  8. Re-evaluate eligibility when the paid cart changes. If the order no longer qualifies, the previous free state must not survive just because it was valid earlier.
Simplified BOGO calculation
function freeQuantity(categoryCount, buy, get) {
  const groupSize = buy + get;
  return Math.floor(categoryCount / groupSize) * get;
}

const gift = findFirstAvailableVariant({
  size: preferredSize,
  productPriority,
  inventory,
});

assertSinglePromotionalGift(cart, gift);

What should be verified before shipping

  • Test the spend threshold just below, exactly at, and above qualification.
  • Verify excluded spend never qualifies the order by itself.
  • Test the preferred gift in stock, low stock, and out of stock so fallback selection is deterministic.
  • Change the size or product that originally determined the gift and confirm the free variant updates correctly.
  • Repeat cart updates and checkout attempts and verify only one threshold gift is created.
  • Test BOGO quantities at the boundaries where the first and next free groups become eligible.

What changed

The promotion behaved like a simple customer benefit while inventory, free quantity, and fallback selection stayed tied to actual Shopify variants.

Reusable lesson

Treat free merchandise as an order-integrity rule, not only a discount. Eligibility, inventory selection, and duplicate prevention should all be deterministic and testable.

Official documentation and standards