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

# Shopify Checkout Script

> Install, inspect, switch, and remove the Tagada checkout script on a connected Shopify store — via the API or the Node SDK

# Shopify Checkout Script

When you connect a Shopify store to Tagada, we inject a small **checkout script** (internally `TgdMapper`) into your store's **active theme** (`layout/theme.liquid`). This script rewrites your storefront **Buy Now / Checkout** buttons so the cart is handed off to a **Tagada funnel checkout** instead of Shopify's native checkout.

<Info>
  The script is what makes "buy on Shopify, pay on Tagada" work. **Which funnel/step the script is bound to decides which checkout — and therefore which payment routing — your storefront uses.** Switching a store from one processor to another often comes down to re-pointing this script at a new funnel.
</Info>

## Prerequisites

* The store must have **Shopify connected** (OAuth) in the dashboard (Integrations tab).
* All endpoints require your API key as a Bearer token:

```
Authorization: Bearer YOUR_API_KEY
```

## The four operations

| Operation                                  | Method & path                                | SDK                                                |
| ------------------------------------------ | -------------------------------------------- | -------------------------------------------------- |
| **Read** the installed script + its config | `GET /stores/{storeId}/shopify-script`       | `tagada.shopify.checkScript(storeId)`              |
| **Install / update** the script            | `PUT /stores/{storeId}/shopify-script`       | `tagada.shopify.updateScript(storeId, { config })` |
| **Remove** the script                      | `DELETE /stores/{storeId}/shopify-script`    | `tagada.shopify.removeScript(storeId)`             |
| **Audit** the theme for conflicts          | `GET /stores/{storeId}/shopify-script/audit` | `tagada.shopify.audit(storeId)`                    |

<Note>
  There is **one script per store**. `PUT` replaces any existing Tagada block in the theme — it does not stack a second one.
</Note>

***

## Read the current script

Find out whether the script is installed and which funnel/step it currently points at. Pass `funnelId` + `stepId` to also get **conflict detection** against a target funnel.

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://app.tagadapay.com/api/public/v1/stores/store_123/shopify-script?funnelId=funnelv2_new&stepId=step_1" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```ts Node SDK theme={null}
  const status = await tagada.shopify.checkScript('store_123', {
    funnelId: 'funnelv2_new',
    stepId: 'step_1',
  });

  console.log(status.isInjected);        // true
  console.log(status.config?.funnelId);  // funnelv2_old  ← currently bound funnel
  console.log(status.isConflict);        // true → the store points at a different funnel
  ```
</CodeGroup>

```json Response theme={null}
{
  "isInjected": true,
  "themeName": "Dawn",
  "shopUrl": "my-shop.myshopify.com",
  "config": { "storeId": "store_123", "funnelId": "funnelv2_old", "stepId": "step_1" },
  "isConflict": true,
  "conflictDetails": { "currentFunnelId": "funnelv2_old", "currentStepId": "step_1" }
}
```

***

## Install or switch the script

Send a **partial config** — the server fills sensible defaults for anything you omit. The most common use is **binding the storefront checkout to a specific funnel/step**.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT https://app.tagadapay.com/api/public/v1/stores/store_123/shopify-script \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "config": {
        "funnelId": "funnelv2_new",
        "stepId": "step_1",
        "shopifyCheckoutSplitRatio": 100
      }
    }'
  ```

  ```ts Node SDK theme={null}
  await tagada.shopify.updateScript('store_123', {
    config: {
      funnelId: 'funnelv2_new',
      stepId: 'step_1',
      shopifyCheckoutSplitRatio: 100, // 0–100: share of checkouts routed to Tagada
    },
  });
  ```
</CodeGroup>

```json Response theme={null}
{ "success": true, "message": "TagadaPay script updated successfully", "themeId": 140363235490 }
```

<Warning>
  Shopify's Theme API is **eventually consistent**. Right after a `PUT`, a `checkScript` call may briefly still report the old config. Give it a few seconds, then re-read to confirm.
</Warning>

### Migrating a store to a new processor

Re-pointing the script is exactly how you move a live Shopify store onto a new payment funnel (e.g. a new Stripe-MoR or cascade funnel) without touching the storefront theme by hand:

<Steps>
  <Step title="Publish the new funnel">
    Save and promote the new funnel to its production domain — see [Funnel Lifecycle](/developer-tools/funnels/funnel-lifecycle).
  </Step>

  <Step title="Check the current binding">
    `checkScript(storeId, { funnelId, stepId })` — confirm `isConflict` shows the store still points at the old funnel.
  </Step>

  <Step title="Switch">
    `updateScript(storeId, { config: { funnelId, stepId } })` — the storefront now routes new carts through the new funnel's payment flow.
  </Step>

  <Step title="Verify">
    Re-read with `checkScript` (after a few seconds) and place a test order.
  </Step>
</Steps>

***

## Remove the script

Strips **all** Tagada script blocks (current and legacy v1) from the active theme. The storefront reverts to Shopify's native checkout.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://app.tagadapay.com/api/public/v1/stores/store_123/shopify-script \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```ts Node SDK theme={null}
  await tagada.shopify.removeScript('store_123');
  ```
</CodeGroup>

***

## Audit the theme

Even with the script installed, a theme can silently **bypass or break** the integration — a commented-out native button, a hardcoded external redirect, a `fetch` interceptor, or a leftover legacy script. The audit scans checkout-critical theme files and reports findings by severity.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://app.tagadapay.com/api/public/v1/stores/store_123/shopify-script/audit \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```ts Node SDK theme={null}
  const audit = await tagada.shopify.audit('store_123');
  if (!audit.isHealthy) {
    for (const f of audit.findings) {
      console.log(`[${f.severity}] ${f.file}: ${f.message}`);
    }
  }
  ```
</CodeGroup>

```json Response theme={null}
{
  "isHealthy": false,
  "summary": { "high": 1, "medium": 0, "low": 0 },
  "filesScanned": 12,
  "shopUrl": "my-shop.myshopify.com",
  "themeName": "Dawn",
  "scannedAt": "2026-07-08T18:00:00.000Z",
  "findings": [
    {
      "ruleId": "hardcoded-external-redirect",
      "severity": "high",
      "file": "snippets/buy-buttons.liquid",
      "line": 42,
      "snippet": "window.location.href = 'https://checkout.example.com'",
      "message": "Buy button redirects to an external checkout, bypassing Tagada.",
      "recommendation": "Remove the hardcoded redirect so the Tagada script can intercept the click."
    }
  ]
}
```

***

## Authentication troubleshooting

<AccordionGroup>
  <Accordion title="401 Missing or invalid API key">
    Send `Authorization: Bearer YOUR_API_KEY` with a **non-empty, valid** key. In shell scripts, an empty variable produces `Authorization: Bearer ` with nothing after it — the same 401 as a missing header. Verify with `echo ${#KEY}` before calling.
  </Accordion>

  <Accordion title="Shopify connection not found">
    The store has no active Shopify OAuth connection. Connect Shopify in the dashboard (Integrations tab) and retry.
  </Accordion>

  <Accordion title="403 You do not have access to this store">
    Your API key belongs to a different account than the store's owner. Use a key from the account that owns `storeId`.
  </Accordion>
</AccordionGroup>
