Shopify Webhooks Tutorial: How to Use the Shopify API
Tags: shopify, webhook, tutorial, api
Published: 2021-12-16 19:46:54

---
title: Shopify Webhooks Tutorial: How to Use the Shopify API
published: true
description: In this tutorial, you will learn how to create and manage Shopify webhhooks using the Shopify API
tags: #shopify #webhook #tutorial #api
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oph8ur8ynr3peix0hhmg.gif
canonical_url: https://hookdeck.com/guides/platforms/post/how-create-shopify-webhooks-with-shopify-api-tutorial
---
## Introduction

Shopify webhooks help build integrations with external applications that need to respond in real-time to events taking place in a Shopify store. You can create and manage Shopify webhooks using the Shopify admin dashboard. Although easy to use, the admin interface does not allow developers to perform automated tasks on their webhooks. Instead, users have to log into the admin interface and manually perform webhook-related tasks.

As a solution to this drawback, Shopify opened up its [webhook API](https://shopify.dev/api/admin-rest/2021-10/resources/webhook). This allows programmatic interaction with Shopify webhooks, thereby expanding the scope of what is possible with the technology. 

In this article, I will walk you through how to set up authentication with the Shopify API, and then use the Shopify webhooks API to create and view your webhooks. You will also use a locally running API to receive and log your webhooks.

Let's get right into it!

## Prerequisites

To follow along with this tutorial, you will need a couple of things:

- A Shopify store
- The ability to create [Shopify private apps](https://help.shopify.com/en/manual/apps/private-apps) (you may not have this permission if you're not the direct owner of the store you're working with)
- [Node.js](https://nodejs.org) installed on your system (if you already have a local API that you prefer to use, that is fine as long as you make sure it exposes a `POST` endpoint and listens on a known port)
- [Hookdeck CLI](https://hookdeck.com/cli) installed (you can find details on installing the tool [here](https://hookdeck.com/cli))

## Creating a Shopify store app

The first step to accessing and using the Shopify webhooks API is to create a Shopify store app. There are 3 types of Shopify apps: public, custom, and private. To learn more about the different types of Shopify apps and how to create them, read the documentation pages [here](https://help.shopify.com/en/manual/apps/).

To access the Shopify API, we are going to create a private app. Private apps are built to work exclusively for your Shopify store (unlike public apps that can be used by any Shopify store and are listed on the [Shopify App store](https://apps.shopify.com/)). Private apps also allow you to access your store's data directly using the Shopify API.

To create a Shopify app, click `Apps` on the side menu of the admin interface. Just below the main section on the Apps page, click the `Manage Private Apps` link and then click the `Create private app` button.

On the app creation page, enter the name for the application you are about to create (in this example, `Purchase Log API`) and enter your email. Next, in the `Admin API` section, expand the `Show Inactive Admin API` and give `Read and write` access to the following resources...

- Order editing
- Orders

...as shown below:

![Order permissions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/efe0ac3biahvbaqko81l.png)

Once the permissions are set, scroll down and select the latest API version (at the time of this writing, the latest version is **2021-10**).

Click `Save` to complete this process. You will be prompted with a pre-save message informing you that an API key will be generated to provide access to the store's data.

![Pre-save message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mokflpjkcb7glw7sv2u2.png)

Click `Create app` on this prompt and you will be taken to the app page. On this page, you will find the following credentials in the `Admin API` section:

- **API key** (this is your username when using [Basic authentication](https://shopify.dev/apps/auth/basic-http))
- **Password** (this is your API access token)
- **Example URL** (a sample URL format for performing basic authentication using a username and password)
- **Shared Secret** (used for verifying webhooks, more on this later)

![Admin API masked](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fb2xfgzqx773m542jfaa.png)

With these credentials, you have all you need to authenticate with the Shopify API.

## Authenticating with the Shopify API

Now that you have your authentication credentials, let's discuss how you will go about making authenticated calls to the Shopify API. It is important to note that the different types of Shopify apps do not use the same authentication strategy.

While public and custom apps use [OAuth](https://shopify.dev/apps/auth/oauth) and [session tokens](https://shopify.dev/apps/auth/session-tokens), private apps use [basic authentication](https://shopify.dev/apps/auth/basic-http). In this section, I will only be discussing authentication for private apps.

There are 3 ways you can authenticate with the Shopify API using credentials from your private app.

### 1) Username and password combo

If your client supports basic authentication, you can include authentication credentials in your URL. This is done by prepending `username:password@` to the hostname in the URL as shown below:

```bash
https://{username}:{password}@{shop}.myshopify.com/admin/api/{version}/webhooks.json
```

- `username`: Your API key.
- `password`: Your private app password.
- `shop`: Your Shopify store subdomain string, e.g. `hookdeck-store`.
- `version`: The version of the API you're using, e.g. `2021-10`.

Any request made to the Shopify API using this URL is automatically authenticated.

### 2) Using an authorization token

Some clients do not support basic authentication as used in the above method. You can go around this issue by using the `Basic {token}` value in the `Authorization` header. The `token` value is derived by joining your store app's API key and password with a colon (`:`) and encoding the resulting string in base64. The `Authorization` header can then be sent, as shown below:

```bash
Authorization: Basic NDQ3OGViN2FjMTM4YTEzNjg1MmJhYmQ4NjE5NTZjMTk6M2U1YTZlZGVjNzFlYWIwMzk0MjJjNjQ0NGQwMjY1OWQ=
```

### 3) Using the X-Shopify-Access-Token header

The last strategy for authenticating private apps is to send the `X-Shopify-Access-Token` header, along with your request, to the Shopify API. The value of this header is your private app's password, which is your access token. The header is sent as follows:

```bash
X-Shopify-Access-Token: {my_app_password}
```

This is the strategy we will be using for all our API calls in this tutorial. 

Now that you know how to authenticate with the Shopify API, let's start creating and receiving Shopify webhooks.

## Setting up and receiving Shopify webhooks using the Shopify API

As described earlier, we will create a webhook using the Shopify API. Then, we'll spin up a local API to receive and log part of the webhook payload.

Before we begin, let's walk you through the steps necessary to achieve this webhook logging setup.

- Clone the demo API and run it locally
- Use the [Hookdeck CLI](https://hookdeck.com/cli) to generate a webhook URL that points to the API endpoint
- Create a webhook using the API
- Test your webhook by triggering the subscription event
- Inspect your webhook and webhook logs
- Verify the webhook payload

Now that you're caught up, let's begin.

### Clone the demo API

Clone the application repository for the API by running the following command:

```bash
git clone --single-branch --branch shopify-webhooks https://github.com/hookdeck/nodejs-webhook-server-example.git
```

Navigate to the root of the project and install the required dependencies by running the following commands:

```bash
cd nodejs-webhook-server-example
npm install
```

When the installation completes, you can then run the Node.js server with the following command:

```bash
npm start
```

This will boot up the API application and print a message to the screen indicating that the API is now running and listening for connections on port `1337`.

We are using two endpoints in this project.

- `/log-shopify-webhook`: This is the endpoint that will be receiving the Shopify webhook and logging it into an in-memory database. It logs a simple object containing a subset of the information from the webhook payload.
- `/fetch-webhooks-logs`: This endpoint can be called to retrieve a collection of the logged webhook data.

### Generate the webhook URL using the Hookdeck CLI

The next step is to use the CLI to generate a webhook URL that points to the running API application. To do this, run the following command (note: replace the port `1337` value with the port number on which your API is running if you're not using the sample project):

```bash
hookdeck listen 1337
```

This command starts an interactive session where the CLI collects information about the endpoint you're about to create. Below are the questions and the answers you should supply to each question. Ensure to hit the `Enter` key after each answer. 

- **What source should you select?** Ans: select ***Create new source** (this prompt does not show up if you have not created any previous connections)*
- **What should your new source label be?** Ans: type the text ***Shopify***
- **What path should the webhooks be forwarded to (i.e.: /webhooks)**? Ans: type ***/log-shopify-webhook*** (if you're using your own custom server, replace this value with your endpoint)
- **What's the connection label (i.e.: My API)?** Ans: type ***Purchase Log API***

With this information, the CLI will begin the process of generating the URL and once it's done, you will see the URL printed to the screen and the CLI indicating that it is ready to receive requests.

![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6d45e136-4e04-4300-a3b1-49a817aaf24f/cli-ready.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6d45e136-4e04-4300-a3b1-49a817aaf24f/cli-ready.png)

**Note:** If you're running the CLI in guest mode, you will need to use the guest `Login URL` link in the console to access the dashboard. Copy and paste this into your browser to begin a guest login session.

### Create a Shopify webhook using the API

Now that you have your webhook URL, let's create the webhook. Shopify's webhook API can be accessed at `https://{shop}.myshopify.com/admin/{version}/webhooks.json` (remember to replace the values in `{}` with yours).

To create a webhook, you need to send a `POST` request to this endpoint containing data. You can use any HTTP client of your choice ([Postman](https://www.postman.com/), [Curl](https://curl.se/), etc.). In this tutorial, I am using [ReqBin](https://reqbin.com) because it is accessible and easy to use.

For the webhook you are creating in this tutorial, you must subscribe to the `orders/create`. This event is fired when a new order is created in your store.

The data to send along with your webhook creation request should be structured as follows:

```json
{
	"webhook" : {
			"topic" : "orders/create",
			"address": "{webhook_url}",
			"format": "json"
	}
}
```

As seen in the above snippet, the format to receive the webhook is set as `json`, so remember to replace `{webhook_url}` with the webhook URL generated on the Hookdeck CLI session.

Open [https://reqbin.com](https://reqbin.com) and paste the API URL in the address field, then set the request method to `POST`. For authentication, add the `X-Shopify-Access-Token` field in the `Headers` section as shown below (replace `MY_ACCESS_TOKEN` with your Shopify app password):

![Set access token](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uouo7jdgyxxtlmkfh9x.png)

The header will now be reflected in the details under the `Raw` section. Lastly, click the `Content` section and paste in your request object. See below a screenshot of the request setup:

![Create webhook API request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4a2x66btne15zskajomh.png)

Now hit the `Send` button to create your new webhook. You should get back a successful response, like you can see below:

![Webhook API response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4q3i34db1gkysc1xcm2o.png)

This indicates that you have successfully created a webhook for the `orders/create` topic on your Shopify store.

Other actions that can be performed on your Shopify webhooks using the API include updating a webhook, fetching a single webhook, and deleting an existing webhook. For more information on how to perform these operations, visit the [Shopify webhooks API documentation](https://shopify.dev/api/admin-rest/2021-10/resources/webhook).

### Test your webhook

With a locally running log API set up to receive webhooks, and a webhook subscription created via the API, the time has come to test your setup.

To receive a webhook for the subscribed topic, you need to trigger the topic's event by creating a new order. You can create a new order easily on your Shopify admin interface. Below, I am placing an order for a Ben Simmons 76er's jersey:

![Create new Shopify order](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqt02qyf72irhra8j7tg.png)

Once the order is created, Shopify will trigger a webhook for the `orders/create` event.

This will be received in your Hookdeck CLI session as shown below:

![CLI success](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1uzfgrpxxjhcfwzgdz6.png)

### Inspect your webhook and webhook logs

The Hookdeck CLI helps us easily inspect the details contained in a Shopify webhook by providing a URL to an event page that breaks down the webhook data. This URL is the last item on the webhook entry, as shown in the CLI output above. Copy this URL and load it in your browser, and you will see an event page where you can view details like the webhook headers in the `Headers` section below:

![Event headers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j8epofb0bzqh5vi5rsqp.png)

You also have a browsable representation of the webhook payload in the `Body` section:

![Event body](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6pcttbt3s9b3vpu7d9fg.png)

Finally, let's check to confirm that the locally running API is indeed logging the webhook payload. Still on your browser, navigate to the `/fetch-webhooks-logs` endpoint of the locally running API, and you will see a display similar to the one below (ignore the first object):

![Webhook logs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qvcnzyq85gtv9jaq1qiz.png)

As seen, you have been able to log the webhook ID, the total number of items in your order, and the time the webhook was delivered.

### Verify your Shopify webhooks

Shopify sends you an `X-Shopify-Hmac-Sha256` header that can be used to verify that the payload contained in the webhook is from Shopify and has not been spoofed or tampered with.

This header is an encrypted version of the payload and is computed using the private app's shared secret, the webhook payload, and the [HMAC cryptographic algorithm](https://en.wikipedia.org/wiki/HMAC).

To verify your webhook on your external API, you compute the same encrypted version of the webhook payload using the shared key and HMAC, then compare the result with the value sent in the `X-Shopify-Hmac-Sha256` header. If there is a match, then the payload is valid and it originated from Shopify. If not, then it's suspicious and should be ignored.

You can find this verification logic in the `server.js` file as a commented middleware function `validatePayload`, shown below:

```jsx
const sigHeaderName = 'x-shopify-hmac-sha256';
const sigHashAlg = 'sha256';
const secret = "xx-xx-x";

.....

/* function validatePayload(req, res, next) {
    if(req.method == "POST"){
        if (!req.rawBody) {
            return next('Request body empty')
        }
        const body = req.rawBody;
        const hmacHeader = req.get(sigHeaderName);
        //Create a hash based on the parsed body
        const hash = crypto
            .createHmac(sigHashAlg, secret)
            .update(body, "utf8", "hex")
            .digest("base64");
        // Compare the created hash with the value of the X-Shopify-Hmac-Sha256 Header
        if (hash !== hmacHeader) {
            return next(`Request body digest (${hash}) did not match ${sigHeaderName} (${hmacHeader})`)
        }
    }
    return next()
}
app.use(validatePayload); */

```

For more information on security considerations for your webhooks, check out our [security checklist](https://hookdeck.com/guides/webhooks/webhooks-security-checklist).

## Conclusion

In this article, you have learned and demonstrated how to perform Shopify webhook operations using the webhook API. Being a programmatic interface, the Shopify API allows you to run automated tasks that can, for example, update and fetch webhooks on the fly. You can perform these tasks directly in your code or within CI/CD pipelines to tailor Shopify webhooks towards your application/infrastructure needs.

Happy coding!