skills/pricing-promotions/price-rules-engine/SKILL.md
Define stackable pricing rules with priority ordering, customer-segment targeting, product exclusions, and automatic discount combination logic
npx skillsauth add finsilabs/awesome-ecommerce-skills price-rules-engineInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A price rules engine lets you define multiple concurrent promotions — site-wide sales, coupon codes, loyalty discounts — and apply them to a cart in a predictable, controlled order. The key concerns are: which rules apply to which products, which rules can stack with others, and what happens when multiple rules target the same item. Every major platform has some form of this built in; the gap is usually in advanced stacking control and customer-segment targeting.
| Platform | Built-in Capability | When to Extend | |----------|-------------------|----------------| | Shopify | Discounts admin handles basic stacking via "Combinations" settings | Use Bold Discounts or Shopify Scripts (Plus) for advanced rule stacking, customer-segment targeting, and conditional logic | | WooCommerce | Coupons core + Dynamic Pricing plugin for conditional rules | For complex priority ordering and segment targeting: YITH WooCommerce Dynamic Pricing & Discounts provides the most control | | BigCommerce | Promotions engine supports multiple concurrent promotions with priority ordering and stacking rules | BigCommerce's built-in system handles most scenarios natively | | Custom / Headless | Must build | Required when none of the above fits your use case |
Shopify manages discount stacking through the Combinations setting on each discount.
Setting up stacking rules:
Customer-segment targeting:
Priority and exclusions:
Shopify Plus — Shopify Scripts: For rules that cannot be expressed through the Discounts UI (e.g., tiered stacking where the second discount only applies if the cart is above a threshold):
Bold Discounts (App Store, ~$20/month): A visual rule builder for Shopify that supports:
WooCommerce coupons support basic single-rule discounts. For a full price rules engine with priority ordering and stacking control, use the Dynamic Pricing plugin.
Installing and configuring YITH WooCommerce Dynamic Pricing & Discounts:
Customer segment targeting in WooCommerce:
Example: VIP-only 20% off apparel, excludes clearance:
BigCommerce's Promotions engine natively supports priority ordering and stacking control.
BigCommerce evaluates promotions in priority order and respects the "can be combined" setting. Multiple non-combinable promotions will apply only the best-value one for the customer.
For custom storefronts, implement a rule evaluator that processes rules in priority order, enforces stacking constraints, and applies rules to eligible cart lines:
interface PriceRule {
id: string;
name: string;
type: 'percentage_off' | 'fixed_off' | 'free_shipping' | 'buy_x_get_y';
value: number; // percentage or cents
priority: number; // higher = applied first
isStackable: boolean;
couponCode?: string; // null = automatic (no code required)
minCartCents?: number;
customerSegments?: string[];
applicableProducts?: string[];
applicableCategories?: string[];
excludedProducts?: string[];
startsAt: Date;
endsAt?: Date;
}
interface CartContext {
lines: { lineId: string; productId: string; categoryIds: string[]; quantity: number; currentPriceCents: number }[];
subtotalCents: number;
customerSegments: string[];
appliedCouponCode?: string;
}
function evaluateRules(cart: CartContext, rules: PriceRule[]): { ruleId: string; discountCents: number }[] {
const now = new Date();
const active = rules.filter(r =>
r.startsAt <= now && (!r.endsAt || r.endsAt > now)
).sort((a, b) => b.priority - a.priority); // highest priority first
const applications: { ruleId: string; discountCents: number }[] = [];
let nonStackableApplied = false;
for (const rule of active) {
if (!rule.isStackable && nonStackableApplied) continue;
// Coupon-linked rules require the code to be applied
if (rule.couponCode && rule.couponCode !== cart.appliedCouponCode) continue;
// Cart minimum check
if (rule.minCartCents && cart.subtotalCents < rule.minCartCents) continue;
// Customer segment check
if (rule.customerSegments?.length && !rule.customerSegments.some(s => cart.customerSegments.includes(s))) continue;
// Find eligible lines
const eligibleLines = cart.lines.filter(line => {
if (rule.excludedProducts?.includes(line.productId)) return false;
if (rule.applicableProducts?.length) return rule.applicableProducts.includes(line.productId);
if (rule.applicableCategories?.length) return rule.applicableCategories.some(c => line.categoryIds.includes(c));
return true; // no scope restriction = all products
});
if (eligibleLines.length === 0) continue;
let discountCents = 0;
if (rule.type === 'percentage_off') {
discountCents = Math.round(
eligibleLines.reduce((s, l) => s + l.currentPriceCents * l.quantity, 0) * rule.value / 100
);
} else if (rule.type === 'fixed_off') {
discountCents = Math.min(rule.value, cart.subtotalCents);
}
if (discountCents > 0) {
applications.push({ ruleId: rule.id, discountCents });
if (!rule.isStackable) nonStackableApplied = true;
}
}
return applications;
}
Persist rule applications with every order so you can answer customer service questions ("which discount applied?") and track promotion ROI.
priority integer so marketing can control evaluation order without code changes| Problem | Solution | |---------|----------| | Two non-stackable rules both apply | Sort by priority, apply the highest-priority non-stackable first, then skip all other non-stackable rules | | A rule applies to an excluded product | Always check exclusions before inclusions; exclusion takes precedence in all cases | | Total discount causes order to go negative | Cap total discount at cart subtotal; no order total should go below zero | | Marketing edits a live rule mid-campaign | Treat active rules as immutable — create a new rule and deactivate the old one; never edit live rules | | Rule activates/deactivates a few seconds off schedule | Set start/end times conservatively (a few minutes before/after intended time) and verify in staging; for critical timing, use Launchpad (Shopify Plus) or a scheduled job |
tools
Let shoppers save products to a wishlist, share it with friends, and get notified when saved items come back in stock or drop in price
development
Build a themeable storefront with design tokens and CSS custom properties that supports white-labeling, multi-brand variants, and dark mode
development
Speed up product discovery with instant search suggestions, fuzzy typo matching, and category-aware results powered by Algolia or Elasticsearch
development
Build a mobile-first storefront with thumb-friendly navigation, sticky add-to-cart buttons, and touch-optimized components for high mobile conversion