# Develop Shopify apps and webhooks on localhost

A Shopify app needs a public HTTPS URL: Shopify loads the app in the admin from it, redirects to it during OAuth, and sends webhooks to it. Expose gives your local app that URL and shows you every request Shopify makes.

## 1. Share your local app

```bash
expose share http://localhost:3000
```

Shopify stores your app URL and redirect URLs, so a URL that changes means updating the app configuration each time. With [Expose Pro](https://expose.dev/#pricing), keep it stable:

```bash
expose share http://localhost:3000 --subdomain=my-shopify-app
```

## 2. Use the URL in your app configuration

Set your Expose URL as the app URL, and add your OAuth callback under the allowed redirection URLs, for example `https://my-shopify-app.eu-1.sharedwithexpose.com/auth/callback`. You can do this in the Shopify Dev Dashboard or Partner Dashboard, or in `shopify.app.toml` if you use the Shopify CLI.

If you start your app with the Shopify CLI, you can pass your own tunnel instead of the default one:

```bash
shopify app dev --tunnel-url=https://my-shopify-app.eu-1.sharedwithexpose.com:3000
```

The port at the end is the local port the CLI should serve the app on, so share that same port with Expose.

## 3. Receive webhooks

Subscribe to webhook topics such as `orders/create` or `app/uninstalled` in your app configuration, with a path on your Expose URL.

Shopify signs each webhook with your app's client secret and sends the signature in the `X-Shopify-Hmac-Sha256` header, as a base64-encoded HMAC-SHA256 of the raw request body. Compute the same value and compare the two before you trust the payload. The topic is in `X-Shopify-Topic` and the shop in `X-Shopify-Shop-Domain`.

## 4. Inspect and replay

Open `http://127.0.0.1:4040` to see every request from Shopify: app loads, OAuth redirects and webhooks, with headers, body and your response. Click **Replay** on a webhook to send it to your app again while you work on the handler, without placing another test order.

## Troubleshooting

- **The admin shows a blank app or a redirect error.** The app URL or redirect URL in Shopify doesn't match your current Expose URL.
- **HMAC verification fails.** Use the raw body and the client secret of the same app that subscribed to the webhook.
- **Shopify needs a response within a few seconds.** Acknowledge the webhook with a `200` and process it in the background.
