Inventory sync is the single most critical data flow in a WooCommerce-ERP integration. Get it wrong, and you oversell products, disappoint customers, and erode trust. Get it right, and your store reflects reality — always.

The Problem with Batch Syncing

Many WooCommerce stores start with a cron-based approach: every 15 minutes, pull inventory from the ERP and update WooCommerce. This works until it doesn’t.

Consider: your ERP receives a shipment of 50 units at 10:01 AM. Your sync runs at 10:00 and 10:15. For 14 minutes, your website shows “Out of Stock” while your warehouse has 50 units on the shelf. That’s lost revenue.

The inverse is worse: a customer orders the last unit at 10:02, but the sync at 10:15 hasn’t decremented the ERP count yet. Another customer orders the same “last” unit at 10:10. You’ve oversold.

Real-time sync eliminates both scenarios.

Architecture Options

Option 1: Webhook + Queue

ERP (stock change) --> Webhook --> Message Queue --> Sync Worker --> WooCommerce API

WooCommerce (order) --> Webhook --> Message Queue --> Sync Worker --> ERP API

The message queue (RabbitMQ, AWS SQS, or Redis) decouples the webhook receiver from the processing logic. If WooCommerce is temporarily down, the queue holds the updates until it’s back.

Option 2: Change Data Capture (CDC)

For ERPs backed by a relational database, CDC tools (Debezium, AWS DMS) watch the inventory table for changes and push updates to WooCommerce. This catches changes regardless of how they were made — API, manual entry, or batch import.

Option 3: Polling with Delta Detection

If your ERP doesn’t support webhooks or CDC, poll at short intervals (every 60 seconds) but only process records that changed since the last poll. Most ERPs have a modified_at timestamp on inventory records.

// Delta polling pattern

async function syncInventory() {

const lastSync = await getLastSyncTimestamp();

const changes = await erp.getInventoryChanges({ since: lastSync });

for (const item of changes) {

await woocommerce.updateProduct(item.sku, {

stock_quantity: item.quantity,

stock_status: item.quantity > 0 ? 'instock' : 'outofstock'

});

}

await setLastSyncTimestamp(new Date());

}

Conflict Resolution

What happens when WooCommerce and the ERP disagree on stock levels?

Rule 1: The ERP is the source of truth for absolute stock levels. The ERP knows what’s physically in the warehouse. WooCommerce knows what’s been ordered online. The ERP wins.

Rule 2: WooCommerce decrements are events, not states. When a WooCommerce order is placed, send a “decrement by X” message to the ERP — not “set stock to Y.” This prevents race conditions.

Rule 3: Never let the sync overwrite a pending order. If a WooCommerce order is in “processing” state and hasn’t been sent to the ERP yet, the ERP’s stock count doesn’t account for it. Your sync must subtract pending orders from the ERP count.

Display Stock = ERP Stock - Pending WooCommerce Orders Not Yet in ERP

Handling Product Variants

WooCommerce variations and ERP SKUs often have different structures. A WooCommerce variable product “T-Shirt” has variations (Small/Red, Medium/Blue, etc.), each with its own stock. Your ERP might store these as flat SKUs.

Mapping table:

WooCommerce ERP
Product ID: 1234 (parent)
Variation ID: 1235 (S/Red) SKU: TSH-S-RED
Variation ID: 1236 (M/Blue) SKU: TSH-M-BLU

Maintain a SKU mapping table in your integration layer. Never rely on matching product names — they change. SKUs are your stable identifier.

Error Handling

Inventory sync failures are business-critical. Build these safeguards:

  • Dead letter queue: Failed sync messages go to a separate queue for manual review
  • Alerting: Slack/email notification when sync fails or when stock discrepancy exceeds a threshold
  • Retry with exponential backoff: 1s, 2s, 4s, 8s, then dead letter
  • Circuit breaker: If the ERP is down, stop hammering it. Queue updates and process when it recovers
  • Audit log: Every stock change — source, old value, new value, timestamp

WooCommerce API Considerations

WooCommerce’s REST API has rate limits and performance characteristics to consider:

  • Batch endpoint: POST /wp-json/wc/v3/products/batch updates up to 100 products per request
  • Variation updates require the parent product ID in the URL
  • Stock status must be updated alongside stock_quantity — they’re independent fields
  • Webhook reliability: WooCommerce webhooks can fail silently if your server doesn’t respond with 200 within 5 seconds

Monitoring Your Sync

Track these metrics:

Metric Target Alert Threshold
Sync latency < 30 seconds > 2 minutes
Failed syncs / hour 0 > 5
Stock discrepancy 0 items > 10 items
Queue depth < 100 > 1,000

Conclusion

Real-time inventory sync isn’t optional for serious WooCommerce stores. The architecture you choose depends on your ERP’s capabilities, but the principles are universal: treat the ERP as the source of truth, handle decrements as events, build robust error handling, and monitor everything. Start with webhook-driven sync if your ERP supports it; fall back to high-frequency polling with delta detection if it doesn’t.

Leave a Reply

Your email address will not be published. Required fields are marked *

Close Search Window