Discussing Shopify Functions development, deployment, and usage in Shopify apps.
I have started work using the Function - Product discount API and it seems to be very limited in what it can achieve. We are trying to apply different discount amounts to different line items. i.e. 40% to one line item and 5% to another. But there is no strategy that allows for this kind of discounting. The FIRST strategy only applies 1 of the discounts. I have looked briefly at the other cart/discount API's and nothing does what we need. This is really troubling as we have a lot of complex scripts currently that will no longer work with the migration to functions. Have I misunderstood how this works? Is there a better API to use?
{
"discounts": [
{
"targets": [
{
"productVariant": {
"id": "gid://shopify/ProductVariant/45170063278355"
}
}
],
"value": {
"percentage": {
"value": "40.0"
}
}
},
{
"targets": [
{
"productVariant": {
"id": "gid://shopify/ProductVariant/45170063474963"
}
}
],
"value": {
"percentage": {
"value": "5.0"
}
}
}
],
"discountApplicationStrategy": "FIRST"
}
Hi 👋
I believe this type of discounting *should* be possible today!
When you create your Discount Node that you attach your Shopify Function to make sure to specify the `combinesWith` and set `ProductDiscounts: true`. This will allow multiple product discounts to be used.
Let me know if this is working as expected for you!
To learn more visit the Shopify Help Center or the Community Blog.
Not OP, but I'm also trying to combine different discount levels on separate lines. I have made sure that the Discount Node was created with ProductDiscounts: true and it shows as being able to combine with Product Discounts in the Discounts tab of my test store. However, only the first discount in the array is processed on the checkout page. Here's my function output as an example.
{
"discountApplicationStrategy": "MAXIMUM",
"discounts": [
{
"message": "Your member discount has been applied",
"targets": [
{
"productVariant": {
"id": "gid://shopify/ProductVariant/44721908678949"
}
}
],
"value": {
"percentage": {
"value": "10"
}
}
},
{
"message": "Your member discount has been applied",
"targets": [
{
"productVariant": {
"id": "gid://shopify/ProductVariant/44721908613413"
}
}
],
"value": {
"fixedAmount": {
"amount": "30",
"appliesToEachItem": true
}
}
}
]
}
Hi there 👋
While your Function can return an array of discount proposals, only one of those proposals will be applied to the order per discount node: either the first one, or the proposal that will provide the maximum value to the buyer.
If you wanted to apply the result of multiple product discounts to the same cart, you would need to create multiple product discount nodes.
To learn more visit the Shopify Help Center or the Community Blog.
Hi,
I am in same trouble. Can you explain this in details where you says, "you would need to create multiple product discount nodes" What exactly we will have to do?
@lizk , this is a bit confusing. Why does each discount in the array allow specifying its own targets then? If only one of the discount proposals will be applied across all targets, then targets should be outside of the discount proposals array, not inside it. Can you please clarify?
Please add a new DiscountApplicationStrategy type with the value of "ALL".
this way we will be able to apply all discounts in the discounts array to the same DiscountNode.
further more, you are limiting us to only 5 automatic app discounts.
Hi @hagson
I shared this feature request with the team!
To learn more visit the Shopify Help Center or the Community Blog.
Hi @lizk are you able to provide any updates on this? We are trying to replace one of our Scripts with a Function that applies volume based discounts to individual line items (using a metafield as input). This is something many people will need to achieve in an intuitive way before Scripts are deprecated
I can apply 2 discount in 2 differents products, I apply these discounts based on products attributes. Follow the print below.
But I want to apply discount if the product has attribute "_x" for exemple, it works partially but if I apply the discount to the product that has this attribute and I add the same product without this attribute on cart the discount will be added to the product without attribute too (if I only add to cart the product without the attribute, discount is not applied).
I think it might be because the target for discount can be only productVariant, so the discount is added to this variant id, not the line id. That's why the discount is applied to all products that has the same variant id, but not same attribute I guess (sorry for my english, I hope you understand it).
I think, Property 'ALL' does not exist on type 'DiscountApplicationStrategy'. Also in doc, we've two types "FIRST" and "MAXIMUM".
Have you tried "DiscountApplicationStrategy" type "ALL"? @hagson
I tried using "ALL" but it does not work, the code just crashes. We really need an "ALL" strategy. Without it, our site will cease to function properly once scripts are depreciated. @lizk please note that the current discounting methods are far from sufficient. Without an ALL strategy our Quantity Price Breaks, which we have custom-coded using scripts, will cease to function, along with other features we have built into Shopify over the time we have used it.
@lizk @Shopify What we really need is the ability to modify, using a single script, any of the line items. Even an "ALL" strategy (mentioned in other posts) is not sufficient. If the cart contained:
We need to apply discounts on line items based upon not just the variant_id, but the actual line item itself. Because attributes or other properties may make different discount strategies needed. Something like scripts used to do, where you could apply discounts on actually line items. In the example above 1) and 2) share product_id and variant_id, but will use different discounting based upon attribute. Current function based scripts do not allow us to specify the exact line item to discount, only selecting items by variant, which will not work in this use case.
An example of what we need may be:
Foreach lineitem as I;
If(i.attribute.cheaper == true){
Discount = 0.95
If(i.product_id == 123){
Discount = 0.8
}
} else if(i.attribute.cheaper == false){
Discount = 1;
}
i.setDiscount(i.price * Discount);
End Foreach
In reality our scripts are much more complex than the example above, but the functionality we need is to modify actual line items, not variants, not product_id’s etc, but physical line items.
The only way I was able to achieve this happening was using the "unstable" version of the api and adding it into shopify.extension.toml, and in the schema.graphql I had to append in the "ALL" along with the FIRST and MAXIMUM that is currently present.
Now, I did also use @LizaK point about the Discount Node comment from above, but since I am using an Automatic discount I applied it to that instead, not sure if it made a difference to be honest? Lol..
But anyway this is my output as result
As you can see in the image above I used a fixedAmount in this case, but I am assuming percentage could work as well.
Here are my Input and Output from the Logs in the Partners Dash for some additional context:
{ "cart": { "lines": [ { "id": "gid://shopify/CartLine/0", "quantity": 1, "merchandise": { "__typename": "ProductVariant", "id": "gid://shopify/ProductVariant/47315301466387", "sku": "#PIENINJA", "metafield": null, "product": { "metafield": { "value": "0.5" } } } }, { "id": "gid://shopify/CartLine/1", "quantity": 1, "merchandise": { "__typename": "ProductVariant", "id": "gid://shopify/ProductVariant/47318889431315", "sku": "#PIEKNIGHT", "metafield": null, "product": { "metafield": { "value": "0.2" } } } } ] }, "discountNode": { "metafield": { "value": "{\"quantity\":1,\"percentage\":25.0}" } } }
Output:
{ "discountApplicationStrategy": "ALL", "discounts": [ { "message": "Malibu Dynamic Deal!", "targets": [ { "productVariant": { "id": "gid://shopify/ProductVariant/47315301466387" } } ], "value": { "fixedAmount": { "amount": "50", "appliesToEachItem": true } } }, { "message": "Malibu Dynamic Deal!", "targets": [ { "productVariant": { "id": "gid://shopify/ProductVariant/47318889431315" } } ], "value": { "fixedAmount": { "amount": "20", "appliesToEachItem": true } } } ] }
But you can see the discountApplicationStrategy being "ALL"
Hope this helps.. Cheers. (granted unstable API, so who knows if Shopify will let this slide through.. haha) -- But yeah. Really need this folks. Shopify Scripts, has the ability.. odd that you wouldn't include it as a bare min in Functions.
In order to apply multi discounting, you would need to think of it as an actual Discount. You cannot apply multiple discounts when you create a Discount in the Shopify Admin.
You can however, toggle in the Discounts Admin the "Combinations" And combine it with other discounts,
So put simply, how you would achieve your usecase, is have two discount nodes or extensions, ensure both of them when you apply the Shopify function have the combinesWith property set.
Please see here:
https://shopify.dev/docs/api/admin-graphql/unstable/mutations/discountAutomaticAppCreate
The reality is we have far more than two discounts we wish to apply. We could have 100 items in the cart, and each of those could have their own unique discount amount. So we could not use 100's of discount nodes or extensions. If something does not change with the way Shopify allows discounts to be made many of our store's unique features will cease to function.