DATEV and ShipStation integration
DATEV is the German accounting and tax backend, with an on-premise Rechnungswesen ledger and a Unternehmen Online cloud layer. ShipStation is a shipping and order management platform that pulls e-commerce orders from many sales channels, prints labels, and tracks shipments, but it is not an accounting system. Connecting the two means the sales orders and shipment costs ShipStation holds flow into DATEV as bookings, so revenue and carrier charges land in the German books without anyone re-keying them. ShipStation has no GL accounts, journal entries, or vendor invoices, so the integration shapes its order and shipment data into DATEV postings rather than pulling accounting records it does not hold. Because DATEV cannot read its own chart of accounts or posted journals back out, this is a one-way write into accounting.
What moves between them
The flow runs one way, from ShipStation into DATEV. ml-connector reads ShipStation sales orders, with their line items, order totals, and tax, plus the matching shipment and freight detail, and submits the resulting revenue and carrier-cost booking lines to DATEV as EXTF CSV files against the correct sales, freight, and tax accounts. New orders and shipments arrive through ORDER_NOTIFY and SHIP_NOTIFY webhooks, each of which is only a resource_url pointer that ml-connector follows with an authenticated GET to fetch the actual record, and a scheduled poll on modifyDate backfills order edits, which ShipStation never sends a webhook for. Nothing flows back from DATEV: it cannot return its chart of accounts or posted journals, so DATEV is treated as a write-only accounting destination and ShipStation is never written to.
How ml-connector handles it
ml-connector stores both credential sets encrypted. On the ShipStation side it sends the Base64 Basic auth header on V1 order and shipment calls and the API-Key header on V2 label calls, and it converts every V1 timestamp from PST or PDT before the date reaches a DATEV booking. On the DATEV side it runs the Authorization Code flow with PKCE, where the code challenge must use S256 and the state value is at least 20 characters, then holds the access token, which expires in 900 seconds, and refreshes it by sending only the client_id. Each ShipStation order is turned into EXTF CSV rows with Konto, Gegenkonto, Belegfeld 1 set to the order number, Buchungstext, and a tax code, written in UTF-8 with precomposed characters because non-normalized text is silently rejected, and filenames are kept deterministic so DATEV's filename-and-document-type duplicate check, which returns error DCO01253, makes a retry safe. The big gotcha is account mapping: DATEV will not hand over its chart of accounts, so ShipStation sales channels, product categories, and freight charges are mapped to known DATEV SKR accounts and Kostenstelle numbers in advance. New orders and shipments are caught by the ORDER_NOTIFY and SHIP_NOTIFY webhooks, each of which delivers only a resource_url that ml-connector follows with an authenticated GET, while a scheduled poll on modifyDate catches the order edits ShipStation has no event for, and the orderKey is used as the stable external reference so the same order is never booked twice. ShipStation V1 returns HTTP 429 at roughly 40 requests per minute, so ml-connector backs off with jitter, and because DATEV processes asynchronously and sends no webhook, each EXTF job is polled with exponential backoff and jitter until it reports complete or failed, with every job replayable if a submission fails.
A real-world example
A mid-sized German e-commerce retailer with around 120 staff sells across several online channels, runs ShipStation to consolidate those orders and print labels, and keeps its statutory books in DATEV through its Steuerberater. Before the integration, an accounting clerk exported order and shipment reports from ShipStation each week, sorted revenue and freight by channel in a spreadsheet, and typed the booking lines into DATEV by hand, which left the sales accounts behind and produced posting and tax-code mistakes the tax advisor corrected at month-end. With DATEV and ShipStation connected, each new order and shipment is fetched the moment its webhook fires, coded to the right SKR sales or freight account and cost center, and submitted to DATEV as an EXTF booking, while a modifyDate poll catches later edits. The manual re-keying is gone and the tax advisor receives clean, complete order and freight bookings.
What you can do
- Post ShipStation sales orders into DATEV as EXTF CSV bookings against the correct sales and tax accounts.
- Book ShipStation shipment and freight charges into DATEV, coded to the right freight account and cost center.
- Map ShipStation sales channels and product categories to known DATEV SKR accounts and Kostenstelle numbers in advance.
- Bridge ShipStation V1 Basic auth and V2 API-Key to DATEV Authorization Code login with PKCE and automatic token refresh.
- Catch orders and shipments by ORDER_NOTIFY and SHIP_NOTIFY webhooks plus a modifyDate poll, with retries and a full audit trail.
Questions
- Which direction does data move between DATEV and ShipStation?
- The flow is one way, from ShipStation into DATEV. Sales orders, shipment detail, and freight charges move from ShipStation into DATEV as EXTF bookings, coded to the matching sales, freight, and tax accounts. DATEV cannot return its chart of accounts or posted journals through the API, so it is treated as a write-only accounting destination, and ml-connector never writes back into ShipStation.
- ShipStation has no GL accounts or invoices, so what actually posts into DATEV?
- ShipStation is a shipping platform with no GL accounts, journal entries, or vendor invoices. What it does expose is sales orders with line items, totals, and tax, along with customers, products, and shipment and freight detail. ml-connector reads those orders and shipments and turns them into DATEV booking lines, mapping ShipStation sales channels and freight charges to DATEV SKR accounts and cost centers, since DATEV will not return its own chart of accounts.
- How does the integration bridge the two very different logins and event models?
- ShipStation V1 uses HTTP Basic auth over a Base64-encoded key and secret, and its V2 label calls use an API-Key header. DATEV uses OAuth 2.0 Authorization Code with PKCE against Login mit DATEV and requires a real interactive user session, so a tax advisor or client signs in once to grant access, after which the 900-second token is held and refreshed automatically. ShipStation pushes ORDER_NOTIFY and SHIP_NOTIFY webhooks that carry only a resource_url pointer, so ml-connector follows each with an authenticated GET and polls on modifyDate for edits, while DATEV sends nothing back and each EXTF booking job is confirmed by polling until it reports complete or failed.
Related integrations
More DATEV integrations
Other systems that connect to ShipStation
Connect DATEV and ShipStation
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started