Hi everyone,
We build a gift card app. Our app creates gift card products with productCreate, and when one is purchased, our app issues the gift card itself using giftCardCreate and emails it with our own designs and scheduling.
The problem: because these are regular products, any merchant discount code that applies to “All products” or to the entire order also discounts the gift card. A customer can use a 20% code on a $100 gift card, pay $80, and still receive a $100 card.
What we’ve tried or ruled out:
giftCard: trueonproductCreate. Native gift card products aren’t discountable, but Shopify then issues and emails its own gift card when the product is purchased, on top of ours. The customer ends up with two cards.- Collection-scoped discounts. Merchants can limit product discounts to collections that leave out the gift card. But order-level discounts (“Amount off order”) can’t exclude products, and we can’t rely on every merchant setting up their discounts correctly.
- Discount Function API. As far as we can tell, a Discount Function only controls the discounts it creates itself. It can’t remove or narrow the merchant’s own discount codes on a specific line.
- Cart & Checkout Validation Function. Our plan is to block checkout when a gift card line’s
cost.totalAmountis less than itscost.subtotalAmount. The input has nocart.discountCodes, so we can only detect the effect of a discount, not the code itself. A validation can only block the whole checkout; it can’t remove the discount from just the gift card line. We also found that returning an error on$.cartmakes/cart/add.jsreturn 422, so we’ll only return errors on checkout steps (buyerJourney.step).
Questions:
- Is there a supported way to mark a product as not eligible for any discount (product-level and order-level) without making it a native gift card product?
- Alternatively, is there a way to use
giftCard: truebut stop Shopify from issuing its own gift card, so our app handles issuance? - In our testing, product-level discounts reduce
cart.lines[].cost.totalAmountin the validation input, but order-level (“Amount off order”) discounts don’t. Even atbuyerJourney.step: CHECKOUT_INTERACTION, with the discount showing in checkout, every line keepstotalAmount == subtotalAmount. Is there any way for a validation function to see an order-level discount, or its effect on a specific line? - If a cart has a gift card and another product with one discount code, is there any way to keep the discount on the other product while stopping it from applying to the gift card? Or is blocking checkout the only option?
Any pointers or examples would be much appreciated. Thanks!