-->
Syncing Shopify Orders Back to Inventory to Prevent Oversell
When you run a reverse-Taobao style storefront that pushes products to Shopify, the hard problem is not "how to list" — it is "how to keep stock honest across channels." Sell the same SKU on your own site and on Shopify, and a customer on one side can buy the last unit while the other side still shows it in stock. Oversell follows, then a manual apology, then a refund.
Taocarts is a reverse-cross-border system that lets sellers list Chinese marketplace goods (Taobao, 1688, and others) onto storefronts like Shopify, Coupang, Woo, and Base, then syncs orders back for consolidated purchasing. The Shopify leg of that flow taught us a few things about inventory write-back.
The naive approach fails fast
The obvious design is: Shopify order comes in → decrement a local counter → done. It breaks the moment two orders land within the same second, or when the webhook arrives twice (Shopify does redeliver). You end up with a counter that drifts below zero or disagrees with reality.
Treat stock as an event log, not a counter
We model inventory as append-only events: RESERVED, SOLD, RESTOCKED, ADJUSTED. The "available" number is a derived sum, never a field you decrement in place. A Shopify order appends a RESERVED event keyed by (shopify_order_id, line_item_id). A duplicate webhook produces the same key, and a unique constraint drops the second write silently. No double reservation.
Write back only after the source confirms
We do not decrement on "order created." We reserve on creation, then move to SOLD only when the source marketplace confirms the purchase actually went through (1688/taobao confirmations are async). This two-phase step avoids the classic bug where an abandoned cart or a failed procurement leaves stock locked forever.
Reconcile, don't trust
Once a day we pull Shopify's inventory API and diff it against our derived available count. Any mismatch opens a reconciliation ticket instead of auto-correcting — auto-correcting hides the bug that caused the drift. Over a month this surfaced three real issues: a webhook we were not subscribed to, a batch job that double-counted restocks, and a timezone bug in our nightly job.
The lesson: cross-channel inventory is a consistency problem, not a counter problem. Model it as events, make every external write idempotent by key, and reconcile on a schedule. Do that and oversell stops being something you explain to customers and starts being something your dashboards catch first.