
- Pick one system as the owner of stock levels and send stock movements, not just final numbers, from everywhere else.
- Every sellable item and variant needs one unique SKU shared by the POS and the online store.
- Webhooks give fast updates, but Shopify does not guarantee their order or delivery, so add scheduled reconciliation jobs.
- Respect API rate limits with batching and back-off, and log every sync so differences can be traced to a single event.
How do you connect a POS to Shopify or WooCommerce without stock errors?
Make one system the owner of stock levels, give every item and variant one shared SKU, send stock movements as events through webhooks, and run scheduled reconciliation that compares and corrects stock across both systems. Most stock errors come from two systems both believing they are in charge, from duplicate or missing SKUs, and from relying on real-time updates that occasionally fail. A sync designed around those three problems keeps the shop and the website honest.
This is how we approach it when we build or extend a POS that has to share inventory with an online store.
Which system should be the source of truth?
Pick one owner for each kind of data and write it down:
- Stock levels: the POS, the online store, or a separate inventory or ERP system. Only the owner holds the official number.
- Products and prices: often the online store or a product system, with the POS receiving updates.
- Orders: each channel creates its own, and both report the stock they consumed.
Everything that is not the owner sends movements ("sold 2", "received 10", "returned 1") rather than overwriting the stock figure. Movements can be combined safely; two systems overwriting each other's totals cannot.
Why are SKUs the foundation?
The integration matches items by SKU, so every sellable item and every variant needs one unique SKU used in both systems. Before building anything, export both catalogs and look for missing SKUs, duplicates, variants that exist in one system only, and bundles or kits that contain several stock items. Fixing the catalog first prevents most of the errors people later blame on the integration.
Webhooks or polling: how should updates travel?
Webhooks push a message when something changes, so stock can update within moments. Use them, but do not rely on them alone:
- Shopify does not guarantee the order of webhooks within a topic, so an update can arrive before a create. Its documentation recommends ignoring duplicate deliveries using the
X-Shopify-Webhook-Idheader, ordering events by the triggered time orupdated_at, and running reconciliation jobs because webhook delivery is not always guaranteed (Shopify: webhooks). - WooCommerce can send webhooks for orders, products, customers and coupons, signs each delivery with a secret, and disables a webhook after more than five consecutive delivery failures (WooCommerce: webhooks). Monitor webhook status, or a quiet failure can stop stock updates entirely.
Polling the API on a schedule is slower but simpler and more predictable. Most robust integrations use both: webhooks for speed and scheduled jobs for completeness.
How do you deal with API rate limits?
Shopify's APIs use a leaky bucket: each request fills the bucket, it drains at a fixed rate, and when it is full you get a throttle error. Shopify recommends backing off for one second before retrying (Shopify: API limits). The exact limits depend on the API and the plan. In practice:
- Batch updates instead of sending one request per item where the API allows it.
- Queue changes and process them at a steady pace, rather than in bursts after a big delivery.
- Retry throttled requests with a back-off, and alert someone when a queue keeps growing.
What does a reconciliation job do?
A reconciliation job compares stock for every SKU between the owner and the other systems on a schedule, often nightly and after any outage. It then:
- Corrects small differences automatically, in favour of the system that owns stock.
- Flags larger differences for a person to check, because they often reveal a process problem such as unrecorded returns.
- Produces a short report: items checked, items corrected, items flagged.
Combined with a log of every stock movement and which system sent it, the report lets you trace any wrong number back to a single event.
How do multiple locations change the design?
With several shops or a warehouse, stock has to be tracked per location in both systems, and you need rules for which location fulfils online orders. Decide whether online stock is the sum of all locations or only a warehouse, and how transfers between locations are recorded. A safety buffer on fast-selling items helps when the same unit can be sold in a shop and online at the same moment.
How should you test and go live?
- Clean the catalog and agree SKUs.
- Run the sync in read-only mode first, reporting differences without changing anything.
- Fix the differences it finds, then switch on writes for one location or one product range.
- Watch the reconciliation report daily for the first weeks, then weekly.
Our Shopify development and ecommerce development teams build these integrations for Shopify and WooCommerce stores. For the bigger build-or-buy decision, see our guide to custom POS systems.
Frequently asked questions
Should the POS or the online store own inventory?
Choose the system where most stock changes happen and where staff manage stock day to day. Shops with one location and a busy counter often let the POS own stock; brands that sell mostly online often let Shopify or WooCommerce own it. A separate inventory or ERP system can own it when you have warehouses or several channels.
How fast should stock sync between POS and website?
Near real time for sales, so an item sold in the shop disappears online within moments, using webhooks or events. Product details and prices can sync less often. A full reconciliation should still run on a schedule, for example nightly, to catch anything a real-time update missed.
Can I keep a safety buffer to avoid overselling online?
Yes, and it is common for fast-moving items. The integration publishes slightly less stock online than the POS holds, for example holding back the last one or two units, so a sale in the shop and an online order at the same moment do not oversell. It is a business rule worth deciding per product range.
What happens if the integration is down for a while?
Each side keeps selling, and differences build up. When the integration recovers, it should replay the queued events and then run a reconciliation that compares stock for every SKU, fixing small gaps automatically and flagging large ones for a person. That is why logging and a reconciliation report matter from day one.
Last updated