Now in open beta — close the books in 2 days, not 2 weeks.Read the case study →
E-commerce · March 10, 2026 · 10 min read

Shopify POS inventory sync: the architecture

Selling the same SKU in a physical store and on Shopify needs a single source of truth for stock. Get this wrong and you oversell on Shopify or face empty shelves at the till. The architecture that works treats one system as canonical and pushes deltas reliably to the other.

Why a single source of truth matters.

Two-way sync between two systems is the classic distributed-data problem: when both sides accept writes, you eventually get conflicts. A pair of customers buy the last unit, one in-store and one on Shopify, in the same minute. Without a master, both transactions succeed and you owe goods you do not have.

The fix is a single canonical inventory ledger that both systems read from and write to. Stock levels live there. Sales decrement there. Receipts and transfers credit there. Shopify and POS become projection layers on top of the canonical ledger, not authorities. Nonari is built around this model: the BranchInventory ledger is canonical, Shopify and POS are subscribers.

Branch as the unit of stock.

Stock is per branch, not per organization. A SKU has 40 units at the Austin warehouse, 12 at Brooklyn retail, 8 at Manchester retail, 0 at the EU drop-ship branch. Each Shopify storefront connects to a branch and reads/writes that branch’s stock. Each physical store is also a branch.

When a Shopify order ships from the Austin warehouse, the decrement happens on the Austin branch ledger. The other branches’ stock is unchanged. When a customer buys at Brooklyn POS, only the Brooklyn branch decrements. The Shopify storefront connected to Brooklyn (if any) sees the new stock count immediately.

Canonical ledgerBranchInventory in NonariBranch A (Austin)40 units, push outShopify .comSubscriber, not sourceBranch B (Brooklyn)12 units, push outPOS terminalSubscriber, not source
One canonical ledger upstream, multiple subscribers downstream. Conflicts vanish when only one side accepts writes.

Outbound stock sync to Shopify.

When stock changes in Nonari (POS sale, transfer in, receipt, write-off), Nonari pushes the new stock level to Shopify for the connected branch. The push is debounced (no need to push every microsecond) but bounded (no more than a few minutes of staleness). On a high-velocity SKU, the push is more frequent; on a slow-moving one, less.

The push is idempotent: pushing the same level twice is safe. The push is acknowledged: Shopify confirms the new level, Nonari logs the confirmation. If Shopify is unreachable, the push retries with backoff. If a stock level is rejected (Shopify thinks the level is different), Nonari reconciles to determine truth and resolves.

  • Trigger: any inventory mutation on the connected branch
  • Debounce: cluster mutations within a short window
  • Idempotent: same level pushed twice is safe
  • Reconcile on conflict: canonical ledger wins

Inbound order events from Shopify.

When a Shopify order is created on the connected storefront, Nonari decrements the source-branch stock based on the configured location. For multi-location Shopify stores, the source location maps to a specific Nonari branch. The decrement happens before the order is fulfilled, so the canonical ledger reflects committed stock immediately.

For COD orders, the decrement is provisional until courier delivery; on RTO, the stock is restored. For prepaid orders, the decrement is firm at order, reversed only on refund. The bookkeeping flows from the same events but the inventory side is more aggressive: stock is gone the moment the order is committed, regardless of payment status.

Multi-location Shopify and the mapping problem.

Shopify supports multiple locations per store. If you have a Shopify store with three locations (Austin warehouse, Brooklyn retail, Manchester retail) all selling on the same storefront, the order specifies a fulfillment location. Nonari maps each Shopify location to a Nonari branch.

Mapping must be 1:1 to avoid ambiguity. If you have two Nonari branches mapped to one Shopify location, fulfillment events are non-deterministic. The setup wizard in Nonari enforces the 1:1 mapping at configuration time. Re-mapping is a controlled operation with stock reconciliation as a side effect.

Transfer events.

Inter-branch transfers are common: 20 units move from the Austin warehouse to Brooklyn retail to restock. The Shopify storefront on Brooklyn sees stock go up. The Shopify storefront on Austin (if any) sees stock go down. Both pushes happen from the same transfer event.

Transfers are SOURCE_FIFO costed in Nonari: units leave the source branch at FIFO cost and arrive at the destination branch at the same cost (plus any inter-branch freight if you allocate it). The Shopify cost field for the destination location updates to reflect the destination WAC after the transfer lands. Without this, your destination branch COGS will use a stale cost field.

Reconciliation runs.

Periodic reconciliation compares Shopify stock to the Nonari canonical ledger. Drift indicates a missed event (push failed, webhook dropped, manual edit in Shopify admin) or a configuration error (location mapping). Drift surfaces as an exception you can drill into, not a silent inventory loss.

The reconciliation runs nightly per branch by default, with on-demand triggers. The output is a delta report: SKU, expected level, actual Shopify level, branch, last-known-correct-time. Most drifts are explainable (a recent edit, a delayed webhook); the unexplainable ones are usually the real bugs and worth investigating.

Where Nonari fits.

Nonari is the canonical inventory ledger by design. Each branch (online or physical) has its own BranchInventory record with quantity and WAC. Shopify connections per online branch push and pull stock. POS at physical branches uses the same ledger. Transfers move stock with SOURCE_FIFO costing. Reconciliation runs continuously.

For a multi-branch retailer running an Austin warehouse plus Brooklyn retail plus Manchester retail plus an EU online storefront, the inventory architecture is a single ledger with four branches and one Shopify connection. Stock decisions, COGS, and reorder points all flow from the same data. The architecture scales to ten branches and three storefronts without changing.

Frequently asked

Common questions.

Why not have Shopify be the source of truth?

Shopify is great for one storefront. For multi-storefront, multi-location, multi-branch retailers, no single Shopify store covers everything. The canonical layer must be above Shopify.

How fast is the stock sync?

Sub-minute on high-velocity SKUs, debounced for low-velocity. The push is idempotent and acknowledged.

What happens when Shopify and Nonari disagree?

Nonari wins by design as the canonical ledger. Drift surfaces as an exception with a delta report so the merchant can investigate the cause.

Do transfers update Shopify automatically?

Yes. A transfer event triggers stock pushes on both the source and destination branch’s Shopify connections, and updates cost fields to reflect destination WAC.

Can I run Shopify and physical POS together?

Yes. Both connect to the same canonical ledger as branches. Stock, COGS, and reporting flow from one place.

Try nonari

Put your books on autopilot.

Free to start. No credit card. Bring your books, kick the tires, export everything if you decide to leave.