I found the developer experience to be a bit cumbersome, so want to write a summary in case it might help someone. We won’t cover any code because that’s already in docs. This is not a typical tutorial. This is more of a birds eye view of what to do.
This overview is for custom integrations only, only developers might need to see this.
Let’s get to it!
Even if there was perfect developer experience, the way to integrate TaxJar to Stripe is probably not what you’d expect. Stripe does not simply accept a tax amount on API calls, nor does it accept a tax percentage and handle finding the amount form there. One must use the Stripe API endpoint for ‘tax rates‘. Essentially you send that endpoint a percentage amount ( i.e. 7.5% sales tax ) and Stripe creates a tax rate object. You the use the ID of that tax rate object when creating new transactions or subscriptions.
If you’ve decided to use TaxJar to do your tax rate calculations ( using customer address to find accurate tax rates for their specific location, apparently precision is best practice as rates may vary even within the same zip code ), then utilize the TaxJar API endpoint ‘rates‘ to get the ‘combined_rate’.
Once you have the rate from TaxJar, use Stripe API tax rates endpoint to create a Stripe Tax Rate object. On enterprise scale systems you probably want to consolidate these, but for the purpose of this article we’ll assume one tax rate per customer will be fine.
Now we can call Stripe API to make a transaction or subscription and pass the Stripe tax rate ID as the ‘default_tax_rates’ attribute. Stripe will then calculate how much tax to charge and will charge accordingly. Important to note, when creating the tax rate on Stripe, it can be set to either exclusive or inclusive. This tells Stripe to either charge the tax on top of the total amount, and use the total amount to also include the tax. For example if you’re selling subscriptions at 30 per month, do you want to charge customer 32.32 ( total plus tax ) or 30 ( in which case less than thirty would become revenue after tax, and the difference goes to tax ). To be clear, exclusive means not included in the total ( ie added to 30, so resulting charge would be 32.32 in this example ) and inclusive means tax should come out of the total ( leaving the total charge to customer as 30 even, in this example).
From there, TaxJar needs the details of all your transactions. Up to now TaxJar has only provided the ‘combined tax rate’ for you to provide to Stripe for needed calculations. There are two ways to get your transaction data from Stripe to TaxJar. The easiest is to use the TaxJar Stripe importer, which grabs transaction data from Stripe API nightly. This is already build and just needs you to activate it. The other option is to use the TaxJar transactions endpoint to feed that data in at the time of transaction. If you’re selling subscriptions, I wouldn’t set this up just at time of subscription create, but would instead setup a Stripe webhook event for invoice paid and send transaction data to TaxJar on each invoice paid event.
Perhaps what I’m about to tell you should be at the start of the article, but I wanted to start with what I found to be piece that I found to be hidden most from existing developer experience ( telling Stripe how much to charge for tax ).
We’ve by now also covered how to get transaction data from Stripe to TaxJar. There’s one more vital piece needed when you integrate Stripe to TaxJar and that is this. Companies are only required to remit state sales taxes to states in which they have exceeded a certain sales volume. In TaxJar, these states are listed in your companies ‘Nexus’. Before you charge any customer a state sales tax, you probably want to check to see if you are required to do so. This means checking the nexus.
You can check the nexus using the TaxJar nexus endpoint, though for best performance of your app it is advised that you keep a list of nexus states locally ( ie in your apps database ) so you don’t need to make that api call so frequently. Then setup a scheduled job ( CRON or whatever is right for your platform ) to check the nexus on a regular basis ( we chose daily ) in order to keep your local nexus list up to date. Now whenever you’re about to create a transaction or subscription on Stripe, check your local list of states your company is required to remit state taxes for, and formulate transaction or subscription accordingly.
There’s may be other things to consider adding to your specific integration. Things like product tax code, freight, tax exemption status, tracking by customer withing TaxJar, using line items for granular accuracy, penny variance ( you’ll notice TaxJar provides a tax rate ( aka ‘combined_rate’ ) as a percent up to four decimals. This is help account for ‘penny variance’ and should not be disregarded especially on a payment system which might process hundreds of thousands of dollars worth of transactions.
If you would like help to integrate Stripe to TaxJare, please see our landing page for WPCashier and book a call to discuss. Note we primarily work with WordPress and Laravel, if you’re integrating Stripe and Taxjar on these platforms we’re more likely to be a good fit, but may be able to help with general consulting on any Stripe and TaxJar API integrations.
DISCLAIMER – I am a coder and am not a tax professional. This article is provided for information purposes only and is not intended to be legal or financial advice. I am not employed by nor affiliated with Stripe or TaxJar and therefore in no way speak for nor represent them.