d
Topic
Ryan O Shopify Employee
Posts:
233
6 months ago
g
2
upvotes

Discount Applications exposes line level discounts on the Order API

Hi!

If you missed it at Unite this year, we've exposed line level discount information on the Order API with a new readable property: discount_applications.  Take a look at the updated Order API reference for all of the details.  This feature will enable more accurate accounting when discounts are involved in orders.

We look forward to seeing what features this enables, as always please leave questions and comments in the thread below.

Shopify Apps Team

i
Replies
Posts:
3851
6 months ago

Quick Question:

item.price is static as the variant price. Always has been. Always will be. 

item.price less the total of the item's discount_allocations amounts will be the subtotal for the item used for the purpose of taxes?

So if an item is subject to VAT, to know the true item price, we have to do the following:

add up all the discount_allocation amounts. Subtract that from the line item price. Now remove VAT and we would know the price of the item without taxes. 

Correct? In other words, we can do the math now to ensure when dealing with taxes and discounts, we know the whole story for line item pricing now?

 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
Félix Shopify Employee
Posts:
16
Last edited 6 months ago

add up all the discount_allocation amounts. Subtract that from the line item price. Now remove VAT and we would know the price of the item without taxes. 

Yes!

If the tax is included in the line item price, this is how you proceed to know the amount paid by the customer without taxes for the line item. 

(quantity * price) - sum of discount allocations - VAT

If the tax is not included, you simply substract the sum of discount_allocations amounts from the line item total price.

(quantity * price) - sum of discount allocations

Correct? In other words, we can do the math now to ensure when dealing with taxes and discounts, we know the whole story for line item pricing now?

Correct!

Posts:
3851
Last edited 6 months ago

Ahhh you do bring up an interesting point. Always ensure the line item price is multiplied by quantity as the subtotal there, since the discount allocations amounts will be applied not per line item, but per total quantity purchased of that line item. 

In other words, we do not have to worry that a discount was applied  to just **one** or **two** of a quantity of three purchased of a line item, we can safely assume that whatever the total of the discount allocations amounts to, that amount applies to the total quantity purchased. 

 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
Félix Shopify Employee
Posts:
16
Last edited 6 months ago

In other words, we do not have to worry that a discount was applied on just one or two of a quantity of three purchased of a line item, we can safely assume that whatever the total of the discount allocations amounts is, it applies to the total quantity purchased. 

Yes! In the case of BOGO discounts (e.g. buy 1 get 1 for free) which can apply on a specific quantity, we split the line items to apply the discount on the desired quantity.

Posts:
3851
6 months ago

With Shops that use Avalara tax reporting, you have a line item called pre_tax_price which is calculated to ensure discounts are correctly applied to the retail price. 

Can we assume that this can now be ignored since Shopify reports discounting per line item? 

Again, in the name of cleaning up cruft, attributes like this will either be problematic or not depending on their value to the ecosystem. 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
Félix Shopify Employee
Posts:
16
Last edited 6 months ago

Can we assume that this can now be ignored since Shopify reports discounting per line item? 

Yes it can be ignored and we are planning on deprecating it. The same goes for the applied_discount attribute and applied_discounts on line items.

Again, in the name of cleaning up cruft, attributes like this will either be problematic or not depending on their value to the ecosystem. 

I could not agree more :)

Bharath Member
Posts:
16
6 months ago

HI All, 

Can we apply this line level discounts via API? if yes, how can we do that?

Ryan O Shopify Employee
Posts:
233
6 months ago

No, this is read only. Apply discounts the same way as before using PriceRule + Discount code APIs.

Posts:
618
6 months ago

Hi there,

I just wanted to say that we are very happy with this change.

This allows us to compute much more accurate discounts, in particular when a price rule applies only to specific line items.

Thank you!

Clement

Posts:
618
6 months ago

Hi again,

We came across something quite confusing.

It's really not clear how the discount applications relate to the lineitem.total_discount and order.total_discounts properties.

When testing discounts, we see that when using the online store, POS or draft orders, the discount allocation is allocated to line items but lineitem.total_discount always remains 0.

However, we came across an order generated by an app, where the discount amount was in both the discount allocation as well as the lineitem.total_discount. This cause our report to double count to the discount.

Is there a difference between those two scenarios? Is lineitem.total_discount deprecated?

If so, are orders that were placed before the discounts allocations release being changed to change to add the discount allocations property to them?

Félix Shopify Employee
Posts:
16
Last edited 6 months ago

Hi Clement!

order.total_discount will always contain the sum of all discounts so it is safe to use it.

line_item.total_discount will indeed be eventually deprecated as it represents discounts "showing on the line item". In other words, it's a presentation concern baked in the API as all discounts are actually allocated on the line items / shipping lines. This means it's indeed possible to have line_item.total_discount equal to 0, even if order.total_discount is not zero, as you mentioned.

Discount applications and their allocations include all discounts, not matter how they are presented (on the order or the line item). The discount application itself describes the discount calculation intention and type, so it's up to the client to decide how to present discounts given this information, if need be.

Also the API is backward compatible as we, more or less, always stored discounts this way internally, so all orders created before the discount allocations were introduced also expose those attributes.

Let me know if this helps!

Posts:
618
6 months ago

Thanks Felix for the speedy response.

So if I understand correctly, for reporting purposes line_item.total_discount is totally useless right?

We can always use line_item.discount_allocations, instead, even on very old orders?

Also, I wanted to confirm that the following equation is always true:

order.total_discounts = sum of discount allocations of all line items and shipping lines

Correct?

In other words, the entire discount amount is always 100% allocated to line items and/or shipping lines. Which means that there is no need for us to ever manually allocate the order-level discount to line items (pro-rata) as it is already done by Shopify.

Sorry to drill in but I want to make sure I got this correctly.

Félix Shopify Employee
Posts:
16
6 months ago

For reporting purposes line_item.total_discount is totally useless right?

Yes, this is correct.

We can always use line_item.discount_allocations, instead, even on very old orders?

Yes, this is also correct.

Also, I wanted to confirm that the following equation is always true:

order.total_discounts = sum of discount allocations of all line items and shipping lines

Correct?

You got it right!

In other words, the entire discount amount is always 100% allocated to line items and/or shipping lines. Which means that there is no need for us to ever manually allocate the order-level discount to line items (pro-rata) as it is already done by Shopify.

Exactly, you get the exact allocation done by Shopify in the backend. 

Let me know if there is anything else!

Posts:
618
6 months ago

Sweet, that's what I wanted to hear!

Thanks!

Posts:
618
6 months ago

Hi Felix,

We have come accross an order for which the equation does not hold.

It's an order with two discount applications, but only one of the two is allocated.

We are concerned about this because this could mean our reporting is wrong.

Are you able to investigate what happened here?

The order in question is https://nitrocharts-testing.myshopify.com/admin/orders/387291185212

Félix Shopify Employee
Posts:
16
6 months ago

Hi Clement!

I will investigate further as it seems there is a problem with the data itself with this order, the discount across all line items was not allocated properly. The API returns the truth, which is concerning a bit.

I'll get back to you when I have more information.

Thanks for letting me know about this.

Posts:
618
6 months ago

Ok.

We are almost ready to deploy our changes to incorporate discount allocations but we will wait until we hear back from you on this one.

If it's a freak order it may be ok but if it's a more widespread issue then we might hold off for now.

Félix Shopify Employee
Posts:
16
6 months ago

I understand. I am under the impression it's an outlier, but I'll have to confirm. I'll investigate this tomorrow morning as it is late a bit here (EDT) and I'll let you know.

Posts:
618
6 months ago

Sure, thanks for the quick replies!

Félix Shopify Employee
Posts:
16
6 months ago

Hi Clement! Just wanted to give you an update. We fixed the issue and the amount allocations should be showing on that order now. Sorry about the inconvenience. 

Posts:
618
6 months ago

Thanks Felix, I can see this order is fixed.

To clarify, was it fixed across all orders or just that particular one?

I'm hoping the fix is for all orders but if it's just this one, we'll have to make sure our code doesn't blow up and can handle that situation should it arise with another order. 

Félix Shopify Employee
Posts:
16
Last edited 6 months ago

It was a fix for all orders impacted by this defect, not just this single one. Note that the fix might take some time to take effect on all shards because of caching.

Posts:
618
6 months ago

Sweet! Thanks again for the quick turn around.

We are deploying today.

Posts:
618
5 months ago

Hi Felix,

We ended up deploying today only, but we have already come across another order for which the data doesn't add up.

Order.total_discounts is 0 even though there is a discount application of 3,400.

The order id is 186524172301. Can you please take a look?

Posts:
618
5 months ago

And now another order that doesn't add up came through. This time it appears to be a rounding error.

Order.total_discounts is 135.99 but there are two discounts application of 68.00.

(2 x 68 = 136) != 135.99

This is not great and I'd appreciate if you could look into this one as well.

Order id is 527794110523.

We've only deployed this change for a few minutes ago so I'm assuming more of these might come through.

I will not report them anymore if they look like similar to those two cases...

Félix Shopify Employee
Posts:
16
5 months ago

Sure I’ll take a look at both. Thanks for reporting those!

Félix Shopify Employee
Posts:
16
Last edited 5 months ago

The first order was created with bad data using Orders API. total_discounts was sent alongside discount_codes.amount with different values. At the time, we did not do any validation / recalculation if the two values were not synced. In other words, the client could send anything and it would just be persisted as is. We changed that on April 9th, discount_codes.amount now has precendence and total_discounts is calculated from ther former so this won't happen with orders created after that date.

As for the second issue, we are working on a fix for all orders. I will keep you posted.

Félix Shopify Employee
Posts:
16
5 months ago

We found a fix for the penny rounding issue and it should be deployed tomorrow.

Posts:
618
5 months ago

Thanks Felix for another quick turn around.

We've noticed a few more discrepancies in our logs and almost of them are related to the rounding issue so we're glad a fix is coming.

Any reason the first issue will not get a fix as well to set total_discounts  = discount_codes.amount?

Félix Shopify Employee
Posts:
16
5 months ago

Hi Clement!

The penny allocation bug is now fixed. I checked with your order and the amounts add up.

As for the first issue you mentioned, we have decided to not backfill those orders at this time as those were created as is by clients and this could have unintended side-effects.

Posts:
618
5 months ago

You're quick!

Thank you.

Posts:
618
5 months ago

Hi again Felix,

We found another issue which is slightly different.

It concerns an order created with the API so I suspect it's a problem with the order data, but Shopify did let it through.

The order has a non zero order.total_discounts but it has no discount codes.

There are no discount applications. I guess it makes given your earlier comment that discount_codes.amount has precedence.

However, clearly, total_discounts was not calculated from discount_codes.amount, as you had also mentioned, and we end up with an inconsistent order.

The order id is 604345466923.

Félix Shopify Employee
Posts:
16
Last edited 5 months ago

Hi Clement!

Good observation, discount_codes.amount has precendence when both are provided, but total_discounts can still be provided by clients even if there no actual discount on the order (total_discounts usually being the calculated sum of existing discounts). This has been the case for a long time as well as orders are usually imported "as is".

In best of worlds, clients should not be able to send total_discounts, but ignoring the field could be problematic.

We will come up with a solution and get back to you. One possibility I see would be to create a manual discount allocated across all line items if no discount is explicitly provided but total_discounts is.

 

Posts:
618
5 months ago

Ok. I guess it would be nice to have some consistency and invariants that always hold.

 

Félix Shopify Employee
Posts:
16
5 months ago

Definitely 🙂

Chris Member
Posts:
9
3 months ago

Helllo all, do you guys a sample JSON request that makes use of the discount_applications and discount_allocations?  I have not yet been sucessuly been able to create one that works :-S

Félix Shopify Employee
Posts:
16
3 months ago

Hey Chris! The API is read-only. There is no way to write discount applications and allocations directly. You need to go through the existing interface for this which will end up creating a discount application.

Chris Member
Posts:
9
3 months ago

Thanks for the reply Felix. That is so unfortunate :(  - I really wish the Shopify Reference guide was a bit more cleat as to what data elements are read-only vs not - and in which operations, it would have saved me a lot of time.  

Is Shopify Planing on making these APIs usable via the POST Order API any time soon? 

Posts:
3
about 1 month ago

Our integration of the Klarna Payments gateways uses the Shopify Checkout object to display order data (order total, discount, shipping, tax, etc.) on our hosted page and also to create the Klarna order.  In order to accurately support orders with Automatic Discounts, we need the automatic discount data to be available on the Checkout object prior to the customer completing the order.  Currently when a customer selects on of our gateways as a payment method, the customer is redirected to our hosted page, which uses the API data to display checkout prices.  Currently Automatic Discount data is not available in the Checkout object at the point in time when the customer is redirected to our hosted page.  As soon as the order is created in Shopify (which we create using the Shopify REST API), the Checkout object would then get updated with the discount data (in applied_discount field), but that is too late for our integration.  If helpful, feel free to see the flow at our Klarna Shopify demo store. Can you help us determine how we access the Automatic Discount data prior to the customer placing the order?  thanks!  

sebryu Member
Posts:
2
25 days ago

Hi all! Is there any way to check if the discount in order is from automatic discount or other source?