The Problem with Tax on Complex Equipment Quotes
The client manufactures and sells CNC bridge saws, waterjet systems, polishers, and stone fabrication parts to shops across the United States. A single deal often includes the machine, installation, training, and service components as separate line items in HubSpot, each with its own SKU and price. When a sales rep assembled one of these packages, the quote needed accurate regional sales tax before it went to the customer. Getting that number right before the quote leaves matters.
HubSpot’s tax calculation feature was in beta at the time and wasn’t functioning correctly for this client’s setup. The company’s CFO was an active stakeholder in the engagement, which reflects how the accuracy question was being treated internally. A manual state tax lookup had been filling the gap, but it added friction between sales and finance every time a quote was ready. The goal was straightforward: when a rep marks a deal as finalized, the estimated tax should appear on the record automatically, without anyone having to calculate it separately.
Why This Needed a Custom Build
The native HubSpot–QuickBooks Online connector handles contact and deal synchronization between the two platforms, but tax estimation isn’t part of what it does. QuickBooks Online (QBO) has an Estimates API that calculates regional tax accurately. Getting to it in a production environment requires building a full OAuth authentication layer from scratch.
The engagement covered two distinct deliverables: an OAuth server and token manager to establish and maintain authenticated access to the QBO API, and the tax estimation integration itself. If you’re working through the same question—native connector vs. custom build—this breakdown of when to go custom covers the decision criteria in detail.
Building the OAuth Server and Token Manager
Setting Up the OAuth Server
Getting authenticated against QBO’s API in production involves a circular dependency that doesn’t appear in the sandbox environment. Intuit requires a live HTTPS endpoint for the OAuth redirect before they’ll issue production credentials. Getting those credentials requires completing their production questionnaire, which asks for that endpoint URL. You need a functioning server to get the credentials, and you need the credentials to make the server fully functional.
The path through it: deploy a near-complete server to AWS first, capture the HTTPS URL from API Gateway, complete the questionnaire with that URL, then update the app’s client ID and secret once Intuit issued them. It adds a step, but there’s no shortcut through the dependency. Teams doing production QBO OAuth work for the first time tend to hit this and lose time on it.
The server runs on AWS Lambda with API Gateway providing the HTTPS endpoint. When a user navigates to the /oauth route, the app uses the intuit-oauth Node.js SDK to calculate the correct QBO authorization URL and redirects them to it. The user signs in with a QuickBooks account that has admin privileges—QBO requires a human sign-in at this step, and it can’t be automated. QBO then redirects back to the app’s /oauth/redirect route with an authorization code, which the app immediately exchanges for an access token and refresh token. Those initial tokens are manually copied from the OAuth server logs into AWS Parameter Store to start the token lifecycle.
Managing Token Expiry: The Token Manager
QBO access tokens expire in approximately one hour. If a Lambda function tries to call the QBO API with an expired token, the request fails. The Token Manager addresses this by running a refresh cycle every 45 minutes, well inside the expiry window. It uses the stored refresh token to retrieve a fresh access token and refresh token pair, then updates both values in Parameter Store. Every Lambda function that needs to call the QBO API fetches a current credential from the store rather than depending on one that may have aged out.
Once the initial OAuth handshake is complete and the first tokens are seeded manually, the cycle runs without intervention. Developers can invoke Lambda functions against the QBO API without managing token state themselves. For a broader look at how HubSpot’s API handles OAuth and webhook authentication, this post on HubSpot API endpoints covers the underlying mechanics.
How the Tax Estimation Integration Works
The trigger is a custom checkbox property on the HubSpot deal record called “Bundle Now.” When a sales rep checks it—signaling that a package is assembled and ready for quoting—a HubSpot workflow fires and sends a webhook to AWS API Gateway, which routes the request to the tax estimation Lambda function.
The Lambda retrieves two things from HubSpot: the complete list of line items on the deal, and the address of the associated company record. Line items arrive as HubSpot SKU IDs, which don’t correspond directly to QuickBooks Online product IDs. The integration maintains a translation map pairing each HubSpot SKU with its QBO equivalent, so the Lambda can translate each SKU to its QBO product ID, carry the associated quantity into the request, and build a valid Estimates call from data that lives entirely in HubSpot’s format.
To call the QBO Estimates endpoint, the Lambda uses a dummy customer record in QuickBooks named “Tax Calculation,” created specifically for this purpose. Before each estimate, the Lambda updates that dummy customer’s address to match the company’s address from HubSpot. QBO uses the customer address to determine the applicable state tax rate, so the record needs the correct location for each request rather than a fixed placeholder. The Estimates endpoint returns the full tax calculation, which the Lambda parses from the response.
Getting the result back into HubSpot is a single step. The Lambda creates a new line item on the deal with a unit price of $0 and a name in the format “Estimated Tax: $1,235.00.” The $0 price keeps the line item from affecting the deal total or the quote value. The tax figure appears as a labeled line on the customer-facing quote without changing the commercial terms of the deal.
A Note on Product Bundles in QBO
One detail worth flagging for anyone building something similar: QuickBooks Online product bundles aren’t standalone products in the Estimates API. A bundle is a container for its child products, not a billable line item itself. Any HubSpot line item referencing a bundle SKU carries a $0 value, and when constructing the Estimate, only the nested child products go into the API call. The translation map accounts for this distinction, but it’s a QBO data model behavior that only surfaces when you’re working directly with the endpoint. For more on how HubSpot workflow actions can be extended with custom code to support integrations like this, this post on custom-coded workflow actions is worth a read.
What the Integration Delivers
From the sales rep’s side, the workflow is: assemble the deal, check “Bundle Now,” and the estimated tax appears on the record. No separate lookup, no spreadsheet routed to finance, no delay before the quote goes out. For a small team quoting multi-SKU equipment packages to buyers across multiple states, removing that step from the process has a measurable effect on how quickly deals get finalized.
The OAuth server and Token Manager also establish infrastructure that extends to other QBO API use cases. The authentication layer is in place; connecting additional Lambda functions to QBO from here is a smaller project than the initial build. For a similar engagement—connecting a manufacturing client’s legacy ERP to HubSpot via custom API—see how we approached the Global Shop integration.
Connect Multiple Platforms Seamlessly
Is a HubSpot Integration Right for Your Business?
Explore Custom Integration Solutions arrow_forwardWork With Us
If your HubSpot quoting workflow depends on financial data the platform can’t calculate natively—tax, pricing logic, or connections to external financial systems—a custom integration is often more achievable than it looks once the authentication layer is handled correctly.
We’ve built production-grade connections between HubSpot and QuickBooks Online, and we can scope what that looks like for your setup. Get in touch with our integrations team.
