StoreFleet Services

Custom apps

Shopify Integrations That Don't Break: A Practical Checklist

Missed webhooks, duplicate orders, rate limits and expiring API versions: why syncs with accounting, warehouses and sheets fail, and the patterns that keep them right.

In this post
  1. The checklist at a glance
  2. 1. Decide which system owns each number
  3. 2. Plan for webhooks that never arrive
  4. 3. Expect the same event twice
  5. 4. Do not trust arrival order
  6. 5. Verify every webhook, then answer fast
  7. 6. Respect rate limits on big syncs
  8. 7. Keep the API version current
  9. 8. Watch platform changes that touch your data
  10. 9. Make failures visible
  11. Test it before it goes live
  12. A year-end exercise
  13. FAQ
  14. Getting help

Orders live in Shopify. Stock counts, books, customer records and pick lists often live somewhere else: an accounting package, a warehouse system, a marketplace, or a spreadsheet the team opens every morning. An integration keeps them in step. When it fails, it usually fails quietly: an order missing from the warehouse, a stock count that drifted until something oversold.

Most failures come from a short list of causes that Shopify documents. Here is what to check, whether you use a ready-made connector or have one built.

The checklist at a glance

# Check What goes wrong without it
1 One owner per field Two systems overwrite each other
2 Reconciliation job Missed webhooks become missing orders
3 Duplicate protection One order picked or charged twice
4 Ordering by event time Old data overwrites new data
5 Verified, fast webhook handler Fake requests accepted, or timeouts and retries
6 Rate-limit and bulk handling Big syncs stall or fail halfway
7 Current API version Behaviour changes without a deploy
8 Watching platform changes Writes that look fine but change nothing
9 Monitoring and alerts Nobody notices until a customer does

1. Decide which system owns each number

A Shopify Community thread from a coffee roaster shows the classic problem: their accounting sync only went one way, products added after setup never synced, and one sale had to deduct green coffee, roasted coffee and packaging.

Before syncing anything, write down which system owns each field. A simple table is enough:

Field Owner Direction
Stock on hand Warehouse system Warehouse → Shopify
Price Shopify Shopify → marketplace
Cost Accounting Accounting → Shopify
Orders Shopify Shopify → warehouse and accounting

Every connection then follows that rule, in one direction per field. When your rules are unusual, such as one sale using several stock items, that is a sign the integration needs to be built around your business rather than configured from a generic one. If the other side is another Shopify store, our guides to inventory across multiple stores and changing stock across stores safely cover the extra traps.

2. Plan for webhooks that never arrive

Most integrations listen for webhooks such as “order created” or “order updated”. Shopify’s webhook best practices are direct about it: webhook delivery isn’t always guaranteed, and your own downtime or handler errors also cause missed events.

The HTTPS delivery docs add the details that matter: Shopify allows one second to connect and five seconds in total, then retries a failed delivery 8 times over the next 4 hours. After 8 consecutive failures, a subscription created through the Admin API is deleted.

The standard pattern is webhooks for speed, reconciliation for correctness: a scheduled job that asks Shopify for everything changed since the last run, using updated_at filters, and fixes whatever the webhooks missed. Run it often enough that a gap is caught before anyone ships the wrong thing, for example every hour for orders.

3. Expect the same event twice

Because Shopify retries deliveries it is not sure were received, the same event can arrive more than once. That is how one order ends up picked twice in a warehouse. Shopify’s guidance is to use the X-Shopify-Webhook-Id header to recognise and ignore duplicates.

The same idea applies to actions your integration sends back. With idempotent requests, repeated requests with the same key run only once. Without that protection, a retry can duplicate an inventory operation or charge a customer twice.

4. Do not trust arrival order

Your integration may receive “order updated” before “order created”. Shopify does not guarantee ordering within a topic, or across topics for the same resource. Sequence events by when they happened, using the X-Shopify-Triggered-At header or the payload’s updated_at, not by when they arrived. If an event is older than the data you already have, skip it. If its parent record is missing, fetch the current state from Shopify.

5. Verify every webhook, then answer fast

Anyone can send a request to your webhook address. Shopify signs each HTTPS delivery with a base64-encoded HMAC in the X-Shopify-Hmac-SHA256 header, made from your app’s client secret and the raw request body. Check that signature before you do anything with the payload, and read the raw body before any parsing changes it.

Then answer quickly. Any response outside the 200 range counts as a failure, and the whole request has five seconds. Shopify’s docs recommend putting incoming payloads on a queue and processing them afterwards, which also absorbs bursts such as a sale launch.

6. Respect rate limits on big syncs

Every app gets a budget of API calls. Shopify uses a leaky bucket: short bursts are fine as long as the average stays under the restore rate, and a full bucket returns a throttle error. On the GraphQL Admin API, the rate depends on the plan: 100 points per second on standard plans, 200 on Advanced and 1,000 on Plus, with a single query capped at 1,000 points.

For large reads, such as a full catalog or a year of orders, bulk operations are the usual answer: Shopify runs the query in the background and returns a file, without the per-query cost limits.

7. Keep the API version current

Shopify releases a new API version every three months and supports each stable version for at least 12 months. When an integration keeps requesting a version that is no longer supported, Shopify answers with the oldest supported version instead. Behaviour can change without anyone deploying anything; the X-Shopify-API-Version response header shows which version was really used. Know which version each integration uses and who updates it before support ends.

8. Watch platform changes that touch your data

Some changes move where data lives. With market-driven shipping, shipping settings move from delivery profiles into Markets. The rollout to merchants started October 1, 2026, and all merchants move by July 1, 2027. On those stores, merchant-owned delivery profile APIs are deprecated: reads may return a stale snapshot and writes can appear to succeed without changing the live settings. If a custom shipping integration reads or writes those profiles, check it now.

9. Make failures visible

A quiet failure is worse than a loud one. Whoever runs the integration should be able to answer three questions at any time:

  • When did it last run successfully? A sync that stopped on Friday should not be discovered on Monday.
  • What did it skip? Every record it could not process should be listed with the reason, not dropped.
  • Do the totals match? A daily count of orders, or of stock units, on both sides catches drift that no single error message shows.

Send these alerts where the team already looks. Our guide to order alerts in Discord and Telegram covers what to send and what to keep out of chat.

Test it before it goes live

Before switching an integration on for real orders:

  1. Run it against a development store or a copy of your data first.
  2. Send the same webhook twice and check that only one record appears.
  3. Stop the receiving side for a few minutes, then check that reconciliation fills the gap.
  4. Run a full sync of your largest table and watch for throttle errors.
  5. Change one record on both sides and confirm the field owner wins.

A year-end exercise

List every job where someone moved data between Shopify and another tool by hand this year. For a plain daily export, a ready-made sheet or automation tool is often enough, and the format matters: our guide to one row per line item exports shows why. When the sheet is the team’s real workflow, with custom columns, several stores or changes written back to Shopify, a small integration built for it fits better.

Each line on that list is a gap between Shopify and a tool you already use. Some can be closed with Flow or an existing app; custom app or off-the-shelf helps you decide which.

FAQ

Why did my Shopify webhook stop firing?

Shopify retries a failed delivery 8 times over 4 hours. After 8 consecutive failures, a subscription created through the Admin API is deleted. Check your handler’s error logs and response times, fix the cause, then recreate the subscription and run a reconciliation for the gap.

How do I stop duplicate orders in my warehouse or accounting system?

Treat every webhook as possibly repeated. Record the X-Shopify-Webhook-Id of each processed event and skip any you have seen. For calls you send to Shopify, use idempotent requests so a retry runs only once.

Is a webhook enough to keep two systems in sync?

No. Shopify does not guarantee delivery, so pair webhooks with a scheduled job that fetches everything changed since the last run and fixes what was missed.

How often do I need to update the API version?

Shopify releases a new version every three months and supports each for at least 12 months. Plan at least one update a year per integration, and check the X-Shopify-API-Version header to see which version you actually get.

Getting help

Our page on custom Shopify integrations describes how we approach integrations and back-office tools, and how to brief a developer lists the questions to ask whoever builds yours.

Bring the list. Talk to us about which tools should connect, and we will reply with how we would approach it.

  1. Create a Shopify Custom App in the Dev Dashboard (2026 Guide)

    Since January 2026, new custom apps come from the Dev Dashboard or Shopify CLI. How to create one, set scopes, get tokens, install it, and keep the app in your hands.

    · 8 min read

  2. How to Maintain a Custom Shopify App: Routine and Handover

    API versions, webhooks, logs, hosting, secrets and platform changes: what keeping a custom Shopify app alive involves, plus a routine and a handover checklist.

    · 9 min read

  3. Market-Driven Shipping: Audit and Update Your Custom App

    Shopify is moving shipping into Markets from October 1, 2026. Why apps that use delivery profiles see stale data or silent no-op writes, and how to fix yours.

    · 8 min read

Want us to look at your store?

Send a few lines about the job and we reply with how we would approach it.

Email us

or write to hello@reply.getstorefleet.com. We reply with how we would approach it.