How to Keep Shopify and WooCommerce Inventory in Sync
Ensure inventory levels stay consistent across both your Shopify and WooCommerce stores.
What This Integration Does
Selling the same SKUs on two storefronts means a sale on one needs to decrement stock on the other - fast - or you'll oversell. This workflow polls both stores on a tight schedule, identifies which side has the most recent inventory change per SKU, and propagates that quantity to the other side.
The job runs every 10-15 minutes. For each SKU, the most recent updated_at wins, and the older side gets a corrective update. A small per-SKU state cache prevents sync loops (where Shopify's write triggers a WooCommerce write that triggers another Shopify write).
Prerequisites
- A Shopify connection with
read_inventoryandwrite_inventoryscopes. - A WooCommerce connection with product read/write.
- A persistent store (MySQL or MongoDB) for the per-SKU sync state.
- SKUs must match exactly across both platforms.
Step 1: Schedule Trigger
Add a Trigger node of type Schedule, every 10-15 minutes. More frequent and you'll waste rate limit; less frequent and oversell risk climbs.
Step 2: Fetch Inventory From Both Stores in Parallel
Add a Parallel node with two branches. The Shopify branch calls shopify list-products with updated_at_min set to the previous run timestamp, then extracts {sku, variant_id, inventory_quantity, updated_at} per variant. The WooCommerce branch calls woocommerce list-products with modified_after set similarly and extracts {sku, id, stock_quantity, date_modified}.
Step 3: Diff and Decide Direction
Add a Transform node that, for each SKU appearing in either result set, picks the side with the newer updated_at/date_modified as the winner. Skip SKUs where the quantity already matches the cached last-known-good value (this is what prevents sync loops). Emit two arrays: toShopify and toWoo.
Step 4: Push Updates to Shopify
Add a Loop over toShopify. Inside, call shopify update-product (or the variant-level raw-graphql mutation if you have variants) to set inventory_quantity. Capture the response timestamp and write it to your state cache as the new last-known-good for that SKU.
Step 5: Push Updates to WooCommerce
Add a parallel Loop over toWoo calling woocommerce update-product with:
{
"stock_quantity": {{ row.quantity }},
"manage_stock": true
}
Again, capture the response and write last-known-good back to the state cache.
Step 6: Loop-Prevention and Alerting
After both branches, post a summary to slack send-message: SKUs synced in each direction, conflicts (both sides updated since last run - the workflow picks the newer, but flags this), and any failures. Add a Condition that pages on-call if a single SKU is being updated in both directions on multiple successive runs - that's the signature of a real conflict (e.g. a low-stock SKU being hit on both stores simultaneously).
Tips
- The state cache is load-bearing. Without it, every successful write from Shopify to WooCommerce looks like a new WooCommerce change on the next run and gets shipped back to Shopify - an infinite ping-pong.
- Set alerts when stock for any SKU drops below a safety threshold. The same workflow has both quantities and is a natural place to do it.
- Use shopify
get-inventory-levelsif you need location-level precision - the top-levelinventory_quantityis the sum across locations.
Common Pitfalls
- Timezone skew - Shopify timestamps are ISO 8601 with offset; WooCommerce may be UTC or store-local depending on config. Normalise both to UTC before comparing.
- Race during a sale - If both stores sell the same SKU between runs, the workflow will pick the lower of the two recent updates and propagate it. That's correct (more conservative), but make sure your team understands the behaviour.
- Variant handling - On Shopify, inventory lives on variants; on WooCommerce, on the product (or its variations). Make sure your Transform step traverses the right level.
- Initial seed - On the very first run the state cache is empty. Either pre-populate it with a one-off snapshot or accept one run where every SKU appears "different" and lands on both sides.
Testing
Manually set the quantity for a single test SKU on Shopify to a value you'll recognise. Run the workflow once and verify only that SKU appears in toWoo, and that WooCommerce updates to match. Repeat in the other direction. Then enable the schedule.