Replicate master data, financial records, and back-office processes between an enterprise resource planning system and commercetools.
An enterprise resource planning (ERP) system is the system of record for the master data a business runs on: materials, classifications, list prices, stock, accounts, and financial documents. Integrating it with commercetools means replicating the subset of that data your storefront needs, and sending back the transactions the ERP must record.
This guide covers the decisions that shape an ERP integration: which domains the ERP owns, whether to configure a Connector or run the flows through middleware, how to load master data in bulk and keep it current, and how to keep financial data reconcilable between the two systems.
Assign ERP ownership before you design anything
An ERP integration is not one integration. It is a set of one-way flows that differ in direction, volume, and urgency, and that fail independently. The first task is deciding which flows exist at all.
Decide the system of record per data domain
Treat each ERP domain as a one-way contract. Designate one writer and make the replica read-only. Reject or reconcile changes that originate on the read-only side.
| Data domain | Typical owner when an ERP is present | Direction | Where the design lives |
|---|---|---|---|
| Core product data and classification | ERP | ERP to commercetools | Integrate product data |
| Product content and enrichment | PIM, or the ERP when no PIM exists | ERP to commercetools | Integrate product data |
| List and base Prices | ERP | ERP to commercetools | Integrate product data |
| Contract and customer-specific Prices | ERP | ERP to commercetools | This guide |
| Inventory quantities | The system that owns Orders | Usually ERP to commercetools | Integrate an order management system |
| Customer profile | commercetools, or a CRM or customer data platform | Varies | Integrate a CRM |
| B2B accounts, credit limits, and payment terms | ERP | ERP to commercetools | This guide |
| Order capture and contents | commercetools | commercetools to ERP | Integrate an order management system |
| Order fulfillment lifecycle | OMS, or the ERP when it owns the Order lifecycle | ERP to commercetools | Integrate an order management system |
| Invoices and financial documents | ERP | ERP to commercetools | This guide |
| Tax rates and calculation | Tax engine, or the ERP | Varies | Integrate tax |
| Reporting copies of commerce data | commercetools remains the source | commercetools to a warehouse or analytics tool | Integrate an analytics destination |
The rows this guide owns are the ones no other integration claims: the master data that arrives in bulk, and the financial and account data that has to reconcile. Confirm the remaining rows against the linked guides before you rely on the defaults above.
Answer the questions that change the design
Record the following before choosing a runtime, because each answer moves the architecture:
- Which domains are actually in scope? An ERP holds far more than a storefront needs. Replicate only what search, display, pricing, checkout, and fulfillment use, and leave the rest in the ERP.
- What volume, and how often does it change? Core product data changes infrequently, prices change on a schedule, and stock changes constantly. These are different integrations with different cadences, even when they leave the same system.
- How does the ERP publish changes? A push to an endpoint, a queue, a scheduled extract, or a full file drop. A push maps to a
serviceapplication. A schedule maps to ajob, provided the job orchestrates the work rather than performing bulk file processing inside it. - Does the ERP track changes? If it can emit deltas, incremental synchronization is straightforward. If it can only produce full extracts, the integration needs its own change detection or must accept full loads.
- Which markets, currencies, and locales are in scope? This determines the Price and localization mapping, and whether one extract serves every Store.
- How much staleness is tolerable per domain? Stock tolerance is usually minutes, price tolerance hours, and material description tolerance a day. These set the schedules and the alerting thresholds.
- What is the initial load, and when does it run? A first full catalog and account load is a separate project from steady-state synchronization, with different tooling and a different risk profile.
- What happens when the ERP is unavailable? Decide per flow whether the integration retries, queues, or skips a cycle, and who is told.
Record special requirements
Add ERP-specific constraints that could require custom extraction, transformation, or hosting:
- B2B account hierarchies modeled as Business Units with approval workflows.
- Multi-Store or multi-market catalogs that need Product Selections or Product Tailoring.
- Contract pricing that varies by account, volume tier, or negotiated agreement.
- Data residency, retention, or audit constraints that restrict where the integration runs.
- An existing middleware platform or ERP support contract that constrains the runtime.
- Non-commerce data that the business wants replicated for reporting rather than for the storefront. Exporting commerce data itself for reporting is covered by Integrate an analytics destination.
Choose an integration path
Start with the option that requires your team to build and maintain the least custom ERP integration logic. Move to a custom runtime only when the earlier options cannot meet a recorded requirement.
Check for an existing ERP Connector
view_connectors scope. Filter the Search Connectors endpoint by integration type:GET https://connect.{region}.commercetools.com/connectors/search?integrationTypes=erp&integrationTypes=pim
erp and pim, because a Connector that replicates core product data and price data can be published under either type. For the full list of values, see IntegrationType. For the host to use in each Region, see Hosts and authorization. You can also browse the available Public Connectors in Connect in the Merchant Center.Evaluate the candidate against the recorded data domains, directions, mappings, Regions, locales, and peak volume.
Compare middleware and runtime options
Most ERP integrations need logic beyond the commercetools APIs. This logic extracts data from the ERP, transforms it into commercetools resources, and sends it to commercetools. Choose where to run it based on technology your organization already knows how to deploy, secure, monitor, and support.
| Option | Choose it when | What you own |
|---|---|---|
| ERP-vendor middleware | The organization already runs the ERP vendor's integration platform and extraction tooling | Integration flows, mapping, and the calls into commercetools |
| Integration platform | Several systems need connecting, and available adapters reduce custom connection work | Integration flows, mapping, and connection management |
| Cloud services | The team prefers to use functions, queues, and storage in its existing cloud account | Extraction, transformation, scheduling, retries, and hosting |
| Connect | The commercetools-facing logic can run close to the platform, and you want Connect to host and scale it | Application code only; Connect provides hosting, scheduling, and the message broker |
| Import API called directly | An existing job already produces well-formed extracts and needs no separate runtime | The calling job |
| Merchant Center CSV import | Volumes are low, changes are occasional, and business users own the process | Nothing; there is no integration to run |
service request times out after five minutes and has a maximum of 1 CPU and 512 MB. A job request times out after 30 minutes and has a maximum of 2 CPUs and 4 GB. Keep stateful work, bulk file processing, and long-running transformations outside Connect. Review the Connect deployment behavior and when to use an alternative to Connect before choosing it.When comparing runtimes, check whether each option can process the largest ERP data export you expect within the required synchronization window. Also consider how it protects data while moving between systems, whether your team has the skills to operate it, and its ongoing operating cost in addition to its implementation cost.
Prove that a gap is not configuration
Test the candidate controls for field mapping, locales, currencies, enabled domains, and category mapping before treating an apparent limitation as a code gap.
Fork or build
When a source-available Connector covers the core flow, extend only the ERP behavior that its configuration cannot provide. Deploy the result as an Organization Connector.
service application to receive pushed changes, a job application to trigger scheduled loads and reconciliation, and an event application when commercetools changes must flow back. Event applications receive messages at least once without ordering guarantees, and unacknowledged messages are retained for seven days. Make consumers idempotent, tolerate out-of-order delivery, acknowledge only after durable processing, and reconcile records that exceed the retry window.job. A job request times out after 30 minutes, and the application type is intended for lightweight recurring tasks. Scaffold each application with the Connect CLI:commercetools connect init my-erp-connector
commercetools connect application add
Design the master-data flows
Choose the ingestion API per domain
An ERP load is larger and runs to a schedule, so two further properties shape its design:
- Import summaries are eventually consistent. Use ImportSummary to confirm a completed run, not for real-time monitoring. For live status, subscribe to Import API Events.
- Batch by resource count and bytes. An Import Request carries up to
20resources, its request body cannot exceed14 megabytes, and each resulting document cannot exceed16 megabytes. The Import API recommends no more than 300 calls per second per Project. A Project can hold up to1 000Import Containers. Keep fewer than200 000Import Operations in a container so monitoring stays efficient. See Import API best practices.
Separate the initial load from ongoing synchronization
The first load and steady-state replication are different problems. The initial load is large, ordered, and run once under supervision. Steady-state replication is small, continuous, and unattended. Build them as separate processes even when they share mapping code.
imported requires explicit handling. Resubmit a rejected resource after the platform retry limit is reached. Correct the source before resubmitting a validationFailed resource. For canceled and partiallyImported, inspect the errors and submit only the work still required.48 hours after creation. An Import Container without a retentionPolicy is removed after 72 hours. Set a TimeToLiveRetentionPolicy when a load needs longer.Run the initial load against a test Project first, bounded to a small representative sample. Count the resources the run will process before it starts, and treat any full-catalog run as a deliberate decision rather than a default.
Give every resource a key the ERP already owns
key and Orders by orderNumber; review how resources are created or updated before defining the mapping. Fields such as externalId, sku, and SyncInfo can correlate records but do not replace the import identity.key of a resource that already exists, so a material that was created in commercetools without a key cannot be adopted by a later import: the import creates a second resource instead. To adopt existing data, set the keys first with the relevant Set Key update action in the HTTP API, or with the approach described in Add keys to existing resources and objects.Sequence the resources the Import API cannot create
unresolved until the prerequisite exists or the operation expires.Two further constraints change how a multi-source integration must be written:
- Preserve fields owned by other systems. Product imports remove omitted values during an update. Follow the Product import guidance and include every value that must remain on the Product or Product Variant.
- Define the removal policy outside the Import API. The Import API cannot delete resources. Decide whether an ERP discontinuation unpublishes or deactivates the corresponding commerce resource.
When several systems write to the same Product, one process creates it and each source updates only the fields it owns. Never let a source perform a blind full overwrite.
Schedule batch runs so they do not collide
Use scheduled reconciliation extracts to expose master-data drift that delta feeds cannot reveal.
Synchronize financial and back-office data
Align rounding modes before go-live
HalfEven. A mismatch can create minor-unit differences that prevent financial reconciliation. Test representative ERP totals against the selected modes before the first production Order.Replicate invoices and financial documents
Keep invoices, credit notes, and overdue-payment collection records in the ERP as the system of record. In this design, commercetools stores only the references and summary fields needed by the storefront or Merchant Center.
Apply the same boundary to an external ledger. Store a reference and display value in commercetools while the ERP retains the balance and liability. If the balance is not replicated, validate any spend limit against the ERP when the value is applied.
Model B2B accounts, credit, and payment terms
key. Map account availability to BusinessUnitStatus instead of a Custom Field. Store ERP-specific credit limits and payment terms in Custom Fields on the Business Unit.50 000 Standalone Prices, so size the account, Channel, validity, and tier combinations before choosing this model. Confirm the selection model against Integrate product data before building the extract.When the ERP owns the Order lifecycle
Apply that guide to the post-order lifecycle and this one to master data. They are separate flows with separate failure modes, and combining them into a single job means a slow nightly catalog run can delay an order status update.
Secure and operate the integration
Manage credentials and scopes across the middleware boundary
inheritAs.apiClient.scopes so Connect generates the API Client during installation.manage_import_containers and the resource scopes that correspond to each Import Container resourceType. Avoid broad legacy scopes such as manage_products when narrower scopes cover the enabled flow. Determine the final set from Import API authorization and API scopes. Classify ERP credentials according to the connect.yaml configuration rules so secrets never appear in standard configuration or logs.Treat every ERP-facing write route as a privileged public interface. Authenticate processing routes and expose only health checks without authentication. Implement the calling system's documented authentication scheme. If the caller signs the request body, validate the documented header and algorithm instead of assuming a token format.
Validate the ERP connection at deploy time
postDeploy script make a test call to the ERP so invalid credentials surface at deployment instead of during the first load. Decide whether that failure fails the deployment or only warns, and record the decision.postDeploy script, and remove them in preUndeploy. Declare both in the scripts block of connect.yaml, because a script file that is not declared never runs. Create each resource when it is absent and update it in place rather than deleting and recreating it, then confirm the resources exist rather than inferring success from the Deployment status. See Connect development and Deployment logs.Govern who can edit ERP-owned data
Monitor and reconcile
Correlate logs with the ERP record key. Record identifiers and processing decisions without logging customer or account payloads.
imported terminal state, source and platform count differences, reconciliation lag, and replay outcomes. Document how an operator corrects and replays a failed extract.Verify the integration
- Every Import Operation for a bounded sample reaches
importedrather thanrejected,validationFailed,canceled, orpartiallyImported. - A material discontinued in the ERP produces the agreed outcome rather than remaining sellable.
- An account blocked in the ERP is rejected through BusinessUnitStatus rather than only being flagged in a Custom Field.
- An invoice reference written to an Order Custom Field resolves to a retrievable document in the ERP or the document system.
- An Order placed in commercetools totals the same as the ERP calculates it, including rounding. Orders created through Order Import carry the total the ERP supplied, so check those against the source data instead.
validationFailed when the data violates a constraint. ImportSummary can lag behind the operation states because it is eventually consistent. An unresolved operation is not an error while its referenced resource is still expected to arrive. Confirm the terminal state before treating these conditions as defects, and clean up test data afterward so a shared Project does not accumulate partial loads.Apply the design to SAP ERP
This section applies the guidance above to an SAP ERP integration. Verify the interfaces and data formats available in your SAP implementation before using the example mapping.
Map SAP domains to commercetools resources
Start with the commerce outcome each SAP domain must support. Then map the source interface configured for that domain to the corresponding commercetools resource:
| SAP domain | commercetools resource |
|---|---|
| Materials | Product and ProductVariant |
| Classification | ProductType, Attributes, and Product Variant |
| Prices and conditions | Embedded Prices or Standalone Prices |
| Stock levels | InventoryEntry |
| Invoices | Custom Fields on the Order |
Integrate through SAP Cloud Integration
Use cloud services with SAP Gateway
- Expose the approved data. Configure the SAP interface for the domains in scope.
- Protect the endpoints. Route the endpoints through an API gateway that applies authentication, authorization, and network controls.
- Transform and load the records. Convert the source payloads to JSON in a function or container. Use the Import API for bulk domains and the HTTP API for time-sensitive domains. Handle retries, timeouts, and errors in this layer.
Troubleshoot observable symptoms
key or fields blanked by an import that omitted them, are in Troubleshoot observable symptoms in the product data guide.| Symptom | Likely causes | Checks and resolution |
|---|---|---|
| Import operations stay unresolved and eventually expire | The referenced Tax Category, Channel, State, or Shipping Method does not exist, and the Import API cannot import it | Create the prerequisite through the HTTP API, then resubmit |
| Monitoring shows operations still processing after the run finished | Import summaries are eventually consistent | Confirm the individual Import Operation states, or subscribe to Import API Events instead of polling |
| Some resources never arrive, and no retry ever fixes them | The operations are in validationFailed, which the Import API does not retry and resubmitting the same data cannot resolve | Read the errors field, correct the source record, and send it as a new import |
| Concurrent modification errors occur during a load | Middleware resubmitted operations that the Import API was already retrying, or sent duplicate requests whose processing order was unspecified | Resubmit only rejected operations and never send duplicate import requests concurrently |
| The nightly load is slow only at exactly midnight | Scheduled jobs across many Projects start at the same time | Apply the scheduled sync offset and jitter recommendations |
| Order totals differ from the ERP by minor units | The price or tax rounding mode does not match the ERP | Align both rounding modes with the ERP and repeat the reconciliation test |
| An account blocked in the ERP can still place Orders | The ERP status was replicated to a Custom Field instead of BusinessUnitStatus | Map account availability to BusinessUnitStatus and confirm the native status behavior |
| An ERP webhook is rejected as unauthenticated | The endpoint expects a different authentication scheme from the one the caller uses | Implement the authentication scheme documented by the calling system |
| Replicated values keep drifting back to older data | A Merchant Center user is editing ERP-owned Attributes | Group them in an Attribute Group and restrict editing permission to the appropriate teams |
| Stock is deducted twice for the same Order | Both the ERP and commercetools decrement it, because the Cart InventoryMode is not None | Set the mode to None, or subtract the platform-side deduction in the mapping |