
Enterprise eCommerce integrations fail for predictable reasons. Your Adobe Commerce platform and your ERP system have different data models. Your real-time inventory feed arrives just late enough to cause oversells. Your customer records get out of sync between Salesforce and your eCommerce platform and nobody notices until it breaks something. Your order routing to fulfillment works fine at 50 orders a day but starts queuing up when you hit 500. These aren't theoretical problems—they're the operational headaches that cost manufacturers and B2B operations real money in customer service, manual workarounds, and lost orders.
The good news is that these are all solved problems. The pattern is always the same: understand the specific pain point, design a solution that's compatible with both systems' capabilities, build in visibility and error handling, and test the failure modes before you go live. Most of the time, the solution isn't complex. It's just requires thinking through the edges that get ignored in initial design.
Data Synchronization and Consistency
The first problem every enterprise integration hits is keeping data consistent when it lives in two places. You've got customer records in Salesforce and Adobe Commerce. You've got product data in your ERP and your eCommerce platform. Orders exist in Adobe first, then flow to your ERP and your fulfillment system. The naive approach—just sync everything in both directions continuously—creates conflicts, overwrites, and silent data corruption.
The solution starts with clear ownership. Which system is the source of truth for each data type? Is your ERP the source of truth for inventory and your Adobe Commerce platform just a consumer? Or does Adobe Commerce maintain inventory locally and sync to your ERP? For customer data, does Salesforce own it and Adobe Commerce consume it, or vice versa? Does your pricing live in the ERP or in Adobe?
Once you've established ownership, synchronization becomes much clearer. If your ERP owns inventory, you push updates from the ERP to Adobe on a schedule—typically every 15 or 30 minutes for most operations. If a customer's shipping address changes in Salesforce, you sync that to Adobe, but you don't let Adobe overwrite it. You get idempotency by using unique identifiers—the ERP's SKU as the source of truth, never Adobe's product ID.
The real-world challenge is handling conflicts. What happens when a customer record gets modified in both Salesforce and Adobe within seconds of each other? You need a tie-breaker rule. Usually it's "last write wins" for non-critical fields (like address), but "ERP wins" for financial data like price. Or you need middleware that prevents simultaneous writes—a single source of truth that both systems query, with locks that prevent race conditions.
At Bemeir, when we build these integrations, we start with a data audit. We map every field in Adobe Commerce to the corresponding field in the backend system. We identify which fields are sources of truth, which are read-only in one system, and which need bidirectional sync. We build transformation logic that handles the data model differences—the ERP might use numeric country codes while Salesforce uses names. We implement logging that shows every sync operation so if something goes wrong, you can trace exactly what changed and when.
The implementation pattern usually looks like this: a scheduled sync job pulls data from the source system (ERP, Salesforce, WMS) and stages it. Transformation logic maps the data to Adobe Commerce's model. Conflict detection compares the data against what's already in Adobe. Only changes that passed conflict detection actually write to Adobe Commerce. A log records every operation. If something fails, it's queryable and fixable.
Real-Time Inventory Synchronization
Inventory is where real-time matters most. Every minute that your eCommerce platform shows inventory that doesn't match your physical stock is a minute you might oversell. A customer checks out at 2:47 PM thinking you have that item in stock. By 2:49 PM you've actually sold the last unit to someone else. You've created a customer service issue that costs you more in labor than you made on the sale.
The naive solution is polling—Adobe Commerce hits your WMS API every 30 seconds asking "is this item still in stock?" That works for small catalogs but becomes a throughput problem at scale. If you've got 100,000 SKUs and you're checking each one every 30 seconds, you're generating 200,000 API calls a minute. Most systems can't handle that.
The right solution is event-driven. When inventory changes in your WMS, it triggers an event. That event lands in a queue. A listener picks it up and updates the specific SKU in Adobe Commerce. If inventory is actually zero, the event also triggers an alert so your merchandising team knows to pull the product from search or mark it as unavailable. This scales to any catalog size because you're only updating what actually changed.
The implementation requires understanding Adobe Commerce's inventory systems. In Adobe 2, there's the basic stock system that tracks availability per product. In Adobe Commerce cloud, you can use Inventory Management (MSI) which tracks stock across multiple sources (warehouses, fulfillment centers, dropshippers) and gives you more sophisticated allocation logic. If you're a manufacturer with three warehouses, MSI lets you configure which warehouse fulfills what, priority rules, and backorder logic.
The integration pattern: your WMS publishes stock change events to a message queue (Kafka, RabbitMQ, or a cloud equivalent like AWS SNS). A worker service subscribes to those events, validates them against Adobe's data model, and updates inventory via Adobe's REST API. If the update fails (network timeout, rate limiting), the message goes back in the queue for retry. You also need a reconciliation process that runs nightly, comparing your WMS source of truth against what Adobe thinks it has. If there's a discrepancy, you log it and alert ops.
The tricky part is handling the fact that inventory changes are asynchronous. A customer is looking at your product page right now, seeing it in stock. Simultaneously, your warehouse is scanning the last unit and packing it for another order. For a few seconds there are two different truths. The way you handle this is having a small buffer. If inventory is critically low, you add friction—require the customer to confirm they want to wait for a backorder, or route them to a similar product. You build your checkout process so it does a final inventory check right before payment, not five minutes before.
Bemeir built this pattern for Ella Paradis, which operates with fast-moving inventory across multiple fulfillment centers. Real-time sync matters there because stock visibility is a competitive advantage. A customer can check out knowing they're getting something today, not waiting for a backorder. The integration uses event-driven updates with a five-minute reconciliation window, so if something gets out of sync, you catch it and fix it quickly.
Order Routing and Fulfillment Integration
Orders start in Adobe Commerce but need to end up in the right place—your ERP system for accounting, your fulfillment system for picking and packing, your shipping system for carrier rates. Getting orders from Adobe to these downstream systems without manual intervention, and getting fulfillment data back, is where a lot of integrations break down.
The core challenge is impedance mismatch. An Adobe Commerce order is a customer transaction. Your ERP's purchase order is a financial record. Your WMS order is a fulfillment task. They're the same business event, but they have different data structures, different status lifecycles, and different timing.
The solution is having a clear order transformation layer. When an order is placed in Adobe, it triggers a webhook. A service receives that webhook and does several things: it generates a unique order ID that's consistent across all systems; it transforms the Adobe order into the data structures needed by the ERP (account code, cost center, shipping address); it transforms it into the fulfillment format needed by the WMS (pick lists, packing instructions); it creates records in both systems. If either system rejects the order (inventory not available, invalid account code), the transformation service logs the error and alerts ops.
The reverse flow is just as important. As orders progress through fulfillment, status updates need to flow back to Adobe so you can send tracking updates to customers. A shipment tracking event from your shipping carrier needs to update Adobe so customers see "your order shipped" in their account. If a customer initiates a return in Adobe, it needs to flow to your returns system so RMA numbers are created properly.
At scale, this requires serious attention to idempotency. If an order update gets replayed twice, will it create a duplicate shipment record? If a fulfillment status update arrives out of order (shipped before picked), does your system handle it gracefully? Most of the time you solve this with deduplication keys—every integration message has a unique ID and a timestamp. The receiving system checks if it's already processed this message ID, and if so, ignores the duplicate. Order status is a state machine, so out-of-order events get queued until earlier state transitions complete.
CRM Data and Customer Relationship Consistency
Salesforce CRM and Adobe Commerce often serve different purposes—Salesforce is your source of truth for customer relationships and sales activity; Adobe is your transaction system. But they need to share customer master data without creating conflicts.
The typical integration pattern is that Salesforce owns the relationship data. New customers are created in Salesforce by the sales team, then synced to Adobe Commerce so they can log in and place orders. When they place an order in Adobe, that order is synced back to Salesforce so the sales team has visibility. When customer profile data changes—address, billing contact, shipping preferences—it flows from Salesforce to Adobe.
The tricky part is handling customer creation in both directions. A new visitor comes to your website, creates an account, and places an order in Adobe Commerce. Now you have a customer in Adobe that the sales team doesn't know about. You need a process that periodically syncs these new customers from Adobe to Salesforce so the sales team can reach out. But you can't create a duplicate Salesforce record if the same company already has an account.
The solution is account matching logic. Before you sync a customer from Adobe to Salesforce, you do a fuzzy match on company name, email, and domain. If there's a match, you link the Adobe customer to the existing Salesforce account and flag it for the sales team to review. If there's no match, you create a new account.
For manufacturer operations, this is critical. You might have a customer represented by multiple contacts—the procurement person, the plant manager, the finance contact. They all need to be able to log into Adobe and place orders, and all of them need to be linked to the same Salesforce account. You need account hierarchies and contact linkages to flow correctly between systems.
Building Observable and Maintainable Integrations
The most important thing about integration architecture isn't getting the happy path right—it's handling the 200 ways things can go wrong. Your ERP API goes down. A rate limit kicks in unexpectedly. The data format changes and breaks your transformation logic. A customer's address is invalid. An order has a product that's been discontinued.
Observable integrations log every step. They have metrics—how many orders were synced, how many failed, what the error distribution is. They have alerting—if sync volume drops, if error rates spike, if there's a delay in inventory updates. When something breaks, you can query the logs and see exactly what happened and why.
The pattern we use at Bemeir is: every integration operation is logged with structured data (timestamp, operation type, IDs, success or failure reason). Every transformation step is traceable. If an order failed to sync, you can pull up exactly what the error was and manually retry it. You have dashboards that show integration health at a glance. You have runbooks for common failure scenarios so your ops team knows what to do.
The right integration architecture is boring. It doesn't have novel problems. It follows patterns that work because they've been proven at scale. It's observable so you can trust it. It fails gracefully so when something breaks, it doesn't cascade. It's the foundation that lets your eCommerce operation run at speed without surprises.





