Where the tax engine sits relative to the ERP and what each placement affects
The placement decision is the architectural question controllers and platform leads land on during an ERP cutover, a tax-provider switch, or a Black Friday post-mortem where the Shopify checkout total did not match the NetSuite invoice tax. Three placements exist, and each affects three downstream concerns differently: customer experience, audit defensibility, and reconciliation complexity.
| Placement | Where calculation happens | What it affects at checkout | What it affects at audit | What it affects at close |
|---|---|---|---|---|
| Upstream of the ERP | Tax engine called from Shopify or BigCommerce checkout before order creation; ERP receives the calculated tax on the order or invoice | Customer sees an exact tax total at checkout | Calculation log persists at the order level; ERP invoice tax record only complete if write-back is wired | Reconciliation between upstream calculation log and ERP invoice tax record |
| Inside the ERP | Tax engine integrated with NetSuite SuiteTax, Acumatica tax categories, Business Central tax groups, or Sage Intacct Tax Solutions; calculation happens at invoice creation | Checkout display can diverge from invoice tax if the storefront shows an estimate | Invoice tax record is canonical; no separate calculation log | Reconciliation between checkout display total and posted invoice tax |
| Downstream of the ERP | Batch tax calculation runs after invoice posting, typically via SuiteScript scheduled script, Power Automate flow, or external job | Customer's checkout tax may differ from the post-order tax record | Batch-level log does not tie to specific order moments; audit-fragile when an auditor samples a transaction | Reconciliation between the order record and the batch-calculated tax record |
The three placements are not mutually exclusive. The most common $30M to $80M production pattern combines two of them. The rest of this guide works through each placement in turn, what breaks when a brand chooses only that placement, and why the dual-placement pattern has become the default for Shopify Plus brands running NetSuite, Acumatica, Business Central, or Sage Intacct as the ERP.
Upstream of the ERP: customer-facing tax at the Shopify or BigCommerce checkout
The upstream placement is the most common pattern for mid-market DTC brands. The tax engine receives the cart contents from the Shopify or BigCommerce checkout, calculates tax across the resolved jurisdiction stack, returns the result to the storefront, and the customer sees the exact tax total before clicking Pay. The ERP receives the order downstream with tax already determined.
Upstream is what customer experience and audit defense both want. The customer sees the actual amount they will pay. The calculation log persists at the order level, which is the record an auditor expects to sample from. The rate-table version, the jurisdiction stack resolved, and the calculation timestamp can all be attached to that order record for retrieval years later.
What upstream placement does not automatically address is ERP-side audit-trail completeness. The pattern that breaks first under audit is the brand running upstream-only with no write-back to the ERP. The auditor asks for the invoice tax record; the ERP shows zero or a generic placeholder because the field was never populated; the upstream calculation log sits in a separate system the brand has to retrieve under deadline. The brand that did not wire the write-back paid a multi-day audit-defense cost on a placement decision made years earlier, often before the current finance team joined.
The fix is structural: any upstream placement at scale must write the calculated tax back to the ERP's invoice tax field at order sync. The ERP then carries a copy of the upstream calculation, not as an independent calculation but as the record-of-truth at the invoice level. The auditor's invoice-level question is answered from the ERP; the calculation-method question is answered from the upstream log.
The ecommerce platforms that support upstream placement through native integration with a dedicated tax engine include Shopify, Shopify Plus, and BigCommerce. TaxCloud is built for the upstream slot through native Shopify, Shopify Plus, and BigCommerce integration, with a single-API calculation surface across 13,000+ jurisdictions that returns within the checkout latency budget. The same calculation log that powers the customer-facing total feeds the ERP write-back and the monthly reconciliation downstream.
Inside the ERP: invoice-time calculation in NetSuite, Acumatica, Business Central, or Sage Intacct
The inside-ERP placement calculates tax at invoice creation. NetSuite SuiteTax handles this through tax types and tax determination engine rules applied at invoice creation. Acumatica resolves tax through tax categories assigned to items, tax zones assigned to customers, and tax rate schedules looked up at invoice time. Business Central applies tax groups and posting groups configured for the country and state. Sage Intacct routes calculation through Tax Solutions and Tax Detail configurations at the transaction level.
Inside-ERP-only is the pattern brands often default to when the ERP implementation partner owns the tax setup and the ecommerce platform is treated as a sales channel rather than the system that has to display a tax total to a customer.
That default breaks at the moment the customer hits the Shopify checkout. The checkout has to show a tax total. If the ERP is the only system calculating tax, the storefront cannot answer that question. Brands either display an estimate based on a stale rate cache, display tax as "calculated at order processing," or build a parallel checkout-side calculation that immediately diverges from the ERP's invoice-time calculation. None of those produce a customer experience that holds at $30M of order volume.
The other failure mode is product-taxability drift between the ERP item master and the storefront's product feed. If the Shopify product catalog marks an item as taxable and the NetSuite item master maps it to a tax-exempt code, the checkout display will collect tax on a line the ERP will subsequently mark exempt. The customer paid tax at checkout and the invoice records no tax. The refund and reconciliation work that follows scales linearly with order volume.
Inside-ERP placement works cleanly when the customer-facing system is invoice-driven, not checkout-driven. B2B brands with a quote-to-cash workflow on NetSuite or Sage Intacct, where the customer never sees a real-time tax total and the invoice is the first time tax is presented, sit comfortably in inside-ERP-only. DTC brands selling through Shopify or BigCommerce do not.
Downstream of the ERP: batch recalculation after invoice posting
Downstream-only is the architecture brands typically inherit from a QuickBooks Online migration or from an early-stage tax setup that used a scheduled job to backfill tax onto invoices after posting. A SuiteScript scheduled script, a Power Automate flow, or an external batch job runs nightly or weekly, pulls the prior period's invoices from the ERP, calls the tax engine for each, and writes the calculated tax back to the invoice record or to a supplementary record.
The downstream pattern is operationally appealing during early growth. It decouples the checkout from any tax dependency, the ERP does not need a tax engine integration at posting, and the finance team can correct mistakes in a controlled batch window. Many brands run some version of this in the $5M to $15M range without it surfacing as a problem.
It breaks at the audit moment. When the auditor's sample lands on a transaction that was batch-calculated 24 hours after the order, the brand cannot produce a calculation log at the order-record level. The batch log shows the run executed on a date; it does not show that this specific order was calculated with this specific rate-table version at this specific timestamp tied to the order moment. The auditor's chain-of-custody question has a gap, and the gap appears across every transaction in the sampled period.
The customer-experience failure mode is also real, though less expensive. The checkout displays an estimate or no tax at all. The customer receives a separate invoice or order confirmation hours later showing a different tax total. Refund volume tracks the size of the discrepancy.
The brands that run downstream-only as a deliberate choice rather than an inheritance are typically wholesale-heavy operations where the order moment is asynchronous, the customer is invoiced on terms, and the checkout is not a tax-display surface. Outside that profile, downstream-only is the placement that triggers the conversation that produced this guide: the Shopify checkout was showing one total, the NetSuite invoice another, and the brand needed to decide which became the source of truth before the next month's close.
The dual-placement pattern (upstream-and-inside) and why it's the $30M to $80M default
At TaxCloud, we've watched a consistent pattern emerge across brands moving from $20M to $50M on a Shopify Plus plus NetSuite stack. They land on upstream-and-inside: the tax engine calculates at the Shopify checkout for display, the ERP records the invoice tax at posting through a write-back from the upstream calculation, and the two reconcile monthly. Brands that tried tax-inside-NetSuite-only discovered the Shopify checkout was showing wrong totals to customers, which created refund and trust issues before the architectural problem was identified. Brands that tried upstream-only without write-back discovered the gap at audit, often years after the placement decision was made.
The dual pattern works for three reasons. First, it gives the customer an exact tax total at checkout, which removes the most common source of post-purchase refund volume at this scale. Second, it gives the ERP an invoice-level tax record that ties to a calculation log retrievable years later, which is the chain of custody an auditor expects. Third, it gives the finance team one reconciliation surface to manage, the monthly tie-out between the upstream log and the inside-ERP record, rather than two separate gaps generated by parallel calculation engines.
The mechanics of the write-back differ by ERP. NetSuite-running brands typically use a SuiteApp tax engine connector, an iPaaS recipe in Celigo or Workato, or a custom SuiteScript-driven sync that listens for Shopify order events and posts the calculated tax to the NetSuite invoice at sync. Acumatica brands route through the Acumatica Marketplace tax module or through the platform's API-first commerce edition. Sage Intacct brands use the connector ecosystem or a Boomi-orchestrated flow. The placement is the same; the write-back plumbing depends on the stack.
Brands on Business Central or Acumatica with a custom checkout typically choose upstream-only because Business Central's native tax module was not designed for real-time multi-state retail. The trade-off is that Business Central's invoice tax field becomes a copy of the upstream engine's calculation rather than an independent record, which removes a layer of audit-trail redundancy. Those brands compensate by retaining the upstream calculation log at the order level for the state retention window, typically four to seven years depending on the state.
TaxCloud's calculation API supports both placements through one integration. The upstream call at the Shopify Plus or BigCommerce checkout returns the tax total for display, and the same calculation log feeds the write-back to the ERP's invoice tax record at order sync through the connector ecosystem. Brands working in the dual pattern get one calculation surface, one log, and one reconciliation point rather than two separately maintained tax engines on the same transaction.
Reconciliation and audit-trail design across placements
Once placement is settled, the work shifts to the reconciliation surface placement creates. Upstream-only with no write-back has no reconciliation surface and an incomplete audit trail. Inside-ERP-only has no upstream-to-invoice reconciliation but generates a checkout-versus-invoice discrepancy that surfaces as refund volume. Downstream-only has no order-moment audit trail. Only the upstream-and-inside dual placement has both a complete audit trail and a defined reconciliation surface.
That surface most commonly breaks at the refund-and-credit-memo boundary. Shopify's refund flow generates a tax adjustment at refund time based on the original order's tax calculation. NetSuite's credit-memo flow generates a separate tax adjustment based on the inside-ERP tax record on the credit memo. When the two records were calculated by different engines, or by the same engine at different rate-table versions, the two adjustments do not tie out without explicit reconciliation logic that links the credit memo back to the original order and reconciles the tax delta. Most brands at this scale catch this in the monthly close on the third or fourth pass, after the first two passes surface unmatched credits in the reconciliation queue.
The other recurring failure mode is the marketplace facilitator offset on multi-channel brands. Amazon orders fulfilled through Shopify hit the brand's Shopify order ledger; Amazon collected and remitted the tax; the brand's NetSuite invoice should not carry the marketplace-collected portion as its own tax liability. Upstream-and-inside placement makes the offset visible in both layers and reconcilable monthly. Downstream-only typically misses the offset entirely on the first run.
The audit-trail design that holds across placements requires the same three fields on every persisted tax record, regardless of where the calculation happened: the rate-table version active at calculation, the jurisdiction stack resolved, and the calculation timestamp tied to the order moment. The brand that persists those fields at the upstream log and writes the calculated tax back to the ERP's invoice record has the trail an auditor expects. The brand that persists them in one layer and not the other has a placement decision to revisit before the next state inquiry lands.
At a 30-state, $50M steady state, placement is settled. The question is what the operating model looks like at a 30-state, $50M steady state with monthly close on business day three or four. TaxCloud is built for that: a single-API calculation surface usable upstream at the Shopify Plus or BigCommerce checkout and writable back to the ERP's invoice tax record at order sync, consolidated SST filing across the 24 participating states (23 full members and Tennessee as an associate member) drawing from the same calculation log, and the audit documentation trail at the order-record level the dual placement is designed to produce.