product update web-hook firing on each sale/order

Solved

product update web-hook firing on each sale/order

Rafay
Tourist
6 0 0
I have registered to Shopify's product web-hook using topic product/update. I am observing a completely different behavior, when ever a product is sold that fire product/update web-hook.
 

Has anyone else experienced same issue? or i am doing something wrong?

 

Any help in this regard is appreciated.

Accepted Solution (1)

Josh
Shopify Staff
1134 84 235

This is an accepted solution.

Hey there, 

 

I believe it was within the last year that we started to send webhooks when a product is sold, and this behaviour is intentional. If memory serves, it's the inventory of the product being touched that triggers the webhook. 

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

View solution in original post

Replies 8 (8)

Josh
Shopify Staff
1134 84 235

This is an accepted solution.

Hey there, 

 

I believe it was within the last year that we started to send webhooks when a product is sold, and this behaviour is intentional. If memory serves, it's the inventory of the product being touched that triggers the webhook. 

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

JoshHighland
Shopify Partner
213 12 76

This is an old thread but its still relevant . Has there been any talk internally around a webhook that fires when a product is updated via the admin and not a sale?

something like - product/update_admin

There is a very big difference between and admin adjusting the body / title / images etc., compared to a sale happening.

SEO Manager - The all-in-One SEO solution for Shopify
A powerful suite of SEO tools that gets you found in Google results

- Install SEO Manager -
Robel
Visitor
2 0 2

I have the same issue 

MozzoERP
Shopify Partner
84 4 20

Ditto. QuickBooks does this same thing and its annoying and causes a lot of unnecessary overhead. I get Inventory Levels have changed, but that should be a separate webhook just as it is a separate object in the Shopify database.

Chad Richardson
Mozzo Software - Modular Software that grows with you from solopreneur to a 200 person mega team. Why keep outgrowing your Shopify Apps? Start with us, and just use the modules you need, then add more as you grow. http://MozzoERP.com
axelra82
Visitor
2 0 5

Is there any fix for this behavior? It really doesn't make any sense. If you want a product hook to fire on product inventory change (which will be every time a product is soled, which hopefully is very often) why not put this is in a specific product_stock_change or something similar?

As it works now the webhooks are unusable. I've set up a SSG fore storefront in Netlify... problem is, every time someone makes a purchase the site rebuilds, eating away att build hours when nothing except stock has changed (which is checked individually anyway).

So I ask again, is there any workaround on this or do we just have to wait until someone on the dev team understands that firing the product update/change hook every time a sale is made probably isn't how most people are expecting it to work and also is easily fixable by simple adding a product stock specific hook for those that want/need that type of behavior.

daniellanger
Shopify Partner
10 0 13

+1 to @axelra82's request

Eaton
Shopify Partner
13 0 22

I agree. We already have an inventory hook which is suitable for this. 

Product creation/update/delete hooks are clearly meant for the changes by the admin. If any customer can trigger this update hook then what is even the point of it? It's absolutely unusable.

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)
}