Skip to content

Shopify sync

Work orders touch Shopify at three moments: when a build run picks materials, when a build run completes (and produces output), and when the work order itself is marked complete (which can write a per-order metafield). Each of these is independent and idempotent — you can retry without double-counting.

  • Pick-time inventory push
  • Residual roundingResidual RoundingHow Assemblified handles fractional pick quantities when pushing to Shopify, which only supports whole-number inventory. The integer part is sent to Shopify; the leftover decimal is kept in a local "residual" balance and consumed by future picks before another whole unit gets pushed. Read more → for fractional picks
  • Compensation on cancel and reverse
  • Completion-time output sync
  • The retry banner
  • The completion overlay (per-order metafield)
  • Tagging linked orders

When a build run picks Shopify-mapped raw materials, Assemblified pushes a Shopify inventory adjustment to decrement each material at its location. Pre-assembled inventory and virtual materials are not part of this push — they live entirely on Assemblified’s side.

The push happens at pick time, not at completion. The reasoning: once you’ve physically pulled the material off the shelf, Shopify’s count is wrong until you reconcile, even if you haven’t built the units yet.

The push is bundled by (run, location) so a multi-material pick from one location goes out as one call, not many.

Shopify only accepts whole-number deltas. Work order plans frequently have fractional picks — half a metre of fabric, 1.5 cans of paint per unit, a sub-assembly that draws 0.75 of a parent component.

To prevent long-term drift, Assemblified does this:

  1. The fractional delta gets rounded to the nearest integer.
  2. The integer goes to Shopify.
  3. The leftover decimal is parked in a local residual inventory balance.
  4. On the next pick that touches the same material at the same location, the residual is added back into the next delta. Eventually the residual reaches another whole unit and gets pushed.

The total quantity sent to Shopify across all picks of one material always equals the total fractional need, rounded. Local-vs-Shopify never drifts further than one whole unit.

Cancelling or reversing a build run reverses the Shopify push:

  • Cancel (on a picking run) — increments back the materials the pick decremented.
  • Reverse (on a built run) — same, plus the completion-time push gets reversed too.

These compensating mutations run automatically as part of the cancel and reverse actions. Status columns on the build run record whether each compensation succeeded so a retry can pick up where things left off.

If the original pick was skipped (for MATERIAL_LIST_ONLY work orders, virtual-only materials, or because Shopify wasn’t reachable), there’s nothing to compensate, and the compensation is a no-op.

When a build run completes (or, in Build & QC mode, when QC approves the output), Assemblified forwards the produced output to Shopify through the same dynamic-adjustment cascade that order-driven BOM execution uses. This:

  • Pushes the produced quantity onto the BOM’s finished-good variant if the BOM has dynamic-adjustment enabled.
  • Updates onlySellPreassembled BOMs to match the new pre-assembled stock.
  • Cascades to any parent BOM that depends on the completed sub-assembly.

The completion sync runs independently of the pick-time push. It uses its own status column and can be retried independently if it fails.

If any sync (pick, compensation, or completion) fails, the work order detail page shows a Shopify sync failure banner with a Retry button. Click it and Assemblified replays whichever pushes failed, in the right order:

  • A previously-succeeded push is skipped.
  • A previously-failed push is replayed.
  • A push that’s never been attempted (because the prior one failed first) runs for the first time.

The retry is idempotent — replaying a successful push does nothing.

If the retry also fails, the banner sticks around with the latest error message. The most common cause of repeated failures is an expired Shopify session — re-installing the app from the Shopify admin refreshes the session and lets the next retry succeed.

The completion overlay (per-order metafield)

Section titled “The completion overlay (per-order metafield)”

When a work order is created from one or more Shopify orders, completing it triggers a side-effect called the completion overlay. For each linked order, Assemblified writes a material_requirements_json metafield onto the order with:

  • The materials the BOM(s) for the order’s variants required.
  • Any per-work-order operator notes (lot numbers, specifications, free-text from the metafields tab).

This is metadata for downstream fulfillment workflows — pickers and shippers can read the metafield to see what materials went into the order. It’s controlled by a shop setting (defaults to enabled). If you don’t link a work order to any Shopify orders, the overlay is a no-op.

The overlay is fire-and-forget — its errors are logged but don’t affect the work order’s status. If you need to retry it, the only path is to uncomplete and re-complete the work order.

The action menu’s Tag orders dialog applies (or removes) Shopify tags on every order linked to the work order. Operators commonly use it to mark orders as “ready to ship” or “in production” once the work order’s status changes.

The dialog shows the current tags on each linked order side-by-side, so you can see the existing state before applying changes. The mutation is the standard Shopify tagsAdd / tagsRemove — no per-order metadata is written here, just tags.

Tagging is allowed on cancelled and completed work orders too — the tags are meta-information that doesn’t affect the work-order state.

Reduction typePick pushCompensationCompletion pushCompletion overlay
PRE_ASSEMBLYYesYesYesYes
VIRTUAL_ASSEMBLYYes (raw only)YesNo (no output to push)Yes
MATERIAL_LIST_ONLYNo (skipped)No (no-op)NoNo

For Material-List-Only work orders, Assemblified writes everything to its own audit ledger but doesn’t touch Shopify inventory at all. Use this mode for “shopping list” work orders where you’re tracking what was pulled but not actually changing inventory levels.