> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brew.new/llms.txt
> Use this file to discover all available pages before exploring further.

# Shopify

> Trigger Brew automations from Shopify customer, order, checkout, cart, and fulfillment events.

Connect [Shopify](https://shopify.com) so storefront events fire Brew automations. Send a welcome email when a new customer is created, a receipt the moment an order is paid, an abandoned-cart drip when a checkout doesn't convert, and a shipment notification the second a fulfillment is created.

## What you can do

* **Trigger automations from Shopify events.** Welcome flows, receipts, abandoned-cart drips, refund confirmations, shipping notifications
* **Auto-sync customers into your audience.** Every Shopify event upserts the shopper into Brew with `shopify_*` custom fields (`shopify_customer_id`, `shopify_tags`, `shopify_account_status`, `shopify_last_order_id`, `shopify_last_order_total`, `shopify_last_order_at`, `shopify_last_fulfillment_status`, etc.) you can filter and segment on
* **Personalize with order context.** Reference order totals, line items, financial status, and tracking info inside emails
* **Stop maintaining Liquid notifications.** Author the same lifecycle flows on the Brew canvas instead

## How it works

1. Brew mints a unique webhook URL for your brand. You enter your `myshopify.com` domain in Brew and create one Shopify webhook per topic, all pointing at the same Brew URL.
2. Shopify signs every webhook with your store's per-shop signing secret. Brew verifies the HMAC and checks the `X-Shopify-Shop-Domain` header against the domain you registered — so even if your secret leaks, no other store can impersonate your connection.
3. For each verified event Brew (a) starts every **Published** automation whose trigger matches and (b) upserts the Shopify customer into your [audience](/audience/add-contacts) with `shopify_*` custom fields.

See [How event triggers work](/integrations/integrations#how-event-triggers-work) for the conceptual flow shared by every event-source integration.

## Setup

<Steps>
  <Step title="Generate your Brew webhook URL">
    In Brew, open **Integrations**, click the **Shopify** card, and click **Generate URL**. Copy the URL Brew generates.
  </Step>

  <Step title="Enter your myshopify.com shop domain">
    Use the canonical `myshopify.com` host (e.g. `acme.myshopify.com`), NOT your custom storefront domain. Brew matches this against every webhook's `X-Shopify-Shop-Domain` header to block cross-shop replay attacks.
  </Step>

  <Step title="Open Shopify Admin → Settings → Notifications">
    Click **Settings** (gear icon, bottom-left of Shopify admin) then **Notifications**. Scroll to the **Webhooks** section.
  </Step>

  <Step title="Create one webhook per topic you want">
    For each Brew-supported topic (full list below), click **Create webhook**, set **Format** to **JSON**, paste the Brew URL, pick the latest API version, and **Save**.
  </Step>

  <Step title="Copy the per-shop signing secret">
    Scroll to the bottom of the Webhooks section. Copy the long secret under **"Your webhooks will be signed with…"**. The same secret signs every webhook on this shop.
  </Step>

  <Step title="Paste the signing secret into Brew">
    Paste the secret and click **Connect**. Brew verifies every webhook with HMAC-SHA-256 (base64) against the `X-Shopify-Hmac-SHA256` header.
  </Step>

  <Step title="Verify it's working">
    Trigger an event in Shopify (e.g. create a test customer or place a `$0.01` test order via Bogus Gateway). Within a few seconds it should appear in the **Manage → Recent events** panel of the Shopify integration page in Brew. If it doesn't, recheck the signing secret and that you used the canonical `myshopify.com` domain — Brew's shop-domain check rejects mismatches.
  </Step>
</Steps>

<Note>
  If you rotate the per-shop signing secret in Shopify Admin, re-run the last step with the new value to keep webhooks verifying.
</Note>

## Triggering automations

Once connected, every Shopify topic below is provisioned automatically and available as a trigger in the [automation builder](/create-emails/automations). The **Manage** tab is a read-only catalogue plus a live **Recent events** stream — no per-topic enable step. Whether a topic fires is controlled by whether the bound automation is **Published**. (Shopify still has its own per-topic webhook subscription on its end — Brew can only listen for topics you've actually subscribed to in Shopify Admin.)

### Supported events

Brew supports 15 Shopify webhook topics:

**Customer**

* `customers/create`
* `customers/update`
* `customers/delete`
* `customers/enable`
* `customers/disable`

**Order**

* `orders/create`
* `orders/paid`
* `orders/cancelled`
* `orders/fulfilled`
* `orders/refunded`

**Checkout**

* `checkouts/create`
* `checkouts/update`

**Cart**

* `carts/update`

**Fulfillment**

* `fulfillments/create`
* `fulfillments/update`

<Tip>
  In chat, say *"Send an abandoned-cart email 1 hour after the checkout is created"* and Brew will scaffold the automation with `checkouts/create` pre-selected.
</Tip>

## Common patterns

| Goal                                 | Shopify event         |
| ------------------------------------ | --------------------- |
| Welcome new shopper                  | `customers/create`    |
| Order confirmation                   | `orders/create`       |
| Receipt + thank-you                  | `orders/paid`         |
| Cancellation confirmation + win-back | `orders/cancelled`    |
| Refund confirmation                  | `orders/refunded`     |
| Abandoned-cart Stage 1 (1 hr)        | `checkouts/create`    |
| Abandoned-cart Stage 2 (24 hr)       | `checkouts/update`    |
| Pre-checkout nudge / cart reminder   | `carts/update`        |
| Shipment notification with tracking  | `fulfillments/create` |
| Delivery thank-you / review request  | `fulfillments/update` |

## Personalization

| Variable                                           | Example              |
| -------------------------------------------------- | -------------------- |
| `{{@trigger:output.payload.firstName}}`            | `Alex`               |
| `{{@trigger:output.payload.lastName}}`             | `Morgan`             |
| `{{@trigger:output.payload.orderNumber}}`          | `#1042`              |
| `{{@trigger:output.payload.totalPrice}}`           | `49.95`              |
| `{{@trigger:output.payload.currency}}`             | `USD`                |
| `{{@trigger:output.payload.trackingNumber}}`       | `1Z999AA10123456784` |
| `{{@trigger:output.payload.trackingUrl}}`          | `https://...`        |
| `{{@trigger:output.payload.abandonedCheckoutUrl}}` | `https://...`        |

<Warning>
  Shopify removed `tags`, marketing consent, and full inline customer data from some 2025+ customer and order payloads. Brew reads what's available and falls back gracefully — but if you specifically need order history or tags, subscribe to `customers/create` alongside your order webhooks and join on `customerId`.
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="An event arrived but no automation fired" icon="circle-question">
    Open the canvas and confirm at least one automation bound to this topic is set to **Published** (not Draft). The Brew integration's **Manage → Recent events** panel confirms the webhook is arriving — if it isn't there, check that the topic is subscribed in Shopify Admin → Settings → Notifications and that the shop domain stored on the Brew side matches. If the event is there but no email sent, the only remaining gate is `automation.published`.
  </Accordion>

  <Accordion title="Shopify returns 401 with shop_domain_mismatch" icon="triangle-exclamation">
    The shop domain you entered during connect doesn't match the `X-Shopify-Shop-Domain` header on the webhook. Update the stored shop domain (disconnect and reconnect) using your canonical `*.myshopify.com` host — not your custom storefront domain.
  </Accordion>

  <Accordion title="orders/* emails have empty firstName / lastName" icon="user">
    The Shopify January 2025 slim-down removed the inline customer object from some `orders/*` payloads. Either subscribe to `customers/create` and join by `customerId` in your automation's `filter` step, or wait for a later webhook in the order lifecycle (`orders/paid`, `orders/fulfilled`) that still carries customer fields.
  </Accordion>

  <Accordion title="carts/update fires to placeholder emails" icon="cart-shopping">
    Working as intended. Shopify never carries an email on cart events, so Brew uses a synthetic placeholder. Use `checkouts/create` / `checkouts/update` for customer-facing abandoned-cart flows instead.
  </Accordion>

  <Accordion title="I want to test before going live" icon="flask">
    Shopify's Admin → **Settings → Notifications → Webhooks** has a **Send test notification** button. Or trigger real test data (create a draft customer, place a `$0.01` Bogus Gateway order). The **Manage → Recent events** panel surfaces every webhook within seconds.
  </Accordion>
</AccordionGroup>

## Requirements

* A Shopify store on any paid plan
* Admin access to add webhooks under **Settings → Notifications**

## Need Help?

Our team is ready to support you at every step of your journey with Brew. Choose the option that works best for you:

<Tabs>
  <Tab title="Self-Service Tools">
    <CardGroup cols="2">
      <Card title="Search Documentation" icon="magnifying-glass" color="#c44925">
        Type in the "Ask any question" search bar at the top left to instantly find relevant documentation pages.
      </Card>

      <Card title="ChatGPT/Claude Integration" icon="robot" color="#c44925">
        Click "Open in ChatGPT" at the top right of any page to analyze documentation with ChatGPT or Claude for deeper insights.
      </Card>
    </CardGroup>
  </Tab>

  <Tab title="Talk to Our Team">
    <CardGroup cols="2">
      <Card title="Schedule a Call" icon="calendar" color="#c44925" href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ1iYoRUG1J792XQpbuQLjSRRDupr7MwraFK-HQRCtTYdBmrQi8nZu2qXfzKQigb8gbKJK3KN3-R">
        Book time with our founders for personalized guidance on strategy, best practices, or complex implementation questions.
      </Card>

      <Card title="Call Us Directly" icon="phone" color="#c44925">
        Need immediate assistance? Reach us at **+1-(332)-203-2145** for urgent issues or time-sensitive questions.
      </Card>

      <Card title="Slack Channel" icon="slack" color="#c44925">
        Our preferred support channel. You'll receive an invite after signup for direct founder support and fast responses.
      </Card>

      <Card title="Email Support" icon="envelope" color="#c44925" href="mailto:support@brew.new">
        Contact us at **[support@brew.new](mailto:support@brew.new)** for detailed inquiries or if you prefer not to use Slack.
      </Card>
    </CardGroup>
  </Tab>
</Tabs>
