[relaybell docs › Install › Shopify](https://relaybell.com/docs/install-shopify) · [All docs as Markdown](https://relaybell.com/docs.md) · [Index for AI assistants](https://relaybell.com/llms.txt)

# Shopify

> Shopify storefront code, webhook topic mapping, signing secret and signed-in shoppers.

Two parts: (1) the storefront code from the dashboard's **Install** page (choose Shopify), added to your theme, collects subscribers; (2) Shopify webhooks pointed at `https://relaybell.com/api/v1/integrations/shopify/<PROJECT_ID>` send orders and carts to your automations.

> **Warning:** **Push on Shopify needs one extra step from us.** Browsers only accept the service worker (`sw.js`) from your store's own domain, and Shopify doesn't let you upload it. So on a standard Shopify store the subscribe prompt can't appear until we set push up on a custom domain of yours (a CNAME record) — [contact us](https://relaybell.com/contact) to switch it on. The webhooks in part (2) work straight away.

Shopify topics are mapped automatically:

| Shopify topic | relaybell event |
| --- | --- |
| `checkouts/create`, `checkouts/update`, `carts/update` | `cart.updated` with `{ cartTotal, url, items }` (`url` is the abandoned-checkout link; a cart has none, so it links to your store's cart page: the **Website address** from Settings → General followed by `/cart`, or `https://<your-store>.myshopify.com/cart` when that isn't set) |
| `orders/paid` or `orders/create` | `purchase` with `{ value, currency, orderId, url }` (`value` = order total). Subscribe to only one of the two, or each order counts twice. |
| `orders/fulfilled` | `order.fulfilled` with `{ orderId, url }` |

The person is found by the order's or checkout's customer email (their `externalId`), so these events reach shoppers whose browser the storefront code linked to that email. Other topics are acknowledged and ignored.

**Required:** paste your **Shopify signing secret** into Settings → Privacy. relaybell only accepts Shopify updates signed with it (`X-Shopify-Hmac-Sha256`; a wrong signature answers `401 invalid_hmac`); without the secret, they are acknowledged but ignored, so nobody else can send fake orders or carts.

**Signed-in shoppers:** the storefront code links a signed-in customer by their email (`externalId`). Sign it too, so nobody can claim a customer's email to get their notifications — the code on the dashboard's Install → Shopify page already has this, with your key filled in. Then turn on [Require verified User IDs](https://relaybell.com/docs/identity).

```liquid
{% if customer and customer.email != blank %}
externalId: {{ customer.email | json }},
userHash: "{{ customer.email | hmac_sha256: 'YOUR_SECRET_KEY' }}",
{% endif %}
```

Using the `snippet.liquid` file instead? Make sure it sets `config.userHash = "{{ customer.email | hmac_sha256: 'YOUR_SECRET_KEY' }}";` right after its `config.externalId` line before you turn on Require — otherwise signed-in shoppers are no longer linked to their orders and carts.
