ml-connector
Sage 100TaxJar

Sage 100 and TaxJar integration

Sage 100 runs your on-premises financial operations, while TaxJar calculates and tracks sales tax compliance across the states where you have nexus. Connecting them keeps your tax obligations accurate and posted to your general ledger without manual review. Every sales order from Sage 100 flows into TaxJar for real-time tax calculation, and the resulting tax liability returns to Sage 100's GL so your financial statements reflect the true tax owed. ml-connector handles the polling cadence and the authentication bridge between your on-premises system and the cloud tax engine.

How Sage 100 works

Sage 100 exposes customers, sales orders, sales order lines, AR invoices, AP vendors, AP invoices, purchase orders, GL accounts, and journal entries through SOAP Web Services at a customer-hosted IIS endpoint, or through a local Windows agent wrapping the Sage 100 BOI (Business Object Interface) COM layer. SOAP access covers sales orders and customers; full AR, AP, GL, and purchasing access requires the BOI agent running on the customer server. Authentication uses username and password per call with no tokens or OAuth. Sage 100 has no webhooks or event stream, so all syncs are pull-based and must use DateLastUpdated or DateCreated fields to detect changes. Company code (a 3-character identifier) is required on every call, and users must be individually enabled for Web Services in Sage 100 administration.

How TaxJar works

TaxJar is a cloud REST API accessed at https://api.taxjar.com/v2/ (or https://api.sandbox.taxjar.com/v2/ for testing) with JSON requests and responses. It authenticates with an API token passed in the Authorization header as a Bearer token, and merchants generate tokens from the Account menu in the TaxJar web app. The API is versioned via an x-api-version header sent with each request. TaxJar calculates sales tax rates, stores and reports completed transactions, tracks nexus regions per state, and manages customer-level tax exemptions. TaxJar has no webhooks or push events; all integrations are poll-based or merchant-initiated with POST and PUT calls. Sandbox tokens are available on Professional plans and above, and sandbox data is stateless - it validates format only and does not persist.

What moves between them

Sales orders and completed invoices from Sage 100 flow into TaxJar for real-time tax calculation. For each sales order line, ml-connector sends the ship-to address, items, and total to TaxJar's tax endpoint, which returns the applicable state and local tax rates. The calculated tax obligation is posted back to Sage 100's general ledger as a tax payable journal entry, allocated to GL accounts configured per state. Refunds and credit memos in Sage 100 trigger corresponding refund reports to TaxJar so nexus and filing accuracy are maintained. The sync runs on a schedule aligned to your invoice cycle (typically daily or every few hours) and requires no real-time push from Sage 100.

How ml-connector handles it

ml-connector polls Sage 100 for new and updated sales orders and invoices using the DateLastUpdated field, filtering by company code to respect multi-company setups. For each order, it extracts the ship-to address and line items, then posts them to TaxJar's /v2/taxes endpoint with the customer account if exemption status is tracked. TaxJar returns the calculated tax by jurisdiction; ml-connector matches those jurisdictions to GL accounts configured in Sage 100 (mapping state codes to account segments per your chart of accounts) and posts a journal entry to GL with the tax liability. Sage 100's BOI layer enforces record-locking on concurrent writes, so ml-connector retries failed creates with exponential backoff when a lock is detected. TaxJar rate limits are returned as HTTP 429; ml-connector backs off and retries those calls as well. Every transaction record carries an audit trail linking the Sage 100 order, the TaxJar calculation, and the resulting GL posting so discrepancies can be traced.

A real-world example

A regional online retailer operates Sage 100 on-premises for AR, AP, and GL, and sells across twelve states plus local jurisdictions. Before the integration, the accounting team reviewed completed sales orders at month-end, looked up the applicable tax rates in TaxJar for each jurisdiction, and manually journalized the state and local tax liabilities into Sage 100's GL by hand. This process took two days and often had transposition errors. With Sage 100 and TaxJar connected, every order is calculated the moment it ships, the tax GL postings are automated and error-free, and the finance team starts month-end close knowing the tax liabilities are already correct and reconcilable by jurisdiction.

What you can do

  • Calculate real-time sales tax on every Sage 100 sales order using TaxJar's multi-state rate engine and post the obligation to GL.
  • Track Sage 100 sales orders through completion in Sage 100 and report completed transactions to TaxJar for accurate state filing.
  • Map Sage 100 GL account segments to TaxJar jurisdictions so tax payable entries land on the correct accounts per state.
  • Bridge SOAP polling and authentication between Sage 100's on-premises server and TaxJar's cloud API with automatic retries on locks and rate limits.
  • Manage Sage 100 customer exemption status and sync it to TaxJar so tax-exempt customers are correctly handled in calculations.

Questions

How does ml-connector poll Sage 100 if it is on-premises with no cloud API?
ml-connector connects directly to the customer-hosted SOAP endpoint at the Sage 100 instance URL, or to a local Windows agent wrapping the BOI COM layer if SOAP is not available. Both require customer-side setup (enabling Web Services users in Sage 100 admin or deploying the agent), and both are polled on a schedule aligned to the sales order cycle. The customer provides the endpoint URL and credentials to ml-connector, which stores them encrypted.
What happens if a Sage 100 sales order contains items without taxable status?
ml-connector filters line items by taxability flag before sending them to TaxJar. Non-taxable items are excluded from the tax calculation, so only the taxable amount is sent to TaxJar. The tax obligation posted back to Sage 100 reflects only the taxable lines, and a full audit trail records which items were excluded.
Can the integration handle Sage 100 multi-company setups?
Yes. Sage 100 sales orders and GL accounts are scoped by company code (a 3-character ID required in every SOAP call). ml-connector accepts the company code per customer or cell, polls only that company's data, and posts tax GL entries back to that company's ledger. If a customer operates multiple companies in Sage 100, each requires its own cell configuration and polling schedule.

Related integrations

Connect Sage 100 and TaxJar

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started