Files
mozimo.in/docs/research/shopify-headless-commerce-2026-10.md
tanshu de0553d0d4 Wayfinder: chart the Shopify headless commerce map
The route from "mozimo.in displays Shopify products" to "mozimo.in sells them",
as a plan with a phase spine and gates, plus the open decision tickets that
still shape it and the evidence they rest on.

- .scratch/shopify-headless-commerce/: plan.md (phases and gates), map.md (the
  wayfinder map), 10 open decision tickets
- CONTEXT.md: Storefront / Theme store / Cart / Parity vocabulary
- docs/adr/0001-0003: Checkout stays Shopify-hosted, one Variant per product,
  the checkout domain stays shop.mozimo.in
- docs/research/ and docs/shopify-catalog-inventory.md: verified store facts,
  the Cart API probe, and the catalogue inventory

Raw Shopify doc scrapes under .scratch/shopify-research/ are ignored: they are
working material, not record.
2026-10-14 09:00:42 +05:30

1012 lines
78 KiB
Markdown

# Shopify headless commerce: capabilities, limits and dates (verified 2026-10-13)
**Subject context.** Luxury chocolate brand `mozimo.in` (India, INR, small catalog of bars/boxes/hampers).
Custom headless storefront on **TanStack Start (React 19 + Vite)** with a custom Node SSR server
(`server.mjs`), Docker behind Caddy. It reads products/collections from the **Shopify Storefront
GraphQL API** and is **strictly read-only** (`src/lib/shopify.ts`). Buying happens today on a separate
classic Shopify theme storefront at **`shop.mozimo.in`** (the Shopify **Online Store**
channel). Credentials are minted by an OAuth client-credentials app that mints an admin token and then a
storefront access token.
**Purpose.** Facts, constraints, limits and dates only. **No architectural recommendations.**
Every claim carries the canonical `shopify.dev` (or Shopify-owned) URL it came from. Where a fact could
not be verified against a primary source it is marked **UNVERIFIED** with a description of what was found
instead.
**How this was verified.** All `shopify.dev` pages were fetched as raw Markdown
(`<url>.md`, e.g. <https://shopify.dev/docs/api/usage/versioning.md>), which is the un-truncated source of
the same HTML page; the front-matter `api_version` on Storefront API reference pages was used to confirm
the version actually behind `/latest/`. `shopify.dev` sitemap inventory
(<https://shopify.dev/sitemap_standard.xml.gz>) was used to establish what does and does not exist in the
current API surface. `help.shopify.com` was mostly unreachable (HTTP 403 bot challenge for both `curl` and
the fetch tool); the two pages that did return are cited as such and the failures are recorded in
[§7](#7-verification-notes-and-gaps). Shopify Community threads were read through the forum's own JSON API
(`https://community.shopify.com/t/<id>.json`) — these are community pages, **not** Shopify documentation,
and are labelled as such.
---
## 0. Critical version findings (read first)
### 0.1 Current stable API version is `2026-10`; `2025-01` is retired
From Shopify's own release-schedule table (<https://shopify.dev/docs/api/usage/versioning>):
| Stable version | Release date | Accessible until | Status |
| - | - | - | - |
| 2025-04 | April 1, 2025 | April 16, 2026 15:00 UTC | Unsupported |
| 2025-07 | July 1, 2025 | July 16, 2026 15:00 UTC | Unsupported |
| 2025-10 | October 1, 2025 | **October 16, 2026 15:00 UTC** | Unsupported |
| 2026-01 | January 1, 2026 | January 16, 2027 15:00 UTC | Stable |
| 2026-04 | April 1, 2026 | April 16, 2027 15:00 UTC | Stable |
| 2026-07 | July 1, 2026 | July 16, 2027 15:00 UTC | Stable |
| 2026-10 | October 1, 2026 | October 16, 2027 15:00 UTC | **Latest stable** |
| 2027-01 | January 1, 2027 | January 16, 2028 15:00 UTC | Release candidate |
* **Current stable (and what `/latest/` resolves to): `2026-10`.** Confirmed by the front-matter of the
current reference pages — e.g. `api_version: 2026-10` on
<https://shopify.dev/docs/api/storefront/latest/mutations/cartCreate> and on
<https://shopify.dev/docs/api/customer/latest>.
* **`2025-01` is not in the table at all.** The oldest accessible stable version is `2026-01`, so
`2025-01` is past its support window. The exact retirement date is **not published in that table**;
because each stable version is "supported for a minimum of 12 months"
(<https://shopify.dev/docs/api/usage/versioning>), `2025-01` would have gone inaccessible around
January 2026. Treat the precise date as **UNVERIFIED**; the retirement itself is certain.
* Shopify **falls forward** rather than erroring: *"If your app targets an inaccessible version, Shopify
falls forward and responds using the oldest accessible stable version."* Responses carry
`X-Shopify-API-Version` reflecting the version actually used, so a repository pinned to `2025-01` is in
practice being served `2026-01`.
Source: <https://shopify.dev/docs/api/usage/versioning>
* **Imminent:** `2025-10` becomes inaccessible on **October 16, 2026 15:00 UTC** (three days after this
research). Source: <https://shopify.dev/docs/api/usage/versioning>
* `src/lib/shopify.ts` currently sets `API_VERSION = "2025-01"` and `ADMIN_API_VERSION = "2026-07"`.
Stated as fact only: `2025-01` is retired, and `2026-07` (Admin API) is still a supported stable
version until July 16, 2027.
### 0.2 Release and deprecation cadence
* New version **every three months at 5pm UTC on the first day of the quarter**; version names are
date-based. Each stable version is supported **≥12 months**, with **≥9 months of overlap** between
consecutive versions. Source: <https://shopify.dev/docs/api/usage/versioning>
* Deprecation practice: *"Deprecated fields or types are removed in a subsequent release—for example,
something deprecated in `2026-10` might be removed in `2027-01`."* Deprecations are announced in the
developer changelog (<https://shopify.dev/changelog>). An entire API can be deprecated: *"A deprecated
API stays available but is unsupported, and it can stop working at any time."*
Source: <https://shopify.dev/docs/api/usage/versioning>
* The Shopify CLI *"prevents deploys targeting versions older than 12 months"* (Polaris section of the
same page).
* App-Store-specific enforcement (applies to published apps, not to a merchant's private integration):
continuing to use unsupported resources after the upgrade deadline causes delisting and blocks installs
for a minimum of seven days. Source: <https://shopify.dev/docs/api/usage/versioning>
### 0.3 Plan naming: two vocabularies in Shopify's own materials
* Merchant-facing plans are **Basic / Grow / Advanced / Plus** — with INR pricing on Shopify's India
pricing page: Basic ₹1,499/mo (yearly), Grow ₹5,599/mo, Advanced ₹22,680/mo, Plus from ₹1,75,000/mo.
Source: <https://www.shopify.com/in/pricing>
* API rate-limit documentation uses a different vocabulary: **Standard / Advanced Shopify / Shopify Plus /
Shopify for enterprise (Commerce Components)**. Sources:
<https://shopify.dev/docs/apps/build/apis/graphql-admin/rate-limits>,
<https://shopify.dev/docs/api/customer#rate-limits>
* Plan gates in the docs are usually written as "Shopify Plus" vs "all plans except Shopify Starter", so
they are unaffected by the Basic/Grow/Advanced renaming. Where a gate is expressed as a rate-limit tier
this document says so explicitly.
---
## 1. Cart API on the Storefront GraphQL API
Endpoint pattern (current): `POST https://{shop}.myshopify.com/api/2026-10/graphql.json`
(<https://shopify.dev/docs/api/storefront>).
### 1.1 Current shape of the operations
| Operation | Signature (2026-10) | Returns |
| - | - | - |
| `cartCreate` | `cartCreate(input: CartInput!)` | `CartCreatePayload { cart, userErrors: [CartUserError!]!, warnings: [CartWarning!]! }` |
| `cartLinesAdd` | `cartLinesAdd(cartId: ID!, lines: [CartLineInput!]!)` | `CartLinesAddPayload { cart, userErrors!, warnings! }` |
| `cartLinesUpdate` | `cartLinesUpdate(cartId: ID!, lines: [CartLineUpdateInput!]!)` | `CartLinesUpdatePayload { cart, userErrors!, warnings! }` |
| `cartLinesRemove` | `cartLinesRemove(cartId: ID!, lineIds: [ID!], viewKeys: [String!])` | `CartLinesRemovePayload { cart, userErrors!, warnings! }` |
| `cartBuyerIdentityUpdate` | `cartBuyerIdentityUpdate(cartId: ID!, buyerIdentity: CartBuyerIdentityInput!)` | `CartBuyerIdentityUpdatePayload { cart, userErrors!, warnings! }` |
| `cart` (query) | `cart(id: ID!): Cart` | `Cart` |
Sources: <https://shopify.dev/docs/api/storefront/latest/mutations/cartCreate>,
<https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesAdd>,
<https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesUpdate>,
<https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesRemove>,
<https://shopify.dev/docs/api/storefront/latest/mutations/cartBuyerIdentityUpdate>,
<https://shopify.dev/docs/api/storefront/latest/queries/cart>.
Documented behaviour that matters:
* `cartCreate` — *"Creates a new `Cart` for a buyer session. You can optionally initialize the cart with
merchandise lines, discount codes, gift card codes, buyer identity for international pricing, and custom
attributes. The returned cart includes a `checkoutUrl` that directs the buyer to complete their
purchase."* (<https://shopify.dev/docs/api/storefront/latest/mutations/cartCreate>)
* `cartLinesAdd` — *"Quantity defaults to `1` if not provided."* Each line takes merchandise, quantity,
selling plan, custom attributes, and parent relationships for nested line items such as warranties or
add-ons. (<https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesAdd>)
* `cartLinesUpdate` — *"You can modify the quantity, swap the merchandise, change custom attributes, or
update the selling plan for each line."* Omitting `attributes` or setting it to `null` preserves
existing line attributes; an empty array clears them all.
(<https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesUpdate>)
* `cartLinesRemove` — accepts **either** `lineIds` **or** `viewKeys`, *"Mutually exclusive with
`lineIds`."* (<https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesRemove>)
* `cartBuyerIdentityUpdate` — used to *"associate a logged-in customer via access token, set a B2B company
location, or configure checkout preferences like delivery method. Preferences prefill checkout fields
but don't sync back to the cart if overwritten at checkout."* The buyer's country determines
international pricing. (<https://shopify.dev/docs/api/storefront/latest/mutations/cartBuyerIdentityUpdate>)
* `cart` query — *"Returns a `Cart` by its ID. The cart contains the merchandise lines a buyer intends to
purchase, along with estimated costs, applied discounts, gift cards, and delivery options."*
(<https://shopify.dev/docs/api/storefront/latest/queries/cart>)
* `Cart` object: *"Use the `checkoutUrl` field to direct buyers to Shopify's web checkout to complete their
purchase."* (<https://shopify.dev/docs/api/storefront/latest/objects/Cart>)
* Cart IDs carry a key in the ID itself, e.g.
`gid://shopify/Cart/Z2NwLXVzLWV4YW1wbGU6MDEyMzQ1Njc4OTAxMjM0NTY3ODkw?key=examplekey1234567890`
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage>).
### 1.2 Documented limits
| Limit | Value | Source |
| - | - | - |
| Line items per cart (total) | **500** — *"The cart supports a maximum of 500 line items."* | <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart> |
| Lines per request (`cartLinesAdd`, `cartLinesUpdate`, `cartLinesRemove`) | **250** — *"You can add up to 250 lines in a single request"*; argument is annotated *"The input must not contain more than `250` values."* Same for update and remove. | <https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesAdd>, <https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesUpdate>, <https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesRemove> |
| Array-input cap, all Shopify APIs | **250** — *"Input arguments that accept an array have a maximum size of 250, on every Shopify API. Requests return an error if an input array exceeds 250 items."* | <https://shopify.dev/docs/api/usage/limits> |
| Quantity per line | **No maximum documented.** `CartLineInput.quantity` is `Int`, `Default: 1`, described only as *"The quantity of the merchandise."* | <https://shopify.dev/docs/api/storefront/latest/input-objects/CartLineInput>, <https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesAdd> |
| Cart lifetime (abandoned) | *"Unused and abandoned carts automatically expire within 30 days of creation."* | <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart> |
| Cart lifetime (completed) | *"Shopify automatically deletes the cart when the customer completes their checkout."* | <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart> |
| Number of carts | *"A shop or customer can create an unlimited number of carts."* | <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart> |
| Cart rate limits | *"Carts don't have any global API rate limits."* But: *"The cart is subject to the same throttling restrictions as the Storefront API."* | <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart> |
| Bot protection on cart | *"Shopify Plus bot protection is available for cart."* → **Shopify Plus only** | <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart>, matching the "Just for Plus" bullet on <https://www.shopify.com/in/pricing> |
| Headless storefronts per shop | Docs: *"You can have a maximum of 100 active storefronts and access tokens per shop."* Pricing page feature row "Build headless storefronts": **1 / 1 / 1 / 25** (Basic / Grow / Advanced / Plus). These two figures are not obviously measuring the same thing — see [§6.3](#63-headless-storefront-entitlements). | <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/manage-headless-channels>, <https://www.shopify.com/in/pricing> |
| Active storefront access tokens | *"Apps can have a maximum of 100 active storefront access tokens per shop."* | <https://shopify.dev/docs/api/storefront> |
### 1.3 `checkoutUrl` behaviour and domain
What the docs state:
* Field type `checkoutUrl: URL!` (non-null), documented as *"The URL of the checkout for the cart."*
(<https://shopify.dev/docs/api/storefront/latest/objects/Cart>)
* It *"direct[s] buyers to Shopify's web checkout"*
(<https://shopify.dev/docs/api/storefront/latest/objects/Cart>) and the manage-cart guide says the
response *"includes a URL that redirects customers through Shopify's web checkout."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage>)
* Documented example value — note the host and path shape:
`{"checkoutUrl": "https://exam.myshopify.com/cart/c/29567c413f68cf5e8c1cb623954f3a28"}`
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage>)
* *"For security reasons, the `checkoutUrl` should be requested when the buyer is ready to navigate to
checkout and can be re-requested if it is stale."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage>)
* When a customer access token is set on the cart, the `checkoutUrl` yields a logged-in checkout; to
preserve that for **server-side** Storefront API calls you must send the `Shopify-Storefront-Buyer-IP`
header. *"Without the `Shopify-Storefront-Buyer-IP` header, Shopify can't differentiate requests from
different buyers, which can result in throttled API requests, limited bot protection, and
unauthenticated flows at checkout."*
(<https://shopify.dev/docs/api/storefront>, <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage>)
**UNVERIFIED (domain selection).** No current `shopify.dev` page states which host the `checkoutUrl` uses.
The only first-party statement found is a **Shopify maintainer reply (September 8, 2022)** in Shopify's own
`storefront-api-feedback` repository: the reporter's `checkoutCreate.webUrl` returned
`foo.myshopify.com` while the `cart` query returned the merchant's custom domain; the maintainer's accepted
answer was *"try initializing the API (ex. yourcustomdomain.com/api/graphql) with your custom domain vs.
the `.myshopify.com` domain."* (<https://github.com/Shopify/storefront-api-feedback/discussions/130>)
That implies the returned URL follows the host used for the API request (or the shop's primary domain), not
the headless storefront's domain. This is **four years old and should be treated as unconfirmed**; the
current documented example uses `*.myshopify.com`
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage>). Practical
consequence to be aware of: the checkout host is a Shopify-owned host, and because the headless storefront
lives on `mozimo.in` while the Online Store channel is `shop.mozimo.in`, a checkout redirect crosses
domains.
### 1.4 Cart-related changes you inherit when you leave `2025-01`
Because the API falls forward, cart behaviour observed in production today is `2026-01` behaviour, and new
cart work is written against `2026-01`+ semantics. Relevant entries:
* **`2026-01`** — *"Calls to the Storefront API `cartDiscountCodesUpdate` mutation must now include the
`discountCodes` argument"* (previously accepted but a no-op). Also returns
`GIFT_CARD_RECIPIENT_INVALID` in `userErrors` for `cartCreate`/`cartLinesAdd` instead of an empty cart.
(<https://shopify.dev/changelog/release-notes/2026-01>)
* **`2026-04`** — Storefront API returns `MERCHANDISE_LINE_TRANSFORMERS_RUN_ERROR` when a Cart Transform
Function errors during `cartCreate`/`cartLinesAdd`, replacing the generic `INVALID`.
(<https://shopify.dev/changelog/release-notes/2026-04>)
* **`2026-07`** — `CartLine.viewKey` added (*"returning the same value rendered by Liquid storefronts and
accepted by `cartLinesUpdate` and `cartLinesRemove`"*); `cartLinesUpdate`/`cartLinesRemove` accept
`view_key`/`viewKeys`; new `CartWarning` code `PRODUCT_UNAVAILABLE_IN_BUYER_LOCATION`; and an
action-required migration away from deprecated `cart.discountAllocations` to
`cart.discountApplications`, `cart.lines[].discountAllocations(lineLevelOnly: false)` and
`cart.deliveryGroups[].discountAllocations`.
(<https://shopify.dev/changelog/release-notes/2026-07>)
* **`2026-10`** — `@inContext` gained an optional `channelId` argument to apply a sales channel's context
(channel-specific availability and pricing) across a query.
(<https://shopify.dev/changelog/release-notes/2026-10>)
---
## 2. Can checkout be rendered on the merchant's own domain?
**Short answer, stated from primary sources:** no supported mechanism exists to render or host Shopify's
checkout yourself, on any plan. What varies by plan is *how much you may customise the Shopify-hosted
checkout*, not *where it runs*.
### 2.1 The headless cart hands off to Shopify's hosted checkout
* Storefront Cart API: *"The returned cart includes a `checkoutUrl` that directs the buyer to complete
their purchase."* / *"the response includes a URL that redirects customers through Shopify's web
checkout."* / *"Use the `checkoutUrl` field to direct buyers to Shopify's web checkout to complete their
purchase."*
(<https://shopify.dev/docs/api/storefront/latest/mutations/cartCreate>,
<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage>,
<https://shopify.dev/docs/api/storefront/latest/objects/Cart>)
* The documented headless checkout step is literally *"Redirect the buyer to the `checkoutUrl`."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/checkout-authentication>)
### 2.2 The API that used to complete orders outside checkout is gone
* *"In API version 2024-04, Checkout APIs on the REST Admin and Storefront API are deprecated, with the
exception of the REST Admin API's Abandoned checkouts resource. In version 2025-04, the Checkout APIs
will be sunset and no longer function."* The documented replacement is the Storefront Cart API or
Checkout Kit for native mobile apps.
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/migrate-to-cart-api>)
* Corroborated by the current API inventory: the `shopify.dev` sitemap contains **no** Storefront API
mutations or queries under `checkout*` for the current version. The only surviving payment-adjacent
members of the Storefront API are `shopPayPaymentRequestSessionCreate`,
`shopPayPaymentRequestSessionSubmit`, the `paymentSettings` query and the `PaymentSettings` object
(<https://shopify.dev/sitemap_standard.xml.gz>, and see <https://shopify.dev/docs/api/storefront>).
Those Shop Pay mutations are the single documented exception to "checkout happens on Shopify's
checkout" — see [§2.6](#26-the-one-documented-exception-shop-pay-wallet-merchant-built-checkout).
* Consequence: setting the Shop Pay exception aside, there is no documented API path to create a Shopify
order (and therefore to take payment for one) outside Shopify's own checkout, on any plan.
### 2.3 What Checkout Extensibility actually allows
Checkout Extensibility is Shopify's supported customisation surface, and it runs inside Shopify's checkout:
| Technology | Customisation type | Availability (verbatim) |
| - | - | - |
| Checkout UI extensions | *"Add custom UI or content to the checkout process and **Order status** page"* | *"Shopify Plus. Thank you and Order status extensions are available to all plans except Shopify Starter. Market overrides are available to Advanced."* |
| Checkout UI extensions: post-purchase | *"Add new content to the post-purchase page"* | *"All plans except Shopify Starter. Currently in beta."* Live-store use requires access request. |
| GraphQL Admin API (`checkoutAndAccountsConfigurationUpdate`) | *"Customize the look and feel of checkout"* | *"Shopify Plus"* |
| Shopify Functions | *"Extend or replace key parts of Shopify's backend with custom logic"* | *"All plans except Shopify Starter."* Merchants with `checkout.liquid` customisations must upgrade first. |
| Web pixel extensions | *"Track customer behavior"* | *"All plans except Shopify Starter."* |
Source: <https://shopify.dev/docs/apps/build/checkout/technologies>.
Additional plan statements from Shopify's own docs:
* Checkout **styling**: *"Checkout styling customizations are available only to Shopify Plus merchants."*
(<https://shopify.dev/docs/apps/build/checkout/styling>)
* The Checkout **and Accounts** Configuration API *"styles checkout, customer accounts, and sign-in through
a single, unified API"* and is likewise gated: *"Checkout styling customizations are available only to
Shopify Plus merchants."*
(<https://shopify.dev/docs/apps/build/checkout/styling/checkout-and-accounts-configuration>)
* Market-specific checkout/account overrides: *"Merchants on Advanced or Plus who use markets can tailor
their checkout and customer accounts experience for regional and company location markets."*
(<https://shopify.dev/docs/apps/build/checkout/technologies>)
* Extensions run with declared **capabilities** in `shopify.extension.toml` — `api_access`,
`network_access`, `block_progress`, `collect_buyer_consent`
(<https://shopify.dev/docs/apps/build/checkout/capabilities>). The presence of a declared-capability
sandbox, rather than arbitrary page control, is the shape of the customisation model.
* Shopify's India pricing page summarises the same gating as a feature row, "Checkout customization":
**Limited / Limited / Limited / Full** across Basic / Grow / Advanced / Plus, and lists "Fully
customizable checkout" under "Just for Plus". (<https://www.shopify.com/in/pricing>)
### 2.4 `checkout.liquid` — deprecation, sunset and status
Verbatim current notice (*Deprecated* banner) on
<https://shopify.dev/docs/storefronts/themes/architecture/layouts/checkout-liquid> and repeated on
<https://shopify.dev/docs/apps/build/checkout>:
> *"`checkout.liquid` is now unsupported for the Information, Shipping, and Payment checkout steps.
> `checkout.liquid` and additional scripts were sunset for the **Thank you** and **Order status** pages on
> August 28, 2025. Script tags were sunset on those pages on August 28, 2025 for Plus stores, and are
> sunset for non-Plus stores on August 26, 2026."*
* `checkout.liquid` *"renders the checkout and is available only to Shopify Plus merchants."*
Non-Plus merchants customise in the theme editor instead.
(<https://shopify.dev/docs/storefronts/themes/architecture/layouts/checkout-liquid>)
* Guidance: *"Stores that still use `checkout.liquid` for the Thank you and Order status pages must upgrade
to Shopify Extensions in Checkout."* Merchants can *"revert to `checkout.liquid` … until its sunset
dates"*. (<https://shopify.dev/docs/apps/build/checkout>)
* **Dates summary:** Information/Shipping/Payment steps — already unsupported (no date restated on the
current page); Thank you + Order status `checkout.liquid` and additional scripts — sunset
**2025-08-28**; script tags on those pages — **2025-08-28** for Plus, **2026-08-26** for non-Plus.
* The **original** deprecation announcement date is **UNVERIFIED**: it is not restated on the current
pages, the `changelog.shopify.com` legacy site returns 404 for its sitemap/JSON/search endpoints, and
archived announcement URLs were not retrievable. The dates above are the authoritative current ones.
### 2.5 Is a fully custom (non-Shopify-hosted) checkout possible on any plan?
**No general-purpose path is documented, on any plan** — with one narrow, heavily gated exception for
Shop Pay Wallet (§2.6). The evidence chain for the general case:
1. The only documented successor to the removed Checkout APIs is a redirect to *"Shopify's web checkout"*
(§2.1, §2.2).
2. No `checkout*` mutation survives in the current Storefront API inventory (see §2.2 for the exact
surviving payment-adjacent members, and §2.6 for the Shop Pay exception).
3. Custom payment providers are not a merchant-side capability: *"The option to build a custom payment
extensions is limited to eligible Shopify Plus Merchants only. Contact Shopify Plus Support to confirm
eligibility."* and *"Only approved Partners can build payments extensions on Shopify's Payments
Platform."* (<https://shopify.dev/docs/apps/build/payments>) Those extensions still process payments
*"during the customer's purchase flow"* **in Shopify checkout**
(<https://shopify.dev/docs/apps/build/payments>).
4. If 3-D Secure is mandated in a country, a payment provider must support it: *"If you offer credit card
payment methods in a country where 3-D Secure authentication is mandated, then you must support 3-D
Secure authentication."* (<https://shopify.dev/docs/apps/build/payments/requirements>)
**UNVERIFIED (custom checkout domain).** No `shopify.dev` page was found that documents serving Shopify
checkout, or a Shopify-completed order flow, on a merchant-controlled non-Shopify domain. Even in the one
merchant-built-checkout path (§2.6), *"Most interactions in Shop Pay checkout happen within the context of a
Shopify-hosted popup window."* Shopify's India pricing FAQ instead describes embedding *buy buttons*
elsewhere: *"you can use the Buy Button sales channel to embed buy buttons on an external website or blog,
and let customers check out using Shopify Checkout."* (<https://www.shopify.com/in/pricing>) Absence of a
documented capability is reported here as "not documented", not as a contractual prohibition — Shopify's
Terms of Service were not reviewed for this.
**Payment-gateway implications if attempted (facts, not recommendations):** taking money outside Shopify's
checkout leaves no documented API to create the corresponding Shopify order (§2.2, §2.6 is the sole
exception); Shopify's supported custom-gateway mechanism (payments extensions) is Plus-only and
Partner-only (§2.5 point 3); and using a third-party provider at Shopify's checkout incurs Shopify's
third-party transaction fee, which on India plans is **2% (Basic) / 1% (Grow) / 0.6% (Advanced) / 0.2%
(Plus)** (<https://www.shopify.com/in/pricing>). Shopify also requires Shopify Payments for some adjacent
features — the India pricing comparison marks local-currency presentment, accepting local payment methods,
and estimating/collecting duties and taxes with *"Requires Shopify Payments"*
(<https://www.shopify.com/in/pricing>).
### 2.6 The one documented exception: Shop Pay Wallet (merchant-built checkout)
This is the only current first-party mechanism found where the **merchant's own checkout surface** takes
the buyer through payment and Shopify creates the order. Its constraints are strict and, for this merchant,
decisive.
* **What exists in the Storefront API** (`api_version: 2026-10`):
* `shopPayPaymentRequestSessionCreate` — *"Creates a Shop Pay payment request session for processing
payments. The session includes a checkout URL where customers complete their purchase and a token for
subsequent operations like submitting the payment."*
(<https://shopify.dev/docs/api/storefront/latest/mutations/shopPayPaymentRequestSessionCreate>)
* `shopPayPaymentRequestSessionSubmit` — *"Finalizes a Shop Pay payment request session… The
`idempotencyKey` argument ensures the payment transaction occurs only once, preventing duplicate
charges. On success, returns a `ShopPayPaymentRequestReceipt` with the processing status and a receipt
token."*
(<https://shopify.dev/docs/api/storefront/latest/mutations/shopPayPaymentRequestSessionSubmit>)
* **Purpose, verbatim:** *"Use Shop Pay Wallet to offer Shop Pay in your existing checkout… Add the Shop Pay
frontend components to your checkout. Create payment request sessions and respond to Shop Pay checkout
events. Submit payment requests and reconcile asynchronous order creation."*
(<https://shopify.dev/docs/api/commerce-components/pay>)
* **Hard eligibility constraints, verbatim from the same page:**
* *"You can't use the Shop Pay Wallet API on an existing Shopify store. To get started, create a new
store for Shop Pay Wallet."*
* Requirements include *"Complete the full Shopify Payments sign-up, then activate test mode for
development"*, declaring the allowed origins where the SDK loads, *"Configure API access for the
Storefront API and the GraphQL Admin API"*, and a content security policy allowing
`cdn.shopifycloud.com`, `cdn.shopify.com`, `shop.app`, `pay.shopify.com`, `*.shopifysvc.com` and
`*.stripe.com`.
* Production readiness requires *"Complete production Shopify Payments setup."*
* **It is a separate plan on that new store:** *"you'll notice that this plan has a refined UI, including
only the features and settings that are relevant to Shop Pay Wallet"*; *"🟡 Plan: Information about your
Shopify plan"*; *"Credit card rates vary by plan, and may require manual configuration by Shopify"*; and
*"the Shop Pay Wallet plan will have a Custom App pre-configured with the essential Storefront API
permissions required for use of Shop Pay Wallet."*
(<https://shopify.dev/docs/api/commerce-components/pay/shop-configuration>)
* **Division of responsibility:** the merchant system remains source of truth for catalog/cart, while
*"Shopify is the source of truth for Shop Pay payment and order records"*, *"Shopify processes the payment
using Shop Pay and Shopify Payments"*, and *"Most interactions in Shop Pay checkout happen within the
context of a Shopify-hosted popup window."* Order creation is asynchronous: *"Shopify creates orders
asynchronously. Don't rely only on the client-side `paymentcomplete` event to confirm order creation,
because the customer can close the popup or lose network connectivity. Use webhooks and a reconciliation
job…"* — subscribing to `ORDERS_CREATE` and `ORDER_TRANSACTIONS_CREATE`.
(<https://shopify.dev/docs/api/commerce-components/pay>)
* **Net characterisation:** not a general-purpose custom checkout. It is Shop-Pay-only,
Shopify-Payments-only, unavailable on an existing store, and provisioned as its own plan; the payment
authorisation itself still runs in a Shopify-hosted popup. Whether an India-based merchant can obtain
Shopify Payments (and therefore this plan at all) is the open question in [§4.1](#41-shopify-payments-in-india-inr-domestic)
— **UNVERIFIED** for India specifically, since Shopify does not publish a country eligibility list for
Shop Pay Wallet on the pages reviewed.
---
## 3. Headless customer accounts
### 3.1 Which API is current
* **Current: the Customer Account API** — a versioned GraphQL API (`api_version: 2026-10` on
<https://shopify.dev/docs/api/customer/latest>), listed as versioned alongside the Admin, Storefront and
other APIs on <https://shopify.dev/docs/api/usage/versioning>. *"The Customer Account API offers a secure
way to access private customer-scoped data… You can access data including customers, orders, payments,
fulfillment, discounts, refunds, and metafields."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api>)
* **Older: the Storefront API customer flow** (`customerAccessTokenCreate`, `customerAccessTokenRenew`,
`customer(customerAccessToken:)`, `customerCreate`, `customerRecover`, …). The reference for
`customerAccessTokenCreate` now opens with: *"Requires `unauthenticated_write_customers` access scope.
For **legacy customer accounts only**."*
(<https://shopify.dev/docs/api/storefront/latest/mutations/customerAccessTokenCreate>)
Note the precise status: the mutation itself is **not** flagged `Deprecated` in the reference (only its
`userErrors` field is); what is deprecated is **legacy customer accounts** as a product surface, and
Shopify recommends the Customer Account API for custom storefronts.
* **Legacy customer accounts deprecation (dated):** changelog post *"Legacy customer accounts are now
deprecated"* — `postedAt 2026-02-26`, `effectiveAt 2026-02-19`, tagged *"Deprecation announcement"*.
Verbatim: *"Legacy customer accounts are no longer available to new stores and existing stores not using
it. Shopify will stop providing feature updates and technical support for this older version."* and
*"A final sunset date for legacy customer accounts will be announced later in 2026."* For custom
storefronts: *"If you build custom storefronts or apps that currently use Storefront API customer-scoped
mutations, we recommend switching to the Customer Account API as soon as possible."*
(<https://shopify.dev/changelog/posts/legacy-customer-accounts-are-deprecated>)
* **UNVERIFIED (final legacy sunset date):** as of 2026-10-13 no final sunset date appears in the recent
changelog feed (<https://shopify.dev/changelog.md>) or the 2026-01/2026-04/2026-07/2026-10 release notes.
The changelog explicitly says it will be announced "later in 2026", so it is still pending.
### 3.2 How authentication works
* **Protocol:** OAuth 2.0 / OpenID Connect. Two client types: *"Confidential - A client capable of keeping
a client secret confidential… typically used for server-side applications"* and *"Public - A client
unable to keep a client secret confidential."* — *"For public clients, we use Proof Key for Code Exchange
or PKCE."* (<https://shopify.dev/docs/api/customer>)
* **Discovery (use these, not hardcoded URLs):** on the storefront domain,
`GET /.well-known/openid-configuration` (standard OIDC format) and
`GET /.well-known/customer-account-api` (Shopify-specific: GraphQL + MCP endpoints).
(<https://shopify.dev/docs/api/customer>)
* **Documented endpoint values:**
```
"authorization_endpoint": "https://{shopDomain}/authentication/oauth/authorize",
"token_endpoint": "https://{shopDomain}/authentication/oauth/token",
"end_session_endpoint": "https://{shopDomain}/authentication/logout",
"jwks_uri": "https://{shopDomain}/authentication/.well-known/jwks.json",
"issuer": "https://shopify.com/authentication/{shopId}"
```
(<https://shopify.dev/docs/api/customer>)
* **Scope string:** `openid email customer-account-api:full` (required)
(<https://shopify.dev/docs/api/customer>)
* **Session/silent auth:** append `&sso=silent` to the cart's `checkoutUrl` to have checkout verify the
buyer's live Customer Accounts browser session via an OIDC-compliant flow. Caveat, verbatim: *"`sso=silent`
does not fall back to the buyer identity on the cart… If the buyer's session on the Customer Accounts
domain has expired, checkout treats them as a guest — even if a valid `customerAccessToken` is set on the
cart. The two authorization scopes are independent."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/checkout-authentication>)
* **Cart-based checkout auth:** *"The `customerAccessToken` on the cart authenticates the buyer and
authorizes the checkout session for that specific cart. The authorization is scoped to this cart — it
doesn't establish a broader session on the Customer Accounts domain."* Requirements: set it via
`cartBuyerIdentityUpdate` (or at cart creation), refresh it before expiry, and after refreshing you
*"must also call `cartBuyerIdentityUpdate` again to update the cart with the new token."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/checkout-authentication>)
* **Where the login UI lives (hosted).** *"**Seamless authentication**: The **hosted** customer
authentication system enables passwordless login for customers, allowing them to have a single sign-on
experience across custom storefronts, online store, accounts, and checkout."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api>) The documented
integration is a full-page redirect (`window.location.href = authorizationRequestUrl.toString()`), not an
embedded widget (<https://shopify.dev/docs/api/customer>).
* **UNVERIFIED (embedding / login-page customisation):** no `shopify.dev` page was found documenting an
embedded/iframe login, nor a documented iframe-blocking statement. What *is* documented is branding of
sign-in surfaces via the Plus-only Checkout and Accounts Configuration API
(<https://shopify.dev/docs/apps/build/checkout/styling/checkout-and-accounts-configuration>).
### 3.3 Setup and plan requirement
* **Required app configuration:** enable customer accounts in admin (Settings → Customer accounts →
*"Under **Accounts in online store and checkout** … Choose **Customer accounts**"*), then in the
**Headless** channel choose **Customer Account API settings** (or Hydrogen → **Storefront settings**),
pick the client type (Public clients / Web clients / Mobile clients / Confidential clients), copy the
client ID (and secret if applicable), set storefront permission controls, record the Authorization /
Token / Logout endpoints, and configure **Callback URL(s)**.
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/getting-started>)
* **Prerequisites:** *"You have **Apps and channels** permissions on the Shopify store that you're working
with."* and *"Shopify's customer accounts is required to use the Customer Account API."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/getting-started>)
* **Plan requirement — no minimum plan documented.** The Customer Account API docs name rate-limit tiers by
plan (see §3.5) but never state a required plan. **UNVERIFIED / partly evidenced:** the error list does
include a generic gate — `402 Payment Required` → `{"errors": "This shop's plan does not have access to
this feature"}` — which shows some Customer Account API features can be plan-gated, but the doc does not
say which. (<https://shopify.dev/docs/api/customer>) It is **not** documented as Plus-only.
* **Merchant-side state:** because legacy accounts are closed to new stores and existing stores not using
them, and the recommended path is upgrading customer accounts
(<https://shopify.dev/changelog/posts/legacy-customer-accounts-are-deprecated>), a store's
customer-accounts version determines whether the legacy Storefront mutations work at all.
### 3.4 What data it exposes
* Top-level scope, verbatim: *"customers, orders, payments, fulfillment, discounts, refunds, and
metafields."* (<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api>)
* The reference's connection types include `OrderConnection`, `FulfillmentConnection`,
`CustomerAddressConnection`, `ReturnConnection`/`ReturnableLineItemConnection`,
`DraftOrderConnection`, `PaymentScheduleConnection`, `CompanyLocationConnection`/`CompanyContactConnection`
(B2B), `MetafieldReferenceConnection`, `SaleConnection`, `SalesAgreementConnection`.
(<https://shopify.dev/sitemap_standard.xml.gz> → `docs/api/customer/latest/connections/…`;
entry point <https://shopify.dev/docs/api/customer>)
* Addresses: `customerAddressCreate` / `customerAddressUpdate` / `customerAddressDelete` / `customerUpdate`
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/customer-accounts>).
* **`2026-10` removals (action required):** *"The deprecated `Customer.lastIncompleteCheckout` field is
removed, along with the unreachable `Checkout` type subtree. Remove any queries for
`Customer.lastIncompleteCheckout` or nested `Checkout` fields before upgrading; there is no Customer
Account API replacement."* Also `CustomerAddressInput`/`CustomerAddress` gained `countryCode` (two-letter
`CountryCode`), with `territoryCode` deprecated but still working and `countryCode` taking precedence.
(<https://shopify.dev/changelog/release-notes/2026-10>)
* **Channel granularity of order history:** no `shopify.dev` statement was found restricting Customer
Account API order history to one sales channel. **UNVERIFIED** — the docs do not describe channel
filtering of the customer's orders.
### 3.5 Rate limits (relevant, because a headless account area multiplies calls)
* *"Rate-limiting method: Calculated query cost, plus a per-customer request limit"*
* *"Quota: 7,500 cost points per app, per store and customer"*
* Standard **100 points/second**; Advanced Shopify **200**; Shopify Plus **200**; Shopify for enterprise
(Commerce Components) **400**
* *"Per-customer request limit: 3,000 requests per minute per store and customer, shared across all apps, in
a fixed 60-second window"*
* Most fields cost 1 point and most mutations 10 points; responses return `requestedQueryCost` /
`actualQueryCost`; `Shopify-GraphQL-Cost-Debug=1` returns a per-field breakdown. Over-quota → `THROTTLED`
(HTTP 200 for cost, HTTP 429 for the per-customer request limit, with `Retry-After`).
Source: <https://shopify.dev/docs/api/customer#rate-limits>
### 3.6 India-specific caveats
**UNVERIFIED — no India-specific customer-account restriction was found on primary sources.** What was
searched: the full Customer Account API reference and the headless Customer Account API guide set
(<https://shopify.dev/docs/api/customer>,
<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api>,
…/getting-started, …/authenticate-customers, …/customer-accounts, …/checkout-authentication,
…/market-aware-auth-urls) contain no India-specific limitation; and a Shopify Community search for
India-specific customer-account/OTP issues returned no relevant thread
(<https://community.shopify.com/search.json?q=customer+accounts+India+OTP>). `help.shopify.com`'s customer
accounts pages could not be retrieved (§7), so a merchant-facing India caveat there cannot be ruled out.
Note only, not a caveat: `market-aware-auth-urls` documents `locale` and `region_country` parameters for
market-aware login (<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/market-aware-auth-urls>).
### 3.7 Cross-channel customer identity
Documented sharing, which is directly relevant to running a theme storefront and a headless storefront on
one shop:
* *"The hosted customer authentication system enables passwordless login for customers, allowing them to
have a single sign-on experience across custom storefronts, online store, accounts, and checkout."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api>)
* *"Customer accounts allow you to seamlessly persist customer logins across online store, Hydrogen, and
checkout."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/getting-started>)
* *"Shopify's customer accounts is required to use the Customer Account API."* (same page) — so the sharing
claim holds when both surfaces use the same (current) customer accounts.
---
## 4. India-specific constraints
### 4.1 Shopify Payments in India (INR, domestic)
* Shopify's own India pricing FAQ states Shopify Payments is country-restricted: *"Some features vary by
country—for example, **Shopify Payments is available only in certain countries**—so pricing and payment
options can differ depending on where your business is based."* (<https://www.shopify.com/in/pricing>)
* Shopify's **Shopify Payments Terms of Service** list Part II (Regional Terms) as exactly:
**A. Australia, B. Canada, C. United Kingdom, D. United States** — with no India regional terms, and
*"The Regional Terms applicable to your Designated Country supplement… the Global Terms."* Identical for
the India-locale copy. (<https://www.shopify.com/legal/terms-payments>,
<https://www.shopify.com/in/legal/terms-payments>; no occurrence of "Designated Country is India")
* **Community evidence (not documentation):** on <https://community.shopify.com/t/why-shopify-payments-is-not-available-in-india/412204>
a community member replied on 2025-05-02: *"While Shopify Payments is not yet available in India, you can
check other supported payment gateways here: …"*. A thread opened **2026-09-02** — *"Shopify Payments in
India — Can Shopify Please Share an Update?"* — has three posts, **all from merchants, with no Shopify
staff reply**, and no availability statement; the merchants describe having to *"rely on third-party
payment gateways"* (<https://community.shopify.com/t/shopify-payments-in-india-can-shopify-please-share-an-update/675672>).
Earlier threads in the same vein: <https://community.shopify.com/t/shopify-payments-in-india/396271>,
<https://community.shopify.com/t/when-will-shopify-payments-option-be-available-in-india/557214>.
* **Verdict:** the weight of Shopify's own country-scoping statements plus consistent, still-active
merchant reports indicates **Shopify Payments is not available to India-based merchants for domestic INR
selling**. **The official confirmation page could not be retrieved** (`help.shopify.com` returns HTTP 403
bot challenges — see §7), so treat the *official* availability wording as **UNVERIFIED** and the
conclusion as strongly evidenced but not first-party-verbatim.
* Practical consequence documented on the pricing page: features marked *"Requires Shopify Payments"*
(showing prices in local currencies, accepting local payment methods, estimating/collecting duties and
taxes) are therefore unavailable in India as configured.
(<https://www.shopify.com/in/pricing>)
### 4.2 Third-party gateways Shopify supports for India
* Shopify's canonical list is the country-filtered page
**<https://www.shopify.com/payment-gateways?country=in>** (the help centre points to this list:
*"Shopify's list of payment gateways by country can help you find out which payment gateway are available
in your country and what currency they support."* — <https://help.shopify.com/en/manual/payments>).
The page is client-rendered; the gateway dataset is embedded in the page payload.
* I parsed that payload (country identifier `21`; inferred as India because several unmistakably
India-only providers are tagged with exactly `[21]`, and "CCAvenue UAE" is tagged `[1042]`, not `21`).
India-tagged providers, as named in Shopify's data:
| Provider (as displayed) | India tag | Internal name in payload |
| - | - | - |
| `01 Cards, UPI, NB, Wallets by Razorpay` | 21 + others | Razorpay Payments-New |
| `Cards Onsite by 1Razorpay` | 21 + 1 | Razorpay Direct - Credit Cards |
| `Cards, UPI, NB by PayU India` | 21 + 2 | Payu India |
| `Onsite Card Payments by PayU India` | 21 only | Seamless Payment App Dev |
| `CCAvenue` | 21 only | CCAVTest |
| `BillDesk Payment App` | 21 only | BilldeskPaymentApp |
| `01 PhonePe PG (UPI, Cards, EMI & NetBanking)` | 21 only | PPE PG |
| `Pay securely with Pine Labs` | 21 only | Plural |
| `PayGlocal` | 21 only | PGDeveloperApp |
| `airpay` | 21 + 1 | Airpay Payment Services |
| `2C2P` | 21 + 12 | 2C2P Payment Gateway |
**Confidence note:** this list is reconstructed from the minified client data payload of Shopify's own
page (so the provider names are first-party), but the `21 ⇒ India` mapping is **inferred**, not printed
anywhere on the page. Verify against <https://www.shopify.com/payment-gateways?country=in> in a browser
before relying on it. Treat as **partially verified**.
* Distinction to keep in mind: "integrated"/onsite gateway apps (selected at Shopify checkout) versus
manual payment methods recorded against an order. The India-tagged entries above are provider apps
surfaced through Shopify's payment-gateway list; `help.shopify.com`'s manual-payment-methods page could
not be retrieved to enumerate those separately (§7).
### 4.3 Cash on Delivery
* Shopify's help centre documents manual payment methods including Cash on Delivery at
<https://help.shopify.com/en/manual/payments/manual-payments> and
<https://help.shopify.com/en/manual/payments/manual-payments/cash-on-delivery> (a legacy
"Advanced Cash on Delivery" app page also exists at
<https://help.shopify.com/en/manual/payments/cash-on-delivery>). One such page load did succeed during
this research for the sibling section on additional payment methods
(<https://help.shopify.com/en/manual/payments/additional-payment-methods>), but **every COD page request
returned HTTP 403**, so **COD's exact configuration, availability and India-specific rules are
UNVERIFIED**.
* Structural fact that is verified and relevant: payment-method choice happens **at Shopify's checkout**
(*"When a customer checks out, they can choose to pay for their order using any of the methods that
you've activated in the Payment providers area"* — <https://help.shopify.com/en/manual/payments>), and
the headless cart's `checkoutUrl` redirects there
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage>). The
Storefront Cart API reference exposes **no** documented mutation for selecting or configuring a payment
method on a cart (inventory check: <https://shopify.dev/sitemap_standard.xml.gz>; the only related type is
the `PaymentSettings` object).
### 4.4 Who can be a payment provider in India
* Verified, plan-gated statement applicable to any country: *"The option to build a custom payment
extensions is limited to eligible Shopify Plus Merchants only. Contact Shopify Plus Support to confirm
eligibility."* and *"Only approved Partners can build payments extensions on Shopify's Payments
Platform."* (<https://shopify.dev/docs/apps/build/payments>)
* Payment extensions must integrate with Shopify checkout, and five types are documented (credit card;
credit card with UI extensibility; custom credit card hosted fields; alternative payment; offsite;
redeemables). (<https://shopify.dev/docs/apps/build/payments>)
* *"If you offer credit card payment methods in a country where 3-D Secure authentication is mandated, then
you must support 3-D Secure authentication."* (<https://shopify.dev/docs/apps/build/payments/requirements>)
* **UNVERIFIED (India-specific provider rules):** no `shopify.dev` or retrievable `help.shopify.com` page
was found stating RBI/regulatory requirements for who may be a payment provider in India, nor any
rule that an Indian entity/Indian gateway is mandatory. Nothing found either way. Community threads
discuss the practical need for Indian gateways but are not authoritative
(<https://community.shopify.com/t/how-can-i-enable-multi-currency-checkout-in-india-without-shopify-payments/270149>).
### 4.5 Shopify Markets / multi-currency for a single-country INR store
* **Markets context on the Storefront API is supported and opt-in.** The Storefront API exposes markets /
international pricing, and `@inContext` applies country/language (and, from `2026-10`, `channelId`)
context to a query; the cart's `buyerIdentity.countryCode` drives cart pricing
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/markets>,
<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/in-context>,
<https://shopify.dev/docs/changelog/release-notes/2026-10>,
<https://shopify.dev/docs/api/storefront/latest/mutations/cartBuyerIdentityUpdate>).
* **No documentation requires enabling Markets for a single-country INR store**, and no India-specific
restriction on the Storefront API's `@inContext` usage was found in those pages. **UNVERIFIED** as a
positive statement (absence of a requirement in the docs is not the same as a documented "not required").
* **Documented plan/feature coupling:** presenting prices in local currencies, accepting local payment
methods, and estimating/collecting duties and taxes are all marked *"Requires Shopify Payments"* on
Shopify's India pricing comparison (<https://www.shopify.com/in/pricing>) — and Shopify Payments'
availability in India is the open question in §4.1.
* **Community evidence (not documentation):** a 2024-08-24 reply in
<https://community.shopify.com/t/selling-in-multiple-currencies-from-india/349404> states: *"since
multi-currency is not available because India is not supported by Shopify payments, you can only choose
one currency that you will use to your store"*; follow-ups in 2025 and new threads in 2026 repeat the
same complaint, including a 2026-02-16 thread seeking multi-currency checkout "in India directly"
(<https://community.shopify.com/t/how-to-enable-multicurrency-checkout-on-my-store-based-in-india/588501>).
Label this as community-sourced, **not** a Shopify statement.
* **India tax/invoicing (GST display, INR invoicing rules):** **UNVERIFIED** — no `shopify.dev` page
describing India GST price-display or invoicing requirements for headless storefronts was found, and the
relevant `help.shopify.com` pages were unreachable (§7).
---
## 5. Shopify changes in 2026 that materially affect a headless build
### 5.1 API sunset cadence
See [§0.2](#02-release-and-deprecation-cadence). The load-bearing facts: quarterly releases, ≥12 months of
support per stable version, ≥9 months of overlap, fields deprecated in one release can be removed in the
next, inaccessible versions fall forward rather than failing, and `X-Shopify-API-Version` reports the
version actually used (<https://shopify.dev/docs/api/usage/versioning>). Triggering events inside 2026:
`2025-10` dies 2026-10-16; `2026-01` is the oldest accessible stable version.
### 5.2 Storefront API rate limits — the model has changed, and the bucket figures are not current
Verbatim from the Storefront API overview, section **Rate limits**
(<https://shopify.dev/docs/api/storefront#rate-limits>):
> *"The Storefront API scales with buyer traffic: requests from real buyers aren't subject to a fixed
> request-per-minute limit. Automated traffic and checkout creation are limited."*
>
> * **Rate-limiting method**: None for buyer traffic
> * **Automated traffic**: Bots and crawlers are limited, most strictly when unsigned. Sign with Web Bot
> Auth for higher limits.
> * **Checkout creation**: Throttled per minute, returning a `200 Throttled` error
> * **Tokenless access**: Query complexity limit of 1,000
Additional documented details:
* *"If a request appears to be malicious, Shopify responds with a `430 Shopify Security Rejection` error
code."* (<https://shopify.dev/docs/api/storefront#rate-limits>)
* **Checkout-level throttle:** *"Shopify limits the amount of checkouts that can be created on the
Storefront API per minute. If an API client exceeds this throttle, then a `200 Throttled` error response
is returned."* Recommended handling: a request queue with exponential backoff.
(<https://shopify.dev/docs/api/storefront#rate-limits>)
* **Tokenless access** has a query complexity limit of **1,000**, calculated like GraphQL Admin API costs;
exceeding it returns `MAX_COMPLEXITY_EXCEEDED` with `cost` and `maxCost` in `errors.extensions`.
(<https://shopify.dev/docs/api/storefront#rate-limits>)
* **Public access capacity scales with the number of buyers, based on their IP address**; apps can have a
maximum of 100 active storefront access tokens per shop. Private tokens must be sent in
`Shopify-Storefront-Private-Token`; buyer-derived server requests must also send the case-sensitive
`Shopify-Storefront-Buyer-IP` header. (<https://shopify.dev/docs/api/storefront>)
* **Web Bot Auth, dated:** changelog *"Bots and agents should identify themselves via Web Bot Auth"* —
`postedAt 2026-05-07`, `effectiveAt 2026-05-30`, flagged *"Action required"*: *"Shopify now applies
stricter rate limits to bots and agents that access the Storefront API and Shopify-hosted online store
pages. Bots and agents that don't sign their requests are subject to the strictest limits."*
(<https://shopify.dev/changelog/posts/bots-and-agents-should-identify-themselves-via-web-bot-auth>)
**On the specific "leaked/actual" figures in the question (query-cost bucket size and restore rate per
storefront token): these are not published for the Storefront API in the current documentation, and the
current documentation says the model does not work that way for buyer traffic.** The generic
leaky-bucket page explains that *"Most Shopify rate limits are enforced with a leaky bucket algorithm"* and
that *"Both the bucket size and the restore rate vary by API and by plan"*, but then explicitly carves out
the Storefront API: *"The Storefront API works differently. Buyer traffic isn't rate-limited at all, and
the limits it does apply are described in Storefront API rate limits."*
(<https://shopify.dev/docs/api/usage/limits>) The only current cost-based bucket figures in Shopify's docs
are for other APIs:
| API | Documented figures | Source |
| - | - | - |
| Storefront API | **No** bucket size / restore rate published; buyer traffic not fixed-rate-limited; bots limited; checkout creation throttled per minute; tokenless complexity 1,000 | <https://shopify.dev/docs/api/storefront#rate-limits>, <https://shopify.dev/docs/api/usage/limits> |
| Customer Account API | Quota 7,500 cost points per app per store+customer; 100 pts/s Standard, 200 Advanced/Plus, 400 enterprise; 3,000 requests/min per store+customer | <https://shopify.dev/docs/api/customer#rate-limits> |
| GraphQL Admin API | 100 pts/s Standard, 200 Advanced Shopify, 1000 Plus, 2000 enterprise (leaky bucket) | <https://shopify.dev/docs/apps/build/apis/graphql-admin/rate-limits> |
| Carts specifically | *"Carts don't have any global API rate limits"* but the cart *"is subject to the same throttling restrictions as the Storefront API"* | <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart> |
So: any figure like "1,000-point bucket, 50 points/second restore per storefront token" should be treated as
**legacy/unverified** against current primary sources.
### 5.3 `unauthenticated_read_*` scopes do **not** cover cart mutations
From the access-scopes reference, the unauthenticated (Storefront API) scope table maps:
| Scope | Access |
| - | - |
| `unauthenticated_read_checkouts` **`unauthenticated_write_checkouts`** | **`Cart`** |
| `unauthenticated_read_content` | Storefront content: `Article`, `Blog`, `Comment` |
| `unauthenticated_read_customer_tags` | `tags` field on `Customer` |
| `unauthenticated_read_customers` `unauthenticated_write_customers` | `Customer` |
| `unauthenticated_read_metaobjects` | `Metaobject`, `MetaobjectField`, `MetaobjectSEO` |
| `unauthenticated_read_product_inventory` | `quantityAvailable`, `totalAvailable` |
| `unauthenticated_read_product_listings` | `Product`, `Collection` |
| `unauthenticated_read_product_pickup_locations` | `Location`, `StoreAvailability` |
| `unauthenticated_read_product_tags` | `tags` field on `Product` |
| `unauthenticated_read_selling_plans` | Selling plan content on `Product` |
| `unauthenticated_read_shop_pay_installments_pricing` | `shopPayInstallmentsPricing` |
Source: <https://shopify.dev/docs/api/usage/access-scopes#unauthenticated-access-scopes>
* **So: read scopes alone are insufficient for cart writes. Cart reads need
`unauthenticated_read_checkouts`; cart mutations need `unauthenticated_write_checkouts`.** The docs
further state: *"Use unauthenticated access scopes to interact with a store on behalf of a customer"* and
*"For the Headless channel, permissions are managed in your Shopify admin. Refer to request storefront
permissions."* (<https://shopify.dev/docs/api/usage/access-scopes>, and
<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/manage-headless-channels>
which lists *"Edit storefront permissions"* as a Headless-channel task).
* Related scope requirements seen in the reference: `customerAccessTokenCreate` *"Requires
`unauthenticated_write_customers` access scope."*
(<https://shopify.dev/docs/api/storefront/latest/mutations/customerAccessTokenCreate>)
* Token model: public access token (`storefrontAccessTokenCreate` on the GraphQL Admin API, sent as
`X-Shopify-Storefront-Access-Token`) vs private access token (sent as `Shopify-Storefront-Private-Token`,
obtained via the Headless channel, a delegate access token, or by requesting unauthenticated access
scopes). (<https://shopify.dev/docs/api/storefront>) The repository's current flow — client-credentials
admin token, then mint a storefront access token via `…/admin/api/{version}/storefront_access_tokens.json`
(`src/lib/shopify.ts`) — corresponds to the **public** token category; the GraphQL equivalent
`storefrontAccessTokenCreate` is not marked deprecated in the current reference
(<https://shopify.dev/docs/api/admin-graphql/latest/mutations/storefrontAccessTokenCreate>).
### 5.4 Other 2026 changes worth knowing
* **2027-01 action required (announced 2026-10-08):** *"New `owner_type` field for metafield declarations in
Checkout and Customer Account UI extensions, required in 2027-01"*
(<https://shopify.dev/changelog/posts/metafield-owner-types-required-for-checkout-and-customer-account-ui-extensions>).
* **Customer Account API `2026-10` removals** (§3.4) and **`countryCode` on addresses**
(<https://shopify.dev/changelog/release-notes/2026-10>).
* **Cart line identification (`viewKey`) landed in `2026-07`** (§1.4), including a required migration away
from `cart.discountAllocations`.
* **`@inContext` `channelId` (`2026-10`)** — channel-scoped availability/pricing in a single query
(<https://shopify.dev/changelog/release-notes/2026-10>).
* **Deprecation announcements in 2026 include legacy customer accounts (2026-02-26)** (§3.1) and the Global
Catalog REST API, *"Global Catalog REST API stops serving traffic on November 2, 2026"*
(<https://shopify.dev/changelog.md>, post dated 10.09).
---
## 6. Alternative headless approaches
### 6.1 Hydrogen — and whether adopting it means abandoning the existing TanStack Start app
* **Hydrogen is a framework, not a drop-in library.** *"Built on React Router, Hydrogen is a Shopify
storefront toolkit that provides a set of components, functions, and utilities used for building custom
storefronts on React Router apps. Hydrogen is built and optimized to use data coming from the Storefront
API."* (<https://shopify.dev/docs/storefronts/headless/getting-started/build-options>)
* Shopify's build-options table frames the three paths as: Hydrogen for *"a custom storefront with a React
Router app"*; **Hydrogen React** for *"a custom storefront using a third-party React framework and
Shopify's library of components, reusable functions, and utilities"*; or the **Headless channel** to build
*"headless using the framework of your choice and Shopify's backend using only the Storefront API."*
(same page)
* **Hydrogen React is explicitly framework-agnostic:** *"Hydrogen React is a performant, framework-agnostic
library of React components, reusable functions, and utilities for interacting with Shopify's Storefront
API. It's bundled with Hydrogen, but can be used by any React-based web app."*
(<https://shopify.dev/docs/api/hydrogen-react>). Stated as fact: adopting Hydrogen the framework means
running a React Router app, whereas Hydrogen React can be used inside any React app.
* **Deployment:** the Hydrogen channel deploys to **Oxygen** (Shopify's included edge hosting) and
*"automatically creates and populates public and private environment variables necessary for integration
with the Storefront API"*, with GitHub integration and order attribution. *"Make headless and self-hosted
Hydrogen experiences possible in the Headless channel without needing to create a custom app."*
(<https://shopify.dev/docs/storefronts/headless/getting-started/build-options>) A migration guide exists at
<https://shopify.dev/docs/custom-storefronts/hydrogen/migrate>.
### 6.2 Running the classic theme storefront and the headless storefront on one Shopify backend
* **Channels are designed for exactly this.** *"You can use the Shopify admin to manage your commerce data
across multiple channels to make sure that all customer touchpoints are in sync. You can also create a
custom channel complementary to your online store channel, such as a mobile app, or create your own custom
website to replace your online store."*
(<https://shopify.dev/docs/storefronts/headless/getting-started/build-options>)
* **Shared — the product catalog and inventory:** one Shopify store, one catalog; the Headless channel
*"gives you all of Shopify's channel features, such as product publishing, scheduled product publishing,
analytics, and reporting sales by channel"*, and *"Order attribution is at the channel level, and a
Headless storefront is treated as a channel."* Publishing is per channel, so per-channel product
publication must be managed in admin.
(<https://shopify.dev/docs/storefronts/headless/getting-started/build-options>,
<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/manage-headless-channels>)
* **Shared — customers and their logins:** see [§3.7](#37-cross-channel-customer-identity): *"single
sign-on experience across custom storefronts, online store, accounts, and checkout"*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api>) and *"persist
customer logins across online store, Hydrogen, and checkout"*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/getting-started>).
* **Not shared — carts.** Two different cart implementations exist and no bridging mechanism is documented:
the theme storefront uses the Liquid/Ajax cart, and *"The Ajax API can only be used by themes that are
hosted by Shopify. **You can't use the Ajax API on a Shopify custom storefront.**"*
(<https://shopify.dev/docs/api/ajax>) The headless storefront uses the Storefront Cart API
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart>). No `shopify.dev`
page documents a cart shared between the two. What *is* shared is the destination: both ultimately send
the buyer to the same shop's Shopify-hosted checkout (§2.1). Treat carts as **explicitly not shared**.
* **Orders:** all channels write orders into the same Shopify admin, attributed by channel
(<https://shopify.dev/docs/storefronts/headless/getting-started/build-options>).
### 6.3 Headless storefront entitlements
* Documentation: *"You can have a maximum of 100 active storefronts and access tokens per shop."*
(<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/manage-headless-channels>)
* Shopify's India pricing feature table row **"Build headless storefronts"** shows **1 / 1 / 1 / 25** for
Basic / Grow / Advanced / Plus. (<https://www.shopify.com/in/pricing>)
* These two figures are not obviously reconcilable, and this is materially important for a merchant on a
non-Plus plan planning a second (or staging) headless storefront. Flagged as an **apparent
discrepancy — verify with Shopify**; neither page explains the relationship.
* Also Plus-only per the same pricing page's "Just for Plus" list: *"High volume checkout"*, *"Bot
protection"*, *"Up to 500% higher API call limits"* (<https://www.shopify.com/in/pricing>), consistent with
cart bot protection being Plus (<https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart>).
---
## 7. Verification notes and gaps
**Source quality**
* Everything cited to `shopify.dev`, `www.shopify.com/legal`, `www.shopify.com/in/pricing` or
`www.shopify.com/payment-gateways` is **Shopify first-party**.
* Items cited to `github.com/Shopify/storefront-api-feedback` are Shopify-hosted but **community/answer
content**, explicitly labelled with their date where used.
* Items cited to `community.shopify.com` are **community forum posts**, not documentation. Where a
community reply is used (India payments, India multi-currency), it is labelled as such and not treated as
establishing a fact.
**What could not be retrieved**
* `help.shopify.com` is behind a bot challenge: the overwhelming majority of requests returned
`403` with a "Verifying your connection…" body, for both `curl` (including a browser User-Agent) and the
fetch tool. Two pages did return —
<https://help.shopify.com/en/manual/payments> and
<https://help.shopify.com/en/manual/payments/additional-payment-methods> — and are cited for the
payment-method-selection statement only. Consequently the following are **UNVERIFIED**: the official
Shopify Payments country-availability list; India's third-party provider list as Shopify's help centre
words it; Cash on Delivery configuration and India rules; Shopify's manual payment method list; India
billing/GST/invoicing guidance.
* The legacy changelog host `changelog.shopify.com` returns 404 for `sitemap.xml`, `posts.json` and
`search`, so the **original** `checkout.liquid` deprecation announcement (and its first-round deadlines)
could not be retrieved; only the current, authoritative deprecation notice on `shopify.dev` is reported.
* `shopify.dev/changelog.md` returns only the most recent window of entries; `?page=2` returns the same
first page. Older announcements (e.g. the Storefront rate-limit model change, if it had a post) were
therefore not systematically enumerable. Individual post URLs work and `.md` fetches succeed.
**Reverse-engineered data (treat as partial)**
* The India payment-gateway table in [§4.2](#42-third-party-gateways-shopify-supports-for-india) comes from
the embedded client data payload of <https://www.shopify.com/payment-gateways?country=in>. The provider
names and their country arrays are first-party data, but the `country id 21 ⇒ India` mapping is inferred.
The parse was validated internally (India-only providers such as BillDesk, PhonePe, Pine Labs/Plural,
PayGlocal, CCAvenue are tagged with exactly `[21]`; "CCAvenue UAE" is `[1042]`), but it is still an
inference.
**Open questions flagged for follow-up**
1. Which host the Storefront API returns in `checkoutUrl` for this shop (myshopify.com vs a custom/primary
domain) — the only first-party statement is from 2022 and unconfirmed (§1.3). An `X-Shopify-API-Version`
/ `checkoutUrl` probe against the live store would settle both this and the fall-forward version in §0.1.
2. The final sunset date for legacy customer accounts (announced as "later in 2026", not yet published)
(§3.1).
3. Whether the Customer Account API is plan-gated, and if so how (only a generic `402 … plan does not have
access` error code is documented) (§3.3).
4. Whether "1 headless storefront" on Basic/Grow/Advanced is a hard entitlement or a documentation
inconsistency with the "100 storefronts per shop" limit (§6.3).
5. Any official India availability statement for Shopify Payments, and India COD/GST rules (§4).
**File location.** This repo keeps prose notes under `docs/` (e.g. `docs/analytics-setup.md`) and has no
existing research folder, so this document was placed in `docs/research/`. Raw fetched sources used for it
are cached (gitignored) under `.cache/shopify-docs/`, with the fetcher at `.cache/fetch.sh`.
---
## 8. Primary source index
| URL | Used for |
| - | - |
| <https://shopify.dev/docs/api/usage/versioning> | Version table, support windows, fall-forward, cadence, deprecation practice |
| <https://shopify.dev/docs/api/usage/limits> | Global array cap 250, pagination cap 25,000, leaky bucket, Storefront carve-out |
| <https://shopify.dev/docs/api/usage/access-scopes> | Unauthenticated scopes → `Cart`/`Customer` mapping |
| <https://shopify.dev/docs/api/storefront> | Endpoint, token types, rate limits, bot auth, buyer-IP header, 100-token cap |
| <https://shopify.dev/docs/api/storefront/latest/objects/Cart> | `checkoutUrl`, Cart fields, 250-value inputs |
| <https://shopify.dev/docs/api/storefront/latest/queries/cart> | `cart(id:)` |
| <https://shopify.dev/docs/api/storefront/latest/mutations/cartCreate> | `cartCreate` shape |
| <https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesAdd> | `cartLinesAdd`, 250 lines, quantity default |
| <https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesUpdate> | `cartLinesUpdate`, 250 lines, attribute semantics |
| <https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesRemove> | `cartLinesRemove`, `lineIds`/`viewKeys` |
| <https://shopify.dev/docs/api/storefront/latest/mutations/cartBuyerIdentityUpdate> | Buyer identity, logged-in checkout |
| <https://shopify.dev/docs/api/storefront/latest/input-objects/CartLineInput> | `quantity: Int` default 1, no max |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart> | 500 lines, 30-day expiry, unlimited carts, no cart rate limit, Plus bot protection |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage> | checkoutUrl example + staleness, buyer-IP header |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/migrate-to-cart-api> | Checkout APIs deprecated 2024-04, sunset 2025-04 |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/manage-headless-channels> | 100 storefronts/tokens, storefront permissions, per-channel publishing |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/markets> | Markets/international pricing on Storefront API |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/in-context> | `@inContext` |
| <https://shopify.dev/docs/storefronts/headless/getting-started/build-options> | Hydrogen vs Hydrogen React vs Headless channel; multi-channel sync |
| <https://shopify.dev/docs/storefronts/headless/hydrogen> | Hydrogen |
| <https://shopify.dev/docs/api/hydrogen-react> | Hydrogen React framework-agnostic claim |
| <https://shopify.dev/docs/api/ajax> | Ajax API unusable on custom storefronts |
| <https://shopify.dev/docs/apps/build/checkout> | Checkout Extensibility entry, checkout.liquid notice, revert window |
| <https://shopify.dev/docs/apps/build/checkout/technologies> | Plan-gating table, market overrides |
| <https://shopify.dev/docs/apps/build/checkout/styling> | Checkout styling Plus-only |
| <https://shopify.dev/docs/apps/build/checkout/styling/checkout-and-accounts-configuration> | Checkout/accounts/sign-in styling Plus-only |
| <https://shopify.dev/docs/apps/build/checkout/capabilities> | Extension capabilities sandbox |
| <https://shopify.dev/docs/storefronts/themes/architecture/layouts/checkout-liquid> | checkout.liquid Plus-only + deprecation notice |
| <https://shopify.dev/docs/apps/build/payments> | Custom payment extensions Plus-only, Partner-only; extension types |
| <https://shopify.dev/docs/apps/build/payments/requirements> | 3-D Secure requirement |
| <https://shopify.dev/docs/api/commerce-components/pay> | Shop Pay Wallet: merchant-built checkout, new-store-only, Shopify Payments required, async order creation |
| <https://shopify.dev/docs/api/commerce-components/pay/shop-configuration> | Shop Pay Wallet plan, per-plan card rates, pre-configured custom app |
| <https://shopify.dev/docs/api/storefront/latest/mutations/shopPayPaymentRequestSessionCreate> | Shop Pay payment request session creation |
| <https://shopify.dev/docs/api/storefront/latest/mutations/shopPayPaymentRequestSessionSubmit> | Shop Pay session submit, idempotency, receipt |
| <https://shopify.dev/docs/api/storefront/latest/queries/paymentSettings> | `paymentSettings` query (only other payment surface) |
| <https://shopify.dev/docs/api/customer> | Customer Account API auth, discovery, scopes, rate limits, 402 gate |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api> | Hosted auth, SSO across surfaces, data scope |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/getting-started> | Enable customer accounts, client types, endpoints, permissions |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/checkout-authentication> | Cart token vs `sso=silent` |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/customer-accounts> | Address/profile mutations |
| <https://shopify.dev/docs/api/storefront/latest/mutations/customerAccessTokenCreate> | Legacy-only status, `unauthenticated_write_customers` |
| <https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/customer-accounts> | Legacy Storefront customer flow |
| <https://shopify.dev/changelog/posts/legacy-customer-accounts-are-deprecated> | Legacy deprecation, 2026-02-26 |
| <https://shopify.dev/changelog/posts/bots-and-agents-should-identify-themselves-via-web-bot-auth> | Web Bot Auth, effective 2026-05-30 |
| <https://shopify.dev/changelog/release-notes/2026-10> | 2026-10 changes, Cart/CAAPI/`@inContext` |
| <https://shopify.dev/changelog/release-notes/2026-07> | Cart `viewKey`, discount field migration |
| <https://shopify.dev/changelog/release-notes/2026-04> | Cart transform error code |
| <https://shopify.dev/changelog/release-notes/2026-01> | `cartDiscountCodesUpdate` requires `discountCodes` |
| <https://shopify.dev/docs/apps/build/apis/graphql-admin/rate-limits> | Admin plan tier names and figures |
| <https://www.shopify.com/in/pricing> | Plan names/prices in INR, 3rd-party fees, checkout customization row, headless storefronts row, "Requires Shopify Payments" features |
| <https://www.shopify.com/legal/terms-payments> | Shopify Payments regional terms (AU/CA/UK/US only) |
| <https://www.shopify.com/payment-gateways?country=in> | Country-filtered provider list (client-rendered) |
| <https://help.shopify.com/en/manual/payments> | Payment methods chosen at checkout; link to gateway list by country |
| <https://help.shopify.com/en/manual/payments/additional-payment-methods> | Additional payment methods; third-party transaction fees |
| <https://github.com/Shopify/storefront-api-feedback/discussions/130> | Maintainer answer on checkoutUrl domain (2022, unconfirmed) |
| <https://community.shopify.com/t/why-shopify-payments-is-not-available-in-india/412204> | Community: Shopify Payments not available in India (2025-05-02) |
| <https://community.shopify.com/t/shopify-payments-in-india-can-shopify-please-share-an-update/675672> | Community: still unavailable, 2026-09-02 |
| <https://community.shopify.com/t/selling-in-multiple-currencies-from-india/349404> | Community: India multi-currency tied to Shopify Payments (2024-08-24) |
| <https://community.shopify.com/t/how-to-enable-multicurrency-checkout-on-my-store-based-in-india/588501> | Community: 2026-02-16, same constraint |