Discount class for auto discount

Background

I have a function-controlled auto discount, handling both order and product based discount. Recently it failed to combine with discount codes, due to the auto discount being treated as order discount class even when no order discount is being issued.

Therefore want to confirm if the discount class of a function-controlled auto discount, is controlled by “whether orderDiscountsAdd object is presented”, or “whether an actual candidate is included in candidates”?

Case

Discount code

  • order discount
  • set to allow combineWith product discounts

Auto discount

  • set to allow combineWith product and order discounts
  • orderDiscountsAdd: empty candidates, selectionStrategy = Maximum
  • productDiscountsAdd: have value for candidates

Based on Discount API doc, this auto discount should be treated as product discount class, thus allowing the combination.

Discount classes are assigned based on their associated Discount Function targets: OrderDiscountCandidateTarget, ProductDiscountCandidateTarget, and DeliveryDiscountCandidateTarget.

In actual use case, this auto discount is also treated a order discount class, which is not expected. This is confirmed by allowing order combineWith in discount code, the two discount successfully combine.

The combination was working until last week, so may I know if the logic regarding discount classes was updated since then?

Thanks in advance.

Hi @Mantis, when you created the discounts, how did you define discountClasses? Did your auto discount only have PRODUCT?

Hi @Paige-Shopify, my auto discount cover both PRODUCT and ORDER. When calling discountAutomaticAppCreate, the input is:

discountClasses: [ ORDER, PRODUCT ]

So the default discount classes should have both type.

But for the affected case, only PRODUCT discount are being granted, so only ProductDiscountCandidateTarget exist.

Hello all, may I know if theres any update on this issue? I just checked the admin combination section, it shows that the two discounts can be combined. I am a bit confused because it used to work. Thanks in advance.

Does this mean that the discount class is fixed when I create the discount, accounting to the defined discountClasses.
Sound contradict to

Discount classes are assigned based on their associated Discount Function targets: OrderDiscountCandidateTarget, ProductDiscountCandidateTarget, and DeliveryDiscountCandidateTarget.

So in high level, if a discount is set to cannot combined with order discount. My auto discount (defined discountClasses [order, product]) can never be combined with this discount, even with empty OrderDiscountCandidateTarget?

Sorry for the delay.

Discount class compatibility at cart/checkout is based on the discountClasses declared at creation, not what the function returns at runtime. A discount registered with discountClasses: [ORDER, PRODUCT] is treated as both an order and product discount for combination purposes, even when the function only returns a productDiscountsAdd operation at cart/checkout. This is intended behavior.

I recommend setting discountClasses to match only the type you intend to apply. If you need a function to conditionally apply different discount types, you’ll need separate discounts with the appropriate class for each scenario.

Hope that clarifies things. Let me know if you have any questions!

The discount class for combineWith matching is declared at create/update time via the discountClasses field on the discount node, not derived from what the function returns at runtime.

The doc passage you quoted —

“Discount classes are assigned based on their associated Discount Function targets: OrderDiscountCandidateTarget, ProductDiscountCandidateTarget, DeliveryDiscountCandidateTarget.”

— refers to which candidate targets the function is capable of emitting, declared upfront. It doesn’t get re-evaluated per-run. So a discount declared with [ORDER, PRODUCT] is treated as both classes for combineWith logic, regardless of whether orderDiscountsAdd.candidates is empty on a given run.

Your own test (allowing orderDiscounts: true on the code made it combine) confirms it — Shopify is using your declared classes.