SAP S/4HANA and Avalara integration
SAP S/4HANA runs finance and procurement. Avalara AvaTax determines sales and use tax across jurisdictions. Connecting the two moves tax calculation out of manually maintained SAP tax tables and into a live tax engine. ml-connector reads invoices from SAP, sends them to Avalara for calculation, records the committed transaction in Avalara for return filing, and writes the resulting tax amount back onto the SAP document. The two systems speak very different APIs, and ml-connector handles both on a cadence you control.
What moves between them
The main flow runs from SAP S/4HANA into Avalara. When a sales invoice or supplier invoice is posted in SAP, ml-connector reads it through the OData service and creates the matching Avalara transaction, a SalesInvoice for customer billing or a PurchaseInvoice for self-assessed use tax, with the SAP company code mapped to the Avalara companyCode and ship-from and ship-to addresses on each line. Avalara returns the calculated tax synchronously, and ml-connector writes that tax amount back onto the SAP document. Tax codes and exemption certificates are read from Avalara so SAP line items reference valid taxability classifications. Avalara is treated as the system of record for tax, so SAP never overwrites committed Avalara transactions.
How ml-connector handles it
ml-connector stores both credential sets encrypted and presents them on the right side: an OAuth2 Bearer token for SAP, refreshed before its roughly twelve-hour expiry, and HTTP Basic auth built from the Avalara account ID and license key. Because SAP requires an X-CSRF-Token on every write, ml-connector fetches the token with a GET, replays the session cookies, and re-fetches and retries if SAP returns 403. SAP invoice numbers become the Avalara document code, so a retried post updates the uncommitted transaction in place rather than recording it twice, and createOrAdjust is used where fully idempotent behavior is needed. Since neither system pushes webhooks, invoices are read from SAP on a schedule using $filter on LastChangeDateTime, and reconciliation polls ListTransactionsByCompany. Both sides throttle with HTTP 429, so ml-connector backs off with jitter, honoring SAP's Retry-After header, and addresses are pre-validated through Avalara address resolve to avoid calculation failures. Every record carries an audit trail and can be replayed if a call fails.
A real-world example
A mid-sized industrial distributor runs SAP S/4HANA Cloud for order-to-cash and procurement and sells into dozens of US states. Before the integration, the tax team kept SAP tax codes and jurisdiction rates current by hand, and as nexus footprints grew the rates fell behind, producing under- and over-charged invoices that surfaced during audits. With SAP S/4HANA and Avalara connected, every posted invoice is priced for tax by Avalara in real time against current jurisdiction rules, the committed transaction sits in Avalara ready for return filing, and the calculated tax is written straight back onto the SAP document. The manual rate maintenance is gone and the filing data reconciles to what was billed.
What you can do
- Calculate sales and use tax in real time on SAP S/4HANA sales and supplier invoices through Avalara AvaTax.
- Record each invoice as a committed Avalara transaction for downstream return filing.
- Write the Avalara-calculated tax amount back onto the matching SAP S/4HANA document.
- Use the SAP invoice number as Avalara's document code so retries update in place instead of double-recording.
- Bridge SAP OAuth2 with the X-CSRF-Token write step and Avalara HTTP Basic auth, with retries and an audit trail on every record.
Questions
- Which direction does data move between SAP S/4HANA and Avalara?
- The main flow is SAP into Avalara. Invoices are read from SAP and posted to Avalara as SalesInvoice or PurchaseInvoice transactions for tax calculation and recording. The calculated tax is then written back onto the SAP document, while tax codes and exemption certificates are read from Avalara so SAP lines reference valid taxability classifications.
- How does the integration avoid recording the same invoice twice in Avalara?
- AvaTax uses the document code field as its idempotency key, and ml-connector sets that code to the SAP invoice number. Re-posting an uncommitted transaction updates it in place, and ml-connector uses createOrAdjust where fully idempotent behavior is needed. Once a transaction is committed its code is reserved, so the integration never silently duplicates a recorded sale.
- Do SAP webhooks or CSRF tokens need special handling?
- SAP Cloud Public Edition has no native outbound webhooks, so ml-connector reads invoices by polling on a schedule using $filter on LastChangeDateTime rather than waiting for a push. SAP also requires an X-CSRF-Token on every write, so when writing tax back ml-connector fetches the token, replays the session cookies, and re-fetches and retries if SAP returns a 403.
Related integrations
More SAP S/4HANA integrations
Other systems that connect to Avalara
Connect SAP S/4HANA and Avalara
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started