You might want to use HTTPS rather than a cloud-based event bus due to infrastructure requirements, where your domain knowledge lies, budget constraints, or because you want full control to customize your webhooks system. This approach will require additional steps, however, to ensure your system is production-ready and can handle receiving Shopify webhooks at scale. Shopify recommends using cloud-based event buses whenever possible to minimize this overhead. ### What you'll learn 1. Notify Shopify that your app is receiving webhooks 1. Validate the origin of each webhook 1. Prepare your system to handle occasional bursts of webhook traffic ### Requirements - An app with webhook subscriptions configured using HTTPS delivery - Ensure your server is correctly configured to support HTTPS with a valid SSL certificate. Shopify sends an HTTP POST request to the URI you have specified every time that event occurs. The HTTP `POST` request's parameters contain the JSON data relevant to the event that triggered the request. Shopify verifies SSL certificates when delivering payloads to HTTPS webhook addresses. > Info: > You might want to use your app URL as the endpoint for webhook subscriptions during development. This URL has your CloudFlare tunnel path as an input, which will change after each time you run `shopify app dev`. > > In this case, leverage Shopify's support of relative paths for the URI: `uri = "/webhooks"` > > Your subscription endpoint will automatically prepend your updated app URL in your subscription endpoint (`uri`) after you run`shopify app deploy`. ## Step 1: Notify Shopify that your app is receiving webhooks ### Respond with a 200 OK, quickly Your system acknowledges that it received webhooks by sending Shopify a `200 OK` response. Any response outside of the 200 range, including 3XX HTTP redirection codes, indicates that you didn't receive the webhook. Shopify will consider these codes to be an error response. Because Shopify has a connection timeout of one second, the your server must accept connections within one second. > Note: > There is a five-second timeout for the entire request: Shopify expects to establish the connection and receive your response in less than five seconds or the request times out. ### Manage your connection to optimize your system Shopify's webhook delivery system uses [HTTP Keep-Alive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive) to reuse connections to the same host and endpoint. This reduces network congestion and the latency in subsequent requests. Ensure that you have Keep-Alive enabled for your endpoint to reduce the overhead of receiving concurrent requests. ### Consider building a reconciliation job if you can't afford to miss webhooks In instances where you can't provide a response in less than five seconds, Shopify recommends queuing your webhooks. Your queue should be persistent. Common practice here is also to build a reconciliation job that retrieves the data that is important for you, and you might have missed, periodically using our APIs. ### Shopify will always try to re-deliver your webhooks even if they are failing Shopify waits five seconds for a response to each request to a webhook. If there's no response, or an error is returned, then Shopify retries the connection 8 times over the next 4 hours. If there are 8 consecutive failures, then the webhook subscription is automatically deleted if it was configured using the Admin API. Warning emails that the subscription is failing, and could be deleted, are sent to the app's emergency developer email address. This is the email address that was used to create your Partner account. You can learn more about troubleshooting your webhooks in the [Troubleshoot your webhooks guide here](/docs/apps/build/webhooks/troubleshooting-webhooks). ## Step 2: Validate the origin of your webhook to ensure it's coming from Shopify Before you respond to a webhook, you need to verify that the webhook was sent from Shopify. You can verify the webhook by calculating a digital signature. [ShopifyApp](/docs/api/shopify-app-remix/latest/entrypoints/shopifyapp) abstracts this from you with the [authenticate](/docs/api/shopify-app-remix/v3/authenticate/webhook) method, which also validates the origin. If you use the default [REMIX template](/docs/api/shopify-app-remix/latest/guide-webhooks#endpoints), then this is already prepared for you right before processing the webhook with the following line: