@zoxllc/shopify-checkout-extensions 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/EXAMPLES.md CHANGED
@@ -360,9 +360,9 @@ export function run(input) {
360
360
 
361
361
  ---
362
362
 
363
- ## Example 11: Multi-Tier Gift with Purchase
363
+ ## Example 11: Multi-Tier Gift with Purchase (Cumulative)
364
364
 
365
- **Use Case:** Offer tiered gifts based on cart spend threshold (e.g., spend $75 get Gift A, $100 get Gift B, $250 get Gift C). Only the highest qualifying tier is applied.
365
+ **Use Case:** Offer cumulative tiered gifts based on cart spend threshold. All qualifying tiers are applied (stackTiers: true).
366
366
 
367
367
  ```json
368
368
  {
@@ -405,23 +405,94 @@ export function run(input) {
405
405
  "label": "Free Cosmic Drift Daily"
406
406
  }
407
407
  ],
408
- ["meta-exclude-gift"]
408
+ ["meta-exclude-gift"],
409
+ true
409
410
  ]
410
411
  }
411
412
  ```
412
413
 
413
- **How It Works:**
414
+ **How It Works (stackTiers: true):**
414
415
  - Customer adds items to cart totaling $150
415
416
  - Cart subtotal is calculated (excluding items tagged "meta-exclude-gift")
416
- - Tiers are evaluated from highest to lowest
417
- - $250 tier doesn't qualify ($150 < $250)
418
- - $100 tier DOES qualify ($150 >= $100)
419
- - Product "6640591011912" (Goldie Mystery ZOX) gets 100% discount
420
- - Lower tiers ($75) are NOT applied
417
+ - All qualifying tiers are found:
418
+ - $75 tier qualifies ($150 >= $75)
419
+ - $100 tier qualifies ($150 >= $100)
420
+ - $250 tier doesn't qualify ($150 < $250)
421
+ - Products get 100% discount:
422
+ - "6638547533896" (Colorwheel F&F) - from $75 tier
423
+ - "6640591011912" (Goldie Mystery ZOX) - from $100 tier
424
+ - Customer receives BOTH gifts (cumulative/stacking)
425
+
426
+ ---
427
+
428
+ ## Example 12: Multi-Tier Bundle Upgrade (Highest Only)
429
+
430
+ **Use Case:** Offer tiered bundle upgrades where higher spend gets a better bundle product. Only the highest qualifying tier is applied (stackTiers: false).
431
+
432
+ ```json
433
+ {
434
+ "__type": "MultiTierDiscount",
435
+ "label": "Spring Bundle Upgrade",
436
+ "active": true,
437
+ "description": "Spend more, get a better bundle!",
438
+ "inputs": [
439
+ ":all",
440
+ [],
441
+ [
442
+ {
443
+ "threshold": 75,
444
+ "discount": {
445
+ "__type": "PercentageDiscount",
446
+ "inputs": [100, "Free Starter Bundle"]
447
+ },
448
+ "productIds": ["1111111111111"],
449
+ "itemsToDiscount": 1,
450
+ "label": "Free Starter Bundle"
451
+ },
452
+ {
453
+ "threshold": 150,
454
+ "discount": {
455
+ "__type": "PercentageDiscount",
456
+ "inputs": [100, "Free Premium Bundle"]
457
+ },
458
+ "productIds": ["2222222222222"],
459
+ "itemsToDiscount": 1,
460
+ "label": "Free Premium Bundle"
461
+ },
462
+ {
463
+ "threshold": 300,
464
+ "discount": {
465
+ "__type": "PercentageDiscount",
466
+ "inputs": [100, "Free Deluxe Bundle"]
467
+ },
468
+ "productIds": ["3333333333333"],
469
+ "itemsToDiscount": 1,
470
+ "label": "Free Deluxe Bundle"
471
+ }
472
+ ],
473
+ ["meta-exclude-gift"],
474
+ false
475
+ ]
476
+ }
477
+ ```
478
+
479
+ **How It Works (stackTiers: false):**
480
+ - Customer adds items to cart totaling $200
481
+ - Cart subtotal is calculated (excluding items tagged "meta-exclude-gift")
482
+ - Highest qualifying tier is selected:
483
+ - $75 tier qualifies ($200 >= $75)
484
+ - $150 tier qualifies ($200 >= $150) ✓ HIGHEST
485
+ - $300 tier doesn't qualify ($200 < $300)
486
+ - Only the Premium Bundle gets 100% discount:
487
+ - "2222222222222" (Premium Bundle) - from $150 tier
488
+ - Customer receives ONLY the Premium Bundle (not the Starter Bundle)
489
+
490
+ ---
421
491
 
422
492
  **Key Features:**
423
493
  - Automatically excludes gift items from threshold calculation
424
- - Only applies the highest qualifying tier (no stacking)
494
+ - **stackTiers: true** - Applies ALL qualifying tiers (cumulative)
495
+ - **stackTiers: false** - Applies ONLY the highest qualifying tier
425
496
  - Supports product IDs or product tags per tier
426
497
  - Perfect for seasonal promotions with start/end dates
427
498
 
@@ -436,6 +507,9 @@ export function run(input) {
436
507
  - `itemsToDiscount` - Maximum items to discount (optional, defaults to all)
437
508
  - `label` - Display name for the tier (optional)
438
509
  4. **Exclude Tags** - Array of product tags to exclude from subtotal calculation (default: `["meta-exclude-gift"]`)
510
+ 5. **Stack Tiers** - Boolean (default: `true`)
511
+ - `true` - Apply all qualifying tiers (cumulative GWP)
512
+ - `false` - Apply only highest tier (bundle upgrades)
439
513
 
440
514
  ---
441
515
 
@@ -1 +1 @@
1
- {"version":3,"file":"CampaignFactory.d.ts","sourceRoot":"","sources":["../../src/common/CampaignFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAEV,SAAS,EAIV,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAa,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAiC5C,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,CACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,WAAW,GACX,OAAO,EAAE,GACT,MAAM,EAAE,GACR,MAAM,EAAE,GACR,WAAW,EAAE,CAChB,EAAE,CAAC;CACL,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,MAAM,EAAE,UAAU,GAAG,qBAAqB,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,qBAAa,eAAe;IAC1B,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GACI,QAAQ;IAG/D,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAuB/B,MAAM,CAAC,kBAAkB,CACvB,MAAM,EAAE,WAAW,GAEjB,QAAQ,GACR,SAAS,GACT,WAAW,GACX,UAAU,GACV,QAAQ,GACR,iBAAiB,GACjB,SAAS;CAyHd"}
1
+ {"version":3,"file":"CampaignFactory.d.ts","sourceRoot":"","sources":["../../src/common/CampaignFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAEV,SAAS,EAIV,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAa,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAiC5C,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,CACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,WAAW,GACX,OAAO,EAAE,GACT,MAAM,EAAE,GACR,MAAM,EAAE,GACR,WAAW,EAAE,CAChB,EAAE,CAAC;CACL,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,MAAM,EAAE,UAAU,GAAG,qBAAqB,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,qBAAa,eAAe;IAC1B,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GACI,QAAQ;IAG/D,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAuB/B,MAAM,CAAC,kBAAkB,CACvB,MAAM,EAAE,WAAW,GAEjB,QAAQ,GACR,SAAS,GACT,WAAW,GACX,UAAU,GACV,QAAQ,GACR,iBAAiB,GACjB,SAAS;CA0Hd"}
@@ -55,7 +55,7 @@ class CampaignFactory {
55
55
  case 'ShippingDiscount':
56
56
  return new ShippingDiscount_1.ShippingDiscount(args[0], args[1], args[2], args[3]);
57
57
  case 'MultiTierDiscount':
58
- return new MultiTierDiscount_1.MultiTierDiscount(args[0], args[1], args[2], args[3]);
58
+ return new MultiTierDiscount_1.MultiTierDiscount(args[0], args[1], args[2], args[3], args[4]);
59
59
  case 'AndSelector':
60
60
  return new AndSelector_1.AndSelector([...args]);
61
61
  case 'OrSelector':
@@ -16,28 +16,32 @@ export interface Tier {
16
16
  * MultiTierDiscount - Applies tiered discounts based on cart subtotal
17
17
  *
18
18
  * This campaign evaluates the cart total (excluding gifts) and applies
19
- * the discount from the highest qualifying tier.
19
+ * discounts based on the stackTiers configuration:
20
20
  *
21
- * Example use case: Tiered gift with purchase
22
- * - Spend $75: Get free product A
23
- * - Spend $100: Get free product B
24
- * - Spend $250: Get free product C
21
+ * - stackTiers: true (default) - Applies ALL qualifying tiers (cumulative)
22
+ * Example: Spend $150 Get products from both $75 and $100 tiers
25
23
  *
26
- * Only the highest qualifying tier is applied (e.g., if cart is $150,
27
- * only the $100 tier applies, not both $75 and $100).
24
+ * - stackTiers: false - Applies ONLY the highest qualifying tier
25
+ * Example: Spend $150 Get product from $100 tier only
26
+ *
27
+ * Use cases:
28
+ * - Cumulative GWP: Spend more, get more gifts (stackTiers: true)
29
+ * - Bundle upgrades: Spend more, get better bundle (stackTiers: false)
28
30
  */
29
31
  export declare class MultiTierDiscount extends Campaign {
30
32
  tiers: Tier[];
31
33
  excludeGiftTags: string[];
32
- constructor(behavior: QualifierBehavior, qualifiers: [Qualifier | AndSelector | OrSelector], tiers: Tier[], excludeGiftTags?: string[]);
34
+ stackTiers: boolean;
35
+ constructor(behavior: QualifierBehavior, qualifiers: [Qualifier | AndSelector | OrSelector], tiers: Tier[], excludeGiftTags?: string[], stackTiers?: boolean);
33
36
  /**
34
37
  * Calculate cart subtotal excluding gift items
35
38
  */
36
39
  private calculateCartSubtotal;
37
40
  /**
38
- * Find the highest qualifying tier based on cart subtotal
41
+ * Find all qualifying tiers based on cart subtotal
42
+ * Returns tiers in descending order by threshold (highest first)
39
43
  */
40
- private findQualifyingTier;
44
+ private findQualifyingTiers;
41
45
  /**
42
46
  * Filter line items that match the tier's product criteria
43
47
  */
@@ -1 +1 @@
1
- {"version":3,"file":"MultiTierDiscount.d.ts","sourceRoot":"","sources":["../../src/lineItem/MultiTierDiscount.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACV,iBAAiB,EACjB,SAAS,EACV,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,WAAW,IAAI;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,eAAe,EAAE,MAAM,EAAE,CAAC;gBAGxB,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,CAAC,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC,EAClD,KAAK,EAAE,IAAI,EAAE,EACb,eAAe,GAAE,MAAM,EAA0B;IASnD;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA8B7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA+B9B,GAAG,CAAC,YAAY,EAAE,YAAY,GAAG,YAAY;CA2E9C"}
1
+ {"version":3,"file":"MultiTierDiscount.d.ts","sourceRoot":"","sources":["../../src/lineItem/MultiTierDiscount.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACV,iBAAiB,EACjB,SAAS,EACV,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,WAAW,IAAI;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;gBAGlB,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,CAAC,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC,EAClD,KAAK,EAAE,IAAI,EAAE,EACb,eAAe,GAAE,MAAM,EAA0B,EACjD,UAAU,GAAE,OAAc;IAU5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA8B7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA+B9B,GAAG,CAAC,YAAY,EAAE,YAAY,GAAG,YAAY;CAqF9C"}
@@ -6,24 +6,28 @@ const Campaign_1 = require("../common/Campaign");
6
6
  * MultiTierDiscount - Applies tiered discounts based on cart subtotal
7
7
  *
8
8
  * This campaign evaluates the cart total (excluding gifts) and applies
9
- * the discount from the highest qualifying tier.
9
+ * discounts based on the stackTiers configuration:
10
10
  *
11
- * Example use case: Tiered gift with purchase
12
- * - Spend $75: Get free product A
13
- * - Spend $100: Get free product B
14
- * - Spend $250: Get free product C
11
+ * - stackTiers: true (default) - Applies ALL qualifying tiers (cumulative)
12
+ * Example: Spend $150 Get products from both $75 and $100 tiers
15
13
  *
16
- * Only the highest qualifying tier is applied (e.g., if cart is $150,
17
- * only the $100 tier applies, not both $75 and $100).
14
+ * - stackTiers: false - Applies ONLY the highest qualifying tier
15
+ * Example: Spend $150 Get product from $100 tier only
16
+ *
17
+ * Use cases:
18
+ * - Cumulative GWP: Spend more, get more gifts (stackTiers: true)
19
+ * - Bundle upgrades: Spend more, get better bundle (stackTiers: false)
18
20
  */
19
21
  class MultiTierDiscount extends Campaign_1.Campaign {
20
22
  tiers;
21
23
  excludeGiftTags;
22
- constructor(behavior, qualifiers, tiers, excludeGiftTags = ['meta-exclude-gift']) {
24
+ stackTiers;
25
+ constructor(behavior, qualifiers, tiers, excludeGiftTags = ['meta-exclude-gift'], stackTiers = true) {
23
26
  super(behavior, qualifiers);
24
27
  // Sort tiers by threshold descending (highest first)
25
28
  this.tiers = [...tiers].sort((a, b) => b.threshold - a.threshold);
26
29
  this.excludeGiftTags = excludeGiftTags;
30
+ this.stackTiers = stackTiers;
27
31
  }
28
32
  /**
29
33
  * Calculate cart subtotal excluding gift items
@@ -49,15 +53,11 @@ class MultiTierDiscount extends Campaign_1.Campaign {
49
53
  return subtotal;
50
54
  }
51
55
  /**
52
- * Find the highest qualifying tier based on cart subtotal
56
+ * Find all qualifying tiers based on cart subtotal
57
+ * Returns tiers in descending order by threshold (highest first)
53
58
  */
54
- findQualifyingTier(cartSubtotal) {
55
- for (const tier of this.tiers) {
56
- if (cartSubtotal >= tier.threshold) {
57
- return tier;
58
- }
59
- }
60
- return null;
59
+ findQualifyingTiers(cartSubtotal) {
60
+ return this.tiers.filter(tier => cartSubtotal >= tier.threshold);
61
61
  }
62
62
  /**
63
63
  * Filter line items that match the tier's product criteria
@@ -89,61 +89,70 @@ class MultiTierDiscount extends Campaign_1.Campaign {
89
89
  }
90
90
  // Calculate cart subtotal (excluding gifts)
91
91
  const cartSubtotal = this.calculateCartSubtotal(discountCart);
92
- // Find the highest qualifying tier
93
- const qualifyingTier = this.findQualifyingTier(cartSubtotal);
94
- if (!qualifyingTier) {
92
+ // Find qualifying tiers based on stackTiers configuration
93
+ const allQualifyingTiers = this.findQualifyingTiers(cartSubtotal);
94
+ if (allQualifyingTiers.length === 0) {
95
95
  // Cart doesn't meet minimum threshold
96
96
  return discountCart;
97
97
  }
98
- // Get line items that match this tier's product criteria
99
- const applicableLineItems = this.getApplicableLineItems(discountCart, qualifyingTier);
100
- if (applicableLineItems.length === 0) {
101
- // No matching products found
102
- return discountCart;
103
- }
104
- // Sort by price (ascending) to discount cheapest items first
105
- applicableLineItems.sort((a, b) => {
106
- const priceA = parseFloat(String(a.cost.amountPerQuantity.amount));
107
- const priceB = parseFloat(String(b.cost.amountPerQuantity.amount));
108
- return priceA - priceB;
109
- });
110
- const itemsToApplyDiscounts = [];
111
- let remainingDiscounts = qualifyingTier.itemsToDiscount;
112
- // Apply discount to matching items up to the limit
113
- applicableLineItems.forEach((lineItem) => {
114
- if (remainingDiscounts === 0)
115
- return;
116
- if (remainingDiscounts !== undefined) {
117
- // Apply to as many items as possible up to the limit
118
- if (lineItem.quantity >= remainingDiscounts) {
119
- itemsToApplyDiscounts.push({
120
- lineItem,
121
- maxDiscounts: remainingDiscounts,
122
- });
123
- remainingDiscounts = 0;
98
+ // Select tiers to apply based on stackTiers configuration
99
+ // Note: allQualifyingTiers is sorted by threshold descending (from constructor)
100
+ // so allQualifyingTiers[0] is the highest qualifying tier
101
+ const tiersToApply = this.stackTiers
102
+ ? allQualifyingTiers // Apply all qualifying tiers (cumulative)
103
+ : [allQualifyingTiers[0]]; // Apply only highest tier
104
+ // Apply each selected tier
105
+ for (const tier of tiersToApply) {
106
+ // Get line items that match this tier's product criteria
107
+ const applicableLineItems = this.getApplicableLineItems(discountCart, tier);
108
+ if (applicableLineItems.length === 0) {
109
+ // No matching products found for this tier
110
+ continue;
111
+ }
112
+ // Sort by price (ascending) to discount cheapest items first
113
+ applicableLineItems.sort((a, b) => {
114
+ const priceA = parseFloat(String(a.cost.amountPerQuantity.amount));
115
+ const priceB = parseFloat(String(b.cost.amountPerQuantity.amount));
116
+ return priceA - priceB;
117
+ });
118
+ const itemsToApplyDiscounts = [];
119
+ let remainingDiscounts = tier.itemsToDiscount;
120
+ // Apply discount to matching items up to the limit
121
+ applicableLineItems.forEach((lineItem) => {
122
+ if (remainingDiscounts === 0)
123
+ return;
124
+ if (remainingDiscounts !== undefined) {
125
+ // Apply to as many items as possible up to the limit
126
+ if (lineItem.quantity >= remainingDiscounts) {
127
+ itemsToApplyDiscounts.push({
128
+ lineItem,
129
+ maxDiscounts: remainingDiscounts,
130
+ });
131
+ remainingDiscounts = 0;
132
+ }
133
+ else {
134
+ // Apply to all items in this line
135
+ itemsToApplyDiscounts.push({
136
+ lineItem,
137
+ maxDiscounts: lineItem.quantity,
138
+ });
139
+ remainingDiscounts -= lineItem.quantity;
140
+ }
124
141
  }
125
142
  else {
126
- // Apply to all items in this line
143
+ // No limit, apply to all matching items
127
144
  itemsToApplyDiscounts.push({
128
145
  lineItem,
129
146
  maxDiscounts: lineItem.quantity,
130
147
  });
131
- remainingDiscounts -= lineItem.quantity;
132
148
  }
133
- }
134
- else {
135
- // No limit, apply to all matching items
136
- itemsToApplyDiscounts.push({
137
- lineItem,
138
- maxDiscounts: lineItem.quantity,
139
- });
140
- }
141
- });
142
- // Apply the tier's discount to all selected items
143
- itemsToApplyDiscounts.forEach((item) => {
144
- const discount = qualifyingTier.discount;
145
- discount.apply([item]);
146
- });
149
+ });
150
+ // Apply the tier's discount to all selected items
151
+ itemsToApplyDiscounts.forEach((item) => {
152
+ const discount = tier.discount;
153
+ discount.apply([item]);
154
+ });
155
+ }
147
156
  return discountCart;
148
157
  }
149
158
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zoxllc/shopify-checkout-extensions",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Configuration-driven runtime engine for Shopify checkout extensions - campaigns, discounts, qualifiers, and selectors",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",