@doswiftly/storefront-operations 7.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +183 -0
- package/CHANGELOG.md +33 -0
- package/README.md +673 -137
- package/fragments.graphql +137 -53
- package/llms-full.txt +4994 -0
- package/mutations.graphql +47 -3
- package/operations.json +3149 -0
- package/package.json +9 -2
- package/queries.graphql +55 -16
package/llms-full.txt
ADDED
|
@@ -0,0 +1,4994 @@
|
|
|
1
|
+
# DoSwiftly Storefront Operations — Full Reference
|
|
2
|
+
|
|
3
|
+
> Schema version: **7.1.0**
|
|
4
|
+
> 48 queries · 44 mutations · 108 fragments
|
|
5
|
+
|
|
6
|
+
Auto-generated from `.graphql` source files. Do not edit by hand — this file is
|
|
7
|
+
regenerated on every release to match the published schema.
|
|
8
|
+
|
|
9
|
+
This file is the deep reference for AI agents and tools that need full operation
|
|
10
|
+
signatures with descriptions, typed variables, and ready-to-execute GraphQL bodies.
|
|
11
|
+
|
|
12
|
+
Companion files:
|
|
13
|
+
- `AGENTS.md` — entry point with critical conventions and progressive disclosure
|
|
14
|
+
- `schema.graphql` — full GraphQL schema (types, fields, enums)
|
|
15
|
+
- `operations.json` — same operations as structured JSON for programmatic tools
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Queries
|
|
20
|
+
|
|
21
|
+
### Query: `Shop`
|
|
22
|
+
|
|
23
|
+
**Section**: Shop
|
|
24
|
+
|
|
25
|
+
**Description**: Returns shop configuration: name, base + supported currencies, supported locales, branding (logo, colors, fonts, social links), contact info, active payment methods, brand metadata, money format template, and the list of countries the shop ships to. Public; no auth required. Call once per session and cache — almost everything else is contextualized by the shop returned here.
|
|
26
|
+
|
|
27
|
+
**Variables**: none
|
|
28
|
+
|
|
29
|
+
**Fragments used**: `Shop`
|
|
30
|
+
|
|
31
|
+
**GraphQL**:
|
|
32
|
+
```graphql
|
|
33
|
+
query Shop {
|
|
34
|
+
shop {
|
|
35
|
+
...Shop
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Query: `Product`
|
|
41
|
+
|
|
42
|
+
**Section**: Products
|
|
43
|
+
|
|
44
|
+
**Description**: Fetches a single product by `id` or `handle` (URL slug). Pass either — whichever is provided wins; if both are missing, returns null. Returns null if the product is not storefront-accessible (must be `ACTIVE` status with `PUBLIC` or `BUNDLE_ONLY` visibility).
|
|
45
|
+
|
|
46
|
+
**Variables**:
|
|
47
|
+
- `$id`: `ID`
|
|
48
|
+
- `$handle`: `String`
|
|
49
|
+
|
|
50
|
+
**Fragments used**: `ProductFull`
|
|
51
|
+
|
|
52
|
+
**GraphQL**:
|
|
53
|
+
```graphql
|
|
54
|
+
query Product($id: ID, $handle: String) {
|
|
55
|
+
product(id: $id, handle: $handle) {
|
|
56
|
+
...ProductFull
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Query: `ProductConfigurator`
|
|
62
|
+
|
|
63
|
+
**Section**: Products
|
|
64
|
+
|
|
65
|
+
**Description**: Fetches a product together with its filtered attribute definitions, optimized for the configurator UI (e.g. customer-facing text fields, finishing options, scoped variants). `fillingMode: "CUSTOMER"` returns only customer-facing attributes; pass `"BOTH"` to also include attributes shared with the merchant admin. Single round-trip — saves a separate `attributes` query.
|
|
66
|
+
|
|
67
|
+
**Variables**:
|
|
68
|
+
- `$handle`: `String!`
|
|
69
|
+
- `$fillingMode`: `String` *(default: `"CUSTOMER"`)*
|
|
70
|
+
|
|
71
|
+
**Fragments used**: `ProductAttributeDefinition`, `ProductFull`
|
|
72
|
+
|
|
73
|
+
**GraphQL**:
|
|
74
|
+
```graphql
|
|
75
|
+
query ProductConfigurator($handle: String!, $fillingMode: String = "CUSTOMER") {
|
|
76
|
+
product(handle: $handle) {
|
|
77
|
+
...ProductFull
|
|
78
|
+
attributes(filter: {fillingMode: $fillingMode}) {
|
|
79
|
+
...ProductAttributeDefinition
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Query: `Products`
|
|
86
|
+
|
|
87
|
+
**Section**: Products
|
|
88
|
+
|
|
89
|
+
**Description**: Paginated product list (Relay Connection, default page size 20, max 100). The `query` argument supports a structured search syntax — `tag:summer`, `vendor:foo`, `product_type:shirts`, `variants.price:>10`, plus `AND`/`OR`/`NOT` — falling back to free-text title/content search. The `filters[]` array uses multi-filter logic: same field name appears multiple times → OR; different fields → AND. Sort: `RELEVANCE`, `TITLE`, `PRICE`, `NEWEST`, `OLDEST`, `BEST_SELLING`. The response includes a `filters` block for faceted navigation (counts per filterable attribute value).
|
|
90
|
+
|
|
91
|
+
**Variables**:
|
|
92
|
+
- `$first`: `Int` *(default: `20`)*
|
|
93
|
+
- `$after`: `String`
|
|
94
|
+
- `$query`: `String`
|
|
95
|
+
- `$sortKey`: `ProductSortKeys` *(default: `RELEVANCE`)*
|
|
96
|
+
- `$reverse`: `Boolean` *(default: `false`)*
|
|
97
|
+
- `$filters`: `[ProductFilter!]`
|
|
98
|
+
|
|
99
|
+
**Fragments used**: `PageInfo`, `ProductCard`
|
|
100
|
+
|
|
101
|
+
**GraphQL**:
|
|
102
|
+
```graphql
|
|
103
|
+
query Products($first: Int = 20, $after: String, $query: String, $sortKey: ProductSortKeys = RELEVANCE, $reverse: Boolean = false, $filters: [ProductFilter!]) {
|
|
104
|
+
products(
|
|
105
|
+
first: $first
|
|
106
|
+
after: $after
|
|
107
|
+
query: $query
|
|
108
|
+
sortKey: $sortKey
|
|
109
|
+
reverse: $reverse
|
|
110
|
+
filters: $filters
|
|
111
|
+
) {
|
|
112
|
+
edges {
|
|
113
|
+
node {
|
|
114
|
+
...ProductCard
|
|
115
|
+
}
|
|
116
|
+
cursor
|
|
117
|
+
}
|
|
118
|
+
nodes {
|
|
119
|
+
...ProductCard
|
|
120
|
+
}
|
|
121
|
+
pageInfo {
|
|
122
|
+
...PageInfo
|
|
123
|
+
}
|
|
124
|
+
totalCount
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Query: `ProductSearch`
|
|
130
|
+
|
|
131
|
+
**Section**: Products
|
|
132
|
+
|
|
133
|
+
**Description**: Full-text product search — `$query` is required. Functionally equivalent to `Products` with `$query` set, minus the `sortKey` argument (search defaults to relevance ranking). Use for the search results page; combine with `filters[]` for guided refinement.
|
|
134
|
+
|
|
135
|
+
**Variables**:
|
|
136
|
+
- `$query`: `String!`
|
|
137
|
+
- `$first`: `Int` *(default: `20`)*
|
|
138
|
+
- `$after`: `String`
|
|
139
|
+
- `$filters`: `[ProductFilter!]`
|
|
140
|
+
|
|
141
|
+
**Fragments used**: `PageInfo`, `ProductCard`
|
|
142
|
+
|
|
143
|
+
**GraphQL**:
|
|
144
|
+
```graphql
|
|
145
|
+
query ProductSearch($query: String!, $first: Int = 20, $after: String, $filters: [ProductFilter!]) {
|
|
146
|
+
products(query: $query, first: $first, after: $after, filters: $filters) {
|
|
147
|
+
edges {
|
|
148
|
+
node {
|
|
149
|
+
...ProductCard
|
|
150
|
+
}
|
|
151
|
+
cursor
|
|
152
|
+
}
|
|
153
|
+
nodes {
|
|
154
|
+
...ProductCard
|
|
155
|
+
}
|
|
156
|
+
pageInfo {
|
|
157
|
+
...PageInfo
|
|
158
|
+
}
|
|
159
|
+
totalCount
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Query: `PredictiveSearch`
|
|
165
|
+
|
|
166
|
+
**Section**: Products
|
|
167
|
+
|
|
168
|
+
**Description**: Type-ahead suggestions for the storefront search input. Returns up to `$limit` matching products (hard cap 50) plus up to 5 styled query suggestions with `<mark>` tags around matched spans. Polish-language aware (handles morphology in suggestions). Run on each keystroke (debounce 200-300ms). The `$query` is capped at 100 characters server-side.
|
|
169
|
+
|
|
170
|
+
**Variables**:
|
|
171
|
+
- `$query`: `String!`
|
|
172
|
+
- `$limit`: `Int` *(default: `10`)*
|
|
173
|
+
|
|
174
|
+
**Fragments used**: `ProductCard`
|
|
175
|
+
|
|
176
|
+
**GraphQL**:
|
|
177
|
+
```graphql
|
|
178
|
+
query PredictiveSearch($query: String!, $limit: Int = 10) {
|
|
179
|
+
predictiveSearch(query: $query, limit: $limit) {
|
|
180
|
+
products {
|
|
181
|
+
...ProductCard
|
|
182
|
+
}
|
|
183
|
+
queries {
|
|
184
|
+
text
|
|
185
|
+
styledText
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Query: `Collection`
|
|
192
|
+
|
|
193
|
+
**Section**: Collections
|
|
194
|
+
|
|
195
|
+
**Description**: Fetches a single collection by `id` or `handle`, with paginated products. Collections come in two types: **MANUAL** (curated — products explicitly added by the merchant) and **AUTO** (rule-based — products matched dynamically). Both surfaces use the same field selection.
|
|
196
|
+
|
|
197
|
+
**Variables**:
|
|
198
|
+
- `$id`: `ID`
|
|
199
|
+
- `$handle`: `String`
|
|
200
|
+
- `$productsFirst`: `Int` *(default: `20`)*
|
|
201
|
+
- `$productsAfter`: `String`
|
|
202
|
+
- `$productsFilters`: `[ProductFilter!]`
|
|
203
|
+
|
|
204
|
+
**Fragments used**: `Collection`, `PageInfo`, `ProductCard`
|
|
205
|
+
|
|
206
|
+
**GraphQL**:
|
|
207
|
+
```graphql
|
|
208
|
+
query Collection($id: ID, $handle: String, $productsFirst: Int = 20, $productsAfter: String, $productsFilters: [ProductFilter!]) {
|
|
209
|
+
collection(id: $id, handle: $handle) {
|
|
210
|
+
...Collection
|
|
211
|
+
products(
|
|
212
|
+
first: $productsFirst
|
|
213
|
+
after: $productsAfter
|
|
214
|
+
filters: $productsFilters
|
|
215
|
+
) {
|
|
216
|
+
edges {
|
|
217
|
+
node {
|
|
218
|
+
...ProductCard
|
|
219
|
+
}
|
|
220
|
+
cursor
|
|
221
|
+
}
|
|
222
|
+
nodes {
|
|
223
|
+
...ProductCard
|
|
224
|
+
}
|
|
225
|
+
pageInfo {
|
|
226
|
+
...PageInfo
|
|
227
|
+
}
|
|
228
|
+
totalCount
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Query: `Collections`
|
|
235
|
+
|
|
236
|
+
**Section**: Collections
|
|
237
|
+
|
|
238
|
+
**Description**: Paginated list of all active collections (default 20, max 100). Sort by `TITLE` or `UPDATED_AT` via `sortKey`. Note: the `query` argument is reserved for future text filtering — it is currently accepted but ignored.
|
|
239
|
+
|
|
240
|
+
**Variables**:
|
|
241
|
+
- `$first`: `Int` *(default: `20`)*
|
|
242
|
+
- `$after`: `String`
|
|
243
|
+
- `$query`: `String`
|
|
244
|
+
- `$sortKey`: `CollectionSortKeys` *(default: `TITLE`)*
|
|
245
|
+
- `$reverse`: `Boolean` *(default: `false`)*
|
|
246
|
+
|
|
247
|
+
**Fragments used**: `Collection`, `PageInfo`
|
|
248
|
+
|
|
249
|
+
**GraphQL**:
|
|
250
|
+
```graphql
|
|
251
|
+
query Collections($first: Int = 20, $after: String, $query: String, $sortKey: CollectionSortKeys = TITLE, $reverse: Boolean = false) {
|
|
252
|
+
collections(
|
|
253
|
+
first: $first
|
|
254
|
+
after: $after
|
|
255
|
+
query: $query
|
|
256
|
+
sortKey: $sortKey
|
|
257
|
+
reverse: $reverse
|
|
258
|
+
) {
|
|
259
|
+
edges {
|
|
260
|
+
node {
|
|
261
|
+
...Collection
|
|
262
|
+
}
|
|
263
|
+
cursor
|
|
264
|
+
}
|
|
265
|
+
pageInfo {
|
|
266
|
+
...PageInfo
|
|
267
|
+
}
|
|
268
|
+
totalCount
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Query: `Category`
|
|
274
|
+
|
|
275
|
+
**Section**: Categories
|
|
276
|
+
|
|
277
|
+
**Description**: Fetches a single category by `id` or `slug` with its parent and immediate children. Use for breadcrumbs and sub-navigation. Nested queries on `parent` / `children` are batched server-side — safe to use in lists without N+1 concerns.
|
|
278
|
+
|
|
279
|
+
**Variables**:
|
|
280
|
+
- `$id`: `ID`
|
|
281
|
+
- `$slug`: `String`
|
|
282
|
+
|
|
283
|
+
**Fragments used**: `Category`
|
|
284
|
+
|
|
285
|
+
**GraphQL**:
|
|
286
|
+
```graphql
|
|
287
|
+
query Category($id: ID, $slug: String) {
|
|
288
|
+
category(id: $id, slug: $slug) {
|
|
289
|
+
...Category
|
|
290
|
+
parent {
|
|
291
|
+
...Category
|
|
292
|
+
}
|
|
293
|
+
children {
|
|
294
|
+
...Category
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Query: `Categories`
|
|
301
|
+
|
|
302
|
+
**Section**: Categories
|
|
303
|
+
|
|
304
|
+
**Description**: Returns active categories for the shop. Each category exposes its `parent` and `children` — build the tree client-side by walking those fields (server batches the lookups, no N+1). The hierarchy is not depth-capped server-side. Use for nav mega-menus and category pages.
|
|
305
|
+
|
|
306
|
+
**Variables**: none
|
|
307
|
+
|
|
308
|
+
**Fragments used**: `Category`
|
|
309
|
+
|
|
310
|
+
**GraphQL**:
|
|
311
|
+
```graphql
|
|
312
|
+
query Categories {
|
|
313
|
+
categories {
|
|
314
|
+
roots {
|
|
315
|
+
...Category
|
|
316
|
+
children {
|
|
317
|
+
...Category
|
|
318
|
+
children {
|
|
319
|
+
...Category
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
totalCount
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Query: `Cart`
|
|
329
|
+
|
|
330
|
+
**Section**: Cart
|
|
331
|
+
|
|
332
|
+
**Description**: Fetches a cart by `id` (the value persisted by the SDK in the `cart-id` cookie). The cart query is public — no auth needed to read it — but once a customer logs in and gets associated with the cart, mutations enforce ownership. Returns line items (paginated up to 100), totals, applied discount codes, gift cards, buyer identity, note, attributes, and warnings. Refetch after every cart mutation.
|
|
333
|
+
|
|
334
|
+
**Variables**:
|
|
335
|
+
- `$id`: `ID!`
|
|
336
|
+
|
|
337
|
+
**Fragments used**: `Cart`
|
|
338
|
+
|
|
339
|
+
**GraphQL**:
|
|
340
|
+
```graphql
|
|
341
|
+
query Cart($id: ID!) {
|
|
342
|
+
cart(id: $id) {
|
|
343
|
+
...Cart
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Query: `Customer`
|
|
349
|
+
|
|
350
|
+
**Section**: Customer (requires auth)
|
|
351
|
+
|
|
352
|
+
**Description**: Full customer profile — basic info plus the first 10 addresses and first 10 orders. Heaviest customer query; for narrow use cases prefer `CustomerProfile` (no orders / addresses) or `CustomerOrder` (single order). Returns null if unauthenticated.
|
|
353
|
+
|
|
354
|
+
**Variables**: none
|
|
355
|
+
|
|
356
|
+
**Fragments used**: `Customer`, `MailingAddress`, `Order`, `PageInfo`
|
|
357
|
+
|
|
358
|
+
**GraphQL**:
|
|
359
|
+
```graphql
|
|
360
|
+
query Customer {
|
|
361
|
+
customer {
|
|
362
|
+
...Customer
|
|
363
|
+
addresses(first: 10) {
|
|
364
|
+
edges {
|
|
365
|
+
cursor
|
|
366
|
+
node {
|
|
367
|
+
...MailingAddress
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
nodes {
|
|
371
|
+
...MailingAddress
|
|
372
|
+
}
|
|
373
|
+
pageInfo {
|
|
374
|
+
...PageInfo
|
|
375
|
+
}
|
|
376
|
+
totalCount
|
|
377
|
+
}
|
|
378
|
+
orders(first: 10) {
|
|
379
|
+
edges {
|
|
380
|
+
node {
|
|
381
|
+
...Order
|
|
382
|
+
}
|
|
383
|
+
cursor
|
|
384
|
+
}
|
|
385
|
+
pageInfo {
|
|
386
|
+
...PageInfo
|
|
387
|
+
}
|
|
388
|
+
totalCount
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Query: `CustomerProfile`
|
|
395
|
+
|
|
396
|
+
**Section**: Customer (requires auth)
|
|
397
|
+
|
|
398
|
+
**Description**: Lightweight customer profile (no orders, no addresses list). Use for settings / profile pages that only need basic customer info — much cheaper than `Customer`. Returns null if unauthenticated.
|
|
399
|
+
|
|
400
|
+
**Variables**: none
|
|
401
|
+
|
|
402
|
+
**Fragments used**: `Customer`
|
|
403
|
+
|
|
404
|
+
**GraphQL**:
|
|
405
|
+
```graphql
|
|
406
|
+
query CustomerProfile {
|
|
407
|
+
customer {
|
|
408
|
+
...Customer
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Query: `CustomerOrder`
|
|
414
|
+
|
|
415
|
+
**Section**: Customer (requires auth)
|
|
416
|
+
|
|
417
|
+
**Description**: Single order by `orderId`. Returns only orders that belong to the authenticated customer (cross-customer access returns null, not an error). Much cheaper than fetching the full `Customer` payload to access one order. Use on the order detail page.
|
|
418
|
+
|
|
419
|
+
**Variables**:
|
|
420
|
+
- `$orderId`: `ID!`
|
|
421
|
+
|
|
422
|
+
**Fragments used**: `Order`
|
|
423
|
+
|
|
424
|
+
**GraphQL**:
|
|
425
|
+
```graphql
|
|
426
|
+
query CustomerOrder($orderId: ID!) {
|
|
427
|
+
customerOrder(orderId: $orderId) {
|
|
428
|
+
...Order
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Query: `Checkout`
|
|
434
|
+
|
|
435
|
+
**Section**: Checkout
|
|
436
|
+
|
|
437
|
+
**Description**: Fetches a checkout session by `id`. **Important**: `checkoutId` and `cartId` are 1:1 — there is no separate "checkout" record, the response is built dynamically from the cart. Returns line items, addresses, selected shipping rate, available shipping rates + payment methods, applied discount/gift cards (gift card codes are masked for security), and totals (`cost`, `tax`, `paymentDue`). Public read; ownership enforced on mutations. Refetch after every checkout mutation.
|
|
438
|
+
|
|
439
|
+
**Variables**:
|
|
440
|
+
- `$id`: `ID!`
|
|
441
|
+
|
|
442
|
+
**Fragments used**: `Checkout`
|
|
443
|
+
|
|
444
|
+
**GraphQL**:
|
|
445
|
+
```graphql
|
|
446
|
+
query Checkout($id: ID!) {
|
|
447
|
+
checkout(id: $id) {
|
|
448
|
+
...Checkout
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Query: `AvailablePaymentMethods`
|
|
454
|
+
|
|
455
|
+
**Section**: Payment Methods
|
|
456
|
+
|
|
457
|
+
**Description**: Returns the active payment methods for the shop, sorted by the merchant-configured display position. Shop-level — does NOT vary by cart amount or currency. Each method exposes `type` (`CARD`, `BANK_TRANSFER`, `BLIK`, `PAYPAL`, `APPLE_PAY`, `GOOGLE_PAY`, `CASH_ON_DELIVERY`, `OTHER`), provider, icon, description, and supported currencies. Use to render the payment step of checkout.
|
|
458
|
+
|
|
459
|
+
**Variables**: none
|
|
460
|
+
|
|
461
|
+
**Fragments used**: `AvailablePaymentMethods`
|
|
462
|
+
|
|
463
|
+
**GraphQL**:
|
|
464
|
+
```graphql
|
|
465
|
+
query AvailablePaymentMethods {
|
|
466
|
+
availablePaymentMethods {
|
|
467
|
+
...AvailablePaymentMethods
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### Query: `Shipment`
|
|
473
|
+
|
|
474
|
+
**Section**: Shipments / Tracking
|
|
475
|
+
|
|
476
|
+
**Description**: Fetches a shipment by `id` with status, tracking events, recipient address, and shipped/delivered timestamps. **Auth required** — customer access token plus ownership of the parent order. Wrapped response: `{ shipment, userErrors[] }`. Error codes: `INVALID_TOKEN`, `NOT_FOUND` (also returned on ownership mismatch to prevent enumeration), `FETCH_FAILED`.
|
|
477
|
+
|
|
478
|
+
**Variables**:
|
|
479
|
+
- `$id`: `ID!`
|
|
480
|
+
|
|
481
|
+
**Fragments used**: `Shipment`, `UserError`
|
|
482
|
+
|
|
483
|
+
**GraphQL**:
|
|
484
|
+
```graphql
|
|
485
|
+
query Shipment($id: ID!) {
|
|
486
|
+
shipment(id: $id) {
|
|
487
|
+
shipment {
|
|
488
|
+
...Shipment
|
|
489
|
+
}
|
|
490
|
+
userErrors {
|
|
491
|
+
...UserError
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Query: `ShipmentByTrackingNumber`
|
|
498
|
+
|
|
499
|
+
**Section**: Shipments / Tracking
|
|
500
|
+
|
|
501
|
+
**Description**: **Public** shipment lookup by carrier tracking number — no auth required. Designed for "Track my order" landing pages reachable without login. Returns the basic shipment fragment including recipient address. Wrapped response: `{ shipment, userErrors[] }`. Error codes: `INVALID_INPUT`, `NOT_FOUND`, `FETCH_FAILED`.
|
|
502
|
+
|
|
503
|
+
**Variables**:
|
|
504
|
+
- `$trackingNumber`: `String!`
|
|
505
|
+
|
|
506
|
+
**Fragments used**: `ShipmentBasic`, `UserError`
|
|
507
|
+
|
|
508
|
+
**GraphQL**:
|
|
509
|
+
```graphql
|
|
510
|
+
query ShipmentByTrackingNumber($trackingNumber: String!) {
|
|
511
|
+
shipmentByTrackingNumber(trackingNumber: $trackingNumber) {
|
|
512
|
+
shipment {
|
|
513
|
+
...ShipmentBasic
|
|
514
|
+
}
|
|
515
|
+
userErrors {
|
|
516
|
+
...UserError
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Query: `Return`
|
|
523
|
+
|
|
524
|
+
**Section**: Returns / RMA
|
|
525
|
+
|
|
526
|
+
**Description**: Fetches a single return (RMA) by `id` with line items, refund/compensation info, and history. **Auth required** — customer access token plus ownership of the return. Wrapped response: `{ return, userErrors[] }`. Error codes: `INVALID_TOKEN`, `NOT_FOUND` (also returned on ownership mismatch), `FETCH_FAILED`.
|
|
527
|
+
|
|
528
|
+
**Variables**:
|
|
529
|
+
- `$id`: `ID!`
|
|
530
|
+
|
|
531
|
+
**Fragments used**: `Return`, `UserError`
|
|
532
|
+
|
|
533
|
+
**GraphQL**:
|
|
534
|
+
```graphql
|
|
535
|
+
query Return($id: ID!) {
|
|
536
|
+
return(id: $id) {
|
|
537
|
+
return {
|
|
538
|
+
...Return
|
|
539
|
+
}
|
|
540
|
+
userErrors {
|
|
541
|
+
...UserError
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### Query: `ReturnsByOrder`
|
|
548
|
+
|
|
549
|
+
**Section**: Returns / RMA
|
|
550
|
+
|
|
551
|
+
**Description**: Lists returns for a given order (paginated, default page size 20, cursor-based). **Auth required** — customer access token plus ownership of the order; the connection is empty (no explicit error) on auth failure. Use on the order detail page to show return history.
|
|
552
|
+
|
|
553
|
+
**Variables**:
|
|
554
|
+
- `$orderId`: `ID!`
|
|
555
|
+
|
|
556
|
+
**Fragments used**: `PageInfo`, `Return`
|
|
557
|
+
|
|
558
|
+
**GraphQL**:
|
|
559
|
+
```graphql
|
|
560
|
+
query ReturnsByOrder($orderId: ID!) {
|
|
561
|
+
returnsByOrder(orderId: $orderId) {
|
|
562
|
+
edges {
|
|
563
|
+
node {
|
|
564
|
+
...Return
|
|
565
|
+
}
|
|
566
|
+
cursor
|
|
567
|
+
}
|
|
568
|
+
pageInfo {
|
|
569
|
+
...PageInfo
|
|
570
|
+
}
|
|
571
|
+
totalCount
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### Query: `ReturnReasons`
|
|
577
|
+
|
|
578
|
+
**Section**: Returns / RMA
|
|
579
|
+
|
|
580
|
+
**Description**: Returns the standard list of return reasons used by the RMA flow: `DEFECTIVE`, `NOT_AS_DESCRIBED`, `WRONG_ITEM`, `CHANGED_MIND`, `BETTER_PRICE`, `DAMAGED_SHIPPING`, `OTHER`. The list is fixed across all shops — not per-shop configurable. Public; no auth required.
|
|
581
|
+
|
|
582
|
+
**Variables**: none
|
|
583
|
+
|
|
584
|
+
**Fragments used**: `ReturnReasonOption`
|
|
585
|
+
|
|
586
|
+
**GraphQL**:
|
|
587
|
+
```graphql
|
|
588
|
+
query ReturnReasons {
|
|
589
|
+
returnReasons {
|
|
590
|
+
...ReturnReasonOption
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### Query: `GiftCard`
|
|
596
|
+
|
|
597
|
+
**Section**: Gift Cards
|
|
598
|
+
|
|
599
|
+
**Description**: Public gift-card lookup by `code`. Returns balance, currency, expiry, and `maskedCode` (first 4 + last 4 chars only — the full code never leaks back). Returns null if the code is unknown (rather than an explicit error, to limit enumeration). **Rate-limited**: 10 requests per 60 seconds per IP.
|
|
600
|
+
|
|
601
|
+
**Variables**:
|
|
602
|
+
- `$code`: `String!`
|
|
603
|
+
|
|
604
|
+
**Fragments used**: `GiftCard`
|
|
605
|
+
|
|
606
|
+
**GraphQL**:
|
|
607
|
+
```graphql
|
|
608
|
+
query GiftCard($code: String!) {
|
|
609
|
+
giftCard(code: $code) {
|
|
610
|
+
...GiftCard
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### Query: `GiftCardValidate`
|
|
616
|
+
|
|
617
|
+
**Section**: Gift Cards
|
|
618
|
+
|
|
619
|
+
**Description**: Validates whether a gift card is usable (and optionally for a given `$amount`). Checks status (`DISABLED`, `USED`, `EXPIRED`), expiry date, and — when `$amount` is provided — sufficient balance. Returns `{ validation: { isValid, availableBalance, error: { code, message } }, userErrors[] }`. Validation error codes: `NOT_FOUND`, `DISABLED`, `ALREADY_USED`, `EXPIRED`, `INSUFFICIENT_BALANCE`. **Rate-limited**: 10 / 60s.
|
|
620
|
+
|
|
621
|
+
**Variables**:
|
|
622
|
+
- `$code`: `String!`
|
|
623
|
+
- `$amount`: `Float`
|
|
624
|
+
|
|
625
|
+
**Fragments used**: `GiftCardValidation`, `UserError`
|
|
626
|
+
|
|
627
|
+
**GraphQL**:
|
|
628
|
+
```graphql
|
|
629
|
+
query GiftCardValidate($code: String!, $amount: Float) {
|
|
630
|
+
giftCardValidate(code: $code, amount: $amount) {
|
|
631
|
+
validation {
|
|
632
|
+
...GiftCardValidation
|
|
633
|
+
}
|
|
634
|
+
userErrors {
|
|
635
|
+
...UserError
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
### Query: `AvailableShippingMethods`
|
|
642
|
+
|
|
643
|
+
**Section**: Shipping Methods
|
|
644
|
+
|
|
645
|
+
**Description**: Returns shipping methods for a given destination address and cart shape (subtotal, total weight, currency). The query computes everything from the inputs alone — no existing cart is required, so it can be used for "shipping cost preview" UIs before the customer adds anything to a cart. Each method includes price, free-shipping progress (`{ qualifies, currentAmount, threshold, remaining, progressPercent }`), estimated delivery, and carrier metadata. Sorted by the merchant's `sortOrder`, then by price.
|
|
646
|
+
|
|
647
|
+
**Variables**:
|
|
648
|
+
- `$address`: `ShippingAddressInput!`
|
|
649
|
+
- `$cart`: `CartShippingInput`
|
|
650
|
+
|
|
651
|
+
**Fragments used**: `AvailableShippingMethod`, `FreeShippingProgress`, `UserError`
|
|
652
|
+
|
|
653
|
+
**GraphQL**:
|
|
654
|
+
```graphql
|
|
655
|
+
query AvailableShippingMethods($address: ShippingAddressInput!, $cart: CartShippingInput) {
|
|
656
|
+
availableShippingMethods(address: $address, cart: $cart) {
|
|
657
|
+
methods {
|
|
658
|
+
...AvailableShippingMethod
|
|
659
|
+
}
|
|
660
|
+
freeShippingProgress {
|
|
661
|
+
...FreeShippingProgress
|
|
662
|
+
}
|
|
663
|
+
userErrors {
|
|
664
|
+
...UserError
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
### Query: `AvailableFilters`
|
|
671
|
+
|
|
672
|
+
**Section**: Attribute Filters
|
|
673
|
+
|
|
674
|
+
**Description**: Returns the dynamic facet filters available for a listing context — pass `collectionId`, `categoryId`, or `searchQuery`. For each visible & filterable attribute, returns either discrete value counts (for `SELECT` / `CHECKBOX` types) or numeric range bounds (for `SLIDER` types). Plus `priceRange`, per-category counts, `activeCount` (length of `currentFilters` input), and `matchCount` (total products in the context). Use to render filter sidebars on listing/search pages.
|
|
675
|
+
|
|
676
|
+
**Variables**:
|
|
677
|
+
- `$input`: `AvailableFiltersInput`
|
|
678
|
+
|
|
679
|
+
**Fragments used**: `AvailableFilters`
|
|
680
|
+
|
|
681
|
+
**GraphQL**:
|
|
682
|
+
```graphql
|
|
683
|
+
query AvailableFilters($input: AvailableFiltersInput) {
|
|
684
|
+
availableFilters(input: $input) {
|
|
685
|
+
...AvailableFilters
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Query: `LoyaltyMember`
|
|
691
|
+
|
|
692
|
+
**Section**: Loyalty Program
|
|
693
|
+
|
|
694
|
+
**Description**: Returns the logged-in customer's loyalty membership: points (current, pending, redeemed, expired, expiring), current tier, tier progress, annual spend, last activity. Returns null if the customer is not enrolled — there is **no auto-enrollment** here (enrollment happens via signup or a first qualifying order). Auth required.
|
|
695
|
+
|
|
696
|
+
**Variables**: none
|
|
697
|
+
|
|
698
|
+
**Fragments used**: `LoyaltyMember`
|
|
699
|
+
|
|
700
|
+
**GraphQL**:
|
|
701
|
+
```graphql
|
|
702
|
+
query LoyaltyMember {
|
|
703
|
+
loyaltyMember {
|
|
704
|
+
...LoyaltyMember
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
### Query: `LoyaltyTiers`
|
|
710
|
+
|
|
711
|
+
**Section**: Loyalty Program
|
|
712
|
+
|
|
713
|
+
**Description**: Lists the loyalty tiers configured for the shop (`BRONZE`, `SILVER`, `GOLD`, `PLATINUM`, `DIAMOND` etc.) with their `minPoints`, `minAnnualSpend`, `pointsMultiplier`, and custom benefits. Sorted by `minPoints` ASC. Public; no auth required.
|
|
714
|
+
|
|
715
|
+
**Variables**: none
|
|
716
|
+
|
|
717
|
+
**Fragments used**: `LoyaltyTier`
|
|
718
|
+
|
|
719
|
+
**GraphQL**:
|
|
720
|
+
```graphql
|
|
721
|
+
query LoyaltyTiers {
|
|
722
|
+
loyaltyTiers {
|
|
723
|
+
...LoyaltyTier
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
### Query: `LoyaltyRewards`
|
|
729
|
+
|
|
730
|
+
**Section**: Loyalty Program
|
|
731
|
+
|
|
732
|
+
**Description**: Lists rewards customers can redeem (free shipping, percent off, free product, gift card). Filtered to **active** rewards only (`is_active = true` AND inside their `starts_at`/`ends_at` window). Public; no auth required.
|
|
733
|
+
|
|
734
|
+
**Variables**: none
|
|
735
|
+
|
|
736
|
+
**Fragments used**: `LoyaltyReward`
|
|
737
|
+
|
|
738
|
+
**GraphQL**:
|
|
739
|
+
```graphql
|
|
740
|
+
query LoyaltyRewards {
|
|
741
|
+
loyaltyRewards {
|
|
742
|
+
...LoyaltyReward
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
### Query: `LoyaltyTransactions`
|
|
748
|
+
|
|
749
|
+
**Section**: Loyalty Program
|
|
750
|
+
|
|
751
|
+
**Description**: Paginated history of loyalty point transactions for the logged-in customer (default 20). Transaction `type` enum: `EARN_PURCHASE`, `EARN_SIGNUP`, `EARN_REFERRAL`, `EARN_REVIEW`, `EARN_BIRTHDAY`, `EARN_BONUS`, `REDEEM`, `EXPIRE`, `ADJUST`, `REFUND_REVERSAL`. Auth required — empty connection if unauthenticated.
|
|
752
|
+
|
|
753
|
+
**Variables**:
|
|
754
|
+
- `$first`: `Int` *(default: `20`)*
|
|
755
|
+
- `$after`: `String`
|
|
756
|
+
|
|
757
|
+
**Fragments used**: `LoyaltyPageInfo`, `LoyaltyTransaction`
|
|
758
|
+
|
|
759
|
+
**GraphQL**:
|
|
760
|
+
```graphql
|
|
761
|
+
query LoyaltyTransactions($first: Int = 20, $after: String) {
|
|
762
|
+
loyaltyTransactions(first: $first, after: $after) {
|
|
763
|
+
edges {
|
|
764
|
+
node {
|
|
765
|
+
...LoyaltyTransaction
|
|
766
|
+
}
|
|
767
|
+
cursor
|
|
768
|
+
}
|
|
769
|
+
pageInfo {
|
|
770
|
+
...LoyaltyPageInfo
|
|
771
|
+
}
|
|
772
|
+
totalCount
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### Query: `LoyaltySettings`
|
|
778
|
+
|
|
779
|
+
**Section**: Loyalty Program
|
|
780
|
+
|
|
781
|
+
**Description**: Returns the loyalty program configuration: `isEnabled`, `pointsName` (e.g. "stars"), `pointsPerCurrency`, `pointsExpiryMonths`, available earn actions, referral settings. Use this at app boot to decide whether to render any loyalty UI at all. Public; no auth required.
|
|
782
|
+
|
|
783
|
+
**Variables**: none
|
|
784
|
+
|
|
785
|
+
**Fragments used**: `LoyaltySettings`
|
|
786
|
+
|
|
787
|
+
**GraphQL**:
|
|
788
|
+
```graphql
|
|
789
|
+
query LoyaltySettings {
|
|
790
|
+
loyaltySettings {
|
|
791
|
+
...LoyaltySettings
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### Query: `EstimatePoints`
|
|
797
|
+
|
|
798
|
+
**Section**: Loyalty Program
|
|
799
|
+
|
|
800
|
+
**Description**: Estimates how many loyalty points the customer would earn for an order of `$orderTotal` (in major currency units). When the customer is authenticated, the result accounts for their current tier's points multiplier. Use on cart/checkout to show "Earn X points with this order".
|
|
801
|
+
|
|
802
|
+
**Variables**:
|
|
803
|
+
- `$orderTotal`: `Float!`
|
|
804
|
+
|
|
805
|
+
**Fragments used**: `PointsEstimate`
|
|
806
|
+
|
|
807
|
+
**GraphQL**:
|
|
808
|
+
```graphql
|
|
809
|
+
query EstimatePoints($orderTotal: Float!) {
|
|
810
|
+
estimatePoints(orderTotal: $orderTotal) {
|
|
811
|
+
...PointsEstimate
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### Query: `ReferralStats`
|
|
817
|
+
|
|
818
|
+
**Section**: Loyalty Program
|
|
819
|
+
|
|
820
|
+
**Description**: Returns the customer's referral statistics: `referralCode`, `shareUrl`, `totalReferred`, `completedReferrals`, `pendingReferrals`, `totalPointsEarned`. Auth required. Returns null if unauthenticated or if the referral program is disabled for the shop.
|
|
821
|
+
|
|
822
|
+
**Variables**: none
|
|
823
|
+
|
|
824
|
+
**Fragments used**: `ReferralStats`
|
|
825
|
+
|
|
826
|
+
**GraphQL**:
|
|
827
|
+
```graphql
|
|
828
|
+
query ReferralStats {
|
|
829
|
+
referralStats {
|
|
830
|
+
...ReferralStats
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
### Query: `ProductReviews`
|
|
836
|
+
|
|
837
|
+
**Section**: Reviews
|
|
838
|
+
|
|
839
|
+
**Description**: Paginated list of customer reviews for a product, **filtered to APPROVED reviews only** (PENDING / REJECTED reviews are not exposed to the storefront). Sort by `CREATED_AT` (default), helpfulness, or rating. Public; no auth required.
|
|
840
|
+
|
|
841
|
+
**Variables**:
|
|
842
|
+
- `$productId`: `ID!`
|
|
843
|
+
- `$first`: `Int` *(default: `10`)*
|
|
844
|
+
- `$after`: `String`
|
|
845
|
+
- `$sortKey`: `ReviewSortKey` *(default: `CREATED_AT`)*
|
|
846
|
+
- `$reverse`: `Boolean` *(default: `true`)*
|
|
847
|
+
|
|
848
|
+
**Fragments used**: `PageInfo`, `ProductReview`
|
|
849
|
+
|
|
850
|
+
**GraphQL**:
|
|
851
|
+
```graphql
|
|
852
|
+
query ProductReviews($productId: ID!, $first: Int = 10, $after: String, $sortKey: ReviewSortKey = CREATED_AT, $reverse: Boolean = true) {
|
|
853
|
+
productReviews(
|
|
854
|
+
productId: $productId
|
|
855
|
+
first: $first
|
|
856
|
+
after: $after
|
|
857
|
+
sortKey: $sortKey
|
|
858
|
+
reverse: $reverse
|
|
859
|
+
) {
|
|
860
|
+
edges {
|
|
861
|
+
node {
|
|
862
|
+
...ProductReview
|
|
863
|
+
}
|
|
864
|
+
cursor
|
|
865
|
+
}
|
|
866
|
+
pageInfo {
|
|
867
|
+
...PageInfo
|
|
868
|
+
}
|
|
869
|
+
totalCount
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
### Query: `ReviewStats`
|
|
875
|
+
|
|
876
|
+
**Section**: Reviews
|
|
877
|
+
|
|
878
|
+
**Description**: Aggregate review statistics for a product: average rating, total count, distribution per star (1-5). Computed from APPROVED reviews only. Use for product card review summaries. Public; no auth required.
|
|
879
|
+
|
|
880
|
+
**Variables**:
|
|
881
|
+
- `$productId`: `ID!`
|
|
882
|
+
|
|
883
|
+
**Fragments used**: `ReviewStats`
|
|
884
|
+
|
|
885
|
+
**GraphQL**:
|
|
886
|
+
```graphql
|
|
887
|
+
query ReviewStats($productId: ID!) {
|
|
888
|
+
reviewStats(productId: $productId) {
|
|
889
|
+
...ReviewStats
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
### Query: `Wishlists`
|
|
895
|
+
|
|
896
|
+
**Section**: Wishlists
|
|
897
|
+
|
|
898
|
+
**Description**: Paginated list of the logged-in customer's wishlists (default 20). Auth required — empty connection if unauthenticated. Customers typically have a small set (<10).
|
|
899
|
+
|
|
900
|
+
**Variables**:
|
|
901
|
+
- `$first`: `Int` *(default: `20`)*
|
|
902
|
+
- `$after`: `String`
|
|
903
|
+
|
|
904
|
+
**Fragments used**: `Wishlist`
|
|
905
|
+
|
|
906
|
+
**GraphQL**:
|
|
907
|
+
```graphql
|
|
908
|
+
query Wishlists($first: Int = 20, $after: String) {
|
|
909
|
+
wishlists(first: $first, after: $after) {
|
|
910
|
+
edges {
|
|
911
|
+
cursor
|
|
912
|
+
node {
|
|
913
|
+
...Wishlist
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
nodes {
|
|
917
|
+
...Wishlist
|
|
918
|
+
}
|
|
919
|
+
pageInfo {
|
|
920
|
+
hasNextPage
|
|
921
|
+
hasPreviousPage
|
|
922
|
+
startCursor
|
|
923
|
+
endCursor
|
|
924
|
+
}
|
|
925
|
+
totalCount
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
```
|
|
929
|
+
|
|
930
|
+
### Query: `WishlistById`
|
|
931
|
+
|
|
932
|
+
**Section**: Wishlists
|
|
933
|
+
|
|
934
|
+
**Description**: Fetches a single wishlist by `id`. Private wishlists are visible only to the owner; public wishlists are visible to anyone. Note: this query supports lookup by `id` only — there is currently no way to fetch a wishlist by its share token.
|
|
935
|
+
|
|
936
|
+
**Variables**:
|
|
937
|
+
- `$id`: `ID!`
|
|
938
|
+
|
|
939
|
+
**Fragments used**: `Wishlist`
|
|
940
|
+
|
|
941
|
+
**GraphQL**:
|
|
942
|
+
```graphql
|
|
943
|
+
query WishlistById($id: ID!) {
|
|
944
|
+
wishlist(id: $id) {
|
|
945
|
+
...Wishlist
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
```
|
|
949
|
+
|
|
950
|
+
### Query: `BlogPosts`
|
|
951
|
+
|
|
952
|
+
**Section**: Blog
|
|
953
|
+
|
|
954
|
+
**Description**: Paginated list of published blog posts. Filter by `categorySlug`, `tagSlug`, or `featured` (boolean flag, not enum). Sort: `PUBLISHED_AT` (default), `TITLE`, `VIEW_COUNT`, or `CREATED_AT`. Public; no auth required.
|
|
955
|
+
|
|
956
|
+
**Variables**:
|
|
957
|
+
- `$first`: `Int` *(default: `20`)*
|
|
958
|
+
- `$after`: `String`
|
|
959
|
+
- `$categorySlug`: `String`
|
|
960
|
+
- `$tagSlug`: `String`
|
|
961
|
+
- `$featured`: `Boolean`
|
|
962
|
+
- `$sortKey`: `BlogPostSortKey` *(default: `PUBLISHED_AT`)*
|
|
963
|
+
- `$reverse`: `Boolean` *(default: `false`)*
|
|
964
|
+
|
|
965
|
+
**Fragments used**: `BlogPost`, `PageInfo`
|
|
966
|
+
|
|
967
|
+
**GraphQL**:
|
|
968
|
+
```graphql
|
|
969
|
+
query BlogPosts($first: Int = 20, $after: String, $categorySlug: String, $tagSlug: String, $featured: Boolean, $sortKey: BlogPostSortKey = PUBLISHED_AT, $reverse: Boolean = false) {
|
|
970
|
+
blogPosts(
|
|
971
|
+
first: $first
|
|
972
|
+
after: $after
|
|
973
|
+
categorySlug: $categorySlug
|
|
974
|
+
tagSlug: $tagSlug
|
|
975
|
+
featured: $featured
|
|
976
|
+
sortKey: $sortKey
|
|
977
|
+
reverse: $reverse
|
|
978
|
+
) {
|
|
979
|
+
edges {
|
|
980
|
+
node {
|
|
981
|
+
...BlogPost
|
|
982
|
+
}
|
|
983
|
+
cursor
|
|
984
|
+
}
|
|
985
|
+
pageInfo {
|
|
986
|
+
...PageInfo
|
|
987
|
+
}
|
|
988
|
+
totalCount
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
### Query: `BlogPost`
|
|
994
|
+
|
|
995
|
+
**Section**: Blog
|
|
996
|
+
|
|
997
|
+
**Description**: Fetches a single blog post by `id` or `slug`. Visibility-gated: returns null if the post is not yet `PUBLISHED` or if its publish date is in the future (scheduled posts stay hidden until their publish time). Side effect: fetching a post increments its `view_count` asynchronously (does not block the response).
|
|
998
|
+
|
|
999
|
+
**Variables**:
|
|
1000
|
+
- `$id`: `ID`
|
|
1001
|
+
- `$slug`: `String`
|
|
1002
|
+
|
|
1003
|
+
**Fragments used**: `BlogPost`
|
|
1004
|
+
|
|
1005
|
+
**GraphQL**:
|
|
1006
|
+
```graphql
|
|
1007
|
+
query BlogPost($id: ID, $slug: String) {
|
|
1008
|
+
blogPost(id: $id, slug: $slug) {
|
|
1009
|
+
...BlogPost
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
### Query: `BlogCategories`
|
|
1015
|
+
|
|
1016
|
+
**Section**: Blog
|
|
1017
|
+
|
|
1018
|
+
**Description**: Lists all blog categories with per-category `postCount` and SEO metadata. Use to render category navigation on blog pages. Public; no auth required.
|
|
1019
|
+
|
|
1020
|
+
**Variables**: none
|
|
1021
|
+
|
|
1022
|
+
**Fragments used**: `BlogCategory`
|
|
1023
|
+
|
|
1024
|
+
**GraphQL**:
|
|
1025
|
+
```graphql
|
|
1026
|
+
query BlogCategories {
|
|
1027
|
+
blogCategories {
|
|
1028
|
+
...BlogCategory
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
### Query: `BlogTags`
|
|
1034
|
+
|
|
1035
|
+
**Section**: Blog
|
|
1036
|
+
|
|
1037
|
+
**Description**: Lists blog tags with usage counts (`postCount` per tag). Use to render a tag cloud. Public; no auth required.
|
|
1038
|
+
|
|
1039
|
+
**Variables**: none
|
|
1040
|
+
|
|
1041
|
+
**Fragments used**: `BlogTag`
|
|
1042
|
+
|
|
1043
|
+
**GraphQL**:
|
|
1044
|
+
```graphql
|
|
1045
|
+
query BlogTags {
|
|
1046
|
+
blogTags {
|
|
1047
|
+
...BlogTag
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
### Query: `ProductRecommendations`
|
|
1053
|
+
|
|
1054
|
+
**Section**: Recommendations
|
|
1055
|
+
|
|
1056
|
+
**Description**: Returns up to `$limit` recommended products related to `$productId`. Default `$intent: SIMILAR` — products sharing categories or tags. Use on PDP "You may also like" sections. Public; no auth required.
|
|
1057
|
+
|
|
1058
|
+
**Variables**:
|
|
1059
|
+
- `$productId`: `ID!`
|
|
1060
|
+
- `$limit`: `Int` *(default: `8`)*
|
|
1061
|
+
- `$intent`: `RecommendationIntent` *(default: `SIMILAR`)*
|
|
1062
|
+
|
|
1063
|
+
**Fragments used**: `ProductCard`
|
|
1064
|
+
|
|
1065
|
+
**GraphQL**:
|
|
1066
|
+
```graphql
|
|
1067
|
+
query ProductRecommendations($productId: ID!, $limit: Int = 8, $intent: RecommendationIntent = SIMILAR) {
|
|
1068
|
+
productRecommendations(productId: $productId, limit: $limit, intent: $intent) {
|
|
1069
|
+
...ProductCard
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
### Query: `Page`
|
|
1075
|
+
|
|
1076
|
+
**Section**: Content: Pages
|
|
1077
|
+
|
|
1078
|
+
**Description**: Fetches a single CMS page (About, Privacy, Returns Policy, Terms, etc.) by `handle` or `id`. Visibility-gated: returns null if the page is hidden or if its publish date is in the future. Public; no auth required.
|
|
1079
|
+
|
|
1080
|
+
**Variables**:
|
|
1081
|
+
- `$handle`: `String`
|
|
1082
|
+
- `$id`: `ID`
|
|
1083
|
+
|
|
1084
|
+
**Fragments used**: `ShopPage`
|
|
1085
|
+
|
|
1086
|
+
**GraphQL**:
|
|
1087
|
+
```graphql
|
|
1088
|
+
query Page($handle: String, $id: ID) {
|
|
1089
|
+
page(handle: $handle, id: $id) {
|
|
1090
|
+
...ShopPage
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
```
|
|
1094
|
+
|
|
1095
|
+
### Query: `Pages`
|
|
1096
|
+
|
|
1097
|
+
**Section**: Content: Pages
|
|
1098
|
+
|
|
1099
|
+
**Description**: Paginated list of visible, already-published CMS pages. Use for sitemap, footer link list, or page directory. The `query` argument supports text search over the page title/handle. Public; no auth required.
|
|
1100
|
+
|
|
1101
|
+
**Variables**:
|
|
1102
|
+
- `$first`: `Int` *(default: `20`)*
|
|
1103
|
+
- `$after`: `String`
|
|
1104
|
+
- `$sortKey`: `PageSortKeys` *(default: `TITLE`)*
|
|
1105
|
+
- `$reverse`: `Boolean` *(default: `false`)*
|
|
1106
|
+
- `$query`: `String`
|
|
1107
|
+
|
|
1108
|
+
**Fragments used**: `PageInfo`, `ShopPage`
|
|
1109
|
+
|
|
1110
|
+
**GraphQL**:
|
|
1111
|
+
```graphql
|
|
1112
|
+
query Pages($first: Int = 20, $after: String, $sortKey: PageSortKeys = TITLE, $reverse: Boolean = false, $query: String) {
|
|
1113
|
+
pages(
|
|
1114
|
+
first: $first
|
|
1115
|
+
after: $after
|
|
1116
|
+
sortKey: $sortKey
|
|
1117
|
+
reverse: $reverse
|
|
1118
|
+
query: $query
|
|
1119
|
+
) {
|
|
1120
|
+
edges {
|
|
1121
|
+
node {
|
|
1122
|
+
...ShopPage
|
|
1123
|
+
}
|
|
1124
|
+
cursor
|
|
1125
|
+
}
|
|
1126
|
+
pageInfo {
|
|
1127
|
+
...PageInfo
|
|
1128
|
+
}
|
|
1129
|
+
totalCount
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
### Query: `Menu`
|
|
1135
|
+
|
|
1136
|
+
**Section**: Content: Navigation Menus
|
|
1137
|
+
|
|
1138
|
+
**Description**: Fetches a navigation menu by `handle` (e.g. `"main-menu"`, `"footer"`, `"mobile"`). Returns the nested item tree. Each item is typed as one of: `HTTP`, `FRONTPAGE`, `SEARCH`, `CATALOG`, `BLOG`, `PRODUCT`, `COLLECTION`, `CATEGORY`, or `PAGE` — switch on the type to render the right link target. Linked resources and URLs are resolved on demand by the field selections in the `Menu` fragment.
|
|
1139
|
+
|
|
1140
|
+
**Variables**:
|
|
1141
|
+
- `$handle`: `String!`
|
|
1142
|
+
|
|
1143
|
+
**Fragments used**: `Menu`
|
|
1144
|
+
|
|
1145
|
+
**GraphQL**:
|
|
1146
|
+
```graphql
|
|
1147
|
+
query Menu($handle: String!) {
|
|
1148
|
+
menu(handle: $handle) {
|
|
1149
|
+
...Menu
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
```
|
|
1153
|
+
|
|
1154
|
+
### Query: `UrlRedirects`
|
|
1155
|
+
|
|
1156
|
+
**Section**: Content: URL Redirects
|
|
1157
|
+
|
|
1158
|
+
**Description**: Returns the shop's URL redirects (legacy `path` → new `target` mappings). Use server-side at the edge or in SSR to issue 301 redirects for migrated routes (preserves SEO equity). Default page size 250 — most shops fit in a single page.
|
|
1159
|
+
|
|
1160
|
+
**Variables**:
|
|
1161
|
+
- `$first`: `Int` *(default: `250`)*
|
|
1162
|
+
- `$after`: `String`
|
|
1163
|
+
|
|
1164
|
+
**Fragments used**: `PageInfo`, `UrlRedirect`
|
|
1165
|
+
|
|
1166
|
+
**GraphQL**:
|
|
1167
|
+
```graphql
|
|
1168
|
+
query UrlRedirects($first: Int = 250, $after: String) {
|
|
1169
|
+
urlRedirects(first: $first, after: $after) {
|
|
1170
|
+
nodes {
|
|
1171
|
+
...UrlRedirect
|
|
1172
|
+
}
|
|
1173
|
+
pageInfo {
|
|
1174
|
+
...PageInfo
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
### Query: `ProductStoreAvailability`
|
|
1181
|
+
|
|
1182
|
+
**Section**: Store Availability: per-location stock (BOPIS / multi-location)
|
|
1183
|
+
|
|
1184
|
+
**Description**: Fetches a product (by `handle` or `id`) along with per-variant availability across the merchant's physical locations — for the BOPIS / multi-location flow. The `storeAvailability` connection lives on each `ProductVariant`; its arguments (`first`, `after`, `near`, `locationType`) are set inside the `VariantStoreAvailability` fragment. The connection returns null for single-location shops (in which case the storefront can skip the store picker entirely). `availableStock` is null for anonymous users and an integer for authenticated customers. Apply `@inContext(preferredLocationId: ...)` on the operation to pin the customer's preferred location to the top of the result.
|
|
1185
|
+
|
|
1186
|
+
**Variables**:
|
|
1187
|
+
- `$handle`: `String`
|
|
1188
|
+
- `$id`: `ID`
|
|
1189
|
+
|
|
1190
|
+
**Fragments used**: `VariantStoreAvailability`
|
|
1191
|
+
|
|
1192
|
+
**GraphQL**:
|
|
1193
|
+
```graphql
|
|
1194
|
+
query ProductStoreAvailability($handle: String, $id: ID) {
|
|
1195
|
+
product(handle: $handle, id: $id) {
|
|
1196
|
+
id
|
|
1197
|
+
handle
|
|
1198
|
+
title
|
|
1199
|
+
variants {
|
|
1200
|
+
...VariantStoreAvailability
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
```
|
|
1205
|
+
|
|
1206
|
+
### Query: `Locations`
|
|
1207
|
+
|
|
1208
|
+
**Section**: Locations (store picker UI)
|
|
1209
|
+
|
|
1210
|
+
**Description**: Paginated list of active store locations (default 20, max 100). Filters: `near` (`{ latitude, longitude }`) for proximity search — sorts ascending by distance; `hasPickupEnabled` for pickup-only filtering; `locationType` (`RETAIL`, `WAREHOUSE`, `PICKUP_POINT`). When `near` is omitted, results are sorted by the merchant's `priority`, then name. Use for the BOPIS store picker UI. Public; no auth required.
|
|
1211
|
+
|
|
1212
|
+
**Variables**:
|
|
1213
|
+
- `$first`: `Int` *(default: `20`)*
|
|
1214
|
+
- `$after`: `String`
|
|
1215
|
+
- `$near`: `GeoCoordinateInput`
|
|
1216
|
+
- `$hasPickupEnabled`: `Boolean`
|
|
1217
|
+
- `$locationType`: `LocationType`
|
|
1218
|
+
|
|
1219
|
+
**Fragments used**: `Location`, `PageInfo`
|
|
1220
|
+
|
|
1221
|
+
**GraphQL**:
|
|
1222
|
+
```graphql
|
|
1223
|
+
query Locations($first: Int = 20, $after: String, $near: GeoCoordinateInput, $hasPickupEnabled: Boolean, $locationType: LocationType) {
|
|
1224
|
+
locations(
|
|
1225
|
+
first: $first
|
|
1226
|
+
after: $after
|
|
1227
|
+
near: $near
|
|
1228
|
+
hasPickupEnabled: $hasPickupEnabled
|
|
1229
|
+
locationType: $locationType
|
|
1230
|
+
) {
|
|
1231
|
+
totalCount
|
|
1232
|
+
pageInfo {
|
|
1233
|
+
...PageInfo
|
|
1234
|
+
}
|
|
1235
|
+
edges {
|
|
1236
|
+
cursor
|
|
1237
|
+
node {
|
|
1238
|
+
...Location
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
### Query: `Location`
|
|
1246
|
+
|
|
1247
|
+
**Section**: Locations (store picker UI)
|
|
1248
|
+
|
|
1249
|
+
**Description**: Fetches a single store location by `id` — full address, coordinates, business hours, pickup config (lead time, hours, timezone), and services. Returns null if the location is not found, not active, or owned by another shop. Use on the location detail page. Public; no auth required.
|
|
1250
|
+
|
|
1251
|
+
**Variables**:
|
|
1252
|
+
- `$id`: `ID!`
|
|
1253
|
+
|
|
1254
|
+
**Fragments used**: `Location`
|
|
1255
|
+
|
|
1256
|
+
**GraphQL**:
|
|
1257
|
+
```graphql
|
|
1258
|
+
query Location($id: ID!) {
|
|
1259
|
+
location(id: $id) {
|
|
1260
|
+
...Location
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
```
|
|
1264
|
+
|
|
1265
|
+
---
|
|
1266
|
+
|
|
1267
|
+
## Mutations
|
|
1268
|
+
|
|
1269
|
+
### Mutation: `CartCreate`
|
|
1270
|
+
|
|
1271
|
+
**Section**: Cart Mutations
|
|
1272
|
+
|
|
1273
|
+
**Description**: Creates a new cart and optionally pre-populates it with line items. Cart ID is a UUID stored by the SDK in the `cart-id` cookie (30-day TTL); the cart itself expires server-side after 72 hours of inactivity. The `warnings` field is reserved for non-blocking issues — current implementation returns it empty in this path.
|
|
1274
|
+
|
|
1275
|
+
**Variables**:
|
|
1276
|
+
- `$input`: `CartCreateInput`
|
|
1277
|
+
|
|
1278
|
+
**Fragments used**: `Cart`, `CartWarning`, `UserError`
|
|
1279
|
+
|
|
1280
|
+
**GraphQL**:
|
|
1281
|
+
```graphql
|
|
1282
|
+
mutation CartCreate($input: CartCreateInput) {
|
|
1283
|
+
cartCreate(input: $input) {
|
|
1284
|
+
cart {
|
|
1285
|
+
...Cart
|
|
1286
|
+
}
|
|
1287
|
+
userErrors {
|
|
1288
|
+
...UserError
|
|
1289
|
+
}
|
|
1290
|
+
warnings {
|
|
1291
|
+
...CartWarning
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
```
|
|
1296
|
+
|
|
1297
|
+
### Mutation: `CartAddLines`
|
|
1298
|
+
|
|
1299
|
+
**Section**: Cart Mutations
|
|
1300
|
+
|
|
1301
|
+
**Description**: Adds line items to a cart. Each line is `{ merchandiseId, quantity, attributes?, attributeSelections? }`. If the same variant + identical attributes are added twice, quantities merge into one row instead of duplicating. Validates stock (`INSUFFICIENT_STOCK`) and configurator attributes (`ATTRIBUTE_REQUIRED`, `ATTRIBUTE_OPTION_INVALID`). Triggers cart re-pricing including discount recalculation.
|
|
1302
|
+
|
|
1303
|
+
**Variables**:
|
|
1304
|
+
- `$id`: `ID!`
|
|
1305
|
+
- `$lines`: `[CartLineInput!]!`
|
|
1306
|
+
|
|
1307
|
+
**Fragments used**: `Cart`, `CartWarning`, `UserError`
|
|
1308
|
+
|
|
1309
|
+
**GraphQL**:
|
|
1310
|
+
```graphql
|
|
1311
|
+
mutation CartAddLines($id: ID!, $lines: [CartLineInput!]!) {
|
|
1312
|
+
cartAddLines(id: $id, lines: $lines) {
|
|
1313
|
+
cart {
|
|
1314
|
+
...Cart
|
|
1315
|
+
}
|
|
1316
|
+
userErrors {
|
|
1317
|
+
...UserError
|
|
1318
|
+
}
|
|
1319
|
+
warnings {
|
|
1320
|
+
...CartWarning
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
```
|
|
1325
|
+
|
|
1326
|
+
### Mutation: `CartUpdateLines`
|
|
1327
|
+
|
|
1328
|
+
**Section**: Cart Mutations
|
|
1329
|
+
|
|
1330
|
+
**Description**: Updates quantity and/or attributes of existing cart lines by `id`. Setting `quantity: 0` auto-deletes the line. Passing `attributes: []` clears them; omitting the field preserves existing values. Re-validates stock and re-prices the cart after each update.
|
|
1331
|
+
|
|
1332
|
+
**Variables**:
|
|
1333
|
+
- `$id`: `ID!`
|
|
1334
|
+
- `$lines`: `[CartLineUpdateInput!]!`
|
|
1335
|
+
|
|
1336
|
+
**Fragments used**: `Cart`, `CartWarning`, `UserError`
|
|
1337
|
+
|
|
1338
|
+
**GraphQL**:
|
|
1339
|
+
```graphql
|
|
1340
|
+
mutation CartUpdateLines($id: ID!, $lines: [CartLineUpdateInput!]!) {
|
|
1341
|
+
cartUpdateLines(id: $id, lines: $lines) {
|
|
1342
|
+
cart {
|
|
1343
|
+
...Cart
|
|
1344
|
+
}
|
|
1345
|
+
userErrors {
|
|
1346
|
+
...UserError
|
|
1347
|
+
}
|
|
1348
|
+
warnings {
|
|
1349
|
+
...CartWarning
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
```
|
|
1354
|
+
|
|
1355
|
+
### Mutation: `CartRemoveLines`
|
|
1356
|
+
|
|
1357
|
+
**Section**: Cart Mutations
|
|
1358
|
+
|
|
1359
|
+
**Description**: Removes specific lines from cart by `lineIds[]`. Internally delegates to `cartUpdateLines` with `quantity: 0` — both endpoints are functionally equivalent; this one exists for API ergonomics when intent is explicit removal. Triggers cart re-pricing.
|
|
1360
|
+
|
|
1361
|
+
**Variables**:
|
|
1362
|
+
- `$id`: `ID!`
|
|
1363
|
+
- `$lineIds`: `[ID!]!`
|
|
1364
|
+
|
|
1365
|
+
**Fragments used**: `Cart`, `CartWarning`, `UserError`
|
|
1366
|
+
|
|
1367
|
+
**GraphQL**:
|
|
1368
|
+
```graphql
|
|
1369
|
+
mutation CartRemoveLines($id: ID!, $lineIds: [ID!]!) {
|
|
1370
|
+
cartRemoveLines(id: $id, lineIds: $lineIds) {
|
|
1371
|
+
cart {
|
|
1372
|
+
...Cart
|
|
1373
|
+
}
|
|
1374
|
+
userErrors {
|
|
1375
|
+
...UserError
|
|
1376
|
+
}
|
|
1377
|
+
warnings {
|
|
1378
|
+
...CartWarning
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
```
|
|
1383
|
+
|
|
1384
|
+
### Mutation: `CartApplyDiscountCodes`
|
|
1385
|
+
|
|
1386
|
+
**Section**: Cart Mutations
|
|
1387
|
+
|
|
1388
|
+
**Description**: Replaces (NOT appends) the cart's discount codes with the given list. Pass `[]` to clear all codes. Each code is validated against `discounts` table (existence, active status); invalid codes appear in `userErrors[]` as `DISCOUNT_CODE_INVALID`. Triggers cart re-pricing — discount allocations are recomputed and stored in `cart.discountAmount`.
|
|
1389
|
+
|
|
1390
|
+
**Variables**:
|
|
1391
|
+
- `$id`: `ID!`
|
|
1392
|
+
- `$discountCodes`: `[String!]!`
|
|
1393
|
+
|
|
1394
|
+
**Fragments used**: `Cart`, `CartWarning`, `UserError`
|
|
1395
|
+
|
|
1396
|
+
**GraphQL**:
|
|
1397
|
+
```graphql
|
|
1398
|
+
mutation CartApplyDiscountCodes($id: ID!, $discountCodes: [String!]!) {
|
|
1399
|
+
cartApplyDiscountCodes(id: $id, discountCodes: $discountCodes) {
|
|
1400
|
+
cart {
|
|
1401
|
+
...Cart
|
|
1402
|
+
}
|
|
1403
|
+
userErrors {
|
|
1404
|
+
...UserError
|
|
1405
|
+
}
|
|
1406
|
+
warnings {
|
|
1407
|
+
...CartWarning
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
```
|
|
1412
|
+
|
|
1413
|
+
### Mutation: `CartUpdateBuyerIdentity`
|
|
1414
|
+
|
|
1415
|
+
**Section**: Cart Mutations
|
|
1416
|
+
|
|
1417
|
+
**Description**: Associates a customer with the cart. Despite the input shape accepting `email`, `phone`, `countryCode`, `languageCode`, only `customerId` is currently persisted — other fields are silently ignored. Does NOT trigger tax / shipping recalculation; pure cart-to-customer linking. Use during login or guest-to-account upgrade.
|
|
1418
|
+
|
|
1419
|
+
**Variables**:
|
|
1420
|
+
- `$id`: `ID!`
|
|
1421
|
+
- `$buyerIdentity`: `CartBuyerIdentityInput!`
|
|
1422
|
+
|
|
1423
|
+
**Fragments used**: `Cart`, `CartWarning`, `UserError`
|
|
1424
|
+
|
|
1425
|
+
**GraphQL**:
|
|
1426
|
+
```graphql
|
|
1427
|
+
mutation CartUpdateBuyerIdentity($id: ID!, $buyerIdentity: CartBuyerIdentityInput!) {
|
|
1428
|
+
cartUpdateBuyerIdentity(id: $id, buyerIdentity: $buyerIdentity) {
|
|
1429
|
+
cart {
|
|
1430
|
+
...Cart
|
|
1431
|
+
}
|
|
1432
|
+
userErrors {
|
|
1433
|
+
...UserError
|
|
1434
|
+
}
|
|
1435
|
+
warnings {
|
|
1436
|
+
...CartWarning
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
```
|
|
1441
|
+
|
|
1442
|
+
### Mutation: `CartUpdateNote`
|
|
1443
|
+
|
|
1444
|
+
**Section**: Cart Mutations
|
|
1445
|
+
|
|
1446
|
+
**Description**: Sets a free-text note on the cart (gift message, special instructions). Pass empty string to clear. Stored on the `Cart` row, propagated to the `Order` at checkout completion, visible to merchant in admin.
|
|
1447
|
+
|
|
1448
|
+
**Variables**:
|
|
1449
|
+
- `$id`: `ID!`
|
|
1450
|
+
- `$note`: `String!`
|
|
1451
|
+
|
|
1452
|
+
**Fragments used**: `Cart`, `CartWarning`, `UserError`
|
|
1453
|
+
|
|
1454
|
+
**GraphQL**:
|
|
1455
|
+
```graphql
|
|
1456
|
+
mutation CartUpdateNote($id: ID!, $note: String!) {
|
|
1457
|
+
cartUpdateNote(id: $id, note: $note) {
|
|
1458
|
+
cart {
|
|
1459
|
+
...Cart
|
|
1460
|
+
}
|
|
1461
|
+
userErrors {
|
|
1462
|
+
...UserError
|
|
1463
|
+
}
|
|
1464
|
+
warnings {
|
|
1465
|
+
...CartWarning
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
```
|
|
1470
|
+
|
|
1471
|
+
### Mutation: `CustomerSignup`
|
|
1472
|
+
|
|
1473
|
+
**Section**: Customer Auth Mutations
|
|
1474
|
+
|
|
1475
|
+
**Description**: Registers a new customer. Returns `customerAccessToken` immediately — the customer record is created with status `ACTIVE` (no pending state). The activation email containing `customerActivate` token is sent for `emailVerified=true` confirmation, but is NOT required for login. Cookie: `customerAccessToken`, 30-day max-age, httpOnly. JWT TTL: 24h. Bot-protection guarded.
|
|
1476
|
+
|
|
1477
|
+
**Variables**:
|
|
1478
|
+
- `$input`: `CustomerCreateInput!`
|
|
1479
|
+
|
|
1480
|
+
**Fragments used**: `Customer`, `CustomerAccessToken`, `UserError`
|
|
1481
|
+
|
|
1482
|
+
**GraphQL**:
|
|
1483
|
+
```graphql
|
|
1484
|
+
mutation CustomerSignup($input: CustomerCreateInput!) {
|
|
1485
|
+
customerSignup(input: $input) {
|
|
1486
|
+
customer {
|
|
1487
|
+
...Customer
|
|
1488
|
+
}
|
|
1489
|
+
customerAccessToken {
|
|
1490
|
+
...CustomerAccessToken
|
|
1491
|
+
}
|
|
1492
|
+
userErrors {
|
|
1493
|
+
...UserError
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
```
|
|
1498
|
+
|
|
1499
|
+
### Mutation: `CustomerLogin`
|
|
1500
|
+
|
|
1501
|
+
**Section**: Customer Auth Mutations
|
|
1502
|
+
|
|
1503
|
+
**Description**: Logs in with email + password. JWT lifetime 24h; cookie max-age 30d (cookie outlives JWT — call `customerRefreshToken` before JWT expiry to extend session). Brute-force protected: 10 failed attempts per email = 15-min Redis-backed lockout. Failed attempts are recorded for non-existent emails too (timing-attack safe).
|
|
1504
|
+
|
|
1505
|
+
**Variables**:
|
|
1506
|
+
- `$input`: `CustomerAccessTokenCreateInput!`
|
|
1507
|
+
|
|
1508
|
+
**Fragments used**: `CustomerAccessToken`, `UserError`
|
|
1509
|
+
|
|
1510
|
+
**GraphQL**:
|
|
1511
|
+
```graphql
|
|
1512
|
+
mutation CustomerLogin($input: CustomerAccessTokenCreateInput!) {
|
|
1513
|
+
customerLogin(input: $input) {
|
|
1514
|
+
customerAccessToken {
|
|
1515
|
+
...CustomerAccessToken
|
|
1516
|
+
}
|
|
1517
|
+
userErrors {
|
|
1518
|
+
...UserError
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
```
|
|
1523
|
+
|
|
1524
|
+
### Mutation: `CustomerLogout`
|
|
1525
|
+
|
|
1526
|
+
**Section**: Customer Auth Mutations
|
|
1527
|
+
|
|
1528
|
+
**Description**: Clears the `customerAccessToken` cookie. Note: the JWT itself is NOT server-side invalidated — it remains valid until its 24h expiry. Server-side token revocation is on the roadmap. Idempotent.
|
|
1529
|
+
|
|
1530
|
+
**Variables**: none
|
|
1531
|
+
|
|
1532
|
+
**Fragments used**: `UserError`
|
|
1533
|
+
|
|
1534
|
+
**GraphQL**:
|
|
1535
|
+
```graphql
|
|
1536
|
+
mutation CustomerLogout {
|
|
1537
|
+
customerLogout {
|
|
1538
|
+
deletedAccessToken
|
|
1539
|
+
deletedCustomerAccessTokenId
|
|
1540
|
+
userErrors {
|
|
1541
|
+
...UserError
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
```
|
|
1546
|
+
|
|
1547
|
+
### Mutation: `CustomerRefreshToken`
|
|
1548
|
+
|
|
1549
|
+
**Section**: Customer Auth Mutations
|
|
1550
|
+
|
|
1551
|
+
**Description**: Issues a fresh JWT (24h TTL) for the currently-authenticated customer. Reads identity from the current cookie/Bearer token; takes no input. Use proactively before JWT expiry or reactively on a 401 retry. The new token replaces the cookie value.
|
|
1552
|
+
|
|
1553
|
+
**Variables**: none
|
|
1554
|
+
|
|
1555
|
+
**Fragments used**: `CustomerAccessToken`, `UserError`
|
|
1556
|
+
|
|
1557
|
+
**GraphQL**:
|
|
1558
|
+
```graphql
|
|
1559
|
+
mutation CustomerRefreshToken {
|
|
1560
|
+
customerRefreshToken {
|
|
1561
|
+
customerAccessToken {
|
|
1562
|
+
...CustomerAccessToken
|
|
1563
|
+
}
|
|
1564
|
+
userErrors {
|
|
1565
|
+
...UserError
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
```
|
|
1570
|
+
|
|
1571
|
+
### Mutation: `CustomerUpdate`
|
|
1572
|
+
|
|
1573
|
+
**Section**: Customer Profile Mutations
|
|
1574
|
+
|
|
1575
|
+
**Description**: Updates the logged-in customer's profile. Supported fields include `firstName`, `lastName`, `phone`, marketing preferences, and B2B identity (`customerType`, `companyName`, `taxId`, `vatNumber`, `regon`). Concurrent updates from the storefront and the merchant admin are reconciled safely — the loser of a race retries against the latest version. Marketing consent changes are recorded separately for audit purposes.
|
|
1576
|
+
|
|
1577
|
+
**Variables**:
|
|
1578
|
+
- `$customer`: `CustomerUpdateInput!`
|
|
1579
|
+
|
|
1580
|
+
**Fragments used**: `Customer`, `UserError`
|
|
1581
|
+
|
|
1582
|
+
**GraphQL**:
|
|
1583
|
+
```graphql
|
|
1584
|
+
mutation CustomerUpdate($customer: CustomerUpdateInput!) {
|
|
1585
|
+
customerUpdate(customer: $customer) {
|
|
1586
|
+
customer {
|
|
1587
|
+
...Customer
|
|
1588
|
+
}
|
|
1589
|
+
userErrors {
|
|
1590
|
+
...UserError
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
```
|
|
1595
|
+
|
|
1596
|
+
### Mutation: `CustomerAddAddress`
|
|
1597
|
+
|
|
1598
|
+
**Section**: Customer Address Mutations
|
|
1599
|
+
|
|
1600
|
+
**Description**: Adds a new mailing address. If `isDefaultShipping` or `isDefaultBilling` is `true` in the input, the new address is set as default and any other address for this customer holding that flag is atomically cleared in the same transaction.
|
|
1601
|
+
|
|
1602
|
+
**Variables**:
|
|
1603
|
+
- `$address`: `MailingAddressInput!`
|
|
1604
|
+
|
|
1605
|
+
**Fragments used**: `MailingAddress`, `UserError`
|
|
1606
|
+
|
|
1607
|
+
**GraphQL**:
|
|
1608
|
+
```graphql
|
|
1609
|
+
mutation CustomerAddAddress($address: MailingAddressInput!) {
|
|
1610
|
+
customerAddAddress(address: $address) {
|
|
1611
|
+
address {
|
|
1612
|
+
...MailingAddress
|
|
1613
|
+
}
|
|
1614
|
+
userErrors {
|
|
1615
|
+
...UserError
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
```
|
|
1620
|
+
|
|
1621
|
+
### Mutation: `CustomerUpdateAddress`
|
|
1622
|
+
|
|
1623
|
+
**Section**: Customer Address Mutations
|
|
1624
|
+
|
|
1625
|
+
**Description**: Updates an existing address owned by the logged-in customer. If `isDefaultShipping` or `isDefaultBilling` toggles to `true`, default flag is atomically cleared on all other addresses for this customer.
|
|
1626
|
+
|
|
1627
|
+
**Variables**:
|
|
1628
|
+
- `$id`: `ID!`
|
|
1629
|
+
- `$address`: `MailingAddressInput!`
|
|
1630
|
+
|
|
1631
|
+
**Fragments used**: `MailingAddress`, `UserError`
|
|
1632
|
+
|
|
1633
|
+
**GraphQL**:
|
|
1634
|
+
```graphql
|
|
1635
|
+
mutation CustomerUpdateAddress($id: ID!, $address: MailingAddressInput!) {
|
|
1636
|
+
customerUpdateAddress(id: $id, address: $address) {
|
|
1637
|
+
address {
|
|
1638
|
+
...MailingAddress
|
|
1639
|
+
}
|
|
1640
|
+
userErrors {
|
|
1641
|
+
...UserError
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
```
|
|
1646
|
+
|
|
1647
|
+
### Mutation: `CustomerRemoveAddress`
|
|
1648
|
+
|
|
1649
|
+
**Section**: Customer Address Mutations
|
|
1650
|
+
|
|
1651
|
+
**Description**: Hard-deletes an address row from `customer_addresses`. Historical orders that referenced this address are unaffected (address is snapshotted into the order at checkout completion).
|
|
1652
|
+
|
|
1653
|
+
**Variables**:
|
|
1654
|
+
- `$id`: `ID!`
|
|
1655
|
+
|
|
1656
|
+
**Fragments used**: `UserError`
|
|
1657
|
+
|
|
1658
|
+
**GraphQL**:
|
|
1659
|
+
```graphql
|
|
1660
|
+
mutation CustomerRemoveAddress($id: ID!) {
|
|
1661
|
+
customerRemoveAddress(id: $id) {
|
|
1662
|
+
deletedAddressId
|
|
1663
|
+
userErrors {
|
|
1664
|
+
...UserError
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
```
|
|
1669
|
+
|
|
1670
|
+
### Mutation: `CustomerSetDefaultAddress`
|
|
1671
|
+
|
|
1672
|
+
**Section**: Customer Address Mutations
|
|
1673
|
+
|
|
1674
|
+
**Description**: Marks the given address as the customer's default **shipping** address. Atomically clears the shipping-default flag from all other addresses. Note: there is no separate setter for default billing — set `isDefaultBilling: true` via `customerAddAddress` / `customerUpdateAddress` instead.
|
|
1675
|
+
|
|
1676
|
+
**Variables**:
|
|
1677
|
+
- `$addressId`: `ID!`
|
|
1678
|
+
|
|
1679
|
+
**Fragments used**: `Customer`, `UserError`
|
|
1680
|
+
|
|
1681
|
+
**GraphQL**:
|
|
1682
|
+
```graphql
|
|
1683
|
+
mutation CustomerSetDefaultAddress($addressId: ID!) {
|
|
1684
|
+
customerSetDefaultAddress(addressId: $addressId) {
|
|
1685
|
+
customer {
|
|
1686
|
+
...Customer
|
|
1687
|
+
}
|
|
1688
|
+
userErrors {
|
|
1689
|
+
...UserError
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
```
|
|
1694
|
+
|
|
1695
|
+
### Mutation: `CustomerRequestPasswordReset`
|
|
1696
|
+
|
|
1697
|
+
**Section**: Customer Password Mutations
|
|
1698
|
+
|
|
1699
|
+
**Description**: Sends a password reset email. Always returns success regardless of whether the email exists (no account enumeration). The email is dispatched asynchronously, so a small delay between request and inbox arrival is normal. Rate-limited to 3 requests per 10 minutes.
|
|
1700
|
+
|
|
1701
|
+
**Variables**:
|
|
1702
|
+
- `$email`: `String!`
|
|
1703
|
+
|
|
1704
|
+
**Fragments used**: `UserError`
|
|
1705
|
+
|
|
1706
|
+
**GraphQL**:
|
|
1707
|
+
```graphql
|
|
1708
|
+
mutation CustomerRequestPasswordReset($email: String!) {
|
|
1709
|
+
customerRequestPasswordReset(email: $email) {
|
|
1710
|
+
userErrors {
|
|
1711
|
+
...UserError
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
```
|
|
1716
|
+
|
|
1717
|
+
### Mutation: `CustomerActivate`
|
|
1718
|
+
|
|
1719
|
+
**Section**: Customer Password Mutations
|
|
1720
|
+
|
|
1721
|
+
**Description**: Activates a newly-created account using the 64-hex activation token from the welcome email + a chosen password. Token TTL is 24h, single-use (atomically marked `used_at`). On success: sets `email_verified=true`, transitions status `INACTIVE`→`ACTIVE`, returns a fresh JWT for auto-login. Rate-limited.
|
|
1722
|
+
|
|
1723
|
+
**Variables**:
|
|
1724
|
+
- `$token`: `String!`
|
|
1725
|
+
- `$password`: `String!`
|
|
1726
|
+
|
|
1727
|
+
**Fragments used**: `Customer`, `CustomerAccessToken`, `UserError`
|
|
1728
|
+
|
|
1729
|
+
**GraphQL**:
|
|
1730
|
+
```graphql
|
|
1731
|
+
mutation CustomerActivate($token: String!, $password: String!) {
|
|
1732
|
+
customerActivate(token: $token, password: $password) {
|
|
1733
|
+
customer {
|
|
1734
|
+
...Customer
|
|
1735
|
+
}
|
|
1736
|
+
customerAccessToken {
|
|
1737
|
+
...CustomerAccessToken
|
|
1738
|
+
}
|
|
1739
|
+
userErrors {
|
|
1740
|
+
...UserError
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
```
|
|
1745
|
+
|
|
1746
|
+
### Mutation: `CustomerResetPassword`
|
|
1747
|
+
|
|
1748
|
+
**Section**: Customer Password Mutations
|
|
1749
|
+
|
|
1750
|
+
**Description**: Resets the password using the 64-hex reset token from the password-reset email. Token TTL is 1h, single-use (atomically marked `used_at`). On success: updates the password hash and returns a fresh JWT for auto-login (no second login step needed). Rate-limited.
|
|
1751
|
+
|
|
1752
|
+
**Variables**:
|
|
1753
|
+
- `$token`: `String!`
|
|
1754
|
+
- `$newPassword`: `String!`
|
|
1755
|
+
|
|
1756
|
+
**Fragments used**: `Customer`, `CustomerAccessToken`, `UserError`
|
|
1757
|
+
|
|
1758
|
+
**GraphQL**:
|
|
1759
|
+
```graphql
|
|
1760
|
+
mutation CustomerResetPassword($token: String!, $newPassword: String!) {
|
|
1761
|
+
customerResetPassword(token: $token, newPassword: $newPassword) {
|
|
1762
|
+
customer {
|
|
1763
|
+
...Customer
|
|
1764
|
+
}
|
|
1765
|
+
customerAccessToken {
|
|
1766
|
+
...CustomerAccessToken
|
|
1767
|
+
}
|
|
1768
|
+
userErrors {
|
|
1769
|
+
...UserError
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
```
|
|
1774
|
+
|
|
1775
|
+
### Mutation: `CheckoutCreate`
|
|
1776
|
+
|
|
1777
|
+
**Section**: Checkout Mutations
|
|
1778
|
+
|
|
1779
|
+
**Description**: Creates a new checkout session for the given cart (or a fresh cart if `cartId` is omitted). Inherits applied discounts and gift cards from the cart by reference (not snapshot). Errors: `CART_NOT_FOUND`, `EMPTY_CART`, `ALREADY_COMPLETED` (cart already converted to order). NOT idempotent — multiple calls create multiple checkouts.
|
|
1780
|
+
|
|
1781
|
+
**Variables**:
|
|
1782
|
+
- `$input`: `CheckoutCreateInput!`
|
|
1783
|
+
|
|
1784
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
1785
|
+
|
|
1786
|
+
**GraphQL**:
|
|
1787
|
+
```graphql
|
|
1788
|
+
mutation CheckoutCreate($input: CheckoutCreateInput!) {
|
|
1789
|
+
checkoutCreate(input: $input) {
|
|
1790
|
+
checkout {
|
|
1791
|
+
...Checkout
|
|
1792
|
+
}
|
|
1793
|
+
userErrors {
|
|
1794
|
+
...UserError
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
```
|
|
1799
|
+
|
|
1800
|
+
### Mutation: `CheckoutShippingAddressUpdate`
|
|
1801
|
+
|
|
1802
|
+
**Section**: Checkout Mutations
|
|
1803
|
+
|
|
1804
|
+
**Description**: Sets the shipping address (full replace, not patch). Triggers cart re-pricing. Address format is NOT validated here — full validation runs at `checkoutComplete` (`validateOrderReadiness`).
|
|
1805
|
+
|
|
1806
|
+
**Variables**:
|
|
1807
|
+
- `$checkoutId`: `ID!`
|
|
1808
|
+
- `$shippingAddress`: `CheckoutAddressInput!`
|
|
1809
|
+
|
|
1810
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
1811
|
+
|
|
1812
|
+
**GraphQL**:
|
|
1813
|
+
```graphql
|
|
1814
|
+
mutation CheckoutShippingAddressUpdate($checkoutId: ID!, $shippingAddress: CheckoutAddressInput!) {
|
|
1815
|
+
checkoutShippingAddressUpdate(
|
|
1816
|
+
checkoutId: $checkoutId
|
|
1817
|
+
shippingAddress: $shippingAddress
|
|
1818
|
+
) {
|
|
1819
|
+
checkout {
|
|
1820
|
+
...Checkout
|
|
1821
|
+
}
|
|
1822
|
+
userErrors {
|
|
1823
|
+
...UserError
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
```
|
|
1828
|
+
|
|
1829
|
+
### Mutation: `CheckoutBillingAddressUpdate`
|
|
1830
|
+
|
|
1831
|
+
**Section**: Checkout Mutations
|
|
1832
|
+
|
|
1833
|
+
**Description**: Sets the billing address (full replace). Independent of shipping address — pass it explicitly even when "billing same as shipping".
|
|
1834
|
+
|
|
1835
|
+
**Variables**:
|
|
1836
|
+
- `$checkoutId`: `ID!`
|
|
1837
|
+
- `$billingAddress`: `CheckoutAddressInput!`
|
|
1838
|
+
|
|
1839
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
1840
|
+
|
|
1841
|
+
**GraphQL**:
|
|
1842
|
+
```graphql
|
|
1843
|
+
mutation CheckoutBillingAddressUpdate($checkoutId: ID!, $billingAddress: CheckoutAddressInput!) {
|
|
1844
|
+
checkoutBillingAddressUpdate(
|
|
1845
|
+
checkoutId: $checkoutId
|
|
1846
|
+
billingAddress: $billingAddress
|
|
1847
|
+
) {
|
|
1848
|
+
checkout {
|
|
1849
|
+
...Checkout
|
|
1850
|
+
}
|
|
1851
|
+
userErrors {
|
|
1852
|
+
...UserError
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
```
|
|
1857
|
+
|
|
1858
|
+
### Mutation: `CheckoutEmailUpdate`
|
|
1859
|
+
|
|
1860
|
+
**Section**: Checkout Mutations
|
|
1861
|
+
|
|
1862
|
+
**Description**: Sets or updates the contact email on the checkout (used for guest checkout, order confirmation, and tracking emails). Validated against a regex; returns `INVALID` for malformed format.
|
|
1863
|
+
|
|
1864
|
+
**Variables**:
|
|
1865
|
+
- `$checkoutId`: `ID!`
|
|
1866
|
+
- `$email`: `String!`
|
|
1867
|
+
|
|
1868
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
1869
|
+
|
|
1870
|
+
**GraphQL**:
|
|
1871
|
+
```graphql
|
|
1872
|
+
mutation CheckoutEmailUpdate($checkoutId: ID!, $email: String!) {
|
|
1873
|
+
checkoutEmailUpdate(checkoutId: $checkoutId, email: $email) {
|
|
1874
|
+
checkout {
|
|
1875
|
+
...Checkout
|
|
1876
|
+
}
|
|
1877
|
+
userErrors {
|
|
1878
|
+
...UserError
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
```
|
|
1883
|
+
|
|
1884
|
+
### Mutation: `CheckoutShippingLineUpdate`
|
|
1885
|
+
|
|
1886
|
+
**Section**: Checkout Mutations
|
|
1887
|
+
|
|
1888
|
+
**Description**: Selects a shipping method by `shippingRateHandle` (a stable shipping-method UUID, NOT an opaque per-request token). The id comes from `availableShippingMethods` query, computed for the current address + cart subtotal at request time.
|
|
1889
|
+
|
|
1890
|
+
**Variables**:
|
|
1891
|
+
- `$checkoutId`: `ID!`
|
|
1892
|
+
- `$shippingRateHandle`: `String!`
|
|
1893
|
+
|
|
1894
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
1895
|
+
|
|
1896
|
+
**GraphQL**:
|
|
1897
|
+
```graphql
|
|
1898
|
+
mutation CheckoutShippingLineUpdate($checkoutId: ID!, $shippingRateHandle: String!) {
|
|
1899
|
+
checkoutShippingLineUpdate(
|
|
1900
|
+
checkoutId: $checkoutId
|
|
1901
|
+
shippingRateHandle: $shippingRateHandle
|
|
1902
|
+
) {
|
|
1903
|
+
checkout {
|
|
1904
|
+
...Checkout
|
|
1905
|
+
}
|
|
1906
|
+
userErrors {
|
|
1907
|
+
...UserError
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
```
|
|
1912
|
+
|
|
1913
|
+
### Mutation: `CheckoutDiscountCodeApply`
|
|
1914
|
+
|
|
1915
|
+
**Section**: Checkout Mutations
|
|
1916
|
+
|
|
1917
|
+
**Description**: Appends a discount code to the cart's `discount_codes` array. Note: while multiple codes can be stored, the pricing engine currently uses **only the first applied code** — codes do not stack. Validated for existence, active status, and customer usage limits via `discountService.validateDiscount`.
|
|
1918
|
+
|
|
1919
|
+
**Variables**:
|
|
1920
|
+
- `$checkoutId`: `ID!`
|
|
1921
|
+
- `$discountCode`: `String!`
|
|
1922
|
+
|
|
1923
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
1924
|
+
|
|
1925
|
+
**GraphQL**:
|
|
1926
|
+
```graphql
|
|
1927
|
+
mutation CheckoutDiscountCodeApply($checkoutId: ID!, $discountCode: String!) {
|
|
1928
|
+
checkoutDiscountCodeApply(checkoutId: $checkoutId, discountCode: $discountCode) {
|
|
1929
|
+
checkout {
|
|
1930
|
+
...Checkout
|
|
1931
|
+
}
|
|
1932
|
+
userErrors {
|
|
1933
|
+
...UserError
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
```
|
|
1938
|
+
|
|
1939
|
+
### Mutation: `CheckoutDiscountCodeRemove`
|
|
1940
|
+
|
|
1941
|
+
**Section**: Checkout Mutations
|
|
1942
|
+
|
|
1943
|
+
**Description**: Removes a code from the cart's `discount_codes` array (filters by exact match). Triggers re-pricing.
|
|
1944
|
+
|
|
1945
|
+
**Variables**:
|
|
1946
|
+
- `$checkoutId`: `ID!`
|
|
1947
|
+
- `$discountCode`: `String!`
|
|
1948
|
+
|
|
1949
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
1950
|
+
|
|
1951
|
+
**GraphQL**:
|
|
1952
|
+
```graphql
|
|
1953
|
+
mutation CheckoutDiscountCodeRemove($checkoutId: ID!, $discountCode: String!) {
|
|
1954
|
+
checkoutDiscountCodeRemove(checkoutId: $checkoutId, discountCode: $discountCode) {
|
|
1955
|
+
checkout {
|
|
1956
|
+
...Checkout
|
|
1957
|
+
}
|
|
1958
|
+
userErrors {
|
|
1959
|
+
...UserError
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
```
|
|
1964
|
+
|
|
1965
|
+
### Mutation: `CheckoutDiscountCodeValidate`
|
|
1966
|
+
|
|
1967
|
+
**Section**: Checkout Mutations
|
|
1968
|
+
|
|
1969
|
+
**Description**: READ-ONLY validation of a discount code against the current checkout — does NOT modify state. Returns `{ isValid, discount, error }` for previewing the effect (e.g. inline UI feedback as the user types).
|
|
1970
|
+
|
|
1971
|
+
**Variables**:
|
|
1972
|
+
- `$checkoutId`: `ID!`
|
|
1973
|
+
- `$discountCode`: `String!`
|
|
1974
|
+
|
|
1975
|
+
**Fragments used**: `UserError`
|
|
1976
|
+
|
|
1977
|
+
**GraphQL**:
|
|
1978
|
+
```graphql
|
|
1979
|
+
mutation CheckoutDiscountCodeValidate($checkoutId: ID!, $discountCode: String!) {
|
|
1980
|
+
checkoutDiscountCodeValidate(
|
|
1981
|
+
checkoutId: $checkoutId
|
|
1982
|
+
discountCode: $discountCode
|
|
1983
|
+
) {
|
|
1984
|
+
result {
|
|
1985
|
+
isValid
|
|
1986
|
+
discount {
|
|
1987
|
+
code
|
|
1988
|
+
title
|
|
1989
|
+
type
|
|
1990
|
+
value
|
|
1991
|
+
discountAmount {
|
|
1992
|
+
amount
|
|
1993
|
+
currencyCode
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
error {
|
|
1997
|
+
code
|
|
1998
|
+
message
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
userErrors {
|
|
2002
|
+
...UserError
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
```
|
|
2007
|
+
|
|
2008
|
+
### Mutation: `CheckoutPaymentMethodUpdate`
|
|
2009
|
+
|
|
2010
|
+
**Section**: Checkout Mutations
|
|
2011
|
+
|
|
2012
|
+
**Description**: Selects a payment method by `paymentMethodId` (UUID from `availablePaymentMethods` query). Validates existence and active status; no pre-authorization is performed here.
|
|
2013
|
+
|
|
2014
|
+
**Variables**:
|
|
2015
|
+
- `$checkoutId`: `ID!`
|
|
2016
|
+
- `$paymentMethodId`: `ID!`
|
|
2017
|
+
|
|
2018
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
2019
|
+
|
|
2020
|
+
**GraphQL**:
|
|
2021
|
+
```graphql
|
|
2022
|
+
mutation CheckoutPaymentMethodUpdate($checkoutId: ID!, $paymentMethodId: ID!) {
|
|
2023
|
+
checkoutPaymentMethodUpdate(
|
|
2024
|
+
checkoutId: $checkoutId
|
|
2025
|
+
paymentMethodId: $paymentMethodId
|
|
2026
|
+
) {
|
|
2027
|
+
checkout {
|
|
2028
|
+
...Checkout
|
|
2029
|
+
}
|
|
2030
|
+
userErrors {
|
|
2031
|
+
...UserError
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
```
|
|
2036
|
+
|
|
2037
|
+
### Mutation: `CheckoutComplete`
|
|
2038
|
+
|
|
2039
|
+
**Section**: Checkout Mutations
|
|
2040
|
+
|
|
2041
|
+
**Description**: Finalizes the checkout: creates the `Order`, marks the cart `CONVERTED`, deducts gift cards, emits `ORDER_CREATED` (and `ORDER_CONFIRMED` for COD) — all in a single serializable transaction. **Idempotent on `idempotencyKey`** (NOT on `checkoutId`); auto-generated from `cartId + timestamp` if the caller omits it. The `paymentUrl` field is reserved but is NOT populated here — for hosted gateways (PayU, P24) the storefront calls a separate `paymentCreate` mutation after this returns.
|
|
2042
|
+
|
|
2043
|
+
**Variables**:
|
|
2044
|
+
- `$checkoutId`: `ID!`
|
|
2045
|
+
- `$input`: `CheckoutCompleteInput`
|
|
2046
|
+
|
|
2047
|
+
**Fragments used**: `Checkout`, `Order`, `UserError`
|
|
2048
|
+
|
|
2049
|
+
**GraphQL**:
|
|
2050
|
+
```graphql
|
|
2051
|
+
mutation CheckoutComplete($checkoutId: ID!, $input: CheckoutCompleteInput) {
|
|
2052
|
+
checkoutComplete(checkoutId: $checkoutId, input: $input) {
|
|
2053
|
+
checkout {
|
|
2054
|
+
...Checkout
|
|
2055
|
+
}
|
|
2056
|
+
order {
|
|
2057
|
+
...Order
|
|
2058
|
+
}
|
|
2059
|
+
paymentUrl
|
|
2060
|
+
userErrors {
|
|
2061
|
+
...UserError
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
```
|
|
2066
|
+
|
|
2067
|
+
### Mutation: `CheckoutGiftCardApply`
|
|
2068
|
+
|
|
2069
|
+
**Section**: Gift Card Checkout Mutations
|
|
2070
|
+
|
|
2071
|
+
**Description**: Applies a gift card to the cart, stackable with discount codes. Consumption is FIFO: each card consumes `min(remainingBalance, paymentDue)` against the current cart total in the order they were applied. The gift card balance is NOT debited yet — actual deduction happens atomically inside the `checkoutComplete` transaction. Errors: `GIFT_CARD_NOT_FOUND`, `GIFT_CARD_DEPLETED`, `GIFT_CARD_UNUSABLE`, `GIFT_CARD_ALREADY_APPLIED`.
|
|
2072
|
+
|
|
2073
|
+
**Variables**:
|
|
2074
|
+
- `$checkoutId`: `ID!`
|
|
2075
|
+
- `$giftCardCode`: `String!`
|
|
2076
|
+
|
|
2077
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
2078
|
+
|
|
2079
|
+
**GraphQL**:
|
|
2080
|
+
```graphql
|
|
2081
|
+
mutation CheckoutGiftCardApply($checkoutId: ID!, $giftCardCode: String!) {
|
|
2082
|
+
checkoutGiftCardApply(checkoutId: $checkoutId, giftCardCode: $giftCardCode) {
|
|
2083
|
+
checkout {
|
|
2084
|
+
...Checkout
|
|
2085
|
+
}
|
|
2086
|
+
userErrors {
|
|
2087
|
+
...UserError
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
```
|
|
2092
|
+
|
|
2093
|
+
### Mutation: `CheckoutGiftCardRemove`
|
|
2094
|
+
|
|
2095
|
+
**Section**: Gift Card Checkout Mutations
|
|
2096
|
+
|
|
2097
|
+
**Description**: Removes a gift card from the applied list and recalculates FIFO `appliedAmount` for the remaining cards. Since gift card balances are only debited at `checkoutComplete`, removing before completion has no effect on the underlying gift card balance.
|
|
2098
|
+
|
|
2099
|
+
**Variables**:
|
|
2100
|
+
- `$checkoutId`: `ID!`
|
|
2101
|
+
- `$giftCardCode`: `String!`
|
|
2102
|
+
|
|
2103
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
2104
|
+
|
|
2105
|
+
**GraphQL**:
|
|
2106
|
+
```graphql
|
|
2107
|
+
mutation CheckoutGiftCardRemove($checkoutId: ID!, $giftCardCode: String!) {
|
|
2108
|
+
checkoutGiftCardRemove(checkoutId: $checkoutId, giftCardCode: $giftCardCode) {
|
|
2109
|
+
checkout {
|
|
2110
|
+
...Checkout
|
|
2111
|
+
}
|
|
2112
|
+
userErrors {
|
|
2113
|
+
...UserError
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
```
|
|
2118
|
+
|
|
2119
|
+
### Mutation: `CheckoutGiftCardRecipientUpdate`
|
|
2120
|
+
|
|
2121
|
+
**Section**: Gift Card Checkout Mutations
|
|
2122
|
+
|
|
2123
|
+
**Description**: Sets per-line-item recipient details (name, email, message, delivery date) for digital gift card products in the cart (variants with `type: GIFT_CARD`). Required before `checkoutComplete` for any line item with a gift-card variant. Recipient details are associated with each gift-card line item and propagated to the resulting order.
|
|
2124
|
+
|
|
2125
|
+
**Variables**:
|
|
2126
|
+
- `$input`: `CheckoutGiftCardRecipientInput!`
|
|
2127
|
+
|
|
2128
|
+
**Fragments used**: `Checkout`, `UserError`
|
|
2129
|
+
|
|
2130
|
+
**GraphQL**:
|
|
2131
|
+
```graphql
|
|
2132
|
+
mutation CheckoutGiftCardRecipientUpdate($input: CheckoutGiftCardRecipientInput!) {
|
|
2133
|
+
checkoutGiftCardRecipientUpdate(input: $input) {
|
|
2134
|
+
checkout {
|
|
2135
|
+
...Checkout
|
|
2136
|
+
}
|
|
2137
|
+
userErrors {
|
|
2138
|
+
...UserError
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
```
|
|
2143
|
+
|
|
2144
|
+
### Mutation: `ReturnCreate`
|
|
2145
|
+
|
|
2146
|
+
**Section**: Return Mutations
|
|
2147
|
+
|
|
2148
|
+
**Description**: Creates an RMA in `REQUESTED` status (awaits merchant approval — NOT auto-approved). Input: `orderId`, `reason`, `items[{ variantId, quantity, reason, condition }]`, optional `compensationType` (REFUND or STORE_CREDIT) and `customerNote`. Validates the order's `fulfillmentStatus` permits returns and that requested quantities don't exceed already-shipped/unreturned quantities. Supports optional `idempotencyKey` for retry-safe creation.
|
|
2149
|
+
|
|
2150
|
+
**Variables**:
|
|
2151
|
+
- `$input`: `ReturnCreateInput!`
|
|
2152
|
+
|
|
2153
|
+
**Fragments used**: `Return`, `UserError`
|
|
2154
|
+
|
|
2155
|
+
**GraphQL**:
|
|
2156
|
+
```graphql
|
|
2157
|
+
mutation ReturnCreate($input: ReturnCreateInput!) {
|
|
2158
|
+
returnCreate(input: $input) {
|
|
2159
|
+
return {
|
|
2160
|
+
...Return
|
|
2161
|
+
}
|
|
2162
|
+
userErrors {
|
|
2163
|
+
...UserError
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
```
|
|
2168
|
+
|
|
2169
|
+
### Mutation: `ReturnCancel`
|
|
2170
|
+
|
|
2171
|
+
**Section**: Return Mutations
|
|
2172
|
+
|
|
2173
|
+
**Description**: Cancels a return that is currently in `REQUESTED`, `APPROVED`, or `DRAFT` status (cancellation is allowed even AFTER merchant approval, as long as the return shipment hasn't been processed). Sets `cancelled_at` timestamp. Customer can only cancel returns they own.
|
|
2174
|
+
|
|
2175
|
+
**Variables**:
|
|
2176
|
+
- `$id`: `ID!`
|
|
2177
|
+
|
|
2178
|
+
**Fragments used**: `Return`, `UserError`
|
|
2179
|
+
|
|
2180
|
+
**GraphQL**:
|
|
2181
|
+
```graphql
|
|
2182
|
+
mutation ReturnCancel($id: ID!) {
|
|
2183
|
+
returnCancel(id: $id) {
|
|
2184
|
+
return {
|
|
2185
|
+
...Return
|
|
2186
|
+
}
|
|
2187
|
+
userErrors {
|
|
2188
|
+
...UserError
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
```
|
|
2193
|
+
|
|
2194
|
+
### Mutation: `RedeemLoyaltyReward`
|
|
2195
|
+
|
|
2196
|
+
**Section**: Loyalty Program Mutations
|
|
2197
|
+
|
|
2198
|
+
**Description**: Redeems a loyalty reward by `rewardId`. Three reward types are supported, distinguished by which output field is populated: `discountCode` (issues a `LOYALTY-XXXX` code with 30-day expiry), `productDiscountCode` (issues a single-use 100%-off code for a specific product), or `giftCardCode` (creates a new gift card for the customer). Points are deducted atomically inside a transaction — if external creation (e.g. gift card service) fails after deduction, points are reversed.
|
|
2199
|
+
|
|
2200
|
+
**Variables**:
|
|
2201
|
+
- `$input`: `RedeemRewardInput!`
|
|
2202
|
+
|
|
2203
|
+
**Fragments used**: `RedeemRewardPayload`
|
|
2204
|
+
|
|
2205
|
+
**GraphQL**:
|
|
2206
|
+
```graphql
|
|
2207
|
+
mutation RedeemLoyaltyReward($input: RedeemRewardInput!) {
|
|
2208
|
+
redeemLoyaltyReward(input: $input) {
|
|
2209
|
+
...RedeemRewardPayload
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
```
|
|
2213
|
+
|
|
2214
|
+
### Mutation: `GenerateReferralCode`
|
|
2215
|
+
|
|
2216
|
+
**Section**: Loyalty Program Mutations
|
|
2217
|
+
|
|
2218
|
+
**Description**: Returns the customer's referral code, generating one on first call. Idempotent UPSERT — subsequent calls return the existing code from `customers.referral_code`. Format: `REF-XXXXXXXX` (8 random alphanumeric chars). Output also includes a `shareUrl` built from the shop's domain.
|
|
2219
|
+
|
|
2220
|
+
**Variables**: none
|
|
2221
|
+
|
|
2222
|
+
**Fragments used**: `GenerateReferralCodePayload`
|
|
2223
|
+
|
|
2224
|
+
**GraphQL**:
|
|
2225
|
+
```graphql
|
|
2226
|
+
mutation GenerateReferralCode {
|
|
2227
|
+
generateReferralCode {
|
|
2228
|
+
...GenerateReferralCodePayload
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
```
|
|
2232
|
+
|
|
2233
|
+
### Mutation: `ReviewCreate`
|
|
2234
|
+
|
|
2235
|
+
**Section**: Review Mutations
|
|
2236
|
+
|
|
2237
|
+
**Description**: Submits a product review (rating 1-5, content 10-5000 chars, sanitized via `sanitizePlainText`). Default state is `PENDING` — review is hidden from public until merchant approves. If the input includes `orderId`, `isVerifiedPurchase` is auto-set to `true`. Bot-protected and rate-limited (10/min by default).
|
|
2238
|
+
|
|
2239
|
+
**Variables**:
|
|
2240
|
+
- `$input`: `ReviewCreateInput!`
|
|
2241
|
+
|
|
2242
|
+
**Fragments used**: `ProductReview`, `UserError`
|
|
2243
|
+
|
|
2244
|
+
**GraphQL**:
|
|
2245
|
+
```graphql
|
|
2246
|
+
mutation ReviewCreate($input: ReviewCreateInput!) {
|
|
2247
|
+
reviewCreate(input: $input) {
|
|
2248
|
+
review {
|
|
2249
|
+
...ProductReview
|
|
2250
|
+
}
|
|
2251
|
+
userErrors {
|
|
2252
|
+
...UserError
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
```
|
|
2257
|
+
|
|
2258
|
+
### Mutation: `ReviewUpvote`
|
|
2259
|
+
|
|
2260
|
+
**Section**: Review Mutations
|
|
2261
|
+
|
|
2262
|
+
**Description**: Records an upvote (helpful) on a review. UPSERT semantics — one `ReviewVote` row per `(reviewId, customerId)`. Calling upvote twice is a no-op; calling downvote afterwards replaces the vote. Increments `helpful_count` on the review (and decrements `unhelpful_count` if replacing a downvote).
|
|
2263
|
+
|
|
2264
|
+
**Variables**:
|
|
2265
|
+
- `$reviewId`: `ID!`
|
|
2266
|
+
|
|
2267
|
+
**Fragments used**: `ProductReview`, `UserError`
|
|
2268
|
+
|
|
2269
|
+
**GraphQL**:
|
|
2270
|
+
```graphql
|
|
2271
|
+
mutation ReviewUpvote($reviewId: ID!) {
|
|
2272
|
+
reviewUpvote(reviewId: $reviewId) {
|
|
2273
|
+
review {
|
|
2274
|
+
...ProductReview
|
|
2275
|
+
}
|
|
2276
|
+
userErrors {
|
|
2277
|
+
...UserError
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
```
|
|
2282
|
+
|
|
2283
|
+
### Mutation: `ReviewDownvote`
|
|
2284
|
+
|
|
2285
|
+
**Section**: Review Mutations
|
|
2286
|
+
|
|
2287
|
+
**Description**: Records a downvote (unhelpful) on a review. Same UPSERT semantics as `reviewUpvote` — one vote row per `(reviewId, customerId)`, replacing any prior vote. Increments `unhelpful_count`.
|
|
2288
|
+
|
|
2289
|
+
**Variables**:
|
|
2290
|
+
- `$reviewId`: `ID!`
|
|
2291
|
+
|
|
2292
|
+
**Fragments used**: `ProductReview`, `UserError`
|
|
2293
|
+
|
|
2294
|
+
**GraphQL**:
|
|
2295
|
+
```graphql
|
|
2296
|
+
mutation ReviewDownvote($reviewId: ID!) {
|
|
2297
|
+
reviewDownvote(reviewId: $reviewId) {
|
|
2298
|
+
review {
|
|
2299
|
+
...ProductReview
|
|
2300
|
+
}
|
|
2301
|
+
userErrors {
|
|
2302
|
+
...UserError
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
```
|
|
2307
|
+
|
|
2308
|
+
### Mutation: `WishlistCreate`
|
|
2309
|
+
|
|
2310
|
+
**Section**: Wishlist Mutations
|
|
2311
|
+
|
|
2312
|
+
**Description**: Creates a new wishlist for the logged-in customer. `name` is optional (defaults to "My Wishlist"); name uniqueness is NOT enforced — customers can have multiple lists with the same name. Setting `isPublic: true` generates a 16-byte hex `shareToken` for public sharing.
|
|
2313
|
+
|
|
2314
|
+
**Variables**:
|
|
2315
|
+
- `$input`: `WishlistCreateInput!`
|
|
2316
|
+
|
|
2317
|
+
**Fragments used**: `Wishlist`
|
|
2318
|
+
|
|
2319
|
+
**GraphQL**:
|
|
2320
|
+
```graphql
|
|
2321
|
+
mutation WishlistCreate($input: WishlistCreateInput!) {
|
|
2322
|
+
wishlistCreate(input: $input) {
|
|
2323
|
+
wishlist {
|
|
2324
|
+
...Wishlist
|
|
2325
|
+
}
|
|
2326
|
+
userErrors
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
```
|
|
2330
|
+
|
|
2331
|
+
### Mutation: `WishlistAddItem`
|
|
2332
|
+
|
|
2333
|
+
**Section**: Wishlist Mutations
|
|
2334
|
+
|
|
2335
|
+
**Description**: Adds an item by `productId` (and optional `variantId`) to a wishlist. Idempotent on the `(wishlist_id, product_id, variant_id)` unique constraint — adding an already-present item is a silent no-op (`ON CONFLICT DO NOTHING`). Captures `priceAtAdd` for price-drop notifications.
|
|
2336
|
+
|
|
2337
|
+
**Variables**:
|
|
2338
|
+
- `$wishlistId`: `ID!`
|
|
2339
|
+
- `$input`: `WishlistItemInput!`
|
|
2340
|
+
|
|
2341
|
+
**Fragments used**: `Wishlist`
|
|
2342
|
+
|
|
2343
|
+
**GraphQL**:
|
|
2344
|
+
```graphql
|
|
2345
|
+
mutation WishlistAddItem($wishlistId: ID!, $input: WishlistItemInput!) {
|
|
2346
|
+
wishlistAddItem(wishlistId: $wishlistId, input: $input) {
|
|
2347
|
+
wishlist {
|
|
2348
|
+
...Wishlist
|
|
2349
|
+
}
|
|
2350
|
+
userErrors
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
```
|
|
2354
|
+
|
|
2355
|
+
### Mutation: `WishlistRemoveItem`
|
|
2356
|
+
|
|
2357
|
+
**Section**: Wishlist Mutations
|
|
2358
|
+
|
|
2359
|
+
**Description**: Hard-deletes a wishlist item by `itemId` (the `WishlistItem` row id, NOT the product id).
|
|
2360
|
+
|
|
2361
|
+
**Variables**:
|
|
2362
|
+
- `$wishlistId`: `ID!`
|
|
2363
|
+
- `$itemId`: `ID!`
|
|
2364
|
+
|
|
2365
|
+
**Fragments used**: `Wishlist`
|
|
2366
|
+
|
|
2367
|
+
**GraphQL**:
|
|
2368
|
+
```graphql
|
|
2369
|
+
mutation WishlistRemoveItem($wishlistId: ID!, $itemId: ID!) {
|
|
2370
|
+
wishlistRemoveItem(wishlistId: $wishlistId, itemId: $itemId) {
|
|
2371
|
+
wishlist {
|
|
2372
|
+
...Wishlist
|
|
2373
|
+
}
|
|
2374
|
+
userErrors
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
```
|
|
2378
|
+
|
|
2379
|
+
### Mutation: `WishlistDelete`
|
|
2380
|
+
|
|
2381
|
+
**Section**: Wishlist Mutations
|
|
2382
|
+
|
|
2383
|
+
**Description**: Hard-deletes the wishlist row. All `WishlistItem` rows are removed via FK cascade. No soft-delete; cannot be undone.
|
|
2384
|
+
|
|
2385
|
+
**Variables**:
|
|
2386
|
+
- `$wishlistId`: `ID!`
|
|
2387
|
+
|
|
2388
|
+
**Fragments used**: `Wishlist`
|
|
2389
|
+
|
|
2390
|
+
**GraphQL**:
|
|
2391
|
+
```graphql
|
|
2392
|
+
mutation WishlistDelete($wishlistId: ID!) {
|
|
2393
|
+
wishlistDelete(wishlistId: $wishlistId) {
|
|
2394
|
+
wishlist {
|
|
2395
|
+
...Wishlist
|
|
2396
|
+
}
|
|
2397
|
+
userErrors
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
```
|
|
2401
|
+
|
|
2402
|
+
### Mutation: `CartUpdateAttributes`
|
|
2403
|
+
|
|
2404
|
+
**Section**: Cart Attributes
|
|
2405
|
+
|
|
2406
|
+
**Description**: Replaces (NOT merges) the cart's custom attributes — free-form `[{ key, value }]` pairs visible to merchant in admin. Use for delivery instructions, gift wrap flags, B2B PO numbers, etc. Limit: 250 pairs per cart (returns `CART_ATTRIBUTES_LIMIT_EXCEEDED`); each `key` max 255 chars.
|
|
2407
|
+
|
|
2408
|
+
**Variables**:
|
|
2409
|
+
- `$id`: `ID!`
|
|
2410
|
+
- `$attributes`: `[CartAttributeInput!]!`
|
|
2411
|
+
|
|
2412
|
+
**Fragments used**: `Cart`, `CartWarning`, `UserError`
|
|
2413
|
+
|
|
2414
|
+
**GraphQL**:
|
|
2415
|
+
```graphql
|
|
2416
|
+
mutation CartUpdateAttributes($id: ID!, $attributes: [CartAttributeInput!]!) {
|
|
2417
|
+
cartUpdateAttributes(id: $id, attributes: $attributes) {
|
|
2418
|
+
cart {
|
|
2419
|
+
...Cart
|
|
2420
|
+
}
|
|
2421
|
+
userErrors {
|
|
2422
|
+
...UserError
|
|
2423
|
+
}
|
|
2424
|
+
warnings {
|
|
2425
|
+
...CartWarning
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
```
|
|
2430
|
+
|
|
2431
|
+
---
|
|
2432
|
+
|
|
2433
|
+
## Fragments
|
|
2434
|
+
|
|
2435
|
+
Fragments are referenced by name in operations above. Each fragment is defined once below.
|
|
2436
|
+
|
|
2437
|
+
### Fragment: `PageInfo` on `PageInfo`
|
|
2438
|
+
|
|
2439
|
+
**Section**: Common
|
|
2440
|
+
|
|
2441
|
+
**Description**: Standard Relay Connection page metadata. Spread on every paginated query's `pageInfo`.
|
|
2442
|
+
|
|
2443
|
+
**GraphQL**:
|
|
2444
|
+
```graphql
|
|
2445
|
+
fragment PageInfo on PageInfo {
|
|
2446
|
+
hasNextPage
|
|
2447
|
+
hasPreviousPage
|
|
2448
|
+
startCursor
|
|
2449
|
+
endCursor
|
|
2450
|
+
}
|
|
2451
|
+
```
|
|
2452
|
+
|
|
2453
|
+
### Fragment: `UserError` on `UserError`
|
|
2454
|
+
|
|
2455
|
+
**Section**: Common
|
|
2456
|
+
|
|
2457
|
+
**Description**: Generic mutation error envelope — included in every mutation's `userErrors[]` field. Always check before consuming the happy-path payload.
|
|
2458
|
+
|
|
2459
|
+
**GraphQL**:
|
|
2460
|
+
```graphql
|
|
2461
|
+
fragment UserError on UserError {
|
|
2462
|
+
message
|
|
2463
|
+
code
|
|
2464
|
+
field
|
|
2465
|
+
}
|
|
2466
|
+
```
|
|
2467
|
+
|
|
2468
|
+
### Fragment: `CartWarning` on `CartWarning`
|
|
2469
|
+
|
|
2470
|
+
**Section**: Common
|
|
2471
|
+
|
|
2472
|
+
**Description**: Non-blocking cart warning (e.g. low stock, partial availability). Cart mutations succeed but surface these for UI hints.
|
|
2473
|
+
|
|
2474
|
+
**GraphQL**:
|
|
2475
|
+
```graphql
|
|
2476
|
+
fragment CartWarning on CartWarning {
|
|
2477
|
+
message
|
|
2478
|
+
code
|
|
2479
|
+
target
|
|
2480
|
+
}
|
|
2481
|
+
```
|
|
2482
|
+
|
|
2483
|
+
### Fragment: `Image` on `Image`
|
|
2484
|
+
|
|
2485
|
+
**Section**: Common
|
|
2486
|
+
|
|
2487
|
+
**Description**: Base image — original size, no transform. Use for logos, favicons, branding assets that are already sized correctly. ~few KB.
|
|
2488
|
+
|
|
2489
|
+
**GraphQL**:
|
|
2490
|
+
```graphql
|
|
2491
|
+
fragment Image on Image {
|
|
2492
|
+
id
|
|
2493
|
+
url
|
|
2494
|
+
altText
|
|
2495
|
+
width
|
|
2496
|
+
height
|
|
2497
|
+
}
|
|
2498
|
+
```
|
|
2499
|
+
|
|
2500
|
+
### Fragment: `ImageThumbnail` on `Image`
|
|
2501
|
+
|
|
2502
|
+
**Section**: Common
|
|
2503
|
+
|
|
2504
|
+
**Description**: Thumbnail — cart line items, variant swatches, author avatars (rendered ~96px on screen, transform delivers up to 300px for 3x DPI). Includes `thumbhash` for blurred placeholder. Format auto-negotiated from the `Accept` header.
|
|
2505
|
+
|
|
2506
|
+
**GraphQL**:
|
|
2507
|
+
```graphql
|
|
2508
|
+
fragment ImageThumbnail on Image {
|
|
2509
|
+
id
|
|
2510
|
+
url(transform: {maxWidth: 300})
|
|
2511
|
+
altText
|
|
2512
|
+
width
|
|
2513
|
+
height
|
|
2514
|
+
thumbhash
|
|
2515
|
+
}
|
|
2516
|
+
```
|
|
2517
|
+
|
|
2518
|
+
### Fragment: `ImageCard` on `Image`
|
|
2519
|
+
|
|
2520
|
+
**Section**: Common
|
|
2521
|
+
|
|
2522
|
+
**Description**: Card — product cards, collection / category tiles, blog post previews (rendered ~400px, transform delivers up to 800px for 2x DPI). Includes `thumbhash` placeholder.
|
|
2523
|
+
|
|
2524
|
+
**GraphQL**:
|
|
2525
|
+
```graphql
|
|
2526
|
+
fragment ImageCard on Image {
|
|
2527
|
+
id
|
|
2528
|
+
url(transform: {maxWidth: 800})
|
|
2529
|
+
altText
|
|
2530
|
+
width
|
|
2531
|
+
height
|
|
2532
|
+
thumbhash
|
|
2533
|
+
}
|
|
2534
|
+
```
|
|
2535
|
+
|
|
2536
|
+
### Fragment: `ImageFull` on `Image`
|
|
2537
|
+
|
|
2538
|
+
**Section**: Common
|
|
2539
|
+
|
|
2540
|
+
**Description**: Full — product detail gallery, hero banners (rendered ~800px, transform delivers up to 1600px for 2x DPI). Includes `thumbhash` placeholder.
|
|
2541
|
+
|
|
2542
|
+
**GraphQL**:
|
|
2543
|
+
```graphql
|
|
2544
|
+
fragment ImageFull on Image {
|
|
2545
|
+
id
|
|
2546
|
+
url(transform: {maxWidth: 1600})
|
|
2547
|
+
altText
|
|
2548
|
+
width
|
|
2549
|
+
height
|
|
2550
|
+
thumbhash
|
|
2551
|
+
}
|
|
2552
|
+
```
|
|
2553
|
+
|
|
2554
|
+
### Fragment: `Money` on `Money`
|
|
2555
|
+
|
|
2556
|
+
**Section**: Common
|
|
2557
|
+
|
|
2558
|
+
**Description**: Plain `{ amount, currencyCode }` price. Use for `compareAtPrice`, totals, and any field where currency conversion transparency is not needed. `amount` is a String.
|
|
2559
|
+
|
|
2560
|
+
**GraphQL**:
|
|
2561
|
+
```graphql
|
|
2562
|
+
fragment Money on Money {
|
|
2563
|
+
amount
|
|
2564
|
+
currencyCode
|
|
2565
|
+
}
|
|
2566
|
+
```
|
|
2567
|
+
|
|
2568
|
+
### Fragment: `Price` on `PriceMoney`
|
|
2569
|
+
|
|
2570
|
+
**Section**: Common
|
|
2571
|
+
|
|
2572
|
+
**Description**: Lightweight price for listing views (cards, grids, search results) — same shape as `Money`. Spread when full conversion metadata is overkill.
|
|
2573
|
+
|
|
2574
|
+
**GraphQL**:
|
|
2575
|
+
```graphql
|
|
2576
|
+
fragment Price on PriceMoney {
|
|
2577
|
+
amount
|
|
2578
|
+
currencyCode
|
|
2579
|
+
}
|
|
2580
|
+
```
|
|
2581
|
+
|
|
2582
|
+
### Fragment: `PriceMoney` on `PriceMoney`
|
|
2583
|
+
|
|
2584
|
+
**Section**: Common
|
|
2585
|
+
|
|
2586
|
+
**Description**: Full price with currency-conversion transparency — adds `baseAmount`, `baseCurrencyCode`, `exchangeRate`, `marginApplied`, `rateTimestamp`, `isConverted`. Spread on PDP / cart / checkout where the customer needs to see the original price + applied conversion.
|
|
2587
|
+
|
|
2588
|
+
**Uses fragments**: `Price`
|
|
2589
|
+
|
|
2590
|
+
**GraphQL**:
|
|
2591
|
+
```graphql
|
|
2592
|
+
fragment PriceMoney on PriceMoney {
|
|
2593
|
+
...Price
|
|
2594
|
+
baseAmount
|
|
2595
|
+
baseCurrencyCode
|
|
2596
|
+
exchangeRate
|
|
2597
|
+
marginApplied
|
|
2598
|
+
rateTimestamp
|
|
2599
|
+
isConverted
|
|
2600
|
+
}
|
|
2601
|
+
```
|
|
2602
|
+
|
|
2603
|
+
### Fragment: `SelectedOption` on `SelectedOption`
|
|
2604
|
+
|
|
2605
|
+
**Section**: Common
|
|
2606
|
+
|
|
2607
|
+
**Description**: Selected variant option (e.g. `{ name: "Color", value: "Red" }`) on a `ProductVariant`. Use to render variant labels in cart / order summaries.
|
|
2608
|
+
|
|
2609
|
+
**GraphQL**:
|
|
2610
|
+
```graphql
|
|
2611
|
+
fragment SelectedOption on SelectedOption {
|
|
2612
|
+
name
|
|
2613
|
+
value
|
|
2614
|
+
}
|
|
2615
|
+
```
|
|
2616
|
+
|
|
2617
|
+
### Fragment: `ProductVariant` on `ProductVariant`
|
|
2618
|
+
|
|
2619
|
+
**Section**: Products
|
|
2620
|
+
|
|
2621
|
+
**Description**: Single variant of a product — price, compare-at, stock flags, sort, image, selected options. Spread on cart line items, PDP variant selectors, search result rows that need price.
|
|
2622
|
+
|
|
2623
|
+
**Uses fragments**: `ImageThumbnail`, `Money`, `SelectedOption`
|
|
2624
|
+
|
|
2625
|
+
**GraphQL**:
|
|
2626
|
+
```graphql
|
|
2627
|
+
fragment ProductVariant on ProductVariant {
|
|
2628
|
+
id
|
|
2629
|
+
title
|
|
2630
|
+
sku
|
|
2631
|
+
price {
|
|
2632
|
+
...Money
|
|
2633
|
+
}
|
|
2634
|
+
compareAtPrice {
|
|
2635
|
+
...Money
|
|
2636
|
+
}
|
|
2637
|
+
isAvailable
|
|
2638
|
+
availableStock
|
|
2639
|
+
image {
|
|
2640
|
+
...ImageThumbnail
|
|
2641
|
+
}
|
|
2642
|
+
selectedOptions {
|
|
2643
|
+
...SelectedOption
|
|
2644
|
+
}
|
|
2645
|
+
barcode
|
|
2646
|
+
weight {
|
|
2647
|
+
value
|
|
2648
|
+
unit
|
|
2649
|
+
}
|
|
2650
|
+
sortOrder
|
|
2651
|
+
}
|
|
2652
|
+
```
|
|
2653
|
+
|
|
2654
|
+
### Fragment: `ProductCard` on `Product`
|
|
2655
|
+
|
|
2656
|
+
**Section**: Products
|
|
2657
|
+
|
|
2658
|
+
**Description**: Minimal product shape for listing views (collection grids, search results, "you may also like"). Includes price range, featured image (card size), rating + review count, vendor, tags. Use for any list of products where you don't need variants/description.
|
|
2659
|
+
|
|
2660
|
+
**Uses fragments**: `ImageCard`, `Money`
|
|
2661
|
+
|
|
2662
|
+
**GraphQL**:
|
|
2663
|
+
```graphql
|
|
2664
|
+
fragment ProductCard on Product {
|
|
2665
|
+
id
|
|
2666
|
+
handle
|
|
2667
|
+
title
|
|
2668
|
+
vendor
|
|
2669
|
+
category
|
|
2670
|
+
isAvailable
|
|
2671
|
+
averageRating
|
|
2672
|
+
reviewCount
|
|
2673
|
+
tags
|
|
2674
|
+
featuredImage {
|
|
2675
|
+
...ImageCard
|
|
2676
|
+
}
|
|
2677
|
+
priceRange {
|
|
2678
|
+
minVariantPrice {
|
|
2679
|
+
...Money
|
|
2680
|
+
}
|
|
2681
|
+
maxVariantPrice {
|
|
2682
|
+
...Money
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
compareAtPriceRange {
|
|
2686
|
+
minVariantPrice {
|
|
2687
|
+
...Money
|
|
2688
|
+
}
|
|
2689
|
+
maxVariantPrice {
|
|
2690
|
+
...Money
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
```
|
|
2695
|
+
|
|
2696
|
+
### Fragment: `ProductBase` on `Product`
|
|
2697
|
+
|
|
2698
|
+
**Section**: Products
|
|
2699
|
+
|
|
2700
|
+
**Description**: `ProductCard` plus textual content (description, descriptionHtml), stock total, type, visibility flags, and timestamps. Use when you need full product copy but not the heavy variants/images lists. Sweet spot for blog post embeds, related-product cards with description.
|
|
2701
|
+
|
|
2702
|
+
**Uses fragments**: `ProductCard`
|
|
2703
|
+
|
|
2704
|
+
**GraphQL**:
|
|
2705
|
+
```graphql
|
|
2706
|
+
fragment ProductBase on Product {
|
|
2707
|
+
...ProductCard
|
|
2708
|
+
description
|
|
2709
|
+
descriptionHtml
|
|
2710
|
+
stockTotal
|
|
2711
|
+
type
|
|
2712
|
+
requiresRecipientInfo
|
|
2713
|
+
visibility
|
|
2714
|
+
attributeSetId
|
|
2715
|
+
createdAt
|
|
2716
|
+
updatedAt
|
|
2717
|
+
}
|
|
2718
|
+
```
|
|
2719
|
+
|
|
2720
|
+
### Fragment: `ProductFull` on `Product`
|
|
2721
|
+
|
|
2722
|
+
**Section**: Products
|
|
2723
|
+
|
|
2724
|
+
**Description**: Full product shape for the PDP — `ProductBase` plus the full image gallery (up to 20, full-size) and all variants (up to 100) with their pricing/stock. Spread on the product detail page.
|
|
2725
|
+
|
|
2726
|
+
**Uses fragments**: `ImageFull`, `PageInfo`, `ProductBase`, `ProductVariant`
|
|
2727
|
+
|
|
2728
|
+
**GraphQL**:
|
|
2729
|
+
```graphql
|
|
2730
|
+
fragment ProductFull on Product {
|
|
2731
|
+
...ProductBase
|
|
2732
|
+
images(first: 20) {
|
|
2733
|
+
edges {
|
|
2734
|
+
cursor
|
|
2735
|
+
node {
|
|
2736
|
+
...ImageFull
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
nodes {
|
|
2740
|
+
...ImageFull
|
|
2741
|
+
}
|
|
2742
|
+
pageInfo {
|
|
2743
|
+
...PageInfo
|
|
2744
|
+
}
|
|
2745
|
+
totalCount
|
|
2746
|
+
}
|
|
2747
|
+
variants(first: 100) {
|
|
2748
|
+
edges {
|
|
2749
|
+
cursor
|
|
2750
|
+
node {
|
|
2751
|
+
...ProductVariant
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
nodes {
|
|
2755
|
+
...ProductVariant
|
|
2756
|
+
}
|
|
2757
|
+
pageInfo {
|
|
2758
|
+
...PageInfo
|
|
2759
|
+
}
|
|
2760
|
+
totalCount
|
|
2761
|
+
}
|
|
2762
|
+
seo {
|
|
2763
|
+
title
|
|
2764
|
+
description
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
```
|
|
2768
|
+
|
|
2769
|
+
### Fragment: `Collection` on `Collection`
|
|
2770
|
+
|
|
2771
|
+
**Section**: Collections
|
|
2772
|
+
|
|
2773
|
+
**Description**: Collection (manual or rule-based product grouping) — title, description, hero image, SEO. Spread on collection landing pages and collection cards. Does NOT include products — query `collection(id, handle).products` separately for those.
|
|
2774
|
+
|
|
2775
|
+
**Uses fragments**: `ImageCard`
|
|
2776
|
+
|
|
2777
|
+
**GraphQL**:
|
|
2778
|
+
```graphql
|
|
2779
|
+
fragment Collection on Collection {
|
|
2780
|
+
id
|
|
2781
|
+
handle
|
|
2782
|
+
title
|
|
2783
|
+
description
|
|
2784
|
+
descriptionHtml
|
|
2785
|
+
image {
|
|
2786
|
+
...ImageCard
|
|
2787
|
+
}
|
|
2788
|
+
seo {
|
|
2789
|
+
title
|
|
2790
|
+
description
|
|
2791
|
+
}
|
|
2792
|
+
createdAt
|
|
2793
|
+
updatedAt
|
|
2794
|
+
}
|
|
2795
|
+
```
|
|
2796
|
+
|
|
2797
|
+
### Fragment: `Category` on `Category`
|
|
2798
|
+
|
|
2799
|
+
**Section**: Categories
|
|
2800
|
+
|
|
2801
|
+
**Description**: Category node in the shop's taxonomy — name, slug, hero image, depth `level`, materialized `path`, product count, sort order. Spread on category cards and breadcrumb segments. Does NOT include parent / children — query those fields separately and let the server batch them.
|
|
2802
|
+
|
|
2803
|
+
**Uses fragments**: `ImageCard`
|
|
2804
|
+
|
|
2805
|
+
**GraphQL**:
|
|
2806
|
+
```graphql
|
|
2807
|
+
fragment Category on Category {
|
|
2808
|
+
id
|
|
2809
|
+
name
|
|
2810
|
+
slug
|
|
2811
|
+
description
|
|
2812
|
+
image {
|
|
2813
|
+
...ImageCard
|
|
2814
|
+
}
|
|
2815
|
+
level
|
|
2816
|
+
path
|
|
2817
|
+
productCount
|
|
2818
|
+
sortOrder
|
|
2819
|
+
}
|
|
2820
|
+
```
|
|
2821
|
+
|
|
2822
|
+
### Fragment: `MailingAddress` on `MailingAddress`
|
|
2823
|
+
|
|
2824
|
+
**Section**: Customer
|
|
2825
|
+
|
|
2826
|
+
**Description**: Customer mailing address — full street/city/state/country/postal code with names and phone. `isDefault` flips when this address is the default for shipping. Spread on the address book UI and order summaries.
|
|
2827
|
+
|
|
2828
|
+
**GraphQL**:
|
|
2829
|
+
```graphql
|
|
2830
|
+
fragment MailingAddress on MailingAddress {
|
|
2831
|
+
id
|
|
2832
|
+
streetLine1
|
|
2833
|
+
streetLine2
|
|
2834
|
+
city
|
|
2835
|
+
company
|
|
2836
|
+
country
|
|
2837
|
+
countryCode
|
|
2838
|
+
firstName
|
|
2839
|
+
lastName
|
|
2840
|
+
phone
|
|
2841
|
+
state
|
|
2842
|
+
stateCode
|
|
2843
|
+
postalCode
|
|
2844
|
+
isDefault
|
|
2845
|
+
}
|
|
2846
|
+
```
|
|
2847
|
+
|
|
2848
|
+
### Fragment: `CustomerAccessToken` on `CustomerAccessToken`
|
|
2849
|
+
|
|
2850
|
+
**Section**: Customer
|
|
2851
|
+
|
|
2852
|
+
**Description**: Customer access token returned by `customerLogin` / `customerSignup` / `customerActivate` / `customerResetPassword` / `customerRefreshToken`. The token's JWT TTL is 24h; cookie max-age is 30d.
|
|
2853
|
+
|
|
2854
|
+
**GraphQL**:
|
|
2855
|
+
```graphql
|
|
2856
|
+
fragment CustomerAccessToken on CustomerAccessToken {
|
|
2857
|
+
accessToken
|
|
2858
|
+
expiresAt
|
|
2859
|
+
}
|
|
2860
|
+
```
|
|
2861
|
+
|
|
2862
|
+
### Fragment: `Customer` on `Customer`
|
|
2863
|
+
|
|
2864
|
+
**Section**: Customer
|
|
2865
|
+
|
|
2866
|
+
**Description**: Customer profile — basic info plus B2B fields (`taxId`, `vatNumber`, `regon`, `companyName`), default address, lifetime stats (`orderCount`, `totalSpent`), marketing preferences. Use on profile / settings pages.
|
|
2867
|
+
|
|
2868
|
+
**Uses fragments**: `MailingAddress`, `Money`
|
|
2869
|
+
|
|
2870
|
+
**GraphQL**:
|
|
2871
|
+
```graphql
|
|
2872
|
+
fragment Customer on Customer {
|
|
2873
|
+
id
|
|
2874
|
+
email
|
|
2875
|
+
firstName
|
|
2876
|
+
lastName
|
|
2877
|
+
displayName
|
|
2878
|
+
phone
|
|
2879
|
+
isEmailVerified
|
|
2880
|
+
emailMarketing
|
|
2881
|
+
tags
|
|
2882
|
+
customerType
|
|
2883
|
+
companyName
|
|
2884
|
+
taxId
|
|
2885
|
+
vatNumber
|
|
2886
|
+
regon
|
|
2887
|
+
defaultAddress {
|
|
2888
|
+
...MailingAddress
|
|
2889
|
+
}
|
|
2890
|
+
orderCount
|
|
2891
|
+
totalSpent {
|
|
2892
|
+
...Money
|
|
2893
|
+
}
|
|
2894
|
+
createdAt
|
|
2895
|
+
updatedAt
|
|
2896
|
+
}
|
|
2897
|
+
```
|
|
2898
|
+
|
|
2899
|
+
### Fragment: `Order` on `Order`
|
|
2900
|
+
|
|
2901
|
+
**Section**: Customer
|
|
2902
|
+
|
|
2903
|
+
**Description**: Order summary — number, totals (cost / tax / shipping), payment + fulfillment status, shipping address, item count, lifecycle timestamps. Spread on the order list and order detail pages. Line items are not included here.
|
|
2904
|
+
|
|
2905
|
+
**Uses fragments**: `MailingAddress`, `Money`
|
|
2906
|
+
|
|
2907
|
+
**GraphQL**:
|
|
2908
|
+
```graphql
|
|
2909
|
+
fragment Order on Order {
|
|
2910
|
+
id
|
|
2911
|
+
orderNumber
|
|
2912
|
+
totals {
|
|
2913
|
+
total {
|
|
2914
|
+
...Money
|
|
2915
|
+
}
|
|
2916
|
+
subtotal {
|
|
2917
|
+
...Money
|
|
2918
|
+
}
|
|
2919
|
+
totalTax {
|
|
2920
|
+
...Money
|
|
2921
|
+
}
|
|
2922
|
+
totalShipping {
|
|
2923
|
+
...Money
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
status
|
|
2927
|
+
paymentStatus
|
|
2928
|
+
fulfillmentStatus
|
|
2929
|
+
processedAt
|
|
2930
|
+
confirmedAt
|
|
2931
|
+
cancelledAt
|
|
2932
|
+
expiredAt
|
|
2933
|
+
shippingAddress {
|
|
2934
|
+
...MailingAddress
|
|
2935
|
+
}
|
|
2936
|
+
itemCount
|
|
2937
|
+
}
|
|
2938
|
+
```
|
|
2939
|
+
|
|
2940
|
+
### Fragment: `CartCost` on `CartCost`
|
|
2941
|
+
|
|
2942
|
+
**Section**: Cart
|
|
2943
|
+
|
|
2944
|
+
**Description**: Cart-level totals — subtotal, total, tax, duty, checkout charge. Spread inside the `Cart` fragment.
|
|
2945
|
+
|
|
2946
|
+
**Uses fragments**: `Money`
|
|
2947
|
+
|
|
2948
|
+
**GraphQL**:
|
|
2949
|
+
```graphql
|
|
2950
|
+
fragment CartCost on CartCost {
|
|
2951
|
+
total {
|
|
2952
|
+
...Money
|
|
2953
|
+
}
|
|
2954
|
+
subtotal {
|
|
2955
|
+
...Money
|
|
2956
|
+
}
|
|
2957
|
+
totalTax {
|
|
2958
|
+
...Money
|
|
2959
|
+
}
|
|
2960
|
+
totalDuty {
|
|
2961
|
+
...Money
|
|
2962
|
+
}
|
|
2963
|
+
checkoutCharge {
|
|
2964
|
+
...Money
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
```
|
|
2968
|
+
|
|
2969
|
+
### Fragment: `CartLineCost` on `CartLineCost`
|
|
2970
|
+
|
|
2971
|
+
**Section**: Cart
|
|
2972
|
+
|
|
2973
|
+
**Description**: Per-line cost breakdown — unit price, line subtotal/total, compare-at unit price (for showing strikethroughs). Spread inside `CartLine`.
|
|
2974
|
+
|
|
2975
|
+
**Uses fragments**: `Money`
|
|
2976
|
+
|
|
2977
|
+
**GraphQL**:
|
|
2978
|
+
```graphql
|
|
2979
|
+
fragment CartLineCost on CartLineCost {
|
|
2980
|
+
pricePerUnit {
|
|
2981
|
+
...Money
|
|
2982
|
+
}
|
|
2983
|
+
subtotal {
|
|
2984
|
+
...Money
|
|
2985
|
+
}
|
|
2986
|
+
total {
|
|
2987
|
+
...Money
|
|
2988
|
+
}
|
|
2989
|
+
compareAtPricePerUnit {
|
|
2990
|
+
...Money
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
```
|
|
2994
|
+
|
|
2995
|
+
### Fragment: `AttributeSelection` on `AttributeSelection`
|
|
2996
|
+
|
|
2997
|
+
**Section**: Cart
|
|
2998
|
+
|
|
2999
|
+
**Description**: Typed snapshot of a customer-filled product attribute (configurator selection) on a cart line. Includes the chosen option / text value, fillingMode, billingMode, surcharge, tax class, and any linked variant. Distinct from `CartLine.attributes` which holds raw key-value line item properties (free-form, untyped).
|
|
3000
|
+
|
|
3001
|
+
**GraphQL**:
|
|
3002
|
+
```graphql
|
|
3003
|
+
fragment AttributeSelection on AttributeSelection {
|
|
3004
|
+
attributeDefinitionId
|
|
3005
|
+
attributeName
|
|
3006
|
+
type
|
|
3007
|
+
fillingMode
|
|
3008
|
+
billingMode
|
|
3009
|
+
optionId
|
|
3010
|
+
optionLabel
|
|
3011
|
+
optionIds
|
|
3012
|
+
textValue
|
|
3013
|
+
surchargeAmount
|
|
3014
|
+
surchargeType
|
|
3015
|
+
taxClassId
|
|
3016
|
+
linkedVariantId
|
|
3017
|
+
}
|
|
3018
|
+
```
|
|
3019
|
+
|
|
3020
|
+
### Fragment: `CartLine` on `CartLine`
|
|
3021
|
+
|
|
3022
|
+
**Section**: Cart
|
|
3023
|
+
|
|
3024
|
+
**Description**: A single line in the cart — variant + quantity + per-line cost, plus dual attribute storage: `attributes[]` for free-form key-value properties (gift wrap, engraving notes), `attributeSelections[]` for typed configurator answers.
|
|
3025
|
+
|
|
3026
|
+
**Uses fragments**: `AttributeSelection`, `CartLineCost`, `ProductVariant`
|
|
3027
|
+
|
|
3028
|
+
**GraphQL**:
|
|
3029
|
+
```graphql
|
|
3030
|
+
fragment CartLine on CartLine {
|
|
3031
|
+
id
|
|
3032
|
+
quantity
|
|
3033
|
+
variant {
|
|
3034
|
+
...ProductVariant
|
|
3035
|
+
}
|
|
3036
|
+
cost {
|
|
3037
|
+
...CartLineCost
|
|
3038
|
+
}
|
|
3039
|
+
attributes {
|
|
3040
|
+
key
|
|
3041
|
+
value
|
|
3042
|
+
}
|
|
3043
|
+
attributeSelections {
|
|
3044
|
+
...AttributeSelection
|
|
3045
|
+
}
|
|
3046
|
+
productId
|
|
3047
|
+
productTitle
|
|
3048
|
+
productHandle
|
|
3049
|
+
productType
|
|
3050
|
+
}
|
|
3051
|
+
```
|
|
3052
|
+
|
|
3053
|
+
### Fragment: `CartBuyerIdentity` on `CartBuyerIdentity`
|
|
3054
|
+
|
|
3055
|
+
**Section**: Cart
|
|
3056
|
+
|
|
3057
|
+
**Description**: Buyer identity associated with the cart. Note: only `customerId` is currently persisted server-side; `email`, `phone`, `countryCode` are accepted in the input but ignored.
|
|
3058
|
+
|
|
3059
|
+
**GraphQL**:
|
|
3060
|
+
```graphql
|
|
3061
|
+
fragment CartBuyerIdentity on CartBuyerIdentity {
|
|
3062
|
+
email
|
|
3063
|
+
phone
|
|
3064
|
+
countryCode
|
|
3065
|
+
}
|
|
3066
|
+
```
|
|
3067
|
+
|
|
3068
|
+
### Fragment: `CartDiscountCode` on `CartDiscountCode`
|
|
3069
|
+
|
|
3070
|
+
**Section**: Cart
|
|
3071
|
+
|
|
3072
|
+
**Description**: Discount code applied to the cart with its `isApplicable` flag — false means the code was kept on the cart but does not currently qualify (e.g. minimum spend not reached).
|
|
3073
|
+
|
|
3074
|
+
**GraphQL**:
|
|
3075
|
+
```graphql
|
|
3076
|
+
fragment CartDiscountCode on CartDiscountCode {
|
|
3077
|
+
code
|
|
3078
|
+
isApplicable
|
|
3079
|
+
}
|
|
3080
|
+
```
|
|
3081
|
+
|
|
3082
|
+
### Fragment: `CartDiscountAllocation` on `CartDiscountAllocation`
|
|
3083
|
+
|
|
3084
|
+
**Section**: Cart
|
|
3085
|
+
|
|
3086
|
+
**Description**: Allocation of a discount code to the cart total — pairs the code with the actual money discounted. Use to show "saved X with code Y" in cart UI.
|
|
3087
|
+
|
|
3088
|
+
**Uses fragments**: `Money`
|
|
3089
|
+
|
|
3090
|
+
**GraphQL**:
|
|
3091
|
+
```graphql
|
|
3092
|
+
fragment CartDiscountAllocation on CartDiscountAllocation {
|
|
3093
|
+
discountCode
|
|
3094
|
+
amount {
|
|
3095
|
+
...Money
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
```
|
|
3099
|
+
|
|
3100
|
+
### Fragment: `Cart` on `Cart`
|
|
3101
|
+
|
|
3102
|
+
**Section**: Cart
|
|
3103
|
+
|
|
3104
|
+
**Description**: Full cart shape — totals, line items (paginated up to 100), buyer identity, applied discount codes + allocations, note, custom attributes. Spread on the cart drawer / cart page; refetch after every cart mutation.
|
|
3105
|
+
|
|
3106
|
+
**Uses fragments**: `CartBuyerIdentity`, `CartCost`, `CartDiscountAllocation`, `CartDiscountCode`, `CartLine`, `PageInfo`
|
|
3107
|
+
|
|
3108
|
+
**GraphQL**:
|
|
3109
|
+
```graphql
|
|
3110
|
+
fragment Cart on Cart {
|
|
3111
|
+
id
|
|
3112
|
+
checkoutUrl
|
|
3113
|
+
totalQuantity
|
|
3114
|
+
cost {
|
|
3115
|
+
...CartCost
|
|
3116
|
+
}
|
|
3117
|
+
lines(first: 100) {
|
|
3118
|
+
edges {
|
|
3119
|
+
cursor
|
|
3120
|
+
node {
|
|
3121
|
+
... on CartLine {
|
|
3122
|
+
...CartLine
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
nodes {
|
|
3127
|
+
... on CartLine {
|
|
3128
|
+
...CartLine
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
pageInfo {
|
|
3132
|
+
...PageInfo
|
|
3133
|
+
}
|
|
3134
|
+
totalCount
|
|
3135
|
+
}
|
|
3136
|
+
buyerIdentity {
|
|
3137
|
+
...CartBuyerIdentity
|
|
3138
|
+
}
|
|
3139
|
+
discountCodes {
|
|
3140
|
+
...CartDiscountCode
|
|
3141
|
+
}
|
|
3142
|
+
discountAllocations {
|
|
3143
|
+
...CartDiscountAllocation
|
|
3144
|
+
}
|
|
3145
|
+
note
|
|
3146
|
+
attributes {
|
|
3147
|
+
key
|
|
3148
|
+
value
|
|
3149
|
+
}
|
|
3150
|
+
createdAt
|
|
3151
|
+
updatedAt
|
|
3152
|
+
}
|
|
3153
|
+
```
|
|
3154
|
+
|
|
3155
|
+
### Fragment: `ShopColors` on `ShopColors`
|
|
3156
|
+
|
|
3157
|
+
**Section**: Shop
|
|
3158
|
+
|
|
3159
|
+
**Description**: Shop branding colors — primary, secondary, accent, background, text. Use to theme the storefront from server-side config.
|
|
3160
|
+
|
|
3161
|
+
**GraphQL**:
|
|
3162
|
+
```graphql
|
|
3163
|
+
fragment ShopColors on ShopColors {
|
|
3164
|
+
primary
|
|
3165
|
+
secondary
|
|
3166
|
+
accent
|
|
3167
|
+
background
|
|
3168
|
+
text
|
|
3169
|
+
}
|
|
3170
|
+
```
|
|
3171
|
+
|
|
3172
|
+
### Fragment: `ShopFonts` on `ShopFonts`
|
|
3173
|
+
|
|
3174
|
+
**Section**: Shop
|
|
3175
|
+
|
|
3176
|
+
**Description**: Shop branding fonts — body (`primary`) and `heading` font families.
|
|
3177
|
+
|
|
3178
|
+
**GraphQL**:
|
|
3179
|
+
```graphql
|
|
3180
|
+
fragment ShopFonts on ShopFonts {
|
|
3181
|
+
primary
|
|
3182
|
+
heading
|
|
3183
|
+
}
|
|
3184
|
+
```
|
|
3185
|
+
|
|
3186
|
+
### Fragment: `SocialLinks` on `SocialLinks`
|
|
3187
|
+
|
|
3188
|
+
**Section**: Shop
|
|
3189
|
+
|
|
3190
|
+
**Description**: Social media links configured for the shop. Spread on the footer.
|
|
3191
|
+
|
|
3192
|
+
**GraphQL**:
|
|
3193
|
+
```graphql
|
|
3194
|
+
fragment SocialLinks on SocialLinks {
|
|
3195
|
+
facebook
|
|
3196
|
+
instagram
|
|
3197
|
+
twitter
|
|
3198
|
+
youtube
|
|
3199
|
+
tiktok
|
|
3200
|
+
linkedin
|
|
3201
|
+
pinterest
|
|
3202
|
+
}
|
|
3203
|
+
```
|
|
3204
|
+
|
|
3205
|
+
### Fragment: `ShopAddress` on `ShopAddress`
|
|
3206
|
+
|
|
3207
|
+
**Section**: Shop
|
|
3208
|
+
|
|
3209
|
+
**Description**: Shop's physical / business address. Use on the contact page and footer.
|
|
3210
|
+
|
|
3211
|
+
**GraphQL**:
|
|
3212
|
+
```graphql
|
|
3213
|
+
fragment ShopAddress on ShopAddress {
|
|
3214
|
+
streetLine1
|
|
3215
|
+
streetLine2
|
|
3216
|
+
city
|
|
3217
|
+
state
|
|
3218
|
+
postalCode
|
|
3219
|
+
country
|
|
3220
|
+
}
|
|
3221
|
+
```
|
|
3222
|
+
|
|
3223
|
+
### Fragment: `BusinessHour` on `BusinessHour`
|
|
3224
|
+
|
|
3225
|
+
**Section**: Shop
|
|
3226
|
+
|
|
3227
|
+
**Description**: One day's business hours window. Spread inside `Shop.businessHours[]`.
|
|
3228
|
+
|
|
3229
|
+
**GraphQL**:
|
|
3230
|
+
```graphql
|
|
3231
|
+
fragment BusinessHour on BusinessHour {
|
|
3232
|
+
day
|
|
3233
|
+
openTime
|
|
3234
|
+
closeTime
|
|
3235
|
+
isClosed
|
|
3236
|
+
}
|
|
3237
|
+
```
|
|
3238
|
+
|
|
3239
|
+
### Fragment: `ShopBranding` on `ShopBranding`
|
|
3240
|
+
|
|
3241
|
+
**Section**: Shop
|
|
3242
|
+
|
|
3243
|
+
**Description**: Full shop branding bundle — logo + favicon + colors + fonts + social links. Spread inside the `Shop` fragment.
|
|
3244
|
+
|
|
3245
|
+
**Uses fragments**: `Image`, `ShopColors`, `ShopFonts`, `SocialLinks`
|
|
3246
|
+
|
|
3247
|
+
**GraphQL**:
|
|
3248
|
+
```graphql
|
|
3249
|
+
fragment ShopBranding on ShopBranding {
|
|
3250
|
+
logo {
|
|
3251
|
+
...Image
|
|
3252
|
+
}
|
|
3253
|
+
favicon {
|
|
3254
|
+
...Image
|
|
3255
|
+
}
|
|
3256
|
+
colors {
|
|
3257
|
+
...ShopColors
|
|
3258
|
+
}
|
|
3259
|
+
fonts {
|
|
3260
|
+
...ShopFonts
|
|
3261
|
+
}
|
|
3262
|
+
socialLinks {
|
|
3263
|
+
...SocialLinks
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
```
|
|
3267
|
+
|
|
3268
|
+
### Fragment: `BotProtectionProvider` on `BotProtectionProviderInfo`
|
|
3269
|
+
|
|
3270
|
+
**Section**: Shop
|
|
3271
|
+
|
|
3272
|
+
**Description**: Bot-protection provider config (provider name, site key, script URL) for storefront-side challenge widgets.
|
|
3273
|
+
|
|
3274
|
+
**GraphQL**:
|
|
3275
|
+
```graphql
|
|
3276
|
+
fragment BotProtectionProvider on BotProtectionProviderInfo {
|
|
3277
|
+
provider
|
|
3278
|
+
siteKey
|
|
3279
|
+
scriptUrl
|
|
3280
|
+
}
|
|
3281
|
+
```
|
|
3282
|
+
|
|
3283
|
+
### Fragment: `BotProtection` on `BotProtectionInfo`
|
|
3284
|
+
|
|
3285
|
+
**Section**: Shop
|
|
3286
|
+
|
|
3287
|
+
**Description**: Bot-protection setup for the shop — primary + fallback provider, and the list of `protectedOperations` (mutation names that require a challenge token). Spread inside `Shop`.
|
|
3288
|
+
|
|
3289
|
+
**Uses fragments**: `BotProtectionProvider`
|
|
3290
|
+
|
|
3291
|
+
**GraphQL**:
|
|
3292
|
+
```graphql
|
|
3293
|
+
fragment BotProtection on BotProtectionInfo {
|
|
3294
|
+
primary {
|
|
3295
|
+
...BotProtectionProvider
|
|
3296
|
+
}
|
|
3297
|
+
fallback {
|
|
3298
|
+
...BotProtectionProvider
|
|
3299
|
+
}
|
|
3300
|
+
protectedOperations
|
|
3301
|
+
}
|
|
3302
|
+
```
|
|
3303
|
+
|
|
3304
|
+
### Fragment: `Shop` on `Shop`
|
|
3305
|
+
|
|
3306
|
+
**Section**: Shop
|
|
3307
|
+
|
|
3308
|
+
**Description**: The shop itself — name, primary domain, currencies + locales, branding, contact info, business hours, bot-protection config. Spread on the root `shop` query; cache for the session.
|
|
3309
|
+
|
|
3310
|
+
**Uses fragments**: `BotProtection`, `BusinessHour`, `Image`, `ShopAddress`, `ShopBranding`
|
|
3311
|
+
|
|
3312
|
+
**GraphQL**:
|
|
3313
|
+
```graphql
|
|
3314
|
+
fragment Shop on Shop {
|
|
3315
|
+
id
|
|
3316
|
+
name
|
|
3317
|
+
description
|
|
3318
|
+
primaryDomain {
|
|
3319
|
+
host
|
|
3320
|
+
url
|
|
3321
|
+
isSslEnabled
|
|
3322
|
+
}
|
|
3323
|
+
currencyCode
|
|
3324
|
+
supportedCurrencies
|
|
3325
|
+
paymentCurrencies
|
|
3326
|
+
defaultLanguage
|
|
3327
|
+
supportedLanguages
|
|
3328
|
+
logo {
|
|
3329
|
+
...Image
|
|
3330
|
+
}
|
|
3331
|
+
contactEmail
|
|
3332
|
+
contactPhone
|
|
3333
|
+
address {
|
|
3334
|
+
...ShopAddress
|
|
3335
|
+
}
|
|
3336
|
+
businessHours {
|
|
3337
|
+
...BusinessHour
|
|
3338
|
+
}
|
|
3339
|
+
branding {
|
|
3340
|
+
...ShopBranding
|
|
3341
|
+
}
|
|
3342
|
+
botProtection {
|
|
3343
|
+
...BotProtection
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3346
|
+
```
|
|
3347
|
+
|
|
3348
|
+
### Fragment: `PaymentMethod` on `PaymentMethod`
|
|
3349
|
+
|
|
3350
|
+
**Section**: Payment Methods
|
|
3351
|
+
|
|
3352
|
+
**Description**: Single payment method enabled for the shop — type (CARD / BANK_TRANSFER / BLIK / PAYPAL / APPLE_PAY / GOOGLE_PAY / CASH_ON_DELIVERY / OTHER), provider, icon, supported currencies, default flag, sort position. Spread on the checkout payment step.
|
|
3353
|
+
|
|
3354
|
+
**GraphQL**:
|
|
3355
|
+
```graphql
|
|
3356
|
+
fragment PaymentMethod on PaymentMethod {
|
|
3357
|
+
id
|
|
3358
|
+
name
|
|
3359
|
+
provider
|
|
3360
|
+
type
|
|
3361
|
+
icon
|
|
3362
|
+
description
|
|
3363
|
+
isDefault
|
|
3364
|
+
supportedCurrencies
|
|
3365
|
+
position
|
|
3366
|
+
}
|
|
3367
|
+
```
|
|
3368
|
+
|
|
3369
|
+
### Fragment: `AvailablePaymentMethods` on `AvailablePaymentMethods`
|
|
3370
|
+
|
|
3371
|
+
**Section**: Payment Methods
|
|
3372
|
+
|
|
3373
|
+
**Description**: Active payment methods list with the merchant's `defaultMethod`. Returned by the `availablePaymentMethods` query.
|
|
3374
|
+
|
|
3375
|
+
**Uses fragments**: `PaymentMethod`
|
|
3376
|
+
|
|
3377
|
+
**GraphQL**:
|
|
3378
|
+
```graphql
|
|
3379
|
+
fragment AvailablePaymentMethods on AvailablePaymentMethods {
|
|
3380
|
+
methods {
|
|
3381
|
+
...PaymentMethod
|
|
3382
|
+
}
|
|
3383
|
+
defaultMethod {
|
|
3384
|
+
...PaymentMethod
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
```
|
|
3388
|
+
|
|
3389
|
+
### Fragment: `ShippingRate` on `ShippingRate`
|
|
3390
|
+
|
|
3391
|
+
**Section**: Checkout
|
|
3392
|
+
|
|
3393
|
+
**Description**: Single shipping rate option — `handle` is the stable id you pass to `checkoutShippingLineUpdate`, plus title and price.
|
|
3394
|
+
|
|
3395
|
+
**Uses fragments**: `Money`
|
|
3396
|
+
|
|
3397
|
+
**GraphQL**:
|
|
3398
|
+
```graphql
|
|
3399
|
+
fragment ShippingRate on ShippingRate {
|
|
3400
|
+
handle
|
|
3401
|
+
title
|
|
3402
|
+
price {
|
|
3403
|
+
...Money
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
```
|
|
3407
|
+
|
|
3408
|
+
### Fragment: `TaxLine` on `TaxLine`
|
|
3409
|
+
|
|
3410
|
+
**Section**: Checkout
|
|
3411
|
+
|
|
3412
|
+
**Description**: One tax line on the checkout — title, rate (decimal, e.g. 0.23 for 23%), computed amount. Spread on the order summary.
|
|
3413
|
+
|
|
3414
|
+
**Uses fragments**: `Money`
|
|
3415
|
+
|
|
3416
|
+
**GraphQL**:
|
|
3417
|
+
```graphql
|
|
3418
|
+
fragment TaxLine on TaxLine {
|
|
3419
|
+
title
|
|
3420
|
+
rate
|
|
3421
|
+
price {
|
|
3422
|
+
...Money
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
```
|
|
3426
|
+
|
|
3427
|
+
### Fragment: `DiscountAffectedItem` on `DiscountAffectedItem`
|
|
3428
|
+
|
|
3429
|
+
**Section**: Checkout
|
|
3430
|
+
|
|
3431
|
+
**Description**: Item affected by a discount — the discounted product/variant with original + discounted prices and savings. Used on Buy-X-Get-Y promotions to highlight which items the discount applies to.
|
|
3432
|
+
|
|
3433
|
+
**Uses fragments**: `Money`
|
|
3434
|
+
|
|
3435
|
+
**GraphQL**:
|
|
3436
|
+
```graphql
|
|
3437
|
+
fragment DiscountAffectedItem on DiscountAffectedItem {
|
|
3438
|
+
productId
|
|
3439
|
+
variantId
|
|
3440
|
+
title
|
|
3441
|
+
quantity
|
|
3442
|
+
originalPrice {
|
|
3443
|
+
...Money
|
|
3444
|
+
}
|
|
3445
|
+
discountedPrice {
|
|
3446
|
+
...Money
|
|
3447
|
+
}
|
|
3448
|
+
savings {
|
|
3449
|
+
...Money
|
|
3450
|
+
}
|
|
3451
|
+
isFreeItem
|
|
3452
|
+
}
|
|
3453
|
+
```
|
|
3454
|
+
|
|
3455
|
+
### Fragment: `DiscountApplication` on `DiscountApplication`
|
|
3456
|
+
|
|
3457
|
+
**Section**: Checkout
|
|
3458
|
+
|
|
3459
|
+
**Description**: A discount currently applied to the checkout — code, type, value, plus BXGY (Buy X Get Y) metadata when applicable (`buyQuantity`, `getQuantity`, `getDiscountPercent`, `affectedItems`). Use to render a "Discounts applied" panel.
|
|
3460
|
+
|
|
3461
|
+
**Uses fragments**: `DiscountAffectedItem`, `Money`
|
|
3462
|
+
|
|
3463
|
+
**GraphQL**:
|
|
3464
|
+
```graphql
|
|
3465
|
+
fragment DiscountApplication on DiscountApplication {
|
|
3466
|
+
code
|
|
3467
|
+
isApplicable
|
|
3468
|
+
type
|
|
3469
|
+
value {
|
|
3470
|
+
...Money
|
|
3471
|
+
}
|
|
3472
|
+
title
|
|
3473
|
+
affectedItems {
|
|
3474
|
+
...DiscountAffectedItem
|
|
3475
|
+
}
|
|
3476
|
+
buyQuantity
|
|
3477
|
+
getQuantity
|
|
3478
|
+
getDiscountPercent
|
|
3479
|
+
}
|
|
3480
|
+
```
|
|
3481
|
+
|
|
3482
|
+
### Fragment: `DiscountCode` on `DiscountCode`
|
|
3483
|
+
|
|
3484
|
+
**Section**: Checkout
|
|
3485
|
+
|
|
3486
|
+
**Description**: Lightweight discount code entry on the checkout — code + applicability flag.
|
|
3487
|
+
|
|
3488
|
+
**GraphQL**:
|
|
3489
|
+
```graphql
|
|
3490
|
+
fragment DiscountCode on DiscountCode {
|
|
3491
|
+
code
|
|
3492
|
+
isApplicable
|
|
3493
|
+
}
|
|
3494
|
+
```
|
|
3495
|
+
|
|
3496
|
+
### Fragment: `CheckoutLineItem` on `CheckoutLineItem`
|
|
3497
|
+
|
|
3498
|
+
**Section**: Checkout
|
|
3499
|
+
|
|
3500
|
+
**Description**: Single line item in the checkout — variant snapshot, quantity, unit + total prices, image. Use on the order summary panel.
|
|
3501
|
+
|
|
3502
|
+
**Uses fragments**: `ImageThumbnail`, `Money`
|
|
3503
|
+
|
|
3504
|
+
**GraphQL**:
|
|
3505
|
+
```graphql
|
|
3506
|
+
fragment CheckoutLineItem on CheckoutLineItem {
|
|
3507
|
+
id
|
|
3508
|
+
title
|
|
3509
|
+
variantTitle
|
|
3510
|
+
quantity
|
|
3511
|
+
pricePerUnit {
|
|
3512
|
+
...Money
|
|
3513
|
+
}
|
|
3514
|
+
total {
|
|
3515
|
+
...Money
|
|
3516
|
+
}
|
|
3517
|
+
variantId
|
|
3518
|
+
productId
|
|
3519
|
+
sku
|
|
3520
|
+
image {
|
|
3521
|
+
...ImageThumbnail
|
|
3522
|
+
}
|
|
3523
|
+
}
|
|
3524
|
+
```
|
|
3525
|
+
|
|
3526
|
+
### Fragment: `AppliedGiftCard` on `AppliedGiftCard`
|
|
3527
|
+
|
|
3528
|
+
**Section**: Checkout
|
|
3529
|
+
|
|
3530
|
+
**Description**: Gift card applied to the checkout — `maskedCode` (first + last 4 chars), `lastCharacters` (for display matching), the amount applied to this checkout, and remaining balance after this order would complete.
|
|
3531
|
+
|
|
3532
|
+
**Uses fragments**: `Money`
|
|
3533
|
+
|
|
3534
|
+
**GraphQL**:
|
|
3535
|
+
```graphql
|
|
3536
|
+
fragment AppliedGiftCard on AppliedGiftCard {
|
|
3537
|
+
maskedCode
|
|
3538
|
+
lastCharacters
|
|
3539
|
+
appliedAmount {
|
|
3540
|
+
...Money
|
|
3541
|
+
}
|
|
3542
|
+
remainingBalance {
|
|
3543
|
+
...Money
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
```
|
|
3547
|
+
|
|
3548
|
+
### Fragment: `Checkout` on `Checkout`
|
|
3549
|
+
|
|
3550
|
+
**Section**: Checkout
|
|
3551
|
+
|
|
3552
|
+
**Description**: Full checkout shape — line items, shipping + billing addresses, selected + available shipping rates, available payment methods, applied discounts + gift cards, tax lines, totals (`cost`, `paymentDue`, `totalGiftCardAmount`). Spread on the checkout flow; refetch after every checkout mutation. `isReady` flips to true when the checkout has all required fields to call `checkoutComplete`.
|
|
3553
|
+
|
|
3554
|
+
**Uses fragments**: `AppliedGiftCard`, `CheckoutLineItem`, `DiscountApplication`, `DiscountCode`, `MailingAddress`, `Money`, `PaymentMethod`, `ShippingRate`, `TaxLine`
|
|
3555
|
+
|
|
3556
|
+
**GraphQL**:
|
|
3557
|
+
```graphql
|
|
3558
|
+
fragment Checkout on Checkout {
|
|
3559
|
+
id
|
|
3560
|
+
isReady
|
|
3561
|
+
isCompleted
|
|
3562
|
+
completedOrderId
|
|
3563
|
+
webUrl
|
|
3564
|
+
lineItems {
|
|
3565
|
+
...CheckoutLineItem
|
|
3566
|
+
}
|
|
3567
|
+
totalQuantity
|
|
3568
|
+
shippingAddress {
|
|
3569
|
+
...MailingAddress
|
|
3570
|
+
}
|
|
3571
|
+
billingAddress {
|
|
3572
|
+
...MailingAddress
|
|
3573
|
+
}
|
|
3574
|
+
shippingLine {
|
|
3575
|
+
...ShippingRate
|
|
3576
|
+
}
|
|
3577
|
+
availableShippingRates {
|
|
3578
|
+
...ShippingRate
|
|
3579
|
+
}
|
|
3580
|
+
shippingRatesReady
|
|
3581
|
+
email
|
|
3582
|
+
phone
|
|
3583
|
+
customerId
|
|
3584
|
+
discountCodes {
|
|
3585
|
+
...DiscountCode
|
|
3586
|
+
}
|
|
3587
|
+
discountApplications {
|
|
3588
|
+
...DiscountApplication
|
|
3589
|
+
}
|
|
3590
|
+
availablePaymentMethods {
|
|
3591
|
+
...PaymentMethod
|
|
3592
|
+
}
|
|
3593
|
+
selectedPaymentMethodId
|
|
3594
|
+
cost {
|
|
3595
|
+
subtotal {
|
|
3596
|
+
...Money
|
|
3597
|
+
}
|
|
3598
|
+
total {
|
|
3599
|
+
...Money
|
|
3600
|
+
}
|
|
3601
|
+
totalTax {
|
|
3602
|
+
...Money
|
|
3603
|
+
}
|
|
3604
|
+
totalShipping {
|
|
3605
|
+
...Money
|
|
3606
|
+
}
|
|
3607
|
+
totalDiscounts {
|
|
3608
|
+
...Money
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3611
|
+
taxLines {
|
|
3612
|
+
...TaxLine
|
|
3613
|
+
}
|
|
3614
|
+
appliedGiftCards {
|
|
3615
|
+
...AppliedGiftCard
|
|
3616
|
+
}
|
|
3617
|
+
totalGiftCardAmount {
|
|
3618
|
+
...Money
|
|
3619
|
+
}
|
|
3620
|
+
paymentDue {
|
|
3621
|
+
...Money
|
|
3622
|
+
}
|
|
3623
|
+
currencyCode
|
|
3624
|
+
note
|
|
3625
|
+
createdAt
|
|
3626
|
+
updatedAt
|
|
3627
|
+
}
|
|
3628
|
+
```
|
|
3629
|
+
|
|
3630
|
+
### Fragment: `ShipmentEvent` on `ShipmentEvent`
|
|
3631
|
+
|
|
3632
|
+
**Section**: Shipments / Tracking
|
|
3633
|
+
|
|
3634
|
+
**Description**: One tracking event in the shipment timeline — status, description, location, timestamp. Spread on the tracking page timeline.
|
|
3635
|
+
|
|
3636
|
+
**GraphQL**:
|
|
3637
|
+
```graphql
|
|
3638
|
+
fragment ShipmentEvent on ShipmentEvent {
|
|
3639
|
+
id
|
|
3640
|
+
status
|
|
3641
|
+
description
|
|
3642
|
+
location
|
|
3643
|
+
occurredAt
|
|
3644
|
+
providerEventCode
|
|
3645
|
+
}
|
|
3646
|
+
```
|
|
3647
|
+
|
|
3648
|
+
### Fragment: `ShipmentPackage` on `ShipmentPackage`
|
|
3649
|
+
|
|
3650
|
+
**Section**: Shipments / Tracking
|
|
3651
|
+
|
|
3652
|
+
**Description**: Physical package metadata (weight + dimensions). Used in the merchant's label generation; storefronts rarely render this directly.
|
|
3653
|
+
|
|
3654
|
+
**GraphQL**:
|
|
3655
|
+
```graphql
|
|
3656
|
+
fragment ShipmentPackage on ShipmentPackage {
|
|
3657
|
+
weight
|
|
3658
|
+
length
|
|
3659
|
+
width
|
|
3660
|
+
height
|
|
3661
|
+
}
|
|
3662
|
+
```
|
|
3663
|
+
|
|
3664
|
+
### Fragment: `ShipmentItem` on `ShipmentItem`
|
|
3665
|
+
|
|
3666
|
+
**Section**: Shipments / Tracking
|
|
3667
|
+
|
|
3668
|
+
**Description**: One item in a shipment — title, variant, sku, quantity, image URL. Spread inside `Shipment.items[]` for the tracking page item list.
|
|
3669
|
+
|
|
3670
|
+
**GraphQL**:
|
|
3671
|
+
```graphql
|
|
3672
|
+
fragment ShipmentItem on ShipmentItem {
|
|
3673
|
+
id
|
|
3674
|
+
title
|
|
3675
|
+
variantTitle
|
|
3676
|
+
sku
|
|
3677
|
+
quantity
|
|
3678
|
+
imageUrl
|
|
3679
|
+
}
|
|
3680
|
+
```
|
|
3681
|
+
|
|
3682
|
+
### Fragment: `Shipment` on `Shipment`
|
|
3683
|
+
|
|
3684
|
+
**Section**: Shipments / Tracking
|
|
3685
|
+
|
|
3686
|
+
**Description**: Full shipment shape — provider, tracking number + URL, label URL, status, ETA, recipient address, packages, items, full event timeline. Spread on the tracking page.
|
|
3687
|
+
|
|
3688
|
+
**Uses fragments**: `MailingAddress`, `ShipmentEvent`, `ShipmentItem`, `ShipmentPackage`
|
|
3689
|
+
|
|
3690
|
+
**GraphQL**:
|
|
3691
|
+
```graphql
|
|
3692
|
+
fragment Shipment on Shipment {
|
|
3693
|
+
id
|
|
3694
|
+
orderId
|
|
3695
|
+
provider
|
|
3696
|
+
serviceCode
|
|
3697
|
+
trackingNumber
|
|
3698
|
+
trackingUrl
|
|
3699
|
+
labelUrl
|
|
3700
|
+
status
|
|
3701
|
+
estimatedDeliveryAt
|
|
3702
|
+
shippedAt
|
|
3703
|
+
deliveredAt
|
|
3704
|
+
recipientAddress {
|
|
3705
|
+
...MailingAddress
|
|
3706
|
+
}
|
|
3707
|
+
packages {
|
|
3708
|
+
...ShipmentPackage
|
|
3709
|
+
}
|
|
3710
|
+
items {
|
|
3711
|
+
...ShipmentItem
|
|
3712
|
+
}
|
|
3713
|
+
events {
|
|
3714
|
+
...ShipmentEvent
|
|
3715
|
+
}
|
|
3716
|
+
createdAt
|
|
3717
|
+
updatedAt
|
|
3718
|
+
}
|
|
3719
|
+
```
|
|
3720
|
+
|
|
3721
|
+
### Fragment: `ShipmentBasic` on `Shipment`
|
|
3722
|
+
|
|
3723
|
+
**Section**: Shipments / Tracking
|
|
3724
|
+
|
|
3725
|
+
**Description**: Lightweight shipment shape — id, tracking number + URL, status, dates. No items / events / address. Use for order summary cards or on the public `shipmentByTrackingNumber` query.
|
|
3726
|
+
|
|
3727
|
+
**GraphQL**:
|
|
3728
|
+
```graphql
|
|
3729
|
+
fragment ShipmentBasic on Shipment {
|
|
3730
|
+
id
|
|
3731
|
+
orderId
|
|
3732
|
+
provider
|
|
3733
|
+
trackingNumber
|
|
3734
|
+
trackingUrl
|
|
3735
|
+
status
|
|
3736
|
+
estimatedDeliveryAt
|
|
3737
|
+
shippedAt
|
|
3738
|
+
deliveredAt
|
|
3739
|
+
createdAt
|
|
3740
|
+
}
|
|
3741
|
+
```
|
|
3742
|
+
|
|
3743
|
+
### Fragment: `ReturnShippingLabel` on `ReturnShippingLabel`
|
|
3744
|
+
|
|
3745
|
+
**Section**: Returns / RMA
|
|
3746
|
+
|
|
3747
|
+
**Description**: Return shipping label generated by the carrier — URL to download, carrier name, tracking number, expiry. Spread on the return detail page.
|
|
3748
|
+
|
|
3749
|
+
**GraphQL**:
|
|
3750
|
+
```graphql
|
|
3751
|
+
fragment ReturnShippingLabel on ReturnShippingLabel {
|
|
3752
|
+
url
|
|
3753
|
+
carrier
|
|
3754
|
+
trackingNumber
|
|
3755
|
+
expiresAt
|
|
3756
|
+
}
|
|
3757
|
+
```
|
|
3758
|
+
|
|
3759
|
+
### Fragment: `ReturnItemPhoto` on `ReturnItemPhoto`
|
|
3760
|
+
|
|
3761
|
+
**Section**: Returns / RMA
|
|
3762
|
+
|
|
3763
|
+
**Description**: Photo evidence attached to a return item (e.g. damage photo). Spread inside `ReturnItem.photos[]`.
|
|
3764
|
+
|
|
3765
|
+
**GraphQL**:
|
|
3766
|
+
```graphql
|
|
3767
|
+
fragment ReturnItemPhoto on ReturnItemPhoto {
|
|
3768
|
+
id
|
|
3769
|
+
url
|
|
3770
|
+
alt
|
|
3771
|
+
description
|
|
3772
|
+
createdAt
|
|
3773
|
+
}
|
|
3774
|
+
```
|
|
3775
|
+
|
|
3776
|
+
### Fragment: `ReturnItem` on `ReturnItem`
|
|
3777
|
+
|
|
3778
|
+
**Section**: Returns / RMA
|
|
3779
|
+
|
|
3780
|
+
**Description**: Single line in a return request — variant identity, quantity requested, reason, condition, photos, status, approved quantity (set by merchant after review). Spread inside `Return.items[]`.
|
|
3781
|
+
|
|
3782
|
+
**Uses fragments**: `Money`, `ReturnItemPhoto`
|
|
3783
|
+
|
|
3784
|
+
**GraphQL**:
|
|
3785
|
+
```graphql
|
|
3786
|
+
fragment ReturnItem on ReturnItem {
|
|
3787
|
+
id
|
|
3788
|
+
variantId
|
|
3789
|
+
productTitle
|
|
3790
|
+
variantTitle
|
|
3791
|
+
sku
|
|
3792
|
+
imageUrl
|
|
3793
|
+
quantity
|
|
3794
|
+
reason
|
|
3795
|
+
condition
|
|
3796
|
+
unitPrice {
|
|
3797
|
+
...Money
|
|
3798
|
+
}
|
|
3799
|
+
photos {
|
|
3800
|
+
...ReturnItemPhoto
|
|
3801
|
+
}
|
|
3802
|
+
status
|
|
3803
|
+
approvedQuantity
|
|
3804
|
+
}
|
|
3805
|
+
```
|
|
3806
|
+
|
|
3807
|
+
### Fragment: `Return` on `Return`
|
|
3808
|
+
|
|
3809
|
+
**Section**: Returns / RMA
|
|
3810
|
+
|
|
3811
|
+
**Description**: Full return shape — number, parent order, status, reason, customer note, compensation type (`REFUND` / `STORE_CREDIT`), items, refund amount, shipping label, lifecycle timestamps. Spread on the return detail page.
|
|
3812
|
+
|
|
3813
|
+
**Uses fragments**: `Money`, `ReturnItem`, `ReturnShippingLabel`
|
|
3814
|
+
|
|
3815
|
+
**GraphQL**:
|
|
3816
|
+
```graphql
|
|
3817
|
+
fragment Return on Return {
|
|
3818
|
+
id
|
|
3819
|
+
returnNumber
|
|
3820
|
+
orderId
|
|
3821
|
+
orderNumber
|
|
3822
|
+
status
|
|
3823
|
+
reason
|
|
3824
|
+
customerNote
|
|
3825
|
+
compensationType
|
|
3826
|
+
items {
|
|
3827
|
+
...ReturnItem
|
|
3828
|
+
}
|
|
3829
|
+
refundAmount {
|
|
3830
|
+
...Money
|
|
3831
|
+
}
|
|
3832
|
+
shippingLabel {
|
|
3833
|
+
...ReturnShippingLabel
|
|
3834
|
+
}
|
|
3835
|
+
requestedAt
|
|
3836
|
+
approvedAt
|
|
3837
|
+
receivedAt
|
|
3838
|
+
refundedAt
|
|
3839
|
+
completedAt
|
|
3840
|
+
createdAt
|
|
3841
|
+
updatedAt
|
|
3842
|
+
}
|
|
3843
|
+
```
|
|
3844
|
+
|
|
3845
|
+
### Fragment: `ReturnReasonOption` on `ReturnReasonOption`
|
|
3846
|
+
|
|
3847
|
+
**Section**: Returns / RMA
|
|
3848
|
+
|
|
3849
|
+
**Description**: Single option in the return reasons dropdown — `value` enum, human-readable `label`, optional `description`. Returned by `returnReasons` query.
|
|
3850
|
+
|
|
3851
|
+
**GraphQL**:
|
|
3852
|
+
```graphql
|
|
3853
|
+
fragment ReturnReasonOption on ReturnReasonOption {
|
|
3854
|
+
value
|
|
3855
|
+
label
|
|
3856
|
+
description
|
|
3857
|
+
}
|
|
3858
|
+
```
|
|
3859
|
+
|
|
3860
|
+
### Fragment: `GiftCard` on `GiftCard`
|
|
3861
|
+
|
|
3862
|
+
**Section**: Gift Cards
|
|
3863
|
+
|
|
3864
|
+
**Description**: Gift card detail — masked code (first + last 4 chars), status, initial + remaining balance, expiry, recipient/message. Returned by `giftCard($code)` query.
|
|
3865
|
+
|
|
3866
|
+
**Uses fragments**: `Money`
|
|
3867
|
+
|
|
3868
|
+
**GraphQL**:
|
|
3869
|
+
```graphql
|
|
3870
|
+
fragment GiftCard on GiftCard {
|
|
3871
|
+
id
|
|
3872
|
+
maskedCode
|
|
3873
|
+
status
|
|
3874
|
+
initialAmount {
|
|
3875
|
+
...Money
|
|
3876
|
+
}
|
|
3877
|
+
balance {
|
|
3878
|
+
...Money
|
|
3879
|
+
}
|
|
3880
|
+
expiresAt
|
|
3881
|
+
recipientName
|
|
3882
|
+
message
|
|
3883
|
+
createdAt
|
|
3884
|
+
}
|
|
3885
|
+
```
|
|
3886
|
+
|
|
3887
|
+
### Fragment: `GiftCardError` on `GiftCardError`
|
|
3888
|
+
|
|
3889
|
+
**Section**: Gift Cards
|
|
3890
|
+
|
|
3891
|
+
**Description**: Validation error on a gift card check — code (`NOT_FOUND` / `DISABLED` / `ALREADY_USED` / `EXPIRED` / `INSUFFICIENT_BALANCE`) + human message.
|
|
3892
|
+
|
|
3893
|
+
**GraphQL**:
|
|
3894
|
+
```graphql
|
|
3895
|
+
fragment GiftCardError on GiftCardError {
|
|
3896
|
+
code
|
|
3897
|
+
message
|
|
3898
|
+
}
|
|
3899
|
+
```
|
|
3900
|
+
|
|
3901
|
+
### Fragment: `GiftCardValidation` on `GiftCardValidation`
|
|
3902
|
+
|
|
3903
|
+
**Section**: Gift Cards
|
|
3904
|
+
|
|
3905
|
+
**Description**: Result of `giftCardValidate($code, $amount)` — `isValid` flag, available balance, optional `error` (when invalid), and the matched gift card (when found). Use to inline-validate gift card inputs before applying.
|
|
3906
|
+
|
|
3907
|
+
**Uses fragments**: `GiftCard`, `GiftCardError`, `Money`
|
|
3908
|
+
|
|
3909
|
+
**GraphQL**:
|
|
3910
|
+
```graphql
|
|
3911
|
+
fragment GiftCardValidation on GiftCardValidation {
|
|
3912
|
+
isValid
|
|
3913
|
+
availableBalance {
|
|
3914
|
+
...Money
|
|
3915
|
+
}
|
|
3916
|
+
error {
|
|
3917
|
+
...GiftCardError
|
|
3918
|
+
}
|
|
3919
|
+
giftCard {
|
|
3920
|
+
...GiftCard
|
|
3921
|
+
}
|
|
3922
|
+
}
|
|
3923
|
+
```
|
|
3924
|
+
|
|
3925
|
+
### Fragment: `ShippingCarrier` on `ShippingCarrier`
|
|
3926
|
+
|
|
3927
|
+
**Section**: Shipping Methods
|
|
3928
|
+
|
|
3929
|
+
**Description**: Carrier offering the shipping method — id, display name, logo URL, internal service code.
|
|
3930
|
+
|
|
3931
|
+
**GraphQL**:
|
|
3932
|
+
```graphql
|
|
3933
|
+
fragment ShippingCarrier on ShippingCarrier {
|
|
3934
|
+
id
|
|
3935
|
+
name
|
|
3936
|
+
logoUrl
|
|
3937
|
+
serviceCode
|
|
3938
|
+
}
|
|
3939
|
+
```
|
|
3940
|
+
|
|
3941
|
+
### Fragment: `DeliveryEstimate` on `DeliveryEstimate`
|
|
3942
|
+
|
|
3943
|
+
**Section**: Shipping Methods
|
|
3944
|
+
|
|
3945
|
+
**Description**: Estimated delivery window — `minDays` to `maxDays` plus a human-readable description (e.g. "2-4 business days").
|
|
3946
|
+
|
|
3947
|
+
**GraphQL**:
|
|
3948
|
+
```graphql
|
|
3949
|
+
fragment DeliveryEstimate on DeliveryEstimate {
|
|
3950
|
+
minDays
|
|
3951
|
+
maxDays
|
|
3952
|
+
description
|
|
3953
|
+
}
|
|
3954
|
+
```
|
|
3955
|
+
|
|
3956
|
+
### Fragment: `FreeShippingProgress` on `FreeShippingProgress`
|
|
3957
|
+
|
|
3958
|
+
**Section**: Shipping Methods
|
|
3959
|
+
|
|
3960
|
+
**Description**: Free-shipping progress info — `qualifies` flag, current cart amount, threshold, remaining to qualify, percent progress, and a localized message ("Add 20 PLN more for free shipping"). Use to render a free-shipping progress bar in the cart drawer.
|
|
3961
|
+
|
|
3962
|
+
**Uses fragments**: `Money`
|
|
3963
|
+
|
|
3964
|
+
**GraphQL**:
|
|
3965
|
+
```graphql
|
|
3966
|
+
fragment FreeShippingProgress on FreeShippingProgress {
|
|
3967
|
+
qualifies
|
|
3968
|
+
currentAmount {
|
|
3969
|
+
...Money
|
|
3970
|
+
}
|
|
3971
|
+
threshold {
|
|
3972
|
+
...Money
|
|
3973
|
+
}
|
|
3974
|
+
remaining {
|
|
3975
|
+
...Money
|
|
3976
|
+
}
|
|
3977
|
+
progressPercent
|
|
3978
|
+
message
|
|
3979
|
+
}
|
|
3980
|
+
```
|
|
3981
|
+
|
|
3982
|
+
### Fragment: `AvailableShippingMethod` on `AvailableShippingMethod`
|
|
3983
|
+
|
|
3984
|
+
**Section**: Shipping Methods
|
|
3985
|
+
|
|
3986
|
+
**Description**: One shipping method offered for the destination + cart — id, name, carrier, price, free-shipping progress, estimated delivery, sort order. Spread on the checkout shipping step.
|
|
3987
|
+
|
|
3988
|
+
**Uses fragments**: `DeliveryEstimate`, `FreeShippingProgress`, `Money`, `ShippingCarrier`
|
|
3989
|
+
|
|
3990
|
+
**GraphQL**:
|
|
3991
|
+
```graphql
|
|
3992
|
+
fragment AvailableShippingMethod on AvailableShippingMethod {
|
|
3993
|
+
id
|
|
3994
|
+
name
|
|
3995
|
+
description
|
|
3996
|
+
carrier {
|
|
3997
|
+
...ShippingCarrier
|
|
3998
|
+
}
|
|
3999
|
+
price {
|
|
4000
|
+
...Money
|
|
4001
|
+
}
|
|
4002
|
+
isFree
|
|
4003
|
+
estimatedDelivery {
|
|
4004
|
+
...DeliveryEstimate
|
|
4005
|
+
}
|
|
4006
|
+
freeShippingProgress {
|
|
4007
|
+
...FreeShippingProgress
|
|
4008
|
+
}
|
|
4009
|
+
sortOrder
|
|
4010
|
+
}
|
|
4011
|
+
```
|
|
4012
|
+
|
|
4013
|
+
### Fragment: `AttributeSwatch` on `AttributeSwatch`
|
|
4014
|
+
|
|
4015
|
+
**Section**: Attribute Filters
|
|
4016
|
+
|
|
4017
|
+
**Description**: Visual swatch for an attribute filter value — color hex (for color filters) or image URL (for pattern/material swatches).
|
|
4018
|
+
|
|
4019
|
+
**GraphQL**:
|
|
4020
|
+
```graphql
|
|
4021
|
+
fragment AttributeSwatch on AttributeSwatch {
|
|
4022
|
+
colorHex
|
|
4023
|
+
imageUrl
|
|
4024
|
+
}
|
|
4025
|
+
```
|
|
4026
|
+
|
|
4027
|
+
### Fragment: `AttributeRangeBounds` on `AttributeRangeBounds`
|
|
4028
|
+
|
|
4029
|
+
**Section**: Attribute Filters
|
|
4030
|
+
|
|
4031
|
+
**Description**: Numeric range bounds for slider-style filters — min, max, currency code (when relevant).
|
|
4032
|
+
|
|
4033
|
+
**GraphQL**:
|
|
4034
|
+
```graphql
|
|
4035
|
+
fragment AttributeRangeBounds on AttributeRangeBounds {
|
|
4036
|
+
min
|
|
4037
|
+
max
|
|
4038
|
+
currencyCode
|
|
4039
|
+
}
|
|
4040
|
+
```
|
|
4041
|
+
|
|
4042
|
+
### Fragment: `AttributeFilterValue` on `AttributeFilterValue`
|
|
4043
|
+
|
|
4044
|
+
**Section**: Attribute Filters
|
|
4045
|
+
|
|
4046
|
+
**Description**: One discrete value in a filterable attribute (e.g. "Red" for the Color filter). Includes `productCount` in the current listing context (for "(12)" badges next to filter values), optional swatch and price modifier.
|
|
4047
|
+
|
|
4048
|
+
**Uses fragments**: `AttributeSwatch`, `Money`
|
|
4049
|
+
|
|
4050
|
+
**GraphQL**:
|
|
4051
|
+
```graphql
|
|
4052
|
+
fragment AttributeFilterValue on AttributeFilterValue {
|
|
4053
|
+
id
|
|
4054
|
+
value
|
|
4055
|
+
label
|
|
4056
|
+
productCount
|
|
4057
|
+
swatch {
|
|
4058
|
+
...AttributeSwatch
|
|
4059
|
+
}
|
|
4060
|
+
priceModifier {
|
|
4061
|
+
...Money
|
|
4062
|
+
}
|
|
4063
|
+
sortOrder
|
|
4064
|
+
}
|
|
4065
|
+
```
|
|
4066
|
+
|
|
4067
|
+
### Fragment: `AttributeDefinition` on `AttributeDefinition`
|
|
4068
|
+
|
|
4069
|
+
**Section**: Attribute Filters
|
|
4070
|
+
|
|
4071
|
+
**Description**: Filterable attribute exposed on the storefront — name, type (SELECT / CHECKBOX / SLIDER / etc.), filterability flags, display order, and either discrete `filterValues[]` or numeric `rangeBounds`. Spread inside `availableFilters.attributes[]`.
|
|
4072
|
+
|
|
4073
|
+
**Uses fragments**: `AttributeFilterValue`, `AttributeRangeBounds`
|
|
4074
|
+
|
|
4075
|
+
**GraphQL**:
|
|
4076
|
+
```graphql
|
|
4077
|
+
fragment AttributeDefinition on AttributeDefinition {
|
|
4078
|
+
id
|
|
4079
|
+
name
|
|
4080
|
+
handle
|
|
4081
|
+
type
|
|
4082
|
+
isFilterable
|
|
4083
|
+
isVisible
|
|
4084
|
+
displayOrder
|
|
4085
|
+
filterValues {
|
|
4086
|
+
...AttributeFilterValue
|
|
4087
|
+
}
|
|
4088
|
+
rangeBounds {
|
|
4089
|
+
...AttributeRangeBounds
|
|
4090
|
+
}
|
|
4091
|
+
}
|
|
4092
|
+
```
|
|
4093
|
+
|
|
4094
|
+
### Fragment: `PriceRangeFilter` on `PriceRange`
|
|
4095
|
+
|
|
4096
|
+
**Section**: Attribute Filters
|
|
4097
|
+
|
|
4098
|
+
**Description**: Min / max price range across products in the current listing context. Use to bound the price slider.
|
|
4099
|
+
|
|
4100
|
+
**Uses fragments**: `Money`
|
|
4101
|
+
|
|
4102
|
+
**GraphQL**:
|
|
4103
|
+
```graphql
|
|
4104
|
+
fragment PriceRangeFilter on PriceRange {
|
|
4105
|
+
min {
|
|
4106
|
+
...Money
|
|
4107
|
+
}
|
|
4108
|
+
max {
|
|
4109
|
+
...Money
|
|
4110
|
+
}
|
|
4111
|
+
}
|
|
4112
|
+
```
|
|
4113
|
+
|
|
4114
|
+
### Fragment: `CategoryFilterOption` on `CategoryFilterOption`
|
|
4115
|
+
|
|
4116
|
+
**Section**: Attribute Filters
|
|
4117
|
+
|
|
4118
|
+
**Description**: One category option in the categories filter — id, name, slug, count of products in this category within the current listing context, level + parentId for tree rendering.
|
|
4119
|
+
|
|
4120
|
+
**GraphQL**:
|
|
4121
|
+
```graphql
|
|
4122
|
+
fragment CategoryFilterOption on CategoryFilterOption {
|
|
4123
|
+
id
|
|
4124
|
+
name
|
|
4125
|
+
slug
|
|
4126
|
+
productCount
|
|
4127
|
+
level
|
|
4128
|
+
parentId
|
|
4129
|
+
}
|
|
4130
|
+
```
|
|
4131
|
+
|
|
4132
|
+
### Fragment: `AvailableFilters` on `AvailableFilters`
|
|
4133
|
+
|
|
4134
|
+
**Section**: Attribute Filters
|
|
4135
|
+
|
|
4136
|
+
**Description**: Full result of the `availableFilters($input)` query — attribute filters, price range, category filters, count of currently active filters, total products matching the context. Spread on listing pages to render filter sidebars.
|
|
4137
|
+
|
|
4138
|
+
**Uses fragments**: `AttributeDefinition`, `CategoryFilterOption`, `PriceRangeFilter`
|
|
4139
|
+
|
|
4140
|
+
**GraphQL**:
|
|
4141
|
+
```graphql
|
|
4142
|
+
fragment AvailableFilters on AvailableFilters {
|
|
4143
|
+
attributes {
|
|
4144
|
+
...AttributeDefinition
|
|
4145
|
+
}
|
|
4146
|
+
priceRange {
|
|
4147
|
+
...PriceRangeFilter
|
|
4148
|
+
}
|
|
4149
|
+
categories {
|
|
4150
|
+
...CategoryFilterOption
|
|
4151
|
+
}
|
|
4152
|
+
activeFilterCount
|
|
4153
|
+
totalProducts
|
|
4154
|
+
}
|
|
4155
|
+
```
|
|
4156
|
+
|
|
4157
|
+
### Fragment: `LoyaltyPageInfo` on `LoyaltyPageInfo`
|
|
4158
|
+
|
|
4159
|
+
**Section**: Loyalty Program
|
|
4160
|
+
|
|
4161
|
+
**Description**: Page metadata for the loyalty transactions connection (separate type from generic `PageInfo` for legacy reasons; identical shape).
|
|
4162
|
+
|
|
4163
|
+
**GraphQL**:
|
|
4164
|
+
```graphql
|
|
4165
|
+
fragment LoyaltyPageInfo on LoyaltyPageInfo {
|
|
4166
|
+
hasNextPage
|
|
4167
|
+
hasPreviousPage
|
|
4168
|
+
startCursor
|
|
4169
|
+
endCursor
|
|
4170
|
+
}
|
|
4171
|
+
```
|
|
4172
|
+
|
|
4173
|
+
### Fragment: `LoyaltyTier` on `LoyaltyTier`
|
|
4174
|
+
|
|
4175
|
+
**Section**: Loyalty Program
|
|
4176
|
+
|
|
4177
|
+
**Description**: Loyalty tier definition — name, type enum (`BRONZE` / `SILVER` / `GOLD` / `PLATINUM` / `DIAMOND`), entry threshold (`minPoints` and/or `minAnnualSpend`), points multiplier, custom benefits list. Returned by `loyaltyTiers` and embedded in member tier data.
|
|
4178
|
+
|
|
4179
|
+
**Uses fragments**: `Money`
|
|
4180
|
+
|
|
4181
|
+
**GraphQL**:
|
|
4182
|
+
```graphql
|
|
4183
|
+
fragment LoyaltyTier on LoyaltyTier {
|
|
4184
|
+
id
|
|
4185
|
+
name
|
|
4186
|
+
type
|
|
4187
|
+
minPoints
|
|
4188
|
+
minAnnualSpend {
|
|
4189
|
+
...Money
|
|
4190
|
+
}
|
|
4191
|
+
pointsMultiplier
|
|
4192
|
+
customBenefits {
|
|
4193
|
+
name
|
|
4194
|
+
description
|
|
4195
|
+
icon
|
|
4196
|
+
}
|
|
4197
|
+
}
|
|
4198
|
+
```
|
|
4199
|
+
|
|
4200
|
+
### Fragment: `LoyaltyPointsSummary` on `LoyaltyPointsSummary`
|
|
4201
|
+
|
|
4202
|
+
**Section**: Loyalty Program
|
|
4203
|
+
|
|
4204
|
+
**Description**: Customer's points breakdown — total earned, currently spendable, pending (not yet vested), redeemed lifetime, expired lifetime, expiring soon, and the next expiry date. Spread inside `LoyaltyMember`.
|
|
4205
|
+
|
|
4206
|
+
**GraphQL**:
|
|
4207
|
+
```graphql
|
|
4208
|
+
fragment LoyaltyPointsSummary on LoyaltyPointsSummary {
|
|
4209
|
+
totalPoints
|
|
4210
|
+
currentPoints
|
|
4211
|
+
pendingPoints
|
|
4212
|
+
redeemedPoints
|
|
4213
|
+
expiredPoints
|
|
4214
|
+
expiringPoints
|
|
4215
|
+
nextExpiryDate
|
|
4216
|
+
}
|
|
4217
|
+
```
|
|
4218
|
+
|
|
4219
|
+
### Fragment: `TierProgress` on `TierProgress`
|
|
4220
|
+
|
|
4221
|
+
**Section**: Loyalty Program
|
|
4222
|
+
|
|
4223
|
+
**Description**: Customer's progress toward the next tier — current tier, next tier, points + spend remaining, percent progress. Use to render the "X points to GOLD" tracker.
|
|
4224
|
+
|
|
4225
|
+
**Uses fragments**: `LoyaltyTier`, `Money`
|
|
4226
|
+
|
|
4227
|
+
**GraphQL**:
|
|
4228
|
+
```graphql
|
|
4229
|
+
fragment TierProgress on TierProgress {
|
|
4230
|
+
currentTier {
|
|
4231
|
+
...LoyaltyTier
|
|
4232
|
+
}
|
|
4233
|
+
nextTier {
|
|
4234
|
+
...LoyaltyTier
|
|
4235
|
+
}
|
|
4236
|
+
pointsToNextTier
|
|
4237
|
+
progressPercent
|
|
4238
|
+
spendToNextTier {
|
|
4239
|
+
...Money
|
|
4240
|
+
}
|
|
4241
|
+
}
|
|
4242
|
+
```
|
|
4243
|
+
|
|
4244
|
+
### Fragment: `LoyaltyMember` on `LoyaltyMember`
|
|
4245
|
+
|
|
4246
|
+
**Section**: Loyalty Program
|
|
4247
|
+
|
|
4248
|
+
**Description**: Customer's loyalty membership — points summary, current tier, tier progress, annual spend, last activity. Returned by `loyaltyMember` (null if not enrolled).
|
|
4249
|
+
|
|
4250
|
+
**Uses fragments**: `LoyaltyPointsSummary`, `LoyaltyTier`, `Money`, `TierProgress`
|
|
4251
|
+
|
|
4252
|
+
**GraphQL**:
|
|
4253
|
+
```graphql
|
|
4254
|
+
fragment LoyaltyMember on LoyaltyMember {
|
|
4255
|
+
id
|
|
4256
|
+
customerId
|
|
4257
|
+
points {
|
|
4258
|
+
...LoyaltyPointsSummary
|
|
4259
|
+
}
|
|
4260
|
+
tier {
|
|
4261
|
+
...LoyaltyTier
|
|
4262
|
+
}
|
|
4263
|
+
tierProgress {
|
|
4264
|
+
...TierProgress
|
|
4265
|
+
}
|
|
4266
|
+
annualSpend {
|
|
4267
|
+
...Money
|
|
4268
|
+
}
|
|
4269
|
+
lastActivityAt
|
|
4270
|
+
enrolledAt
|
|
4271
|
+
}
|
|
4272
|
+
```
|
|
4273
|
+
|
|
4274
|
+
### Fragment: `LoyaltyTransaction` on `LoyaltyTransaction`
|
|
4275
|
+
|
|
4276
|
+
**Section**: Loyalty Program
|
|
4277
|
+
|
|
4278
|
+
**Description**: One row in the loyalty points history — type (`EARN_PURCHASE` / `EARN_SIGNUP` / `EARN_REFERRAL` / `EARN_REVIEW` / `EARN_BIRTHDAY` / `EARN_BONUS` / `REDEEM` / `EXPIRE` / `ADJUST` / `REFUND_REVERSAL`), points delta, balance after, source order, expiry. Spread on the loyalty dashboard transaction list.
|
|
4279
|
+
|
|
4280
|
+
**GraphQL**:
|
|
4281
|
+
```graphql
|
|
4282
|
+
fragment LoyaltyTransaction on LoyaltyTransaction {
|
|
4283
|
+
id
|
|
4284
|
+
type
|
|
4285
|
+
points
|
|
4286
|
+
balanceAfter
|
|
4287
|
+
orderId
|
|
4288
|
+
description
|
|
4289
|
+
expiresAt
|
|
4290
|
+
createdAt
|
|
4291
|
+
}
|
|
4292
|
+
```
|
|
4293
|
+
|
|
4294
|
+
### Fragment: `LoyaltyReward` on `LoyaltyReward`
|
|
4295
|
+
|
|
4296
|
+
**Section**: Loyalty Program
|
|
4297
|
+
|
|
4298
|
+
**Description**: Reward customers can redeem — name, type, points cost, discount value (% or fixed), tier requirement, availability flag, remaining redemptions. Spread on the rewards page.
|
|
4299
|
+
|
|
4300
|
+
**Uses fragments**: `ImageCard`, `LoyaltyTier`, `Money`
|
|
4301
|
+
|
|
4302
|
+
**GraphQL**:
|
|
4303
|
+
```graphql
|
|
4304
|
+
fragment LoyaltyReward on LoyaltyReward {
|
|
4305
|
+
id
|
|
4306
|
+
name
|
|
4307
|
+
slug
|
|
4308
|
+
type
|
|
4309
|
+
pointsCost
|
|
4310
|
+
discountPercent
|
|
4311
|
+
discountAmount {
|
|
4312
|
+
...Money
|
|
4313
|
+
}
|
|
4314
|
+
description
|
|
4315
|
+
image {
|
|
4316
|
+
...ImageCard
|
|
4317
|
+
}
|
|
4318
|
+
isAvailable
|
|
4319
|
+
tierRequired {
|
|
4320
|
+
...LoyaltyTier
|
|
4321
|
+
}
|
|
4322
|
+
redemptionsRemaining
|
|
4323
|
+
}
|
|
4324
|
+
```
|
|
4325
|
+
|
|
4326
|
+
### Fragment: `PointsEstimate` on `PointsEstimate`
|
|
4327
|
+
|
|
4328
|
+
**Section**: Loyalty Program
|
|
4329
|
+
|
|
4330
|
+
**Description**: Estimated points for an order — base points, bonus points (tier multiplier applied), total, multiplier used. Returned by `estimatePoints($orderTotal)` for "Earn X points" UI on cart/checkout.
|
|
4331
|
+
|
|
4332
|
+
**GraphQL**:
|
|
4333
|
+
```graphql
|
|
4334
|
+
fragment PointsEstimate on PointsEstimate {
|
|
4335
|
+
basePoints
|
|
4336
|
+
bonusPoints
|
|
4337
|
+
totalPoints
|
|
4338
|
+
multiplier
|
|
4339
|
+
}
|
|
4340
|
+
```
|
|
4341
|
+
|
|
4342
|
+
### Fragment: `LoyaltyAction` on `LoyaltyAction`
|
|
4343
|
+
|
|
4344
|
+
**Section**: Loyalty Program
|
|
4345
|
+
|
|
4346
|
+
**Description**: One earn action configured in the loyalty program — type (`PURCHASE` / `SIGNUP` / `REFERRAL` / `REVIEW` / `BIRTHDAY`), enabled flag, points granted.
|
|
4347
|
+
|
|
4348
|
+
**GraphQL**:
|
|
4349
|
+
```graphql
|
|
4350
|
+
fragment LoyaltyAction on LoyaltyAction {
|
|
4351
|
+
type
|
|
4352
|
+
isEnabled
|
|
4353
|
+
points
|
|
4354
|
+
}
|
|
4355
|
+
```
|
|
4356
|
+
|
|
4357
|
+
### Fragment: `LoyaltySettings` on `LoyaltySettings`
|
|
4358
|
+
|
|
4359
|
+
**Section**: Loyalty Program
|
|
4360
|
+
|
|
4361
|
+
**Description**: Loyalty program configuration — `isEnabled` (use to gate UI rendering), points name (e.g. "stars"), earn rate, expiry policy, available actions, referral settings. Returned by `loyaltySettings`.
|
|
4362
|
+
|
|
4363
|
+
**Uses fragments**: `LoyaltyAction`
|
|
4364
|
+
|
|
4365
|
+
**GraphQL**:
|
|
4366
|
+
```graphql
|
|
4367
|
+
fragment LoyaltySettings on LoyaltySettings {
|
|
4368
|
+
isEnabled
|
|
4369
|
+
pointsName
|
|
4370
|
+
pointsPerCurrency
|
|
4371
|
+
pointsExpiryMonths
|
|
4372
|
+
availableActions {
|
|
4373
|
+
...LoyaltyAction
|
|
4374
|
+
}
|
|
4375
|
+
referralEnabled
|
|
4376
|
+
referralPoints
|
|
4377
|
+
referralBonusPoints
|
|
4378
|
+
}
|
|
4379
|
+
```
|
|
4380
|
+
|
|
4381
|
+
### Fragment: `ReferralStats` on `ReferralStats`
|
|
4382
|
+
|
|
4383
|
+
**Section**: Loyalty Program
|
|
4384
|
+
|
|
4385
|
+
**Description**: Customer referral statistics — code, share URL, counts of referred / completed / pending, lifetime points earned. Returned by `referralStats`.
|
|
4386
|
+
|
|
4387
|
+
**GraphQL**:
|
|
4388
|
+
```graphql
|
|
4389
|
+
fragment ReferralStats on ReferralStats {
|
|
4390
|
+
referralCode
|
|
4391
|
+
shareUrl
|
|
4392
|
+
totalReferred
|
|
4393
|
+
completedReferrals
|
|
4394
|
+
pendingReferrals
|
|
4395
|
+
totalPointsEarned
|
|
4396
|
+
}
|
|
4397
|
+
```
|
|
4398
|
+
|
|
4399
|
+
### Fragment: `RedeemRewardPayload` on `RedeemRewardPayload`
|
|
4400
|
+
|
|
4401
|
+
**Section**: Loyalty Program
|
|
4402
|
+
|
|
4403
|
+
**Description**: Result of `redeemLoyaltyReward` — depending on the reward type, exactly one of `discountCode`, `productDiscountCode`, `giftCardCode` is populated. Apply the returned code on cart/checkout.
|
|
4404
|
+
|
|
4405
|
+
**GraphQL**:
|
|
4406
|
+
```graphql
|
|
4407
|
+
fragment RedeemRewardPayload on RedeemRewardPayload {
|
|
4408
|
+
success
|
|
4409
|
+
discountCode
|
|
4410
|
+
productDiscountCode
|
|
4411
|
+
giftCardCode
|
|
4412
|
+
userErrors
|
|
4413
|
+
}
|
|
4414
|
+
```
|
|
4415
|
+
|
|
4416
|
+
### Fragment: `GenerateReferralCodePayload` on `GenerateReferralCodePayload`
|
|
4417
|
+
|
|
4418
|
+
**Section**: Loyalty Program
|
|
4419
|
+
|
|
4420
|
+
**Description**: Result of `generateReferralCode` — the customer's referral code and shareable URL.
|
|
4421
|
+
|
|
4422
|
+
**GraphQL**:
|
|
4423
|
+
```graphql
|
|
4424
|
+
fragment GenerateReferralCodePayload on GenerateReferralCodePayload {
|
|
4425
|
+
success
|
|
4426
|
+
referralCode
|
|
4427
|
+
shareUrl
|
|
4428
|
+
userErrors
|
|
4429
|
+
}
|
|
4430
|
+
```
|
|
4431
|
+
|
|
4432
|
+
### Fragment: `ProductReview` on `ProductReview`
|
|
4433
|
+
|
|
4434
|
+
**Section**: Reviews
|
|
4435
|
+
|
|
4436
|
+
**Description**: Single product review — rating, title, body, optional pros/cons, image attachments, author, verified-purchase flag, helpful/unhelpful counts, optional merchant response. Only `APPROVED` reviews are exposed to the storefront.
|
|
4437
|
+
|
|
4438
|
+
**GraphQL**:
|
|
4439
|
+
```graphql
|
|
4440
|
+
fragment ProductReview on ProductReview {
|
|
4441
|
+
id
|
|
4442
|
+
productId
|
|
4443
|
+
rating
|
|
4444
|
+
title
|
|
4445
|
+
content
|
|
4446
|
+
pros
|
|
4447
|
+
cons
|
|
4448
|
+
images
|
|
4449
|
+
authorName
|
|
4450
|
+
isVerifiedPurchase
|
|
4451
|
+
helpfulCount
|
|
4452
|
+
unhelpfulCount
|
|
4453
|
+
response
|
|
4454
|
+
responseAt
|
|
4455
|
+
createdAt
|
|
4456
|
+
}
|
|
4457
|
+
```
|
|
4458
|
+
|
|
4459
|
+
### Fragment: `ReviewStats` on `ReviewStats`
|
|
4460
|
+
|
|
4461
|
+
**Section**: Reviews
|
|
4462
|
+
|
|
4463
|
+
**Description**: Aggregate review stats for a product — average rating, total count, distribution per star (1-5). Returned by `reviewStats($productId)`.
|
|
4464
|
+
|
|
4465
|
+
**GraphQL**:
|
|
4466
|
+
```graphql
|
|
4467
|
+
fragment ReviewStats on ReviewStats {
|
|
4468
|
+
averageRating
|
|
4469
|
+
totalCount
|
|
4470
|
+
fiveStarCount
|
|
4471
|
+
fourStarCount
|
|
4472
|
+
threeStarCount
|
|
4473
|
+
twoStarCount
|
|
4474
|
+
oneStarCount
|
|
4475
|
+
}
|
|
4476
|
+
```
|
|
4477
|
+
|
|
4478
|
+
### Fragment: `WishlistItem` on `WishlistItem`
|
|
4479
|
+
|
|
4480
|
+
**Section**: Wishlists
|
|
4481
|
+
|
|
4482
|
+
**Description**: One item in a wishlist — references the product and (optionally) a specific variant, snapshots the price at the time it was added, plus notification preferences (`notifyOnSale`, `notifyOnRestock`).
|
|
4483
|
+
|
|
4484
|
+
**Uses fragments**: `Money`, `ProductCard`
|
|
4485
|
+
|
|
4486
|
+
**GraphQL**:
|
|
4487
|
+
```graphql
|
|
4488
|
+
fragment WishlistItem on WishlistItem {
|
|
4489
|
+
id
|
|
4490
|
+
productId
|
|
4491
|
+
variantId
|
|
4492
|
+
product {
|
|
4493
|
+
...ProductCard
|
|
4494
|
+
}
|
|
4495
|
+
priceWhenAdded {
|
|
4496
|
+
...Money
|
|
4497
|
+
}
|
|
4498
|
+
notifyOnSale
|
|
4499
|
+
notifyOnRestock
|
|
4500
|
+
addedAt
|
|
4501
|
+
}
|
|
4502
|
+
```
|
|
4503
|
+
|
|
4504
|
+
### Fragment: `Wishlist` on `Wishlist`
|
|
4505
|
+
|
|
4506
|
+
**Section**: Wishlists
|
|
4507
|
+
|
|
4508
|
+
**Description**: A customer's wishlist — name, public/private flag, share token (when public), items, item count. Spread on the wishlists page.
|
|
4509
|
+
|
|
4510
|
+
**Uses fragments**: `WishlistItem`
|
|
4511
|
+
|
|
4512
|
+
**GraphQL**:
|
|
4513
|
+
```graphql
|
|
4514
|
+
fragment Wishlist on Wishlist {
|
|
4515
|
+
id
|
|
4516
|
+
name
|
|
4517
|
+
isPublic
|
|
4518
|
+
shareToken
|
|
4519
|
+
items {
|
|
4520
|
+
...WishlistItem
|
|
4521
|
+
}
|
|
4522
|
+
itemCount
|
|
4523
|
+
createdAt
|
|
4524
|
+
updatedAt
|
|
4525
|
+
}
|
|
4526
|
+
```
|
|
4527
|
+
|
|
4528
|
+
### Fragment: `BlogCategory` on `BlogCategory`
|
|
4529
|
+
|
|
4530
|
+
**Section**: Blog
|
|
4531
|
+
|
|
4532
|
+
**Description**: Blog category — name, slug, description, post count. Spread on category navigation and post category labels.
|
|
4533
|
+
|
|
4534
|
+
**GraphQL**:
|
|
4535
|
+
```graphql
|
|
4536
|
+
fragment BlogCategory on BlogCategory {
|
|
4537
|
+
id
|
|
4538
|
+
name
|
|
4539
|
+
slug
|
|
4540
|
+
description
|
|
4541
|
+
postCount
|
|
4542
|
+
}
|
|
4543
|
+
```
|
|
4544
|
+
|
|
4545
|
+
### Fragment: `BlogTag` on `BlogTag`
|
|
4546
|
+
|
|
4547
|
+
**Section**: Blog
|
|
4548
|
+
|
|
4549
|
+
**Description**: Blog tag — name, slug, post count. Spread on tag clouds and post tag labels.
|
|
4550
|
+
|
|
4551
|
+
**GraphQL**:
|
|
4552
|
+
```graphql
|
|
4553
|
+
fragment BlogTag on BlogTag {
|
|
4554
|
+
id
|
|
4555
|
+
name
|
|
4556
|
+
slug
|
|
4557
|
+
postCount
|
|
4558
|
+
}
|
|
4559
|
+
```
|
|
4560
|
+
|
|
4561
|
+
### Fragment: `BlogPost` on `BlogPost`
|
|
4562
|
+
|
|
4563
|
+
**Section**: Blog
|
|
4564
|
+
|
|
4565
|
+
**Description**: Full blog post — title, slug, excerpt, content (with `contentFormat` indicating HTML/Markdown), featured image, author, category, tags, publish date, reading time, view + comment counts, SEO metadata. Spread on the post detail page.
|
|
4566
|
+
|
|
4567
|
+
**Uses fragments**: `BlogCategory`, `BlogTag`, `ImageCard`, `ImageThumbnail`
|
|
4568
|
+
|
|
4569
|
+
**GraphQL**:
|
|
4570
|
+
```graphql
|
|
4571
|
+
fragment BlogPost on BlogPost {
|
|
4572
|
+
id
|
|
4573
|
+
title
|
|
4574
|
+
slug
|
|
4575
|
+
excerpt
|
|
4576
|
+
content
|
|
4577
|
+
contentFormat
|
|
4578
|
+
featuredImage {
|
|
4579
|
+
...ImageCard
|
|
4580
|
+
}
|
|
4581
|
+
author {
|
|
4582
|
+
id
|
|
4583
|
+
name
|
|
4584
|
+
bio
|
|
4585
|
+
avatar {
|
|
4586
|
+
...ImageThumbnail
|
|
4587
|
+
}
|
|
4588
|
+
}
|
|
4589
|
+
category {
|
|
4590
|
+
...BlogCategory
|
|
4591
|
+
}
|
|
4592
|
+
tags {
|
|
4593
|
+
...BlogTag
|
|
4594
|
+
}
|
|
4595
|
+
publishedAt
|
|
4596
|
+
readingTimeMinutes
|
|
4597
|
+
viewCount
|
|
4598
|
+
commentCount
|
|
4599
|
+
allowComments
|
|
4600
|
+
isFeatured
|
|
4601
|
+
status
|
|
4602
|
+
seo {
|
|
4603
|
+
title
|
|
4604
|
+
description
|
|
4605
|
+
}
|
|
4606
|
+
createdAt
|
|
4607
|
+
updatedAt
|
|
4608
|
+
}
|
|
4609
|
+
```
|
|
4610
|
+
|
|
4611
|
+
### Fragment: `ProductRecommendation` on `ProductRecommendation`
|
|
4612
|
+
|
|
4613
|
+
**Section**: Recommendations
|
|
4614
|
+
|
|
4615
|
+
**Description**: One recommended product — the product itself (card-level), recommendation type (e.g. SIMILAR / FREQUENTLY_BOUGHT_TOGETHER), score (0-100), human reason text. Spread on PDP "You may also like" sections.
|
|
4616
|
+
|
|
4617
|
+
**Uses fragments**: `ProductCard`
|
|
4618
|
+
|
|
4619
|
+
**GraphQL**:
|
|
4620
|
+
```graphql
|
|
4621
|
+
fragment ProductRecommendation on ProductRecommendation {
|
|
4622
|
+
product {
|
|
4623
|
+
...ProductCard
|
|
4624
|
+
}
|
|
4625
|
+
type
|
|
4626
|
+
score
|
|
4627
|
+
reason
|
|
4628
|
+
}
|
|
4629
|
+
```
|
|
4630
|
+
|
|
4631
|
+
### Fragment: `CartRecommendation` on `CartRecommendations`
|
|
4632
|
+
|
|
4633
|
+
**Section**: Recommendations
|
|
4634
|
+
|
|
4635
|
+
**Description**: Recommendations bundle for the cart drawer — `frequentlyBoughtTogether` (cross-sell) and `youMayAlsoLike` (related). Each entry has the same shape as `ProductRecommendation`.
|
|
4636
|
+
|
|
4637
|
+
**Uses fragments**: `ProductCard`
|
|
4638
|
+
|
|
4639
|
+
**GraphQL**:
|
|
4640
|
+
```graphql
|
|
4641
|
+
fragment CartRecommendation on CartRecommendations {
|
|
4642
|
+
frequentlyBoughtTogether {
|
|
4643
|
+
product {
|
|
4644
|
+
...ProductCard
|
|
4645
|
+
}
|
|
4646
|
+
type
|
|
4647
|
+
score
|
|
4648
|
+
reason
|
|
4649
|
+
}
|
|
4650
|
+
youMayAlsoLike {
|
|
4651
|
+
product {
|
|
4652
|
+
...ProductCard
|
|
4653
|
+
}
|
|
4654
|
+
type
|
|
4655
|
+
score
|
|
4656
|
+
reason
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
```
|
|
4660
|
+
|
|
4661
|
+
### Fragment: `LocationAddress` on `LocationAddress`
|
|
4662
|
+
|
|
4663
|
+
**Section**: Store Availability (BOPIS / multi-location)
|
|
4664
|
+
|
|
4665
|
+
**Description**: Field-access notes: - `isAvailable` — always public. - `pickupTime` — public, localized merchant-configured string. - `availableStock` — token-gated (null for anonymous, integer for authenticated customers). - `location` — public, includes coords + business hours when configured. Physical location address — street, city, country, state, postal code, phone, lat/lng, formatted single-line representation. Spread inside `Location.address`.
|
|
4666
|
+
|
|
4667
|
+
**GraphQL**:
|
|
4668
|
+
```graphql
|
|
4669
|
+
fragment LocationAddress on LocationAddress {
|
|
4670
|
+
streetLine1
|
|
4671
|
+
streetLine2
|
|
4672
|
+
city
|
|
4673
|
+
country
|
|
4674
|
+
countryCode
|
|
4675
|
+
state
|
|
4676
|
+
stateCode
|
|
4677
|
+
postalCode
|
|
4678
|
+
phone
|
|
4679
|
+
latitude
|
|
4680
|
+
longitude
|
|
4681
|
+
formatted
|
|
4682
|
+
}
|
|
4683
|
+
```
|
|
4684
|
+
|
|
4685
|
+
### Fragment: `BusinessHoursWindow` on `BusinessHoursWindow`
|
|
4686
|
+
|
|
4687
|
+
**Section**: Store Availability (BOPIS / multi-location)
|
|
4688
|
+
|
|
4689
|
+
**Description**: One day's open/close window inside `BusinessHours` (24h clock).
|
|
4690
|
+
|
|
4691
|
+
**GraphQL**:
|
|
4692
|
+
```graphql
|
|
4693
|
+
fragment BusinessHoursWindow on BusinessHoursWindow {
|
|
4694
|
+
openHour
|
|
4695
|
+
closeHour
|
|
4696
|
+
}
|
|
4697
|
+
```
|
|
4698
|
+
|
|
4699
|
+
### Fragment: `BusinessHours` on `BusinessHours`
|
|
4700
|
+
|
|
4701
|
+
**Section**: Store Availability (BOPIS / multi-location)
|
|
4702
|
+
|
|
4703
|
+
**Description**: Weekly business hours — one window per day. Spread inside `Location.businessHours`.
|
|
4704
|
+
|
|
4705
|
+
**Uses fragments**: `BusinessHoursWindow`
|
|
4706
|
+
|
|
4707
|
+
**GraphQL**:
|
|
4708
|
+
```graphql
|
|
4709
|
+
fragment BusinessHours on BusinessHours {
|
|
4710
|
+
monday {
|
|
4711
|
+
...BusinessHoursWindow
|
|
4712
|
+
}
|
|
4713
|
+
tuesday {
|
|
4714
|
+
...BusinessHoursWindow
|
|
4715
|
+
}
|
|
4716
|
+
wednesday {
|
|
4717
|
+
...BusinessHoursWindow
|
|
4718
|
+
}
|
|
4719
|
+
thursday {
|
|
4720
|
+
...BusinessHoursWindow
|
|
4721
|
+
}
|
|
4722
|
+
friday {
|
|
4723
|
+
...BusinessHoursWindow
|
|
4724
|
+
}
|
|
4725
|
+
saturday {
|
|
4726
|
+
...BusinessHoursWindow
|
|
4727
|
+
}
|
|
4728
|
+
sunday {
|
|
4729
|
+
...BusinessHoursWindow
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4732
|
+
```
|
|
4733
|
+
|
|
4734
|
+
### Fragment: `Location` on `Location`
|
|
4735
|
+
|
|
4736
|
+
**Section**: Store Availability (BOPIS / multi-location)
|
|
4737
|
+
|
|
4738
|
+
**Description**: Physical store / pickup location — name, type (RETAIL / WAREHOUSE / PICKUP_POINT), address, business hours, pickup support flag + instructions, timezone. Spread on the store picker and location detail pages.
|
|
4739
|
+
|
|
4740
|
+
**Uses fragments**: `BusinessHours`, `LocationAddress`
|
|
4741
|
+
|
|
4742
|
+
**GraphQL**:
|
|
4743
|
+
```graphql
|
|
4744
|
+
fragment Location on Location {
|
|
4745
|
+
id
|
|
4746
|
+
name
|
|
4747
|
+
type
|
|
4748
|
+
supportsPickup
|
|
4749
|
+
timezone
|
|
4750
|
+
pickupInstructions
|
|
4751
|
+
address {
|
|
4752
|
+
...LocationAddress
|
|
4753
|
+
}
|
|
4754
|
+
businessHours {
|
|
4755
|
+
...BusinessHours
|
|
4756
|
+
}
|
|
4757
|
+
}
|
|
4758
|
+
```
|
|
4759
|
+
|
|
4760
|
+
### Fragment: `StoreAvailability` on `StoreAvailability`
|
|
4761
|
+
|
|
4762
|
+
**Section**: Store Availability (BOPIS / multi-location)
|
|
4763
|
+
|
|
4764
|
+
**Description**: Per-location stock entry for one variant — availability flag, stock quantity (token-gated), pickup time, full location detail. Spread inside `StoreAvailabilityConnection.edges[].node`.
|
|
4765
|
+
|
|
4766
|
+
**Uses fragments**: `Location`
|
|
4767
|
+
|
|
4768
|
+
**GraphQL**:
|
|
4769
|
+
```graphql
|
|
4770
|
+
fragment StoreAvailability on StoreAvailability {
|
|
4771
|
+
isAvailable
|
|
4772
|
+
availableStock
|
|
4773
|
+
pickupTime
|
|
4774
|
+
location {
|
|
4775
|
+
...Location
|
|
4776
|
+
}
|
|
4777
|
+
}
|
|
4778
|
+
```
|
|
4779
|
+
|
|
4780
|
+
### Fragment: `StoreAvailabilityConnection` on `StoreAvailabilityConnection`
|
|
4781
|
+
|
|
4782
|
+
**Section**: Store Availability (BOPIS / multi-location)
|
|
4783
|
+
|
|
4784
|
+
**Description**: Relay connection of `StoreAvailability` entries for a variant — used inside the `VariantStoreAvailability` fragment. Pre-paginated to 10 by default.
|
|
4785
|
+
|
|
4786
|
+
**Uses fragments**: `PageInfo`, `StoreAvailability`
|
|
4787
|
+
|
|
4788
|
+
**GraphQL**:
|
|
4789
|
+
```graphql
|
|
4790
|
+
fragment StoreAvailabilityConnection on StoreAvailabilityConnection {
|
|
4791
|
+
totalCount
|
|
4792
|
+
pageInfo {
|
|
4793
|
+
...PageInfo
|
|
4794
|
+
}
|
|
4795
|
+
edges {
|
|
4796
|
+
cursor
|
|
4797
|
+
node {
|
|
4798
|
+
...StoreAvailability
|
|
4799
|
+
}
|
|
4800
|
+
}
|
|
4801
|
+
}
|
|
4802
|
+
```
|
|
4803
|
+
|
|
4804
|
+
### Fragment: `VariantStoreAvailability` on `ProductVariant`
|
|
4805
|
+
|
|
4806
|
+
**Section**: Store Availability (BOPIS / multi-location)
|
|
4807
|
+
|
|
4808
|
+
**Description**: Slim variant projection optimized for the store-picker UI — id, title, sku, isAvailable, total `availableStock` plus per-location `storeAvailability` connection. Use in `productStoreAvailability` query.
|
|
4809
|
+
|
|
4810
|
+
**Uses fragments**: `StoreAvailabilityConnection`
|
|
4811
|
+
|
|
4812
|
+
**GraphQL**:
|
|
4813
|
+
```graphql
|
|
4814
|
+
fragment VariantStoreAvailability on ProductVariant {
|
|
4815
|
+
id
|
|
4816
|
+
title
|
|
4817
|
+
sku
|
|
4818
|
+
isAvailable
|
|
4819
|
+
availableStock
|
|
4820
|
+
storeAvailability(first: 10) {
|
|
4821
|
+
...StoreAvailabilityConnection
|
|
4822
|
+
}
|
|
4823
|
+
}
|
|
4824
|
+
```
|
|
4825
|
+
|
|
4826
|
+
### Fragment: `ShopPage` on `ShopPage`
|
|
4827
|
+
|
|
4828
|
+
**Section**: Pages
|
|
4829
|
+
|
|
4830
|
+
**Description**: CMS page — handle (URL slug), title, body (HTML), excerpt, SEO metadata, publish date. Spread on About / Privacy / Terms / Returns Policy pages.
|
|
4831
|
+
|
|
4832
|
+
**GraphQL**:
|
|
4833
|
+
```graphql
|
|
4834
|
+
fragment ShopPage on ShopPage {
|
|
4835
|
+
id
|
|
4836
|
+
handle
|
|
4837
|
+
title
|
|
4838
|
+
body
|
|
4839
|
+
excerpt
|
|
4840
|
+
seo {
|
|
4841
|
+
title
|
|
4842
|
+
description
|
|
4843
|
+
}
|
|
4844
|
+
publishedAt
|
|
4845
|
+
createdAt
|
|
4846
|
+
updatedAt
|
|
4847
|
+
}
|
|
4848
|
+
```
|
|
4849
|
+
|
|
4850
|
+
### Fragment: `MenuItem` on `MenuItem`
|
|
4851
|
+
|
|
4852
|
+
**Section**: Navigation Menus
|
|
4853
|
+
|
|
4854
|
+
**Description**: One menu item with up to 3 levels of nested children — title, URL, type (`HTTP` / `FRONTPAGE` / `SEARCH` / `CATALOG` / `BLOG` / `PRODUCT` / `COLLECTION` / `CATEGORY` / `PAGE`), `resourceId` for typed items, optional image. Switch on `type` to render the right link target.
|
|
4855
|
+
|
|
4856
|
+
**Uses fragments**: `Image`
|
|
4857
|
+
|
|
4858
|
+
**GraphQL**:
|
|
4859
|
+
```graphql
|
|
4860
|
+
fragment MenuItem on MenuItem {
|
|
4861
|
+
id
|
|
4862
|
+
title
|
|
4863
|
+
url
|
|
4864
|
+
type
|
|
4865
|
+
resourceId
|
|
4866
|
+
image {
|
|
4867
|
+
...Image
|
|
4868
|
+
}
|
|
4869
|
+
items {
|
|
4870
|
+
id
|
|
4871
|
+
title
|
|
4872
|
+
url
|
|
4873
|
+
type
|
|
4874
|
+
resourceId
|
|
4875
|
+
items {
|
|
4876
|
+
id
|
|
4877
|
+
title
|
|
4878
|
+
url
|
|
4879
|
+
type
|
|
4880
|
+
resourceId
|
|
4881
|
+
}
|
|
4882
|
+
}
|
|
4883
|
+
}
|
|
4884
|
+
```
|
|
4885
|
+
|
|
4886
|
+
### Fragment: `Menu` on `Menu`
|
|
4887
|
+
|
|
4888
|
+
**Section**: Navigation Menus
|
|
4889
|
+
|
|
4890
|
+
**Description**: Navigation menu — handle (e.g. "main-menu", "footer", "mobile"), title, nested item tree. Returned by `menu($handle)` query.
|
|
4891
|
+
|
|
4892
|
+
**Uses fragments**: `MenuItem`
|
|
4893
|
+
|
|
4894
|
+
**GraphQL**:
|
|
4895
|
+
```graphql
|
|
4896
|
+
fragment Menu on Menu {
|
|
4897
|
+
id
|
|
4898
|
+
handle
|
|
4899
|
+
title
|
|
4900
|
+
items {
|
|
4901
|
+
...MenuItem
|
|
4902
|
+
}
|
|
4903
|
+
}
|
|
4904
|
+
```
|
|
4905
|
+
|
|
4906
|
+
### Fragment: `UrlRedirect` on `UrlRedirect`
|
|
4907
|
+
|
|
4908
|
+
**Section**: URL Redirects
|
|
4909
|
+
|
|
4910
|
+
**Description**: Single legacy `path` → new `target` redirect entry. Use on the server / edge to issue 301 redirects for migrated routes.
|
|
4911
|
+
|
|
4912
|
+
**GraphQL**:
|
|
4913
|
+
```graphql
|
|
4914
|
+
fragment UrlRedirect on UrlRedirect {
|
|
4915
|
+
path
|
|
4916
|
+
target
|
|
4917
|
+
}
|
|
4918
|
+
```
|
|
4919
|
+
|
|
4920
|
+
### Fragment: `LinkedVariantSummary` on `LinkedVariantSummary`
|
|
4921
|
+
|
|
4922
|
+
**Section**: Product Configurator (per-product attributes)
|
|
4923
|
+
|
|
4924
|
+
**Description**: Slim variant snapshot linked from a configurator option — when an attribute option (e.g. "256 GB" storage) maps to a specific variant, this fragment exposes that variant's id, title, sku, stock flags. Spread inside `ProductAttributeOption.linkedVariant`.
|
|
4925
|
+
|
|
4926
|
+
**GraphQL**:
|
|
4927
|
+
```graphql
|
|
4928
|
+
fragment LinkedVariantSummary on LinkedVariantSummary {
|
|
4929
|
+
id
|
|
4930
|
+
productId
|
|
4931
|
+
title
|
|
4932
|
+
sku
|
|
4933
|
+
availableStock
|
|
4934
|
+
isAvailable
|
|
4935
|
+
trackQuantity
|
|
4936
|
+
}
|
|
4937
|
+
```
|
|
4938
|
+
|
|
4939
|
+
### Fragment: `ProductAttributeOption` on `ProductAttributeOption`
|
|
4940
|
+
|
|
4941
|
+
**Section**: Product Configurator (per-product attributes)
|
|
4942
|
+
|
|
4943
|
+
**Description**: One option (choice) within a configurator attribute — value, label, sort order, optional color hex, surcharge (amount + type), default flag, optional linked variant for variant-mapped options.
|
|
4944
|
+
|
|
4945
|
+
**Uses fragments**: `LinkedVariantSummary`
|
|
4946
|
+
|
|
4947
|
+
**GraphQL**:
|
|
4948
|
+
```graphql
|
|
4949
|
+
fragment ProductAttributeOption on ProductAttributeOption {
|
|
4950
|
+
id
|
|
4951
|
+
value
|
|
4952
|
+
label
|
|
4953
|
+
sortOrder
|
|
4954
|
+
colorHex
|
|
4955
|
+
surchargeAmount
|
|
4956
|
+
surchargeType
|
|
4957
|
+
isDefault
|
|
4958
|
+
linkedVariantId
|
|
4959
|
+
linkedVariant {
|
|
4960
|
+
...LinkedVariantSummary
|
|
4961
|
+
}
|
|
4962
|
+
}
|
|
4963
|
+
```
|
|
4964
|
+
|
|
4965
|
+
### Fragment: `ProductAttributeDefinition` on `ProductAttributeDefinition`
|
|
4966
|
+
|
|
4967
|
+
**Section**: Product Configurator (per-product attributes)
|
|
4968
|
+
|
|
4969
|
+
**Description**: Configurator attribute definition — name, type, fillingMode (CUSTOMER / MERCHANT / BOTH), billingMode, tax class, validation bounds, options (for choice-type attributes), required + visibility flags. Returned by `product.attributes(filter)` for the configurator UI.
|
|
4970
|
+
|
|
4971
|
+
**Uses fragments**: `ProductAttributeOption`
|
|
4972
|
+
|
|
4973
|
+
**GraphQL**:
|
|
4974
|
+
```graphql
|
|
4975
|
+
fragment ProductAttributeDefinition on ProductAttributeDefinition {
|
|
4976
|
+
id
|
|
4977
|
+
name
|
|
4978
|
+
slug
|
|
4979
|
+
description
|
|
4980
|
+
type
|
|
4981
|
+
fillingMode
|
|
4982
|
+
billingMode
|
|
4983
|
+
taxClassId
|
|
4984
|
+
scopeProductId
|
|
4985
|
+
isRequired
|
|
4986
|
+
isVisible
|
|
4987
|
+
displayOrder
|
|
4988
|
+
minValue
|
|
4989
|
+
maxValue
|
|
4990
|
+
options {
|
|
4991
|
+
...ProductAttributeOption
|
|
4992
|
+
}
|
|
4993
|
+
}
|
|
4994
|
+
```
|