This reference explains how Kintsugi calculates sales tax on your Stripe invoices, writes it back to Stripe, and records the transaction for filing. It covers the conditions that have to be true before tax is applied, the Stripe webhook events involved, how Kintsugi picks the address it taxes against, and what to check when tax does not appear.
Use this guide if you are setting up or troubleshooting the Stripe Tax Engine Integration, or if you are building a subscription billing flow on top of Stripe and need to know exactly when Kintsugi can and cannot act on an invoice.
Looking for setup steps instead? Start with the Stripe Tax Engine Integration Guide.
Confirm these four items. Each one is a hard requirement, and any one of them being incomplete is a common reason tax shows as zero on a Stripe invoice.
You are using Stripe Invoicing. Kintsugi calculates tax on Stripe Invoicing transactions, not Stripe Payments. See Stripe Invoicing vs. Stripe Payments for why.
Stripe Tax is turned off. When Kintsugi is your tax engine, Kintsugi owns tax calculation on your Stripe invoices. Leaving Stripe Tax on at the same time can produce conflicting amounts. In Stripe, go to Settings > Product Settings > Tax > Integrations and confirm that Use automatic tax is disabled.
Your products are categorized and approved in Kintsugi. Tax only calculates on line items whose products have an approved tax category. See Updating Product Category and Subcategory, or set a default so new synced products are classified automatically with How to Set a Default Product Classification.
Customer addresses are complete in Stripe. Kintsugi taxes against the address on the Stripe record. If addresses are missing or invalid, see How to Update Invalid Addresses in the Kintsugi App and How to Update Blank Addresses in the Kintsugi App. Address fixes made in Kintsugi do not sync back to Stripe, so correct them in Stripe as well.
Kintsugi writes tax to your Stripe invoices only when both of these are true for your connection:
Your organization is ready to calculate tax. Your initial data import and organization setup are complete, and you have at least one active tax registration.
Tax calculation is enabled on your Stripe connection. See Enable Tax Collection on a Tax-Engine Integration for the enablement checklist.
If either is missing, your Stripe connection still runs as a read-only sync. Kintsugi keeps importing your invoices and transactions and keeps monitoring your exposure, but it does not write tax amounts back to Stripe. For what a read-only connection covers, see the Stripe Read-Only Integration Guide.
Even with tax calculation enabled, Kintsugi applies tax to an individual invoice only when all of the following are also true:
The customer address resolves to a country Kintsugi supports for tax calculation.
Your organization has an active registration for that jurisdiction.
The invoice line items reference products that are classified and approved.
The invoice is still in draft status when Kintsugi receives the event. See Timing: Why the First Subscription Invoice Needs Extra Setup article section below, which is the most common blocker.
The end to end flow for a single invoice:
Stripe creates or updates a draft invoice, usually from a subscription renewal or another billing event.
Stripe sends a webhook event to Kintsugi.
Kintsugi reads the invoice, resolves the customer address, and calculates tax.
Kintsugi writes the tax amounts onto the invoice line items in Stripe.
Kintsugi records the transaction internally for compliance and reporting.
When the invoice is paid, Kintsugi marks the transaction as committed.
Kintsugi uses its own tax engine, not Stripe Automatic Tax. When Kintsugi applies tax to an invoice, it also turns off Stripe Automatic Tax on that invoice so the two engines cannot both calculate. This is a safeguard, not a substitute for turning Stripe Tax off at the account level, which is still a prerequisite.
Kintsugi receives events through the Stripe Connect webhook on OAuth connections. These are the events that drive tax calculation:
Stripe event | What Kintsugi does |
|---|---|
| The main tax path. Calculates tax, writes it to the draft invoice, and creates the internal transaction. |
| Recalculates tax when a new line item is added to a draft invoice. |
| Syncs invoice changes and recalculates tax when quantities or discounts change. |
| Validates that the applied tax matches what Kintsugi calculated. It does not modify the invoice, because finalized invoices are locked. |
| Marks the transaction as committed in Kintsugi. |
| Archives the corresponding transaction in Kintsugi. |
Events with no direct tax action: invoice.voided and invoiceitem.deleted are handled indirectly through invoice.updated. Events such as invoice.upcoming are not used for tax calculation.
Kintsugi can only write tax to an invoice while it is still in draft status. Once Stripe finalizes an invoice, it is immutable and no tax engine, including Kintsugi, can change it.
Stripe normally gives you that draft window automatically through the invoice finalization grace period, which is one hour by default. During the grace period the invoice sits in draft, Kintsugi calculates and writes back the tax, and Stripe then finalizes the invoice with the correct amount already applied. Kintsugi typically writes tax back well within the default hour.
The grace period applies to every invoice on a subscription, including renewals, upgrades, and proration invoices, with a single exception:
The very first invoice of a subscription created with automatic charging skips the grace period entirely. When you create a subscription with the payment method set to Automatically charge a payment method on file (collection_method = charge_automatically in the API), Stripe creates and finalizes that first invoice at the same moment. The created timestamp and the finalized timestamp are identical. There is no draft window, so Kintsugi has no opportunity to write tax back, and the first invoice finalizes showing zero tax.
This is standard Stripe subscription billing behavior, not a Kintsugi setting, and it affects any tax engine connected to Stripe.
There is a straightforward fix, and it is a one time setup change on your side rather than a support request. Choose whichever fits your billing flow:
Use a subscription schedule (recommended). One configuration covers the whole subscription lifecycle, and it still works with automatic charging.
Email the first invoice, then switch to automatic collection. Send the first invoice for manual payment so it gets a draft window, then change the collection method afterward.
Create it through the API in draft. Set collection_method = send_invoice and auto_advance = false, let Kintsugi update the tax on invoice.created, then finalize.
Full step by step instructions for all three approaches, plus the approaches that do not work and why, are in Ensuring Accurate Sales Tax for Initial Subscriptions in Stripe. If you create subscriptions with automatic charging, set this up once before you go live and every invoice after that handles itself.
You can lengthen the draft window if your billing process needs more buffer. In Stripe, go to Settings, search for Billing, open Invoices, and set Invoice finalization grace period. Keep in mind that this setting does not change the exception above, so a longer grace period on its own will not protect the first invoice of a charge automatically subscription.
When an invoice finalizes before Kintsugi can apply tax, Kintsugi logs a discrepancy alert so the gap is visible rather than silent. Stripe will not let that specific invoice be edited, so it needs to be settled in Stripe, usually with a credit note and a corrected invoice, or by collecting the difference separately. Apply one of the setups above so it does not repeat, and reach out through the chat bubble if you would like help deciding how to handle the affected invoices.
Kintsugi does not attach pre-built tax rates from your Stripe Tax Rates catalog. It sets tax directly on each invoice line using the calculated amounts and rates.
On a draft invoice you will see:
Per line tax amounts on the invoice line items.
An invoice total tax that reflects Kintsugi's calculation.
Tax rate labels based on jurisdiction, such as "CA Sales Tax" or "US Sales Tax".
In the Stripe Dashboard you may also see new Tax Rate objects under Product catalog > Tax rates. Stripe creates these automatically when Kintsugi writes tax to an invoice. They are not selected from your catalog.
Seeing a long list of tax rate objects in Stripe, many of them archived, is expected behavior and not an error. Here is what produces them:
Each time Kintsugi applies tax, Stripe creates a new tax rate object from the calculated rate and amount.
When the invoice is updated, for example a discount is applied, a quantity changes, or a line item is added, Kintsugi clears the previous tax and applies fresh amounts.
Tax rate objects from the earlier calculation are no longer linked to any invoice, so Stripe marks them as archived or inactive.
Archived tax rates have no effect on current invoices. The tax on an invoice always reflects the most recent Kintsugi calculation. A large archived list is normal for subscription businesses with frequent renewals and invoice edits.
Stripe stores address data in several places. Kintsugi collects every available address from the invoice and the customer, then selects one bill-to and one ship-to address using fixed priority rules. The first match wins.
Priority | Source in Stripe |
|---|---|
1 | Customer billing address ( |
2 | Invoice customer address ( |
3 | Charge billing address, if a charge exists on the invoice |
4 | Payment source owner address, for legacy payment methods |
5 | If none of the above are usable, a blank bill-to address is used |
Priority | Source in Stripe |
|---|---|
1 | Customer shipping address ( |
2 | Invoice shipping details ( |
3 | Invoice customer shipping ( |
4 | Default payment method billing address on the customer |
If no ship-to address is found, tax estimation uses the bill-to address only.
Priority 4 applies only when the first three sources are all empty. If your Stripe customer has no shipping address on the customer record and none on the invoice, Kintsugi falls back to the billing address stored on the customer's default payment method and treats that as the ship-to address.
This matters because Kintsugi taxes against the ship-to address whenever one is present. A ship-to address sourced from the payment method therefore takes precedence over the bill-to address, even when the two point to different states.
Payment method billing addresses are often only a postal code and a country, which is common when your customer pays with a card on file or through an accounts payable intermediary. Kintsugi fills in the city and county that the postal code maps to, so the transaction can show a location your customer never entered. Addresses built this way appear with a warning icon in Kintsugi rather than a validated one, which is a useful signal when you are reviewing a transaction.
Set a complete shipping address on the Stripe Customer record (customer.shipping) or on the invoice. Either one takes priority over the payment method, so it is the reliable way to control the state Kintsugi taxes against. If your customers have no shipping address in Stripe, check whether the billing address on their default payment method sits in a different state than their billing address, because that state becomes the tax destination.
United States: a postal code is required. If the country field is missing but the postal code is a five digit US ZIP, Kintsugi treats the address as a US address.
Outside the United States: a country is required. A postal code on its own is not enough to place the address.
Postal code only addresses: Kintsugi fills in the city and county that the postal code maps to, then treats the result as usable for tax. A postal code that came from an unrelated source, such as a card on file, can therefore place the transaction in that jurisdiction.
Recommendation for subscription platforms: set the subscriber's tax relevant address on the Stripe Customer object, preferably customer.shipping for physical goods or customer.address for digital goods and services. The earlier that address exists before the invoice is created, the more reliable the tax calculation.
Two quick checks in Stripe tell you whether the integration is working as expected:
Check the tax calculation source. Open the invoice in Stripe and look at the tax line. When Kintsugi has calculated the tax, Stripe shows the tax calculation as Manual. That is expected and means the amount came from Kintsugi rather than from Stripe Tax.
Compare the timestamps. Look at the invoice's created and finalized times. A healthy setup shows a gap between them, which is the draft window Kintsugi used to write the tax back. Identical timestamps mean the invoice was finalized instantly, which points to the first invoice behavior described under the article section Timing: Why the First Subscription Invoice Needs Extra Setup.
It is also worth checking the destination. Open the transaction in Kintsugi and compare its Ship To address against the address you expect to tax. If the Ship To shows a city and county you did not enter, see When the payment method address is used as ship-to above.
Work through these in order. Most zero tax invoices come from the first two rows.
What you are seeing | Likely cause | What to do |
|---|---|---|
Zero tax on the first invoice of a new subscription, and the created and finalized timestamps match | The subscription was created with automatic charging, so the first invoice skipped the grace period. | Set up a subscription schedule or one of the other approaches in Ensuring Accurate Sales Tax for Initial Subscriptions in Stripe. |
Zero tax on some line items but not others | Those products are not classified and approved in Kintsugi. | Approve the product categories in Updating Product Category and Subcategory. |
Zero tax across all invoices for a customer | The address does not resolve, or you have no active registration in that jurisdiction. | Check the customer's address in Stripe against the priority rules above, and confirm your registration is active in Kintsugi. |
Tax calculated for a state that is not your customer's billing state, and the transaction shows a Ship To city you never entered | The customer has no shipping address in Stripe, so the billing address on their default payment method was used as the ship-to address. A postal code only address is then filled out to the matching city and county. | Open the transaction in Kintsugi and check the Ship To address. Set a complete shipping address on the Stripe Customer record so it takes priority on future invoices, then reach out through the chat bubble so we can review the transactions already recorded. |
Zero tax across every invoice on the connection | Tax calculation is not enabled, so the connection is running read-only. | Complete the checklist in Enable Tax Collection on a Tax-Engine Integration. |
Tax amounts look doubled or conflicting | Stripe Tax is still switched on at the account level. | Disable Use automatic tax under Stripe Settings > Product Settings > Tax > Integrations. |
Tax is correct but tax rate objects keep piling up in Stripe | Expected behavior after invoice edits. | No action needed. See Why tax rates are created and then archived article section above. |
Before you go live with the Stripe Tax Engine Integration, confirm that:
Subscriber addresses are written to Stripe Customer records before invoices are created.
If you want a specific address taxed, it is set as a shipping address on the Stripe Customer record or the invoice. Otherwise the billing address on the default payment method becomes the ship-to address and sets the destination state.
Stripe Tax is disabled at the account level.
Products on your invoice line items are synced, classified, and approved in Kintsugi.
You have an active registration for every jurisdiction where you expect tax to calculate.
Subscriptions created with automatic charging use a schedule or another draft window approach, so the first invoice is not finalized instantly.
You understand that archived tax rate objects in the Stripe Dashboard are expected.
Most tax calculation questions are answered by the troubleshooting table above, so it is worth a pass before reaching out. If you still need a hand with a specific invoice, send us these two details and we can trace the webhook flow, confirm which address was used, and check whether tax was applied before finalization:
The Stripe invoice ID (it starts with in_).
Where the subscriber address is set in your integration: customer shipping, customer billing, or an invoice level field.
You can reach us anytime using the chat bubble in the bottom right corner of your screen.