--- title: Subscribe to a webhook topic description: Learn how to set up and configure a webhook subscription using the app configuration file and GCP PubSub. source_url: html: https://shopify.dev/docs/apps/build/webhooks/subscribe/get-started?deliveryMethod=https md: https://shopify.dev/docs/apps/build/webhooks/subscribe/get-started.md?deliveryMethod=https --- # Subscribe to a webhook topic Subscribe your app to Shopify webhook topics so that it will be alerted when an event occurs on a merchant store. Suppose you are building a warranty pricing app that determines which warranty options a customer can add to their cart, based on the cost of an order. When a customer is checking out, the total order cost is used to determine which warranty options a customer can select from. In this tutorial, you'll subscribe your app to a webhook topic to be alerted whenever a new order is created. ## What you'll learn In this tutorial, you'll learn how to do the following tasks: * Use your [app configuration file](https://shopify.dev/docs/apps/tools/cli/configuration#webhooks) to set up a webhook subscription. * Use cloud-based delivery methods like [Google Cloud's Pub/Sub event bus](https://cloud.google.com/pubsub) to receive webhooks. * Test your subscription is configured correctly and you are receiving webhooks. Info Shopify recommends using [Google Pub/Sub](https://cloud.google.com/pubsub) as a cloud-based solution for delivering webhooks. You can also use [Amazon EventBridge](https://aws.amazon.com/eventbridge/). In instances where you want to hand-roll your own webhooks infrastructure, you may prefer your webhooks be delivered through [HTTPS](https://shopify.dev/docs/apps/webhooks/configuration/https). During development, you may choose to use your app's URL or external mock server sites like [webhook.site](https://webhook.site/) and [Beeceptor](https://beeceptor.com/). These are not recommended for production. ## Requirements [Use the latest version of Shopify CLI](https://shopify.dev/docs/api/shopify-cli) Ensure you have the [latest version of Shopify CLI](https://shopify.dev/docs/api/shopify-cli#upgrade) installed to configure app-specific webhook subscriptions. [Scaffold an app](https://shopify.dev/docs/apps/build/scaffold-app) Scaffold an app that uses the [React Router template](https://github.com/Shopify/shopify-app-template-react-router). [Development tools](https://shopify.dev/docs/apps/build/webhooks/subscribe/get-started) For development, you can use mock servers like [Hookdeck Console](https://console.hookdeck.com/) or [webhook.site](https://webhook.site/) can be used for development. [Make your server production ready](https://shopify.dev/docs/apps/build/webhooks/subscribe/https) Ensure that you have `Keep-Alive` enabled. You should also consider implementing a reconciliation job, and consider queuing your webhooks. ## Project HTTPS [View on GitHub](https://github.com/Shopify/shopify-app-template-react-router/blob/webhooks-subscribe-example-https) ## Configure your webhook subscription ### Update your access scopes Some webhook topics require scopes in order to be used. Since we want to know about when a product has been updated, we need to include the `read_products` scope in the configuration file. * To determine which scopes are required for each topic, use the [Webhooks reference](https://shopify.dev/docs/api/webhooks). * The complete list of Shopify API access and approval scopes are listed [here](https://shopify.dev/docs/api/usage/access-scopes). Info Scopes that access private customer data, such as `read_orders`, require manual steps in your Partner Dashboard. Go to your app > **API Access** > **Access requests** > **Protected customer data access**, fill out only the first step, and then save. Reinstall your app in the Shopify admin to register the granted scope. ## /shopify.app.toml ```toml # This file stores configurations for your Shopify app. name = "Example App" client_id = "a61950a2cbd5f32876b0b55587ec7a27" application_url = "https://www.app.example.com/" embedded = true handle = "example-app" [access_scopes] scopes = "write_products, read_orders" [webhooks] api_version = "2024-07" # Handled by: /app/routes/webhooks.app.uninstalled.tsx [[webhooks.subscriptions]] uri = "/webhooks/app/uninstalled" topics = ["app/uninstalled"] # Handled by: /app/routes/webhooks.app.scopes_update.tsx [[webhooks.subscriptions]] topics = [ "app/scopes_update" ] uri = "/webhooks/app/scopes_update" # Webhooks can have filters # Only receive webhooks for product updates with a product price >= 10.00 # See: https://shopify.dev/docs/apps/build/webhooks/customize/filters # [[webhooks.subscriptions]] # topics = ["products/update"] # uri = "/webhooks/products/update" # filter = "variants.price:>=10.00" # Mandatory compliance topic for public apps only # See: https://shopify.dev/docs/apps/build/privacy-law-compliance # [[webhooks.subscriptions]] # uri = "/webhooks/customers/data_request" # compliance_topics = ["customers/data_request"] # [[webhooks.subscriptions]] # uri = "/webhooks/customers/redact" # compliance_topics = ["customers/redact"] # [[webhooks.subscriptions]] # uri = "/webhooks/shop/redact" # compliance_topics = ["shop/redact"] [[webhooks.subscriptions]] topics = ["orders/create"] uri = "pubsub://:" [[webhooks.subscriptions]] topics = ["orders/create"] uri = "/webhooks/app/orders-create" [[webhooks.subscriptions]] topics = ["orders/create"] uri = "arn:aws:events:::event-source/aws.partner/shopify.com//" ``` ### Select the API version The API version impacts which topics are available to subscribe to. The React Router template defaults to the latest version in your app configuration file. However, you can [update the API version](https://shopify.dev/docs/apps/build/webhooks/use-newer-api-version) as needed. ## /shopify.app.toml ```toml # This file stores configurations for your Shopify app. name = "Example App" client_id = "a61950a2cbd5f32876b0b55587ec7a27" application_url = "https://www.app.example.com/" embedded = true handle = "example-app" [access_scopes] scopes = "write_products, read_orders" [webhooks] api_version = "2024-07" # Handled by: /app/routes/webhooks.app.uninstalled.tsx [[webhooks.subscriptions]] uri = "/webhooks/app/uninstalled" topics = ["app/uninstalled"] # Handled by: /app/routes/webhooks.app.scopes_update.tsx [[webhooks.subscriptions]] topics = [ "app/scopes_update" ] uri = "/webhooks/app/scopes_update" # Webhooks can have filters # Only receive webhooks for product updates with a product price >= 10.00 # See: https://shopify.dev/docs/apps/build/webhooks/customize/filters # [[webhooks.subscriptions]] # topics = ["products/update"] # uri = "/webhooks/products/update" # filter = "variants.price:>=10.00" # Mandatory compliance topic for public apps only # See: https://shopify.dev/docs/apps/build/privacy-law-compliance # [[webhooks.subscriptions]] # uri = "/webhooks/customers/data_request" # compliance_topics = ["customers/data_request"] # [[webhooks.subscriptions]] # uri = "/webhooks/customers/redact" # compliance_topics = ["customers/redact"] # [[webhooks.subscriptions]] # uri = "/webhooks/shop/redact" # compliance_topics = ["shop/redact"] [[webhooks.subscriptions]] topics = ["orders/create"] uri = "pubsub://:" [[webhooks.subscriptions]] topics = ["orders/create"] uri = "/webhooks/app/orders-create" [[webhooks.subscriptions]] topics = ["orders/create"] uri = "arn:aws:events:::event-source/aws.partner/shopify.com//" ``` ### Configure topics to subscribe to To determine which topic to subscribe to, use the [Webhooks reference](https://shopify.dev/docs/api/webhooks). In this example, your topic name will be in a list and formatted as: `topics = ["orders/create"]`. Your endpoint should utilize your HTTPS URL. Caution If you're using your app URL as your HTTPS delivery endpoint, then Shopify recommends using a relative URL `"/webhooks/topic"`. This is because your app URL will update every time you run `shopify app dev`. Your endpoint must include` https://` or it will fail validation. ## /shopify.app.toml ```toml # This file stores configurations for your Shopify app. name = "Example App" client_id = "a61950a2cbd5f32876b0b55587ec7a27" application_url = "https://www.app.example.com/" embedded = true handle = "example-app" [access_scopes] scopes = "write_products, read_orders" [webhooks] api_version = "2024-07" # Handled by: /app/routes/webhooks.app.uninstalled.tsx [[webhooks.subscriptions]] uri = "/webhooks/app/uninstalled" topics = ["app/uninstalled"] # Handled by: /app/routes/webhooks.app.scopes_update.tsx [[webhooks.subscriptions]] topics = [ "app/scopes_update" ] uri = "/webhooks/app/scopes_update" # Webhooks can have filters # Only receive webhooks for product updates with a product price >= 10.00 # See: https://shopify.dev/docs/apps/build/webhooks/customize/filters # [[webhooks.subscriptions]] # topics = ["products/update"] # uri = "/webhooks/products/update" # filter = "variants.price:>=10.00" # Mandatory compliance topic for public apps only # See: https://shopify.dev/docs/apps/build/privacy-law-compliance # [[webhooks.subscriptions]] # uri = "/webhooks/customers/data_request" # compliance_topics = ["customers/data_request"] # [[webhooks.subscriptions]] # uri = "/webhooks/customers/redact" # compliance_topics = ["customers/redact"] # [[webhooks.subscriptions]] # uri = "/webhooks/shop/redact" # compliance_topics = ["shop/redact"] [[webhooks.subscriptions]] topics = ["orders/create"] uri = "pubsub://:" [[webhooks.subscriptions]] topics = ["orders/create"] uri = "/webhooks/app/orders-create" [[webhooks.subscriptions]] topics = ["orders/create"] uri = "arn:aws:events:::event-source/aws.partner/shopify.com//" ``` ## Process your webhooks Update your `webhooks` file in your app routes (`apps/routes`) to process the event data once your app has received a webhook. In this case, we will just print to the console. Info Shopify's React Router template requires you to use screaming case (e.g. `ORDERS_CREATE`) for webhook topics. This is GraphQL Enum syntax. You can see the full list of topic enums in the [Webhooks reference](https://shopify.dev/docs/api/webhooks). ## /app/routes/webhooks.app.orders-create.tsx ```tsx import type { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export const action = async ({ request }: ActionFunctionArgs) => { const { shop, topic } = await authenticate.webhook(request); console.log(`Received ${topic} webhook for ${shop}`); // TODO: Process the webhook return new Response(); }; ``` Return a 200 Response to let Shopify know that the webhook has been processed. ## /app/routes/webhooks.app.orders-create.tsx ```tsx import type { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export const action = async ({ request }: ActionFunctionArgs) => { const { shop, topic } = await authenticate.webhook(request); console.log(`Received ${topic} webhook for ${shop}`); // TODO: Process the webhook return new Response(); }; ``` ### Confirm the subscription has been added to this version of your app When working in development mode, webhook subscriptions are automatically updated when you save your TOML file. 1. Save your TOML file. 2. If `app dev` is running, the webhook subscription will be automatically created or updated. 3. The webhook subscription is now active in your development store. Info This step abstracts away calls to the [`pubSubWebhookSubscriptionCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/pubSubWebhookSubscriptionCreate) GraphQL mutation. Learn more about [subscribing to webhook topics using the GraphQL Admin API](https://shopify.dev/docs/apps/build/webhooks/subscribe/subscribe-using-api). ## Test your subscription ### Manually trigger an event in your test shop Most webhook topics will fire immediately if you trigger the corresponding event your dev store. 1. Navigate to your test shop and create a new order. 2. The webhook payload should print to your CLI. Info A small number of webhook topics will not fire immediately if you trigger an event in your test shop. They include: * The [customers/redact topic](https://shopify.dev/docs/apps/build/privacy-law-compliance#customers-redact) * The [shop/redact topic](https://shopify.dev/docs/apps/build/privacy-law-compliance#shop-redact) ### Simulate an event using the command line You can use the CLI to simulate specific events occurring on a shop. This lets you test your processing logic by sending a POST request to your endpoint with a synthetic webhook. Note that it does not test your subscription configuration! [`shopify app webhook trigger`](https://shopify.dev/docs/api/shopify-cli/app/app-webhook-trigger) The address inputted for the `--address` flag should be the HTTPS server URL or the URL provided through the mock server site. ## Deploy your app When you're ready to release your webhook subscriptions to production: When you're ready to release your changes to users, you can create and release an [app version](https://shopify.dev/docs/apps/launch/deployment/app-versions). An app version is a snapshot of your app configuration and all extensions. 1. Navigate to your app directory. 2. Run the following command. Optionally, you can provide a name or message for the version using the `--version` and `--message` flags. ## Terminal ```terminal shopify app deploy ``` Releasing an app version replaces the current active version that's served to stores that have your app installed. It might take several minutes for app users to be upgraded to the new version. Tip If you want to create a version, but avoid releasing it to users, then run the `deploy` command with a `--no-release` flag. You can release the unreleased app version using Shopify CLI's [`release`](https://shopify.dev/docs/api/shopify-cli/app/app-release) command, or through the Dev Dashboard. ## /shopify.app.toml ```toml # This file stores configurations for your Shopify app. name = "Example App" client_id = "a61950a2cbd5f32876b0b55587ec7a27" application_url = "https://www.app.example.com/" embedded = true handle = "example-app" [access_scopes] scopes = "write_products, read_orders" [webhooks] api_version = "2024-07" # Handled by: /app/routes/webhooks.app.uninstalled.tsx [[webhooks.subscriptions]] uri = "/webhooks/app/uninstalled" topics = ["app/uninstalled"] # Handled by: /app/routes/webhooks.app.scopes_update.tsx [[webhooks.subscriptions]] topics = [ "app/scopes_update" ] uri = "/webhooks/app/scopes_update" # Webhooks can have filters # Only receive webhooks for product updates with a product price >= 10.00 # See: https://shopify.dev/docs/apps/build/webhooks/customize/filters # [[webhooks.subscriptions]] # topics = ["products/update"] # uri = "/webhooks/products/update" # filter = "variants.price:>=10.00" # Mandatory compliance topic for public apps only # See: https://shopify.dev/docs/apps/build/privacy-law-compliance # [[webhooks.subscriptions]] # uri = "/webhooks/customers/data_request" # compliance_topics = ["customers/data_request"] # [[webhooks.subscriptions]] # uri = "/webhooks/customers/redact" # compliance_topics = ["customers/redact"] # [[webhooks.subscriptions]] # uri = "/webhooks/shop/redact" # compliance_topics = ["shop/redact"] [[webhooks.subscriptions]] topics = ["orders/create"] uri = "pubsub://:" [[webhooks.subscriptions]] topics = ["orders/create"] uri = "/webhooks/app/orders-create" [[webhooks.subscriptions]] topics = ["orders/create"] uri = "arn:aws:events:::event-source/aws.partner/shopify.com//" ``` ## Tutorial complete! Congratulations! You subscribed your app to a webhook topic using React Router, Google PubSub, and Shopify webhooks. Keep the momentum going with these related tutorials and resources. ### Next steps [![](https://shopify.dev/images/icons/32/build.png)![](https://shopify.dev/images/icons/32/build-dark.png)](https://shopify.dev/docs/apps/deployment/web) [Deploy your app](https://shopify.dev/docs/apps/deployment/web) [Follow our guide to deploy your React Router app to a testing or production environment.](https://shopify.dev/docs/apps/deployment/web) [![](https://shopify.dev/images/icons/32/gear.png)![](https://shopify.dev/images/icons/32/gear-dark.png)](https://shopify.dev/docs/api/webhooks) [Explore the Shopify Webhooks reference](https://shopify.dev/docs/api/webhooks) [Explore the Webhooks reference to learn about the full list of topics Shopify has, required access and approval scopes, and sample payloads.](https://shopify.dev/docs/api/webhooks) [![](https://shopify.dev/images/icons/32/gear.png)![](https://shopify.dev/images/icons/32/gear-dark.png)](https://shopify.dev/docs/apps/build/webhooks/customize) [Learn about customizing your webhooks](https://shopify.dev/docs/apps/build/webhooks/customize) [Customize your webhooks experience by using filters or modifying the payload per webhook.](https://shopify.dev/docs/apps/build/webhooks/customize) [![](https://shopify.dev/images/icons/32/apps.png)![](https://shopify.dev/images/icons/32/apps-dark.png)](https://shopify.dev/docs/apps/distribution) [Select an app distribution method](https://shopify.dev/docs/apps/distribution) [Decide how you want to share your app with users. For example, you might make your app available in the Shopify App Store, and bill customers for usage.](https://shopify.dev/docs/apps/distribution)