With more than 40,000 customers in 250+ countries (ERP.today), Microsoft Dynamics 365 Business Central is the fastest-growing product in the Dynamics family and a standard ERP for the growing mid-market. Anyone running a Shopware 6 shop with BC as the leading system sooner or later faces an integration question: how do customers, items, prices and stock flow reliably, traceably and, ideally, in real time between the two worlds? This guide shows how a Business Central Shopware integration is built cleanly on the technical side - with OData v4, webhooks, Azure Service Bus and a clear middleware strategy - and which B2B scenarios become feasible without expensive add-on modules.
Dynamics 365 BC in the German Mid-Market
The German ERP market is Europe's largest in 2024 with a share of 22.3% (Market Data Forecast) - and Dynamics 365 Business Central plays a central role in it. Germany ranks second worldwide behind the UK with 780 companies running BC, representing 12.89% of all known BC installations (6sense). The target group is clearly anchored in the mid-market: 2,493 companies with 100-249 employees use BC, plus 1,678 with 20-49 and 1,168 with 250-499 employees (6sense/Landbase).
At the same time, the cloud trend is accelerating: 90% of German companies use cloud apps in 2025 (Bitkom Cloud Report 2025), up from 81% the year before. ERP cloud interest has softened slightly from 44% to 37% (Bitkom Research) - a sign that mid-market buyers are becoming more cost-conscious. The "Digital Now" initiative has funded around EUR 3.2 billion for ERP adoption and more than 35,000 implementations in Germany by 2024 (Market Data Forecast). Running BC therefore means working on a modern, cloud-native ERP with a solid regulatory and technological base - an ideal backbone for a Shopware integration.
>40,000 customers in 250+ countries (ERP.today) - 780 BC companies in Germany (6sense) - 22.3% of Europe's ERP market (Market Data Forecast) - 295% ROI in best-in-class ERP projects with payback under six months (Rand Group) - 83% of ERP projects running longer than one year achieve ROI (Rand Group).
Integration Architecture: Direct vs. Middleware
The first architectural decision is fundamental: connect BC directly to Shopware or via a middleware layer? Both approaches have their place. A direct integration calls the Shopware Admin API from BC (or vice versa) - fast to build but tightly coupled. A middleware decouples both systems via a broker, buffers peak loads and enables central mapping, logging and retry. Especially for B2B projects with blanket agreements, tiered pricing and multiple shops, experience shows there is no way around a middleware. Our experience from ERP integrations in Shopware shows that starting lean today pays off tomorrow with a scalable architecture.
| Criterion | Direct integration | Middleware architecture |
|---|---|---|
| Time-to-live | Fast (weeks) | Longer (months) |
| Coupling | Tight - system outage breaks sync | Loose - queue buffers outages |
| Retry & dead-letter | Build it yourself | Built-in via Service Bus |
| Data transformation | Scattered in the plugin | Central mapping layer |
| Monitoring | Two log sources | Central observability |
| Multiple shops / languages | Hard to scale | Natively supported |
| Ideal for | Small B2C scenarios | B2B, multichannel, stock-critical |
OData v4 API: Endpoints and Rate Limits
Business Central has offered an OData v4 REST API as its standard interface for several versions now - the older SOAP variant is considered deprecated for new development (Microsoft Learn). Through OData you can work with companies, customers, items, sales orders, vendors and many other entities, both from standard and custom pages. What matters for stable integrations are the official rate limits: BC OData v4 allows 6,000 requests per 5 minutes per user, which corresponds to about 20 requests per second (Microsoft Learn). On top of that, the limit is 5 concurrent requests with up to 100 queued connections per user - above that BC responds with HTTP 429 and a Retry-After header (Microsoft Learn).
For a clean integration this means: the middleware must handle throttling, retry with exponential backoff and 429 responses. Ignoring this leads to integrations that collapse under load. For more on this, see our article on middleware in e-commerce.
### Retrieve customers (Standard API v2.0)
GET https://api.businesscentral.dynamics.com/v2.0/{tenant}/{env}/api/v2.0/companies({companyId})/customers?$top=100
Authorization: Bearer {token}
Accept: application/json
### Update a single item
PATCH https://api.businesscentral.dynamics.com/v2.0/{tenant}/{env}/api/v2.0/companies({companyId})/items({itemId})
Authorization: Bearer {token}
If-Match: {etag}
Content-Type: application/json
{
"unitPrice": 129.00,
"inventory": 42
}
### Create a SalesOrder (from Shopware)
POST https://api.businesscentral.dynamics.com/v2.0/{tenant}/{env}/api/v2.0/companies({companyId})/salesOrders
Authorization: Bearer {token}
Content-Type: application/json
{
"customerNumber": "K-10042",
"externalDocumentNumber": "SW-ORDER-98312",
"orderDate": "2026-05-02"
}Webhook Subscriptions for Real-Time Events
Polling is expensive and slow. Current measurements show that webhook-based sync achieves sub-200ms propagation versus 5-15 minutes for traditional polling (Codesol). BC officially supports webhook subscriptions via the subscriptions endpoint of API v2.0. A subscription has a maximum lifetime of three days and must be renewed before it expires - otherwise the event stream ends silently (Microsoft Learn). Production-grade integrations therefore implement a renewal job that extends subscriptions on time and logs failures.
A common best practice is to combine webhook triggers for real-time events with periodic API reconciliation - the latter catches lost events (Codesol). You get the speed of a push model with the reliability of a pull.
POST /api/v2.0/subscriptions
{
"notificationUrl": "https://middleware.example.com/bc/webhooks",
"resource": "api/v2.0/companies({companyId})/items",
"clientState": "xictron-prod-items-v1",
"expirationDateTime": "2026-05-05T12:00:00Z"
}
// Renewal pseudocode (middleware)
foreach (sub in activeSubscriptions) {
if (sub.expiresIn < 24h) {
PATCH /api/v2.0/subscriptions(sub.id)
{ "expirationDateTime": now + 3d }
}
}Subscriptions expire after a maximum of three days (Microsoft Learn). Without automated renewal the real-time sync breaks silently - usually on a weekend when nobody is watching. Alerting on missing webhook events belongs in every production BC integration.
$batch for Bulk Sync: Thousands of Records Efficiently
At initial go-live or for price list rollouts, thousands of items or prices often need to land in BC. Pushing every request individually through the OData endpoint blows through the rate limits in minutes. The solution is the $batch endpoint: it bundles multiple create, update and delete operations into a single HTTP request (Microsoft Learn). That is a win both for rate-limit accounting and for transactional semantics, since all operations in a changeset can be treated atomically.
A batch size between 50 and 200 operations per request has proven practical - depending on payload size, network latency and the complexity of the target entity. We cover the B2B side of the architecture and how to embed such bulk operations in larger processes in further articles.
POST /api/v2.0/$batch HTTP/1.1
Content-Type: multipart/mixed; boundary=batch_xictron_001
Authorization: Bearer {token}
--batch_xictron_001
Content-Type: multipart/mixed; boundary=changeset_items_001
--changeset_items_001
Content-Type: application/http
Content-Transfer-Encoding: binary
PATCH companies({id})/items({itemIdA}) HTTP/1.1
Content-Type: application/json
{"unitPrice":119.00,"inventory":120}
--changeset_items_001
Content-Type: application/http
Content-Transfer-Encoding: binary
PATCH companies({id})/items({itemIdB}) HTTP/1.1
Content-Type: application/json
{"unitPrice":89.50,"inventory":58}
--changeset_items_001--
--batch_xictron_001--Azure Service Bus for Asynchronous Queues
For more demanding integrations, a queue between BC and Shopware is a stable building block. Azure Service Bus acts as an asynchronous broker: Shopware events such as new orders or customer registrations are written to queues, the middleware consumes, maps and writes them into BC. The other way around, item, price and stock changes from BC flow via webhooks into queues and from there into Shopware. Dead-letter queues catch faulty messages without blocking the main stream; exponential backoff prevents hammering on failing endpoints.
Alternatives such as self-hosted brokers, generic queues based on RabbitMQ or Kafka, or lightweight SaaS middleware layers are technically just as viable - what matters is that sync flows are not synchronously chained to the HTTP availability of the end systems. Generic iPaaS patterns (Alumio, APIcenter, Codeless BPA) address the same principle; we do not recommend specific third-party vendors but build the right solution based on your requirements.
Every queue message must allow idempotent processing: re-delivering the same order twice must not create duplicate sales orders in BC. External document numbers, Shopware order UUIDs and upsert logic belong in every implementation - regardless of the broker you choose.
Data Model Mapping: BC ↔ Shopware
The technical foundation of every integration is an explicit, documented mapping between BC and Shopware entities. Changes to this mapping are the most common source of bugs when they only live in a single developer's head. We therefore version the mapping as JSON or YAML and validate it in CI - alongside mappings for order statuses, payment methods and currencies.
| Business Central | Shopware 6 | Sync direction | Trigger |
|---|---|---|---|
| Customer | customer | Bidirectional | Webhook + Shopware hook |
| Item | product | BC → SW | Webhook items |
| Item Variant | product (variant) | BC → SW | Webhook itemVariants |
| Unit price / Sales price | product.price | BC → SW | Webhook + nightly $batch |
| Inventory | product.stock | BC → SW | Webhook inventory |
| Sales Order | order | SW → BC | Shopware order hook |
| Sales Invoice | order.invoice | BC → SW | Webhook + reconciliation |
| Customer Price Group | rule / customer_group | BC → SW | Nightly $batch |
B2B Scenarios: Blanket Agreements and Tiered Prices
The real value of a BC integration shows itself in B2B. Blanket agreements, customer-specific assortments, tiered prices, budget controls and approval workflows are almost always maintained in BC - Shopware is the sales channel. Shopware 6 CE offers a powerful rule-builder system that does not require paid extensions: customer groups, company accounts and individual price rules can be mirrored via custom plugins and the Admin API. More context in our articles on B2B pricing strategies, customer-specific assortments and B2B self-service portals.
- Blanket agreements maintained as blanket sales orders in BC - API-mirrored in Shopware as a customer-specific assortment with remaining quantities
- Tiered prices derived SKU-specific from BC price lists and modelled as rule-builder rules in Shopware CE (quantity and customer-group triggers)
- Customer-specific prices from contract data via the rule builder in Shopware CE - without licence-bound package solutions
- Credit limits and payment terms from BC translated into Shopware checkout rules (block on breach)
- Approval workflows for large orders natively in Shopware as a custom development, mirrored in BC as sales-quote status
- Company accounts and offer management as CE-compatible patterns - Shopware-native implementation with BC as the source of truth
- Bidirectional real-time sync for stock - critical when inventory is tight and multiple channels compete for stock
- Multiple shops on one BC company - product visibility per shop managed through channel mapping
Error Handling and Reconciliation
Integrations rarely fail spectacularly - they fail quietly: a webhook is missing, a price is stale, an item looks different in the shop than in BC. 70% of ERP projects miss their goals because of broken data handoffs (Shopify Enterprise) - typically because error handling and reconciliation are implemented after the fact. Teams that set ERP processes up cleanly from the start improve them in 95% of cases (NetSuite).
- Idempotency keys per message (Shopware order UUID, BC ETag) prevent duplicate postings on retries
- Dead-letter queues with alerting - faulty messages must not block healthy flows
- Exponential backoff on HTTP 429 and 5xx - BC provides
Retry-After, respecting it is mandatory - Nightly reconciliation via
$batch- catches missed webhook events and acts as a safety net - Structured logs with correlation IDs spanning Shopware, middleware and BC - otherwise post-mortem debugging becomes nearly impossible
- Business alerts on quantity drift (e.g. ">5% stock difference between shop and BC")
Typical Pitfalls in BC-Shopware Projects
- Underestimating rate limits - 6,000 requests per 5 minutes per user (Microsoft Learn) are consumed faster than many assume, especially with synchronous price lookups per page view
- Webhook expiration not automated - subscriptions end silently after three days; monitoring is mandatory
- Missing idempotency - retry logic without clean keys duplicates orders or invoices in BC
- Time zones and date formats - BC works in UTC internally, Shopware admins think in local time; logic bugs around discounts and campaign windows are common
- Multi-currency scenarios - prices, taxes and rounding rules must be consistent per country and currency, otherwise shop and ERP drift apart
- Tax logic - BC calculates based on business posting groups, Shopware based on tax rules; mapping errors cost compliance later
- Mixing data and business rules - rules like "price X only for customer Y from 100 pieces" belong in a rule engine, not in SQL triggers
- Unclear ownership - who may create an item in the shop: BC, PIM or Shopware? Without a decision, conflicts follow
Implementation Roadmap in 5 Phases
- Analysis & scoping - inventory the data model in BC and Shopware, define sync directions, identify critical scenarios (B2B prices, stock, blanket agreements)
- Architecture decision - direct vs. middleware, pick the queue technology (e.g. Azure Service Bus), set up authentication with Entra ID
- MVP integration - master entities (customers, items, stock) bidirectional, OData client with retry/backoff, webhook subscriptions including renewal job
- Expansion of B2B logic - price lists, customer groups, blanket agreements, approval workflows, customer-specific assortments via rule builder and custom plugins
- Operate & reconcile - monitoring, alerting, nightly
$batchreconciliation, performance tuning, continuous adaptation to new BC and Shopware releases
For customers coming from an older Microsoft ERP generation, also check our take on Dynamics NAV - many NAV installations are on their way to BC, and a future-proof shop integration should account for that from the start. Our integrations services give an overview of all supported system landscapes.
This article is based on data from: Microsoft Learn (OData v4 rate limits, webhook subscriptions, $batch), 6sense (BC customer base DE/worldwide), ERP.today (BC customer count 40,000+), Rand Group (ROI metrics, payback), Market Data Forecast (German ERP market, Digital Now), Bitkom Cloud Report 2025 (cloud usage, ERP cloud interest), Shopify Enterprise (ERP handoffs), NetSuite (ERP process improvement), Codesol (webhook vs. polling performance), Shopware Docs (Admin API patterns). Figures may vary by reporting period.
BC Integration as a Strategic Investment
A Business Central Shopware integration is not a plugin purchase but a strategic architecture decision. Those who bet on OData v4, webhooks and a decoupled middleware get an integration that grows with the business - in B2B as much as in multichannel retail. ROI typically arrives within months in best-in-class projects (Rand Group), provided the data model, error handling and reconciliation are taken seriously from the start. We support you from architecture through implementation to ongoing operations - based on Shopware 6 CE, clean programming and established B2B patterns.
Based on experience, 8-16 weeks for a production-ready integration is realistic - depending on the scope of B2B logic, the number of entities and the desired middleware approach. An MVP with customers, items, stock and orders can usually go live in 6-8 weeks. We are happy to provide an individual estimate for your project.
Not strictly. Azure Service Bus is a well-integrated option within the Microsoft ecosystem; typically, generic queues such as RabbitMQ, Kafka or lightweight SaaS brokers are equally suitable. What matters is the decoupling between BC and Shopware - the specific technology is chosen based on your existing infrastructure.
According to Microsoft Learn, the limit is 6,000 requests per 5 minutes per user, i.e. about 20 requests per second, with a maximum of 5 in parallel. As a rule, a combination of the $batch endpoint for bulk operations, caching of master data in the middleware, webhook-based real-time sync instead of polling and clean retry handling for HTTP 429 with respect for the Retry-After header helps.
Typically yes. Shopware 6 CE provides enough building blocks with customer groups, the rule builder and the Admin API to model tiered and customer-specific prices from BC. We usually develop a custom plugin that translates BC price lists cleanly into Shopware rules - as part of our B2B e-commerce work.
In a middleware architecture with a queue, the message is buffered and, experience shows, automatically delivered once the connection returns - dead-letter queues catch permanently failing messages. Orders from Shopware are therefore usually not lost. Direct integrations without a queue are more fragile in such scenarios and require additional retry logic in the shop.
Authentication typically runs via Entra ID (formerly Azure AD) with OAuth 2.0 and a dedicated service principal, data is transmitted encrypted and access is traceable in BC audit logs. For GDPR requirements we provide a documented data flow architecture, clear role separation and logging - covered in more depth in our blog on ERP integration.