question

jms avatar image
jms asked David Marginian edited

Taxes with Amount Discounts off by $0.01

Hi, we have seen a rare issue with our order tax calculation when an order amount discount is included. Our tax calculation is off by $0.01.

According to https://docs.clover.com/docs/calculating-order-totals#step-3-order-level-discounts, we group lineitems according to taxes, calculate the per item subtotal after discounts (rounded) for each tax, apply the tax rate to each lineItemPriceAfterDiscounts, sum them and round the answer.

For example, what we do (all prices in cents):

Tax1 = 8.25%
ItemPrices= 550, 500, 750, 650 (all items have above tax applied)
Discount = 613
OrderDiscountMultiplier:
(550 + 500 + 750 + 650 - 613) / (550, 500, 750, 650) = 0.749795918

ItemPricesAfterDiscounts:
550 * 0.749795918 = 412
500 * 0.749795918 = 375
750 * 0.749795918 = 562
650 * 0.749795918 = 487
TaxAmounts 
412 * 0.0825 = 33.99
375 * 0.0825 = 30.9375
562 * 0.0825 = 46.365
487 * 0.0825 = 40.1775
TaxAmountRounded = 33.99 + 30.9375 + 46.365 + 40.1775 = 151.47 = 151

However, we noticed that a similar order was calculated with a tax of 152 by clover resulting a 1 cent difference. This means we are doing a rounding off error above.

The problem is that we rely on the calculation to determine the charge amount to pass to the e-commerce API. When this issue occurs, clover considers the order as partially paid since we are charging 1 cent less.

Please help us understand what we are doing wrong here. I feel like we are in accordance with the guides provided in the mentioned link.

Please do not suggest us to set our own totals to the order so that e-commerce doesn't calculate them for us. We can't use that option because then the order will start showing up in the Clover Dashboards and Orders App even if the customer later decides to cancel the payment.

Thank You

Orderse-commerce apiDiscounts
10 |2000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

David Marginian avatar image
David Marginian answered David Marginian edited
There is no place in our system that issues a request like the one you showed. We actually don't set totals for a clover e-commerce payment and we certainly don't use SPLIT_CUSTOM anywhere. (Maybe this was an internal request from clover e-commerce to another service that uses the invoking appId when we attempt the e-commerce payment, and since it is a lower amount, is assumed as a SPLIT_CUSTOM? I can't say)

Your hunch was absolutely correct, that call is coming from our EComm servers when it is setting the total immediately prior to payment. That is something I will watch our for in the future instead of assuming the third party is making the request.

Update:

I would like to thank JMS for his excellent research and persistence on this issue, per JMS, here is an example on how to calculate an order total:

Item{1, 2, 3} = 154, 204, 300 (item prices)
Tax{1, 2} = 10%, 5% (taxes and rates)

1) Group the line items by tax rates:
Tax1 <- Item1, Item2 (tax assignments)
Tax2 <- Item2, Item3  

2) Calculate the discount multiplier:
OrderAmountDiscount = 227
DiscountMultiplier = 0.655015197

3) Sum the subtotals for each tax grouping:
SubtotalForTax1Items = 154+204=358 
SubtotalForTax2Items = 204+300=504

4) Multiple the subtotal for each tax grouping by the discount multiplier:
DiscountedSubtotalForTax1Items = 358*0.655015197 = round(234.49) = 234
DiscountedSubtotalForTax2Items = 504*0.655015197 = round(330.12) = 330

5) Calculate taxes for each tax group:
Tax1Amount = 234 * 0.10 = round(23.4) = 23
Tax2Amount = 330 * 0.05 = round(16.50) = 17
TotalTax = 23 + 17 = 40



6 comments
10 |2000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Hi @ David. We had a feeling something was wrong with the rounding. Thank you for looking into this. But I still have a confusion:

I found the following code in the clover-calc-1.0.jar:

1624164983631.png

1624164166629.png

As you can see, it is a bit different from both our methods. Notice that the getDiscountedSubtotal (which is rounded subtotal for items with a given tax) is used to calculate the tax which is then also rounded. So according to the clover-calc-1.0.jar:

Discounted Subtotal = (550+500+750+650)*0.749795918 = 1837 (rounded)
Tax = 1837 * 0.0825 = 151.55 = 152 (rounded)

It seems double rounding does occur according the the clover-calc-1.0.jar, but it happens on a different level.

Can you please confirm which calculation logic is the definitive method to calculate taxes in this scenario? The reason why I ask this is because I don't want to change the calculation logic to have it again fail for some other scenarios, and I don't know if the clover-calc-1.0.jar is now outdated or not.

Thank You

0 Likes 0 ·
1624164166629.png (14.1 KiB)
1624164983631.png (77.1 KiB)
Well, thank you for being so thorough and correcting my mistakes. I have updated my previous answer because I don't want it to cause confusion. I think what I have posted now is accurate. Please take a look at it and let me know what you think.


I would caution you calculating the total as you are above (total discounted line items * tax rate), as if a line item has multiple tax rates that differ from another line item it would lead to an incorrect calcuation.

0 Likes 0 ·
jms avatar image jms David Marginian ♦♦ ·

Hi @ David. I think you misunderstood me. Let me clarify with a better example:

Item{1, 2, 3} = 154, 204, 300 (item prices)
Tax{1, 2} = 10%, 5% (taxes and rates)
Tax1 <- Item1, Item2 (tax assignments)
Tax2 <- Item2, Item3  
OrderAmountDiscount = 227

DiscountMultiplier = 0.655015197

SubtotalForTax1Items = 154+204=358 (this is the item price of relevant taxes after all item level discounts (none in this question))
DiscountedSubtotalForTax1Items = 358*0.655015197 = round(234.49) = 234
Tax1Amount = 234 * 0.10 = round(23.4) = 23

SubtotalForTax2Items = 204+300=504
DiscountedSubtotalForTax2Items = 504*0.655015197 = round(330.12) = 330
Tax2Amount = 330 * 0.05 = round(16.50) = 17

TotalTax = 23 + 17 = 40

The above calculation is what I see in the clover-calc-1.0.jar. Since our original scenario has only one tax, this basically boils down to the calculation I suggested before:

Discounted Subtotal = (550+500+750+650)*0.749795918 = 1837 (rounded)
Tax = 1837 * 0.0825 = 151.55 = 152 (rounded)

Using your calculation logic for the same scenario, we will have the following:

Discounted Line Item
154 * 0.655015197 = round(100.87) = 101
204 * 0.655015197 = round(133.62) = 134
300 * 0.655015197 = round(196.50) = 197

Line Item Tax
Tax1 = (101 + 134) * 0.10 = round(23.50) = 24
Tax2 = (134 + 197) * 0.05 = round(16.55) = 17

TotalTax = 24 + 17 = 41

Notice that the tax is now off by 1c for different scenarios. The above scenario in the Register App also shows the tax as $0.40 supporting my logic:

reg-3.png


0 Likes 0 ·
reg-3.png (72.2 KiB)
Show more comments
Show more comments
David Marginian avatar image
David Marginian answered David Marginian edited

What is your app id (moderators only comment please)? I am asking because an API request is being made by a third party app and the total is being set to 19.89. I am guessing it isn't your app that is doing this so it sounds like we will need to contact the other third party developer involved and request that they fix their total calculation.

10 |2000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

David Marginian avatar image
David Marginian answered jms edited

Your app XP.......02 is the app making the request that is setting the total to 19.89:

2021-06-16 08:54:54.865
RequestLog{reqBody={"total":1989,"payType":"SPLIT_CUSTOM"},
3 comments
10 |2000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Hi @ David,

There is no place in our system that issues a request like the one you showed. We actually don't set totals for a clover e-commerce payment and we certainly don't use SPLIT_CUSTOM anywhere. (Maybe this was an internal request from clover e-commerce to another service that uses the invoking appId when we attempt the e-commerce payment, and since it is a lower amount, is assumed as a SPLIT_CUSTOM? I can't say)

The real problem I still feel is that our calculation is wrong. We placed the same order with matched amounts and discounts in the sandbox Clover Register App, and this is what we got:

register.png

Notice that this also shows the total as 19.89 and tax as 1.52 instead of our incorrect values. This along with the e-commerce auto calculation both giving the same results indicates that there is something wrong with our calculation.

Could you please verify if the calculation we made is correct or not, because at the end of the day, there should be one value for totals and taxes right?

0 Likes 0 ·
register.png (67.6 KiB)
Very interesting. I will take a closer look and try to get to the bottom of this tomorrow morning.
0 Likes 0 ·
jms avatar image jms David Marginian ♦♦ ·
Thanks @ David. Looking forward to it.
0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Welcome to the
Clover Developer Community