What is a webhook?
Webhooks are a useful tool for apps that want to execute code after a specific event happens on a shop, for example, after a customer creates a cart on the storefront, or a merchant creates a new product in their admin.
Instead of telling your app to make an API call every X number of minutes to check if a specific event has occured on a shop, you can register webhooks, which send an HTTP POST request from the shop telling your app that the event has occurred. This uses many less API requests overall, allowing you to build more robust apps, and update your app instantly after a webhook is received.
Webhook event data can be stored as JSON or XML, and is commonly used when:
- Placing an order
- Changing a product's price
- Notifying your IM client or your pager when you are offline
- Collecting data for data-warehousing
- Integrating your accounting software
- Filtering the order items and informing various shippers about the order
- Removing customer data from your database when they uninstall your app
Another, less-obvious, case for using webhooks is when you're dealing with data that isn't easily searchable through the Shopify API. For example, re-requesting an entire product catalog or order history would benefit from using webhooks since it requires a lot of API requests and takes a lot of time.
Think of it this way, if you would otherwise have to poll for a substantial amount of data, you should be using webhooks.
Webhooks can be registered for many events. Please check the api reference for a full list.
Configure a webhook
Configure a webhook through the API
The trouble with testing your webhooks through the API is that you need a publicly visible URL to handle them. Unlike client-side redirects, webhooks originate directly from the server. This means that you cannot use the following as an endpoint in your testing environment:
- Any URL ending in the word "internal" (i.e. thisshop.com/internal)
- "Fake" domains like www.example.com
- Shopify domains (i.e. shopify.com and myshopify.com)
RequestBin allows you to create a URL that will collect any requests made to it. You can then inspect your requests and see the values returned. The URL provided is temporary and can only be used for 20 requests or for 48 hours (whichever comes first).
Pagekite makes local websites or SSH servers publicly accessible in mere seconds and works over any internet connection.
ngrok creates a tunnel from the public internet (http://subdomain.ngrok.com) to a port on your local machine. You can give this URL to anyone to allow them to try out a web site you're developing without doing any deployment.
View our Webhook API Reference guide.
Configure a webhook through your store admin
If you are developing an app for a particular shop, you can configure your webhooks through your shop admin:
From your Shopify admin, click Settings, and then click Notifications.
In the Webhooks section, click Create a webhook:
Select the event type you want to listen for from the drop-down box and enter the URL (http:// or https://) where you want to receive notifications.
After you have created at least one webhook, you will be presented with a secret that you can use to validate the integrity of these webhooks:
Shopify lets you test your webhooks to verify that the endpoint is receiving notifications. In the list of order notifications you will see your webhook. You will also see a "send test notification" link. This "send test notification" link allows you to send an example order to the URL you provided.
If you want to capture the contents of a webhook to examine them, the easiest way is to set up a new subscription with a service like LocalTunnel, RequestBin or PostCatcher (described above) which will capture the result and let you view it in a browser.
Receive a webhook
Once you register a webhook URL with Shopify, we will issue a HTTP POST request to the URL specified every time that event occurs. The request's POST parameters will contain XML/JSON data relevant to the event that triggered the request.
Respond to a webhook
Your webhook acknowledges that it received data with a 200 OK response. Any response outside of the 200 range will let Shopify know that you did not receive your webhook. To this end, Shopify has implemented a 5-second timeout period and a retry period for subscriptions. We wait 5 seconds for a response to each request, and if there isn't one or we get an error, we retry the connection to a total of 19 times over the next 48 hours. A webhook will be deleted if there are 19 consecutive failures for the exact same webhook.
You should monitor your admin for failing webhooks. If you're receiving a Shopify webhook, the most important thing to do is respond quickly. There have been several historical occurrences of apps that do some lengthy processing when they receive a webhook that triggers the timeout. This has led to situations where webhooks were removed from functioning apps.
To make sure that apps don't accidentally run over the timeout limit, we now recommend that apps defer processing until after the response has been sent.
Verify a webhook created through the API
Webhooks created through the API by a Shopify App can be verified by calculating a digital signature.
Each Webhook request includes a X-Shopify-Hmac-SHA256 header which is generated using the app's shared secret, along with the data sent in the request.
Webhooks created manually through the Shopify admin will need to be verified with the secret found within the webhooks section of the notifications area.
To verify that the request came from Shopify, compute the HMAC digest according to the following algorithm and compare it to the value in the X-Shopify-Hmac-SHA256 header. If they match, you can be sure that the Webhook was sent from Shopify and the data has not been compromised.
Note that if you are using a Rack based framework such as Ruby on Rails or Sinatra the header you are looking for is HTTP_X_SHOPIFY_HMAC_SHA256
Below is a simple example in Ruby using the Sinatra web framework of how one might verify a webhook request.
And here's a PHP version:
What do I do if everything blows up?
Your hosting center exploded and your app has been offline for more than 48 hours. It's back on its feet now, but you've missed a pile of data that was sent to you in the meantime. Not only that, but Shopify has cancelled your webhooks because you weren't responding for an extended period of time. How do you catch up? Let's tackle the problems in order of importance.
Getting your webhook subscriptions back should be straightforward as your app already has the code that registered them in the first place.One thing you should do is add a quick check that fetches all the existing webhooks and only registers the ones that you need. If you know for sure that they're gone you can just re-run that and you'll be good to go.
Importing the missing data is trickier. The best way to get it back is to build a harness that fetches data from the time period you were down for that feeds it into the webhook processing code one object at a time. The only caveat is that you'll need the processing code to be sufficiently decoupled from the request handlers that you can call it separately.