Will products/update webhook always fire when an inventory level is updated?

ClementBR
Shopify Partner
153 2 44

Will products/update webhook always fire when an inventory level is updated?

 

In other words, if the 'available' quantity is changed, is it guaranteed that the underlying variant's product webhook will fire (so that we can use the variant.inventory_quantity in the webhook?)

 

I did a quick test and it seems that the products/update does fire but I also wanted to ask if that is always the case?

 

Thank you!

Replies 19 (19)

Josh
Shopify Staff
1134 84 233

Hey @ClementBR , 

 

I actually hadn't thought that the webhook fired when an order was placed that decremented an inventory count, but looks like it does - same with updating in the admin and making an API call to change the inventory level. Looks like it does in fact always fire! 

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

ClementBR
Shopify Partner
153 2 44

Oh really ?!

It definitely didn't use to fire the product webhook when an order was placed.

But maybe that changed when multi-inventory was released.

 

I hate to be a pain, but is there some sort of more official answer that the product webhook will indeed fire whenever the variant's quantity changed, directly or indirectly because of an order or inventory level update?

 

It is critical for us to keep the variant inventory in sync. Historically we have queried back the API whenever a order webhook or inventory level webhook fires, just to be safe.

It works, but the downside is that we end up making  A LOT of API calls. Basically any time we get  a order/inventory_level webhook we have to query back into the API. 

Josh
Shopify Staff
1134 84 233

I was as surprised as you were! I knew that inventory_levels/update webhooks fired, but I know that for the longest time products/update webhooks didn't. 

 

You're not being a pain at all - I'll do some digging to make sure products/update is safe to use for this purpose and I'll get back in touch ASAP. 

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

ClementBR
Shopify Partner
153 2 44

Thanks Josh, I really appreciate it.

It would be fantastic to know whether it is safe or not.

Josh
Shopify Staff
1134 84 233

Hey @ClementBR , 

 

So official answer - there aren't any plans to change this behaviour right now, so for the time being it is safe to use. But at the same time, products and inventory may become more distinct concerns in the future, at which point it wouldn't make sense to fire products/update webhooks. So if you're already working with inventory_levels/update, in terms of future-proofing it may be easier to just stay the course instead of having to switch back at some point in time. 

 

With that being said, nothing in guaranteed here at the moment and you could likely switch to using products/update for a long time without any issue, possibly even forever. There's nothing on the roadmap right now indicating there's a change coming here. 

 

There's just no way to guarantee how safe it'll be, or for how long - so unless you want to have to potentially switch back again at some point it's likely easiest to just continue as-is. 

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

ClementBR
Shopify Partner
153 2 44

Hi Josh,

 

Thanks for looking into it.

 

I will take action accordingly!

mattrosno
Shopify Partner
1 0 3

Any update here? For headless sites that only interact with Shopify's API, you want that "product updated" webhook to trigger new site builds. But you wouldn't want to re-build/deploy your site every time there is an order (decrementing inventory). So for now, I'm unable to use Shopify product webhooks and we have to manually trigger builds after updating products.

Is there an ETA on either providing a new product updated webhook that excludes inventory changes, or a new version of the current webhook that omits inventory changes?

Thanks,

- Matt

C1
Tourist
5 0 3

This is also a problem for me. Our site is pre-rendering Shopify content and every time someone makes a purchase it is re-building in Netlify costing a lot of build minutes.

Thanks!

fernandorojo
Tourist
5 0 4

Same problem for me. Our website is getting rebuilt every time someone places an order. This is super inefficient and expensive for hundred+ orders/day, none of which should trigger rebuilding the site...

EugeneKim
Shopify Partner
60 3 27

If you store a snapshot of the product information aren't you able to determine whether or not it was actual product properties that changed vs some inventory info and then rebuild the site only in the case of the former?

C1
Tourist
5 0 3

In my case it needs to be triggered by a webhook as clients will be making changes in Shopify. I don’t want to have to manually rebuild every time a change is made.

EugeneKim
Shopify Partner
60 3 27

I wasn't suggesting continuous manual updates.

It sounds as if you're rebuilding your website based off of the `products/update` webhook and you only want to rebuild after a "primary" property of the actual product variant is updated rather than an associated property such as `inventory_quantity`. I'm suggesting that each time you receive a `products/update` webhook you do a diff on the properties you care about against the contents of the `products/update` body and only rebuild if a property that warrants a rebuilt updates. If something like `inventory_quantity` is changed, you merely skip the build.

I'm not familiar with the use case for forgive me if I'm missing something obvious

C1
Tourist
5 0 3

Hey euge,

I see, yes I think that is the only way unfortunately. I was hoping there was a simpler solution, I think there should be as pre-rendering is pretty common now, so it would be good to have a simple solution for triggering new builds.

 

I have created a serverless function that stores the data in a database and then diffs any new changes and ignores it if only quantity field changes. The product diff needs to be checked, and then each variant needs to be looped over and checked also.

Again, I hope there will be a better solution in future.

Robel
Visitor
2 0 2

Hey @EugeneKim 

Hey @C1 which are the fields that you skip in order to do the diff ? I have found `inventory_quantity`, and `updated_at`, but I think I'm still missing something

Rijk
Shopify Partner
3 0 0

I was also very annoyed by this, obviously we don't want to rebuild our static pages on every sale but there is also no other way to be notified of actual product changes (title, image, description, price, etc), than using this webhook.

 

Thankfully, at least the webhook posts some details of the product. So I managed to work around this by generating a checksum of that details, after removing the parts I'm not interested in: inventory_quantity, old_inventory_quantity and updated_at (which obviously changes with inventory updates as well). I then store that in a simple Redis store keyed by GID, and prevent revalidation if it is unchanged.

 

For reference, here is the implementation for Next.js using Vercel KV:

 

 

import { kv } from '@vercel/kv'
import { revalidate } from 'lib/shopify'
import { NextRequest, NextResponse } from 'next/server'

export const runtime = 'edge'

function ignoreInventoryChanges(item: any) {
  const { updated_at, variants, ...rest } = item
  return {
    ...rest,
    variants: variants?.map((v: any) => {
      const { updated_at, inventory_quantity, old_inventory_quantity, ...variant } = v
      return variant
    }),
  }
}

async function createHash(json: any) {
  const text = new TextEncoder().encode(JSON.stringify(json))
  const digest = await crypto.subtle.digest('SHA-256', text)
  return arrayBufferToBase64(digest)
}

function arrayBufferToBase64(buffer: ArrayBuffer) {
  var binary = ''
  var bytes = new Uint8Array(buffer)
  var len = bytes.byteLength
  for (var i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i]!)
  }
  return btoa(binary)
}

export async function POST(req: NextRequest): Promise<NextResponse> {
  const body = await req.json()

  const hash = await createHash(ignoreInventoryChanges(body))
  const previous = await kv.get<string>(body.admin_graphql_api_id)

  if (previous === hash) {
    return NextResponse.json({ status: 200, revalidated: false, now: Date.now() })
  }

  await kv.set(body.admin_graphql_api_id, hash)
  return revalidate(req)
}

 

 
cYberSport91
Tourist
8 0 2

Any update on this?  Or maybe even a suggested workaround?

Right now my Netlify is burning a hole through the credit card completely rebuilding the site after every sale.

Would be awesome to get a separate webhook but i'm not holding my breath on that.  But if there's a proxy workaround for an attribute to check for that would be great too.  I really don't want to set up a db just to compare between deploys 

axelra82
Visitor
2 0 5

I have to chime in with a +1 here for everyone else commenting on this with the exact same issue... https://community.shopify.com/c/Shopify-APIs-SDKs/product-update-web-hook-firing-on-each-sale-order/...

I had to either turn off auto deploy in Netlify or remove Shopify webhooks (for me it was the latter)... so in other words, having the product webhook fire on every purchase is not very usable and counter intuitive to the nature of SSGs.

It would be great if Shopify didn't become one of those "big companies that stops listening to the needs of clients" and then we all have to switch in 5 years because upper management don't understand the constant change that is a part of the internet. Please understand that the future of internet IS statically generated content, for a slew of reasons. You can see new headless/decoupled services popping up every other week now! So I'm asking, please be a part of that Internet, not the one that slowly fades away with all the monolithic Wordpress sites.

It's so tiresome having to switch SaaS every three years because big companies can't shift with the times. I get the feeling everyone is a little bit to "comfy" and don't really feel like there's any real incentive to actually listen and do anything.

Just looking at this thread, it's closing up to two years of age, and the last comment seems to be almost six months+ old. It really isn't that hard to separate the product webhook from firing on stock change and move that to a separate hook. I'm not saying it would take "5 minutes", but it's a question of separating existing logic, not building something from scratch.

hamd64
Visitor
1 0 2

It's still(even after 2 years of this thread started) an issue and I also didn't find any workaround to this. It really seems like Shopify don't want to separate these 2 hooks (product update and inventory update). A simple solution for them would be to just add an extra header field that defines the reason the product update hook is being fired. (i.e fired because of admin made a change, order place, some other did it etc ). This doesn't seem to be difficult to implement and they don't have to separate the webhooks ( for whatever reason they might have ).

cYberSport91
Tourist
8 0 2

Great idea with the header.  Yeah I think they've made their stance clear - which is weird because they're talking more and more about Headless.  how the hell do you run a headless shop like this?

I'm running a caching server in between that's diffing the changes.  Which I never trust.

see y'all in web3 i'm done with this