Ecommerce Developer
 
 

Design & Inspiration

Coding for Tax Calculations: Everything You Never Wanted to Know – Part 1

 

Calculating sales-related taxes is complicated enough for a single retail store in one location, let alone when you have multiple customers and locations worldwide, as is the case with ecommerce sites. Every jurisdiction has its own rules and you need to know these rules when writing code to perform potentially complex tax calculations at checkout.

Elastic Path Software—where I work—is a Canadian company, so we have direct experience working with tax-exclusive calculations in our clients' checkout pages, However, much of the world uses tax-inclusive calculations, which can be confusing for North American web developers. Collecting Taxes is a Must

Writing Code to Calculate Taxes is No Simple Matter

When it comes to writing code to calculate taxes on orders, the simplest and best recommendation I can make is: Let someone else do it, preferably a company specializing in this area.

If life were that simple, this would be a short article. Sadly, sometimes, such as when you are building an ecommerce platform, you can't follow that advice. Even if you are able to use an external service to perform your tax calculations, it pays to have a basic understanding of the issues involved in making these calculations.

In this article, I will discuss some of the issues involved, things you need to know, and the "gotchas" to watch out for as you develop your own code or work with a specialist to develop it for you.

Because this is a complicated topic, this is the first of two articles I will post about calculating taxes.

I Am a Software Engineer, Not a Lawyer or Accountant

Consider this my disclaimer. I'm not a lawyer, and I'm not an accountant. So I’m not providing legal or accounting advice. If you are handling tax calculations in code do yourself and your company or customers a favor and consult a tax expert. But I am a software engineer with experience coding tax calculations, and it is from that experience that I write this.

Tax Basics: Exclusive and Inclusive Taxes

To start with, we need to be clear on what the terms tax exclusive and tax inclusive mean. If prices are tax exclusive, it means that the price you see in a store or online doesn't include the tax you will have to pay. So if you live in beautiful Vancouver, B.C., you'll pay an extra 12 percent tax on top of the list price. For example, if you want to order a movie ticket online which has a list price of $9.00, you'll end up paying $10.08 for your ticket: $9.00 for the merchant and $1.08 in tax.

When prices are tax inclusive, things are simpler for the consumer. The price you see is the price you pay. If a movie ticket is listed as $9.00, you pay $9.00. Things are a more complicated for the merchant, however. If our inclusive jurisdiction also charges 12 percent tax, that $9.00 doesn't all go to the merchant. The merchant (i.e. ticket seller) needs to calculate how much of that $9.00 it needs to remit in tax, and how much it will get to keep.

The equation for determining tax owed is:

taxRate/(1 + taxRate) * list price

taxRate is given as a decimal (for example, 12%=0.12). So if we plug in our values we see that the merchant needs to pay 0.12/(1 + 0.12) * $9.00 = $0.96 in tax. The store keeps $9.00 - $0.96 = $8.04 in revenue.

Rounding

That last example brings us nicely to rounding. I glossed over the fact that 0.12/(1 + 0.12) * $9.00 = $0.96428571428571, at least according to my calculator. Thanks to that pesky division we need to do some rounding. (This can, of course, happen with multiplication as well.)

Since we're talking about money, people really care which way that rounding goes. There are three main issues when rounding: (1) which way to round; (2) how many digits to keep when rounding; and (3) when to round—that is, at what point in the order to round.

Which Way to Round

The complexity in rounding arises when you have decimals ending in a five. For example, if you have a value that is exactly $1.285 but keep only two significant digits, should you round up or down? Should you end up with $1.28 or $1.29? Two of the most common rounding methods are rounding half-up and rounding half-even, also known as banker's rounding.

Rounding half-up will be familiar to many people from school. It means that you round up when you have a five. So $1.285 will become $1.29 and $1.295 will become $1.30. The problem with this rounding method is that it is slightly biased in favor of rounding up. That is, rounding up happens a little more often than rounding down.

Rounding half-even means you always round fives towards the even number, which produces little to no bias in favor of rounding up or down. So $1.285 rounds to $1.28 and $1.295 rounds to $1.30.

Keep in mind that the type of rounding you should use may be determined by rules or practices of your jurisdiction (or the many jurisdictions your company or client does collect tax for), so be sure you check what these are.

How Many Digits to Keep When Rounding

The simplest answer to the question, “How many digits should I keep when rounding?” is to use the same number of digits used by the currency in question. For example, with dollars you should round to two decimal points. With Japanese Yen, you should round to zero decimal points. However, each jurisdiction may have specific requirements about how many significant digits should be kept during calculations, so it is a good idea to make sure this is configurable when you write the code.

Finally, note during your calculations, you may need to round off results with a large numbers of digits after the decimal. That’s fine. But you should not round to the currency level until the end of the calculation.

When to Round

As a rule of thumb, make sure that you round your digits as late as possible in your calculations. Be careful when doing calculations involving division, which may lead to some loss of precision without explicitly rounding. Operations that are arithmetically equivalent may not be when you run them in a computer.

For example, the equation to figure out the tax from inclusive tax prices is:

tax amount = taxRate * inclusiveAmount / (1 + taxRate)

In this calculation, you may choose whether to do (taxRate * inclusiveAmount) / (1 + taxRate) or (taxRate / (1 + taxRate)) * inclusiveAmount. These are equivalent algebraically, but depending on the number of significant digits kept when doing the division, may not be equivalent on a computer.

As a technical note, remember that floating-point numbers have no place anywhere near your money. Floating points do not exactly represent numbers, so can introduce errors before you do any arithmetic. Don't use them. Instead use arbitrary precision numbers such as Java's BigDecimal.

When to Calculate Taxes on An Order and When to Round Results

You have a couple of options for when to calculate taxes on an order, as well as a couple of options for when to round the results off. Let's start with when to calculate taxes on an order.

Your first option is to calculate the taxes at the end on the order subtotal. Your second option is to calculate the tax for each line item in the order, and then add the items up.

Which of the two options should you use in your calculations? The answer, of course, is it depends. In the U.S. and Canada, calculate the taxes on the order subtotal. In the U.K. calculate the taxes at each line, then sum. Preferred options vary in other jurisdictions as well, so be sure to check your own situation before coding.

When to Round Results

As soon as you start to plug values into your code to test it, you'll see you need to decide when to round results. Two key things should guide your decision:

  1. Tax authority rules. If the rules indicate you must calculate taxes on the subtotal, as in the U.S. and Canada, you should round at that point and not before. If the rules indicate you must calculate taxes on the line level, as in the U.K., you should round at the line level, but not before.

  2. Round late, if no tax authority rules. If you can't find any rules, use the rule of thumb stated in the section above: Round your digits as late as possible in your calculations.

Let's look at an example to see how rounding at the line level versus only at the subtotal level affects the results. Say we're back in our tax exclusive jurisdiction with a 7 percent tax and a customer who is ordering two large bags of dog food for $33.33 each and a Great Dane dog for $239.79, all for a subtotal of $306.45.

If you round at the line level:

  • First calculate the tax on the dog food (2*33.33)*0.07 = $4.6662, and round to $4.67.
  • Then calculate the tax on the dog $239.79 * 0.07 = $16.7853, and round to $16.79.
  • Finally, total the taxes $4.67 + $16.79 = $21.46.

If you round only on the final subtotal:

  • First calculate the tax on the dog food (2*33.33)*0.07 = $4.6662.
  • Then calculate the tax on the dog $239.79 * 0.07 = $16.7853.
  • Finally, total the taxes $4.6662 + $16.7853 = $21.45157. Round to $21.45.

In this example, calculating on each line gives us one cent more than calculating tax at the total.

Conclusion

There are many details to consider with tax calculations, and the details have important legal and financial implications. Sadly the details vary significantly around the world, which impacts international ecommerce sites greatly. Hopefully I've given you enough of a look at the issues involved to get started coding, or at least enough to understand the implications when choosing a tax package or expanding into a new jurisdiction.

Editor's Note: Part 2 of this short series discusses calculating multiple tax rates on a single order, changing tax rates, handling taxes on returns, and understanding how discounts affect taxes.

Resources

4 Comments

Rss-sm