# Shopify

> Connect your Shopify store so Attrifast tracks your storefront automatically and attributes every paid order to the traffic source that drove it.

Last updated: 2026-07-17
Canonical: https://attrifast.com/docs/shopify

Connecting Shopify does two things at once:

- **Tracks your storefront** — Attrifast injects its tracker into your Online Store theme automatically. No theme editing, no snippet to paste.
- **Attributes order revenue** — every paid order is linked back to the visitor who placed it and the marketing channel that brought them, including AI engines like ChatGPT and Perplexity.

## Requirements

- An Attrifast website already added to your account, and a **Pro subscription** (Shopify connect is a Pro feature — there's a 7-day free trial).
- A Shopify store on an **Online Store (theme-based) storefront**. Headless and Hydrogen storefronts are not supported yet.
- Your store's `*.myshopify.com` domain (find it under **Settings → Domains** in Shopify admin). The connect form intentionally rejects custom domains.

## Step 1 — Create a custom app in Shopify

Attrifast connects through a private app that you create in your own Shopify organization — you stay in control and can revoke access at any time by uninstalling the app. Attrifast stores the app's credentials to mint short-lived API tokens and verify webhook signatures.

<Steps>
<Step title="Create the app">

In the [Shopify Dev Dashboard](https://shopify.dev/), go to **Apps → Create app** and name it anything you like — for example `Attrifast`.

</Step>
<Step title="Enable the two required scopes">

Under **Configuration → Admin API access scopes**, enable:

- `read_orders` — lets Attrifast receive paid-order webhooks
- `write_script_tags` — lets Attrifast inject the tracker into your storefront

If your app's configuration shows a **Protected customer data access** section (order data counts as protected), request access to order data there — Shopify won't deliver order webhooks without it.

</Step>
<Step title="Release a version and install the app">

Release an app version (scopes only take effect once released), then **install the app on your store**.

</Step>
<Step title="Copy the credentials">

From the app's **Settings → Credentials** page, copy the **Client ID** and the **Client secret** (starts with `shpss_`).

</Step>
</Steps>

## Step 2 — Connect in Attrifast

The connect form lives in two places — use whichever you're closer to:

- **Onboarding** → step 2 "Install script" → **Shopify** tab
- **Dashboard → Settings → Install script** → **Shopify** tab

Fill in the three fields:

| Field | What to paste |
| --- | --- |
| Shopify store domain | `your-store.myshopify.com` |
| Client ID | The Client ID from your app's credentials page |
| Client secret | The `shpss_…` secret from the same page |

Click **Connect Shopify**. On success you'll see: *"Connected to your-store.myshopify.com. Attrifast is now tracking analytics and attributing revenue from orders."*

### What happens when you connect

Behind the scenes, Attrifast:

1. Exchanges your app credentials for a short-lived Admin API token (auto-refreshed — you never handle raw tokens).
2. Registers a **ScriptTag** so the tracker loads on every storefront page.
3. Registers an **`orders/paid` webhook** — the revenue source.
4. Adds your `myshopify.com` and primary domains to the website's allowed hostnames so storefront events are accepted.

Reconnecting first removes the previously registered ScriptTag and webhook, so you won't end up with duplicate tracking.

## How orders are attributed

On your storefront the tracker stamps its visitor ID into the Shopify cart (as the cart attribute `_rp_vid`), and re-asserts it after cart changes so theme updates can't drop it. When the `orders/paid` webhook arrives, Attrifast links the order to that visitor and attributes it using a **7-day last non-direct click** model. Orders that arrive without a visitor link fall back, in order, to the order's landing-page UTMs, then its referrer, then Direct.

See the [revenue attribution guide](/docs/revenue-attribution-guide) for the full model, including how AI-influenced revenue works.

## Verify your setup

<Steps>
<Step title="Check the tracker loads">

Open your storefront in a fresh browser tab. In DevTools → Network you should see `af.js?id=<your-tracking-id>` load, followed by a request to `/api/collect`. The visit usually appears in your Attrifast dashboard within a minute.

</Step>
<Step title="Check the cart attribute">

Add any product to the cart, then open `https://your-store.myshopify.com/cart.js` in the same browser. The JSON should contain `"attributes": { "_rp_vid": "…" }`.

</Step>
<Step title="Place a paid test order">

Complete a checkout using a test gateway (Shopify's Bogus Gateway or Shopify Payments test mode) — the webhook only fires when an order is **paid**, so an unpaid draft won't show up. The order usually appears in your dashboard's revenue within a minute, attributed to a channel.

</Step>
</Steps>

<Callout type="warn">

Test-gateway orders are currently recorded as real revenue — they are not filtered out. Do your test order before sharing dashboards, or keep it small and easy to recognize.

</Callout>

## Limitations

- Only **paid** orders are counted, and revenue is only ever added: refunds, cancellations, and order edits are not reflected yet.
- **Buy Now / dynamic checkout buttons** skip the cart, so those orders can't carry the visitor link — they fall back to UTM/referrer/Direct attribution.
- One Shopify store connects to exactly one Attrifast website (and vice versa).
- The injected tracker isn't guaranteed to run on checkout or thank-you pages. Revenue comes exclusively from the webhook, so this doesn't affect attribution.
- The ScriptTag and webhook registered via the API are not visible in the Shopify admin UI — verify via the storefront checks above instead.

## Troubleshooting

| Error / symptom | Cause and fix |
| --- | --- |
| *"Shopify rejected these credentials…"* | The app isn't installed on this store, or the Client ID/secret are wrong. Confirm the app is installed on this exact store and re-copy both values from **Settings → Credentials**. |
| *"The Shopify app is missing required scopes…"* | Add `read_orders` and `write_script_tags` under **Configuration → Admin API access scopes**, **release a new version**, then retry. Scopes only take effect once released. |
| *"Could not reach Shopify. Check the store domain…"* | Usually a typo'd or custom domain. Use the `*.myshopify.com` address from **Settings → Domains**. |
| *"This Shopify store is already connected to another site."* | The store is attached to a different Attrifast website. Disconnect it there first, then reconnect. |
| 403 *"A subscription is required to access this feature."* | Shopify connect is a Pro feature — start the 7-day free trial, then retry. |
| Connected, but no pageviews | The storefront domain isn't in the website's allowed hostnames (this can happen if you changed your primary domain after connecting). Reconnect Shopify to re-sync the hostname list. |
| Orders show as Direct / UTM channel with no visitor | Expected for cart-bypassing checkouts (Buy Now buttons). For normal flows, verify the cart attribute check above passes. |
| Orders never appear; API logs show *"Invalid webhook signature"* | Your app's Client secret was rotated in Shopify after connecting, so webhook signatures no longer verify. Reconnect with the current secret. |
