Synthetic Industry

Troubleshooting guide · updated 2026-10-11

Reconciling a store's orders and stock with another system: a method that finds drift early

Why notification-based syncs miss or repeat events, and a reconciliation routine of two lists and a difference that works on any store platform.

Three ways a sync goes wrong without telling anyone

A store and another system, say a warehouse tool or accounting package, usually stay in step through notifications: the store says an order was placed, a stock level changed, and the other system reacts. The platform documentation for each of the three we cover says that this is not a perfect channel. Shopify says webhook delivery cannot be relied on every time and that events may arrive out of order. BigCommerce warns that duplicates occasionally occur and deactivates a webhook after retries run out. Stripe says events may arrive in a different order from the one they were generated in, and that duplicate deliveries happen. A sync that only listens will eventually be wrong without any error.

The three failure families are different and need different checks. Missed events leave the other system without an order or a stock change. Duplicated or reordered events create two records, or apply an older change after a newer one. Wrong-state writes put a number in that was right when read and wrong when written, such as an absolute stock level that erases a sale.

  • Missed: something exists in the store and not in the other system.
  • Repeated or reordered: something exists twice, or in the wrong state.
  • Overwritten: both exist, but a number is wrong.

The method: two lists and a difference

Reconciliation does not need to be clever. Take the identifiers from both systems for the same window, compare them, and look at what is on one list and not the other. For orders, use the order number or ID and the creation time. For stock, use the product code, the location and the figure for the same state. Do it on a schedule, daily for orders and weekly for a stock sample is a sensible start, and treat any unexplained difference as the finding.

Shopify's guidance for app builders is the same idea: do not treat webhooks as your only data source; run reconciliation jobs that periodically pull data, and use the updated_at filter on queries to fetch what changed since the last run. A reconciliation does not replace the notification path. It catches what the notification path loses.

  • Name the authoritative system for each kind of data before comparing.
  • Compare the same window and the same state of stock on both sides.
  • Record counts as well as lists; a missing export should read as unverified, not as a pass.

Handling repeats and ordering

The receiving side should assume repeats and disorder. Keep a record of the identifier of each delivery, Shopify's delivery header, BigCommerce's hash or Stripe's event ID, and ignore one you have already processed. Do not rely on arrival order. Shopify suggests sorting by its triggered-at header or the payload's updated_at, and BigCommerce and Stripe both lean on fetching the current object from the API when the notification is light or arrives early. The rule that follows: read the current state when you act, rather than trusting what the notification said when it was sent.

Stock needs one extra rule

Stock changes can be missed by design. Shopify states that changes to committed, reserved, damaged, safety stock and quality control quantities do not fire webhooks, so an app that depends on those states has to query for them. And a stock figure is only comparable if both systems mean the same thing by it: available, on hand, or on hand minus committed. Write the mapping down. Where the sync writes numbers, prefer sending changes, or comparing before writing, to overwriting with a total.

Closing a gap once you find one

A gap list is the practical output: every order or product that is on one side only, with its time. Load the missing items into the other system by a route you control, then re-run the comparison and expect zero. Fix the cause before replaying anything, or the same notification path will lose the same events again. BigCommerce's documentation describes retries lasting 48 hours and then deactivation; it does not describe replaying missed events, so compare the order lists and load the gap from the store's own order records.

A safe first check you can do today

You can try the method on one week of data without touching either system. Export the order numbers for the same recent week from the store and from the other system, put them in two columns, and mark every number that appears in only one of them. Then pick three products, write down the stock figure each system holds for the same state, and note any that differ. Nothing in either system is changed, and a gap you find is a lead to explain, not yet a fault.

  • Use the same week and the same time zone on both sides.
  • Count the rows in each export first; an export that stops early looks like a gap.
  • Write down which system you treat as correct before comparing.

What this does not cover, and how it becomes a service

A comparison tells you where the numbers differ, not what the true stock is; a physical count is yours. It also does not change either system. The one-off fixes for a drifting stock sync and a deactivated order webhook use this method, and the standing service runs the comparison every week and explains up to two separate causes of difference a month, with a monthly summary. The correction itself stays the one-off job. You apply every change to your live systems.

How the paid work is accepted

The fixed stock job is accepted on a test store with copies of your sync and of the other system: the agreed products match under the written rule, a repeat run changes nothing, a test sale reduces both once, and a held sync does not overwrite a sale placed in the middle of its run. The fixed order-webhook job is accepted on synthetic notifications to a copy of your receiver, with a list of the orders in the missed window. The standing service is accepted on a planted difference in a copy of the first exports being found, on each weekly result listing every order on one side only and every stock difference above the threshold, on a written explanation for each cause within the monthly allowance of two, and on a monthly summary. It changes nothing in your systems.

Sources and limits

  • Shopify developer documentation: Webhooks Checked 2026-10-11.
    • Webhook delivery is not always guaranteed, and Shopify does not guarantee ordering within a topic.
    • The page points to a header identifying a webhook delivery for ignoring duplicates, and to a triggered-at header or the payload's updated_at field for sorting events.
    • Webhooks should not be the only data source: reconciliation jobs should periodically pull data from Shopify, and many GraphQL queries accept updated_at filters to fetch what changed since the last run.
  • BigCommerce developer documentation: Webhooks overview Checked 2026-10-11.
    • Duplicates may occasionally occur and can be handled with a temporary list of processed hash values.
    • Payloads carry only an ID, so full details are fetched through the API.
    • Retries last a cumulative 48 hours before a webhook is deactivated.
  • Stripe documentation: Receive Stripe events in your webhook endpoint Checked 2026-10-11.
    • Stripe does not guarantee delivery in the order events are generated, and duplicate deliveries should be identified by event ID.
    • Missing objects can be retrieved through the API.
  • Shopify developer documentation: Inventory management apps Checked 2026-10-11.
    • Changes to committed, reserved, damaged, safety stock and quality control quantities do not fire webhooks.