Odoo Shopware 6 Connector: Asynchronous Synchronization for Complex E-Commerce Systems

The question with an Odoo-Shopware integration is not whether the systems can exchange data. The question is how tightly they are coupled. A synchronous connection makes the availability of the checkout dependent on the response time of the ERP. An asynchronous connection decouples the two from each other.

This decision is made once, at the beginning of the project, and then determines the operational behavior of the entire system. This article describes the asynchronous variant as a reference architecture: event flow, idempotency, error handling, project structure, testing, and deployment.


Why synchronous interfaces are problematic

A direct, blocking query of the ERP system for every customer action – such as a live inventory check at checkout – links the availability of the shop to the availability and response time of a second system. If the ERP response time increases even for a short period, the checkout loading time immediately increases as well. If the ERP system temporarily fails, the entire checkout process will, in the worst case, come to a standstill.

Another risk of synchronous architectures: partial updates. If a multi-stage operation fails in the middle, parts of the data set may have already been written, while others have not yet been processed – an inconsistent intermediate state that can go unnoticed without proper error handling.

These risks are not theoretical: every JSON-2 call to Odoo runs in its own SQL transaction and is committed upon success or discarded upon error. However, multiple calls are not automatically chained into a single transaction. An Odoo to Shopware 6 connector that executes multiple related Odoo calls must actively take this property into account instead of mistakenly assuming an implicit overall transaction.


Event-Driven Architecture

The resilient alternative is an event-based, asynchronous architecture. When an order is placed, the Shopware frontend simply writes it to a message queue in milliseconds and immediately completes the checkout for the customer. A connector, acting as a consumer, processes the queue in the background and transfers the orders to Odoo via the JSON-2 API. If the transfer fails, the message remains in the queue and is reprocessed later using exponential backoff.

The basic data flow of the reference architecture:

Shopware 6 → RabbitMQ Message Queue → Connector (Consumer) → Odoo 19 (JSON-2 API) → PostgreSQL

This decoupling – referred to as "loose coupling" in the underlying architectural concept – means specifically that Odoo and Shopware know as little as possible about each other and communicate exclusively via standardized middleware. If one of the two systems fails temporarily, the other can continue its operation for the decoupled processes; pending messages are buffered and processed later.


RabbitMQ architecture with publisher, exchange, queue, consumer, and error path for an Odoo-Shopware integration.

RabbitMQ and Symfony Messenger

In the described reference implementation, a RabbitMQ Message Queue takes on this intermediary role, connected via established patterns: Publisher Confirm (confirmation that a message has safely arrived in the queue), retry loops, Dead Letter Exchange, and Idempotent Consumer. The complete message flow follows the pattern Publisher → Exchange → Queue → Consumer → Retry Queue → Dead Letter Queue.

If the Shopware to Odoo Connector is integrated directly into the Shopware frontend, it follows the established Symfony architecture with Symfony Messenger as the connection to the message queue – including dedicated directories for client, DTOs, mapper, message handler, services, repositories, and exceptions.

Important for classification: RabbitMQ is the specific message queue solution used in this reference architecture – the "message queue" role is therefore not necessarily tied to this one product. For the architectural decision, the pattern (asynchronous decoupling via a queue) counts, not the specific product choice.


Idempotency and Data Consistency

A connector that can process messages multiple times – for example, after a network error and a renewed delivery attempt – must work idempotently: The specific message can be processed repeatedly without creating duplicates or inconsistent states. Odoo solves this using external IDs in conjunction with the load() method, which updates an existing ID instead of creating a new one.

An additional rule applies to non-idempotent write operations: Before an automatic retry, it must be checked whether the original request has already successfully changed the target system – a pure "resend" without this check can otherwise lead to duplicate orders or incorrect inventory postings.

Immutable business identifiers such as the Shopware UUID or the article number (SKU) serve as business keys between the systems – never technical surrogate keys such as internal database IDs. We explain the logic behind this in data mapping during ERP migration.


Stocks, orders and prices

Typical synchronization areas of an ongoing Odoo-Shopware integration:

  • Inventory: Changes in the ERP are fed back to the frontend on an event-driven basis, instead of Shopware repeatedly actively querying.
  • Prices: including customer-specific B2B prices and volume discounts, maintained as price lists in the ERP.
  • Orders: Asynchronously transferred from the frontend to the ERP, with retry in case of temporary errors.
  • Order status: Feedback on delivery and invoice status to the front end for customer communication and returns processes.

This list describes typical integration areas – the specific scope of functions of a project always depends on the business processes actually required, not on a blanket list.


Fault Tolerance and Monitoring

Fixed basic rules apply to production-ready connectors: no silent errors, no suppressed exceptions, complete logging of each incident, an automatic retry strategy, and the shifting of unprocessable messages to a dead letter queue instead of silent data loss.

Structured logging includes at least the following: timestamp, correlation ID, the affected entity, the relevant business key reference, HTTP status, runtime, and the current retry counter. All external API calls use defined timeouts and exponential backoff with jitter; HTTP 429 and server errors 500, 502, 503, and 504 are generally considered candidates for an automatic retry – provided that the repeated operation is demonstrably idempotent.

During operation, an observability setup (e.g., Grafana, Prometheus, Loki) monitors technical metrics such as CPU and database utilization, as well as the message queue's fill level, supplemented by business metrics like the number of orders per hour. If API accessibility drops, the system automatically triggers an alarm – instead of an outage only being noticed through customer complaints.


Reference Architecture at a Glance

The complete architecture of a production-ready connector:

 Shopware 6 │ Event / Order / Stock Change │ ▼ RabbitMQ Message Queue │ ▼ Connector (Consumer) │ Odoo 19 JSON-2 API │ ▼ PostgreSQL (ERP-Datenbank)

This structure is deliberately modular: each component (producer, queue, consumer, API client) can be tested, monitored, and replaced independently if necessary, without affecting the other components. Configuration values such as API keys, URLs, timeouts, and access data are never versioned in the source code, but are provided exclusively via environment variables or a secret management system.

Project structure: Python or Symfony

For high-performance ETL and connector processes, a modular project structure is recommended, regardless of the language chosen. In Python-based migration tools, a division into separate modules for configuration, authentication, API client, retry logic, data mapping, and separate modules for each entity (products, customers, inventories, orders) has proven effective, supplemented by a dedicated logging module and its own test suite.

If the connector is integrated directly into the Shopware frontend instead, it follows the established Symfony architecture: its own Odoo namespace with separate directories for the API client, data transfer objects (DTOs), mapper classes, messenger messages and their handlers, services, repositories, exceptions, and CLI commands. This separation allows individual components – such as the pure API client – to be tested independently and, if necessary, reused outside the connector.

Before each release, a production-ready connector goes through a fixed test pyramid: Unit Tests → Integration Tests → API Tests → Load Tests → Smoke Tests → Go-Live Tests. Unit tests check individual functions in isolation, integration tests check the interaction of several components, API tests check the actual communication with Odoo, Shopware and PlentyONE, load tests check the behavior under realistic order volumes, smoke tests check the basic functionality after a deployment, and go-live tests check the complete end-to-end functionality immediately before the productive release. Each of these stages covers different error classes – if one is skipped, error detection tends to shift towards live operation.

Deployment and CI/CD Pipeline

The reference architecture relies on isolated, versioned, and immutable containers for the connector itself. An automated CI/CD pipeline ensures code quality and stability through a fixed sequence of stages: linting, static code analysis, unit tests, integration tests, Docker build, deployment to a staging environment, and only then deployment to the production environment. A failing step at any of these stages automatically stops the pipeline instead of passing on faulty code unchecked.

Coding Standards

Professional development requires consistency throughout the entire project: For Python components, PEP 8, static typing, and automated tools like Ruff and Black for formatting apply. For PHP components in the Shopware frontend, PSR-12, PHPStan, Rector, and the CS Fixer are used. SQL scripts for validation and reporting use explicit column specifications instead of wildcard selects, EXPLAIN ANALYZE for performance testing, clear transaction boundaries, and optimized indexes. For each reference implementation, a unique version number and the exact tested Odoo, Shopware, and Python/PHP versions are also documented to ensure that the implementation and reference documentation remain consistent in the long term.


The connector is the permanent link after the migration has been completed. Our overview of the migration from PlentyONE to Odoo describes the path to get there – from system analysis to cut-over.


Request a high-performance Odoo-Shopware integration

A robust, asynchronous integration architecture between your existing Shopware 6 frontend and Odoo 19 cannot be bought off the shelf – it must fit your actual data flows, load profiles, and business processes. This is exactly what we develop as part of our free, non-binding e-commerce audits. For an initial assessment of your system landscape , please contact us directly.

✔ Free ✔ Non-binding ✔ Asynchronous architecture instead of blocking interfaces ✔ Response within 24 hours

Frequently asked questions about the Odoo-Shopware connector

Is RabbitMQ absolutely necessary for every Odoo-Shopware integration?

No. RabbitMQ is the specific message queue solution used in our reference architecture. The underlying pattern of asynchronous, event-based decoupling is crucial for the architecture – which specific product takes on this role depends on your existing infrastructure and your preferences.

What happens if the message queue itself fails?

A production-ready queue architecture runs redundantly and is monitored via the same observability setup as the other system components. A short-term failure would be immediately detected by automatic alarms before it affects the checkout.

Can we gradually convert an existing synchronous integration to this architecture?

Yes. The changeover can usually be done entity by entity – for example, first for orders, then for inventories and prices – instead of replacing the entire integration in a single, high-risk step.

We fear that a new interface will make our checkout more unstable instead of more stable.

The exact opposite is the goal of this architecture: the consistent decoupling via a queue makes the checkout more independent of the ERP system – not more dependent.

Our development team is not familiar with RabbitMQ or Symfony Messenger.

This is not an obstacle to starting the project. We take over the architecture and implementation completely in-house and deliver a documented, maintainable system – including monitoring that remains understandable even without in-depth messaging expertise.

How do we ensure that the integration continues to run reliably after the project?

Through the described observability setup with automatic alerting and clear documentation of the architecture, which your internal team or a successor partner can also understand.

Christopher Einenkel

Senior Integration Architect & API Specialist
Specialist in ERP/PIM Integrations & Enterprise Interfaces

Christopher Einenkel is the strategic mind at HQ GmbH for advanced system integrations and complex API architectures. Whenever data synchronizations reach their limits or demanding enterprise systems such as Salesforce need to be connected to Shopify, he designs tailored, high-performance interface logic.

His track record includes the in-house development of proprietary enterprise solutions, including automated AI translation tools for product master data, seamless B2B procurement systems, as well as automated market evaluation and competitive monitoring solutions. In addition, he manages the technical implementation and API integration of digital software call center systems into existing CRM and ERP environments for our enterprise clients.

View full profile & interface certifications
Christopher Einenkel - Senior Integration Architect at HQ GmbH
↑