@doswiftly/storefront-operations 16.1.0 → 17.0.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 +3 -3
- package/CHANGELOG.md +336 -0
- package/README.md +6 -3
- package/fragments.graphql +32 -1
- package/llms-full.txt +81 -6
- package/mutations.graphql +24 -2
- package/operations.json +50 -8
- package/package.json +1 -1
- package/schema.graphql +205 -9
package/AGENTS.md
CHANGED
|
@@ -27,10 +27,10 @@ consumer's `codegen.ts` references this package's `.graphql` files as
|
|
|
27
27
|
live in the consumer's repo.
|
|
28
28
|
|
|
29
29
|
<!-- AUTOGEN:STATS:BEGIN — auto-regenerated, do not edit by hand -->
|
|
30
|
-
- **Schema version**:
|
|
30
|
+
- **Schema version**: 17.0.0
|
|
31
31
|
- **Queries**: 52
|
|
32
|
-
- **Mutations**:
|
|
33
|
-
- **Fragments**:
|
|
32
|
+
- **Mutations**: 41
|
|
33
|
+
- **Fragments**: 104
|
|
34
34
|
<!-- AUTOGEN:STATS:END -->
|
|
35
35
|
|
|
36
36
|
## Loading order
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,341 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 17.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- d3f0f04: `cartSelectPaymentMethod` mutation is now method-centric.
|
|
8
|
+
|
|
9
|
+
The buyer picks a payment **category** (`BLIK`, `CARD`, `BANK_TRANSFER`, ...) and the backend resolves the preferred gateway from the merchant's `MerchantPaymentConfig` at `paymentCreate` time. Previously the storefront had to look up a per-provider tile UUID via `availablePaymentMethods` and pass it as `paymentMethodId`.
|
|
10
|
+
|
|
11
|
+
**Breaking** — `CartSelectPaymentMethodInput` shape changed:
|
|
12
|
+
|
|
13
|
+
```graphql
|
|
14
|
+
# Before
|
|
15
|
+
input CartSelectPaymentMethodInput {
|
|
16
|
+
cartId: ID!
|
|
17
|
+
paymentMethodId: ID! # UUID of a per-provider tile
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
# After
|
|
21
|
+
input CartSelectPaymentMethodInput {
|
|
22
|
+
cartId: ID!
|
|
23
|
+
methodType: PaymentMethodType! # BLIK, CARD, BANK_TRANSFER, ...
|
|
24
|
+
preferredProviderId: String # optional override (provider code)
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Migration:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// Before
|
|
32
|
+
await sdk.cartSelectPaymentMethod({ input: { cartId, paymentMethodId } });
|
|
33
|
+
|
|
34
|
+
// After
|
|
35
|
+
await sdk.cartSelectPaymentMethod({ input: { cartId, methodType: "BLIK" } });
|
|
36
|
+
// Or with explicit gateway override:
|
|
37
|
+
await sdk.cartSelectPaymentMethod({
|
|
38
|
+
input: { cartId, methodType: "BLIK", preferredProviderId: "payu" },
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The `availablePaymentMethods` query now returns deduplicated rows per `PaymentMethodType` (one row per BLIK, CARD, ...) with `providersAvailable` (gateway codes sorted by merchant priority) and `preferredProvider` (head of the list). The legacy `group: BY_PROVIDER` argument was removed — there is one canonical shape.
|
|
43
|
+
|
|
44
|
+
**Why** — A merchant configuring PayU + Przelewy24 would previously see "PayU BLIK" and "P24 BLIK" as two separate tiles on the storefront. After this change the storefront shows one BLIK tile; the merchant chooses which gateway handles BLIK via priority settings, and the buyer never sees the internal routing.
|
|
45
|
+
|
|
46
|
+
**Live capability sync (opt-in)** — gateway adapters may expose an optional `getAvailablePaymentMethods(credentials, { currency, amount, country })` capability returning the gateway-reported active methods (min/max amount, brand image, enabled flag). When supported, the platform caches the response per shop/currency and uses it to refine the storefront picker. Gateways without the capability fall back to a static capability matrix. Gateway HTTP failures are soft-failed — the buyer always sees the merchant's configured methods even when the upstream is temporarily unreachable.
|
|
47
|
+
|
|
48
|
+
- 7931668: Payment instrument preselection — direct deep-link to a specific instrument screen on the hosted gateway page (BLIK code, branded bank, wallet, card brand) instead of the gateway default landing.
|
|
49
|
+
|
|
50
|
+
**Why**: shoppers picking BLIK from the storefront UI now skip the gateway method picker entirely — the redirect lands directly on the BLIK code entry. Same flow for picking mBank, ING, Apple Pay, etc. Industry shorthand calls this "deep-link checkout" — 5-15% conversion uplift on single-instrument funnels.
|
|
51
|
+
|
|
52
|
+
**Breaking schema changes**:
|
|
53
|
+
1. `CartSelectPaymentMethodInput.preferredProviderId` → `preferredProviderCode`. Rename only — same semantics (override the merchant's preferred provider). Aligns with the `*Code` naming convention (`*Id` reserved for UUIDs, `*Code` for lowercase string identifiers like `payu` / `przelewy24`).
|
|
54
|
+
|
|
55
|
+
```graphql
|
|
56
|
+
# Before
|
|
57
|
+
input CartSelectPaymentMethodInput {
|
|
58
|
+
cartId: ID!
|
|
59
|
+
methodType: PaymentMethodType!
|
|
60
|
+
preferredProviderId: String # ← removed
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# After
|
|
64
|
+
input CartSelectPaymentMethodInput {
|
|
65
|
+
cartId: ID!
|
|
66
|
+
methodType: PaymentMethodType!
|
|
67
|
+
preferredProviderCode: String # ← renamed
|
|
68
|
+
preferredInstrumentCode: String # ← new (additive)
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
2. `PaymentMethod.provider` / `PaymentMethod.providersAvailable` / `PaymentMethod.preferredProvider` / `Order.paymentMethod` / `Payment.provider` are now the typed `ProviderCode` enum (UPPERCASE: `PAYU`, `PRZELEWY24`, `STRIPE`, `CASH_ON_DELIVERY`, `BANK_TRANSFER`, `MANUAL_PAYMENT`, `GIFT_CARD`, `TEST_GATEWAY`) instead of `String`. Replace any `if (provider === 'payu')` storefront branches with the imported enum.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
// Before
|
|
76
|
+
if (paymentMethod.provider === "payu") {
|
|
77
|
+
/* ... */
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// After
|
|
81
|
+
import { ProviderCode } from "@doswiftly/storefront-sdk";
|
|
82
|
+
if (paymentMethod.provider === ProviderCode.PAYU) {
|
|
83
|
+
/* ... */
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
3. `PaymentMethod.amountLimits` removed from the SDK fragment. The field still exists on the schema for backward-compat, but the SDK no longer selects it — most storefronts never used it and the data is provider-specific (PayU/P24 report limits per method, not per checkout). Re-add it to your local fragment if you need it.
|
|
88
|
+
|
|
89
|
+
**Additive (backward-compatible)**:
|
|
90
|
+
- `PaymentMethod.instruments: [PaymentMethodInstrument!]` — concrete instruments exposed by the gateway (BLIK code, branded banks, wallets, card brands). Each instrument carries `providerCode`, `instrumentCode`, `displayName`, `brandImageUrl`, `displayHint` (semantic UX hint: `PIN_ENTRY` / `WALLET_TAP` / `BANK_LIST` / `CARD_FORM`), `enabled`. `null` when the gateway doesn't expose granular data; empty array when all instruments are disabled.
|
|
91
|
+
- `cartSelectPaymentMethod(input: { preferredInstrumentCode })` — pass the chosen instrument's `instrumentCode` to persist it on the cart. Eager validation cross-checks against the gateway's live capabilities — invalid codes return `userErrors[].code = 'CART_INVALID_INSTRUMENT_CODE'`.
|
|
92
|
+
- `Cart.selectedPaymentInstrumentCode: String` — round-trips the persisted choice so the storefront can re-render the selected instrument on cart refresh.
|
|
93
|
+
- `Order.paymentInstrumentCode: String` — propagated from cart at `cartComplete`; the gateway adapter uses it to build the deep-link payload at `paymentCreate`.
|
|
94
|
+
|
|
95
|
+
**Usage example** — instrument-level deep-link checkout:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { useCartManager, ProviderCode } from "@doswiftly/storefront-sdk";
|
|
99
|
+
|
|
100
|
+
const { selectPaymentMethod, complete, createPayment } = useCartManager();
|
|
101
|
+
|
|
102
|
+
// 1. Render the instrument tiles from the gateway-reported list
|
|
103
|
+
const method = availablePaymentMethods.methods.find((m) => m.type === "BLIK");
|
|
104
|
+
const instrument = method?.instruments?.find(
|
|
105
|
+
(i) => i.instrumentCode === "blik",
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
// 2. Persist the buyer's choice on the cart
|
|
109
|
+
await selectPaymentMethod({
|
|
110
|
+
methodType: "BLIK",
|
|
111
|
+
preferredProviderCode: "payu",
|
|
112
|
+
preferredInstrumentCode: instrument.instrumentCode,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// 3. Complete the cart — instrument propagates to the Order
|
|
116
|
+
const { order } = await complete();
|
|
117
|
+
|
|
118
|
+
// 4. Initiate payment — gateway redirects directly to the BLIK code screen
|
|
119
|
+
const session = await createPayment(order.id);
|
|
120
|
+
window.location.href = session.redirectUrl;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Error handling**:
|
|
124
|
+
- `userErrors[].code === 'CART_INVALID_INSTRUMENT_CODE'` — instrument code is not available with the chosen provider (gateway disabled it, merchant config changed, typo). Refresh `availablePaymentMethods` and re-prompt the buyer.
|
|
125
|
+
- `paymentCreate` failed gateway initiation with the preselected instrument? The order's `paymentInstrumentCode` is automatically cleared (best-effort) — the next `paymentCreate` call falls back to the gateway default landing page. Storefront just retries.
|
|
126
|
+
|
|
127
|
+
**Rate limits**:
|
|
128
|
+
- `availablePaymentMethods` Query: 60 requests/min per IP+shop. Live capability lookups (OAuth + gateway list call) are expensive — hitting the limit returns `extensions.code: 'THROTTLED'` with `retryAfter`. Don't poll; cache the result for the duration of the checkout step.
|
|
129
|
+
|
|
130
|
+
**Gateway API version pinning**:
|
|
131
|
+
- PayU API pinned to `v2_1`, Przelewy24 API pinned to `v1`. When the upstream gateway ships a major version migration, the SDK / operations packages will bump major together with the constant update.
|
|
132
|
+
|
|
133
|
+
**Migration checklist for existing storefronts**:
|
|
134
|
+
- [ ] Rename `preferredProviderId` → `preferredProviderCode` everywhere in storefront mutations.
|
|
135
|
+
- [ ] Replace string comparisons (`provider === 'payu'`) with `ProviderCode` enum.
|
|
136
|
+
- [ ] Re-add `amountLimits` to your local PaymentMethod fragment if you used it.
|
|
137
|
+
- [ ] (Optional) Render the new `instruments` array as tiles to enable instrument-level deep-link checkout — 1-2 extra hours of UI work, measurable conversion impact on single-instrument flows.
|
|
138
|
+
|
|
139
|
+
### Minor Changes
|
|
140
|
+
|
|
141
|
+
- fd82b62: `PaymentMethod` type gains availability + amount limit fields.
|
|
142
|
+
|
|
143
|
+
The storefront `PaymentMethod` returned by `availablePaymentMethods` (and `Cart.availablePaymentMethods` / `Cart.selectedPaymentMethod`) now carries three additional fields:
|
|
144
|
+
- **`available: Boolean!`** — `false` when the resolving gateway is temporarily unavailable (incident, maintenance) or reported the method as disabled. Storefront should gray-out the tile instead of hiding it — gives merchants observability into routing failures.
|
|
145
|
+
- **`unavailableReason: PaymentMethodUnavailableReason`** — diagnostic enum (`GATEWAY_DOWN`, `GATEWAY_DISABLED`, `NO_INSTRUMENTS`, `CREDENTIALS_INVALID`). Null when `available` is true. Use for context-aware copy ("Provider is temporarily down" vs "Method not configured").
|
|
146
|
+
- **`amountLimits: PaymentMethodAmountLimits`** — gateway-reported min/max transaction amount in the resolving currency (e.g. BLIK 1-20000 PLN). Filter the picker against cart total. Null when the gateway does not report limits.
|
|
147
|
+
|
|
148
|
+
```graphql
|
|
149
|
+
fragment PaymentMethod on PaymentMethod {
|
|
150
|
+
# existing fields (id, name, provider, type, icon, ...)
|
|
151
|
+
providersAvailable
|
|
152
|
+
preferredProvider
|
|
153
|
+
available
|
|
154
|
+
unavailableReason
|
|
155
|
+
amountLimits {
|
|
156
|
+
min
|
|
157
|
+
max
|
|
158
|
+
currency
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Currency** is automatically resolved from the storefront context (cascade: `@inContext(currency:)` directive → `X-Preferred-Currency` header → cookie → `Accept-Language` → shop default). Override per query via the `@inContext(currency: "EUR")` directive — no new schema argument.
|
|
164
|
+
|
|
165
|
+
**Migration example** for storefront pickers:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
const { methods } = await sdk.cart.availablePaymentMethods();
|
|
169
|
+
return methods.map((method) => (
|
|
170
|
+
<PaymentTile
|
|
171
|
+
key={method.type}
|
|
172
|
+
type={method.type}
|
|
173
|
+
disabled={!method.available}
|
|
174
|
+
tooltip={method.unavailableReason && reasonCopy[method.unavailableReason]}
|
|
175
|
+
badge={method.amountLimits && cart.total > method.amountLimits.max ? 'Cart too large' : null}
|
|
176
|
+
/>
|
|
177
|
+
));
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Backend additionally sanitizes provider error messages (strips OAuth tokens, URLs, JSON secret keys, stack traces) before returning them in admin diagnostic responses — internal logs keep the full error for diagnostics.
|
|
181
|
+
|
|
182
|
+
- c878d14: Payment instrument preselection — storefront UX completion (distinct error code + warnings array + explicit deselect mutation).
|
|
183
|
+
|
|
184
|
+
**Why**: storefront dispatching dla instrument failure stał się context-aware. Dziś generic `PAYMENT_FAILED` post-auto-clear nie pozwalał odróżnić "instrument cleared, retry default landing OK" od "real gateway outage, retry kolejnym attempt". Plus brak explicit deselect — accordion "wróć do wyboru metody" UI wymagał hack typu re-select method.
|
|
185
|
+
|
|
186
|
+
**Additive (backward-compatible)**:
|
|
187
|
+
1. `PaymentErrorCode.INSTRUMENT_PRESELECTION_FAILED` — new enum value. Wystawiany po auto-clear `Order.paymentInstrumentCode` post-`InvalidPaymentInstrumentError`. Distinct od `PAYMENT_FAILED` (generic gateway failure fallback dla credentials / network / 5xx / circuit breaker).
|
|
188
|
+
2. `PaymentCreatePayload.warnings: [PaymentWarning!]!` — new field, default empty array. Emitted post-auto-clear z entry `{ code: INSTRUMENT_CLEARED_FOR_RETRY, message, retryHint: null }`. Storefront dispatches retry hint differently (accordion reset / progress bar / itp.).
|
|
189
|
+
3. `cartClearPaymentSelection(input: { cartId: ID! })` — new mutation. Atomic NULL across all payment selection fields. Idempotent. The cart must be `ACTIVE` — `CONVERTED` carts reject with `userErrors[0].code = 'ALREADY_COMPLETED'`. Rate limit 30/min.
|
|
190
|
+
|
|
191
|
+
**Storefront usage** — handle instrument failure z context-aware retry:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import {
|
|
195
|
+
useCartManager,
|
|
196
|
+
type CartMutationOutcome,
|
|
197
|
+
} from "@doswiftly/storefront-sdk";
|
|
198
|
+
|
|
199
|
+
const { selectPaymentMethod, clearPaymentSelection, createPayment } =
|
|
200
|
+
useCartManager();
|
|
201
|
+
|
|
202
|
+
// 1. Klient wybiera BLIK preselect
|
|
203
|
+
await selectPaymentMethod({
|
|
204
|
+
methodType: "BLIK",
|
|
205
|
+
preferredProviderCode: "payu",
|
|
206
|
+
preferredInstrumentCode: "blik",
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// 2. Try paymentCreate — może rzucić instrument-specific error
|
|
210
|
+
try {
|
|
211
|
+
const session = await createPayment(orderId);
|
|
212
|
+
window.location.href = session.redirectUrl;
|
|
213
|
+
} catch (err) {
|
|
214
|
+
if (err.userErrors?.[0]?.code === "INSTRUMENT_PRESELECTION_FAILED") {
|
|
215
|
+
// Backend auto-cleared instrument — show retry button
|
|
216
|
+
// Warning message available via err.warnings[0].message
|
|
217
|
+
showRetryUI({
|
|
218
|
+
title: "Instrument płatności niedostępny",
|
|
219
|
+
message: err.warnings?.[0]?.message ?? err.message,
|
|
220
|
+
onRetry: () => createPayment(orderId), // next attempt = default landing
|
|
221
|
+
});
|
|
222
|
+
} else if (err.userErrors?.[0]?.code === "PAYMENT_FAILED") {
|
|
223
|
+
// Generic gateway outage — retry z tym samym instrumentem
|
|
224
|
+
showOutageUI({
|
|
225
|
+
message: err.message,
|
|
226
|
+
onRetry: () => createPayment(orderId),
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// 3. Accordion "wróć do wyboru metody" — explicit deselect
|
|
232
|
+
await clearPaymentSelection({ cartId });
|
|
233
|
+
// Cart.selectedPaymentMethod === null, Cart.selectedPaymentInstrumentCode === null
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Migration guide for existing storefronts**:
|
|
237
|
+
- [ ] Add `warnings[]` to your `paymentCreate` selection set (if you use a custom GraphQL document instead of the SDK helpers).
|
|
238
|
+
- [ ] Branch UI dispatch on `userErrors[0].code === 'INSTRUMENT_PRESELECTION_FAILED'` distinct from `PAYMENT_FAILED`.
|
|
239
|
+
- [ ] (Optional) Replace any accordion-reset hack with `cartClearPaymentSelection({ cartId })` — clearer API, idempotent, single round-trip.
|
|
240
|
+
|
|
241
|
+
**Standards note**: splitting `userErrors[]` (blocking) and `warnings[]` (non-blocking) is a common e-commerce convention. The `INSTRUMENT_PRESELECTION_FAILED` semantics match retry-hint patterns used by major payment gateway SDKs (Stripe `payment_method_unavailable`, etc.).
|
|
242
|
+
|
|
243
|
+
- c553c80: Payment instrument preselection — cart re-validation stale signal + headless instrument components + browser data helper.
|
|
244
|
+
|
|
245
|
+
**Why**: previously the storefront kept showing an obsolete instrument selection until the buyer clicked "pay" — only then did the gateway reject it. The signal is now **proactive**: every cart query re-validates the selection against live gateway capabilities and emits a warning when the method or instrument disappeared. Plus a set of pre-built headless React components so the instrument picker no longer requires manual `displayHint` dispatch.
|
|
246
|
+
|
|
247
|
+
**Additive (backward-compatible)**:
|
|
248
|
+
1. `Cart.warnings: [CartWarning!]!` — new field, default empty array. Computed at query time. Currently emitted: `PAYMENT_SELECTION_STALE` (code) when `selectedPaymentMethod` or `selectedPaymentInstrumentCode` no longer matches live gateway capabilities. Read-only signal — backend persistence is preserved (clear via `cartClearPaymentSelection` or a fresh `cartSelectPaymentMethod`).
|
|
249
|
+
2. `Cart.selectedPaymentMethod` re-validation — when the method disappeared from live caps the field returns `null` plus a warning with `target: 'selectedPaymentMethod'`.
|
|
250
|
+
3. `Cart.selectedPaymentInstrumentCode` re-validation — when only the instrument disappeared (method preserved), the field returns `null` plus a warning with `target: 'selectedPaymentInstrumentCode'` (method-level signal stays intact). Backend persistence is preserved — a re-select gets a fresh state.
|
|
251
|
+
4. `CartWarningCode.PAYMENT_SELECTION_STALE` — new enum value in the existing `CartWarning` envelope.
|
|
252
|
+
5. Graceful degradation — when the live capability check fails (gateway timeout / network outage), `Cart` returns the existing selection without a warning (UX continuity over freshness; `cartComplete` time-of-payment validation is the final safety net).
|
|
253
|
+
6. `<PaymentInstrumentTile>` — new pre-built headless component. Single instrument button with full ARIA contract (`role="radio"`, `aria-checked`, `aria-label`, `data-instrument-code`, `data-display-hint`, `data-selected`). Zero opinionated styling — class props per part (button, icon, label). `displayHint` is emitted as a `data-display-hint` attribute so you can style via CSS attribute selectors.
|
|
254
|
+
7. `<PaymentInstrumentSection>` — new pre-built headless component. Radio-group container with keyboard navigation (ArrowUp/Down/Left/Right wrap, Home/End jump). Renders one `<PaymentInstrumentTile>` per instrument in the order received from `availablePaymentMethods` (no client-side resort — the backend ordering is the source of truth).
|
|
255
|
+
8. `getBrowserDataForPayment()` — new helper. Collects PSD2/3DS2 browser context (`userAgent`, `language`, screen dimensions, color depth, timezone offset, IANA timezone, `javaEnabled` fallback). Browser-only — throws `BrowserDataNotAvailableError` in SSR. Forward-looking utility for future 3DS challenge flows.
|
|
256
|
+
|
|
257
|
+
**Storefront usage** — listen to the stale signal in your cart query:
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
const { cart } = useCart(cartId);
|
|
261
|
+
|
|
262
|
+
const staleWarning = cart?.warnings?.find(
|
|
263
|
+
(w) => w.code === "PAYMENT_SELECTION_STALE",
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
if (staleWarning) {
|
|
267
|
+
// The backend signals that the buyer picked a method which is no longer
|
|
268
|
+
// available at the gateway — show a "pick another method" dialog.
|
|
269
|
+
// `target` distinguishes method vs instrument level:
|
|
270
|
+
if (staleWarning.target === "selectedPaymentMethod") {
|
|
271
|
+
// cart.selectedPaymentMethod === null — full re-select required
|
|
272
|
+
} else if (staleWarning.target === "selectedPaymentInstrumentCode") {
|
|
273
|
+
// cart.selectedPaymentMethod is still set, only the instrument cleared
|
|
274
|
+
}
|
|
275
|
+
// Backend persistence is preserved — `cartClearPaymentSelection` or
|
|
276
|
+
// a fresh `cartSelectPaymentMethod` is the consumer's responsibility.
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Storefront usage** — instrument picker with pre-built components:
|
|
281
|
+
|
|
282
|
+
```tsx
|
|
283
|
+
import { PaymentInstrumentSection } from "@doswiftly/storefront-sdk/react";
|
|
284
|
+
import { useState } from "react";
|
|
285
|
+
|
|
286
|
+
function CheckoutPaymentStep({ method }: { method: PaymentMethod }) {
|
|
287
|
+
const [instrumentCode, setInstrumentCode] = useState<string | undefined>(
|
|
288
|
+
undefined,
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<PaymentInstrumentSection
|
|
293
|
+
method={method}
|
|
294
|
+
selectedInstrumentCode={instrumentCode}
|
|
295
|
+
onSelectInstrument={(code) => {
|
|
296
|
+
setInstrumentCode(code);
|
|
297
|
+
cart.selectPaymentMethod({
|
|
298
|
+
methodType: method.type,
|
|
299
|
+
preferredProviderCode: method.preferredProvider,
|
|
300
|
+
preferredInstrumentCode: code,
|
|
301
|
+
});
|
|
302
|
+
}}
|
|
303
|
+
sectionClassName="grid grid-cols-2 gap-2"
|
|
304
|
+
tileClassName="rounded border p-3 hover:bg-gray-50 data-[selected=true]:border-blue-500"
|
|
305
|
+
labelClassName="font-semibold"
|
|
306
|
+
ariaLabel="Pick a payment instrument"
|
|
307
|
+
/>
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
**Storefront usage** — browser data for future 3DS flows:
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
import { getBrowserDataForPayment, BrowserDataNotAvailableError } from '@doswiftly/storefront-sdk/react';
|
|
316
|
+
|
|
317
|
+
function handleCheckoutSubmit() {
|
|
318
|
+
try {
|
|
319
|
+
const browserData = getBrowserDataForPayment();
|
|
320
|
+
// Pass to paymentCreate input when the gateway requires a 3DS challenge
|
|
321
|
+
await cart.createPayment({ ..., browserData });
|
|
322
|
+
} catch (err) {
|
|
323
|
+
if (err instanceof BrowserDataNotAvailableError) {
|
|
324
|
+
// SSR / no DOM — skip browser data; the gateway uses its default flow
|
|
325
|
+
}
|
|
326
|
+
throw err;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Migration checklist for existing storefronts**:
|
|
332
|
+
- [ ] Add `warnings { message code target }` to your cart query selection set (if you use a custom GraphQL document instead of the SDK fragments — SDK fragments are updated automatically).
|
|
333
|
+
- [ ] Branch UI on `cart.warnings[].code === 'PAYMENT_SELECTION_STALE'` to show a re-prompt dialog before checkout submit.
|
|
334
|
+
- [ ] (Optional) Replace a custom instrument picker with `<PaymentInstrumentSection>` — saves boilerplate, ships full ARIA + keyboard nav out of the box.
|
|
335
|
+
- [ ] (Forward-looking) Adopt `getBrowserDataForPayment()` in checkout submit handlers when 3DS flows become relevant (currently optional — the gateway accepts an undefined `browserData`).
|
|
336
|
+
|
|
337
|
+
**Standards reference**: `PaymentInstrumentSection` follows the WAI-ARIA radiogroup pattern (https://www.w3.org/WAI/ARIA/apg/patterns/radio/). The browser data helper shape matches the EMVCo 3DS2 BrowserData specification.
|
|
338
|
+
|
|
3
339
|
## 16.1.0
|
|
4
340
|
|
|
5
341
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -380,12 +380,13 @@ full executable body of each operation.
|
|
|
380
380
|
| `CartSetShippingAddress` | Phase 3 unify-cart-graphql-surface: wszystkie fulfillment + payment + completion operations teraz na Cart aggregate (zamiast Checkout dual-aggregate). Klient robi typowy checkout flow: cart create/add items → setShipping/Billing/Method → selectPayment → (optional) applyGiftCard → cartComplete → Order created. Sets the shipping address on the cart (full replace, not patch). Triggers cart re-pricing (tax recalculation per address country/region). Address format validated against `CartAddressInput` constraints (firstName/lastName/streetLine1/city/country/postalCode required). Errors: `INVALID_ADDRESS`, `CART_NOT_FOUND`. |
|
|
381
381
|
| `CartSetBillingAddress` | Sets the billing address on the cart (full replace). Independent of shipping address — pass it explicitly even when "billing same as shipping". Errors: `INVALID_ADDRESS`, `CART_NOT_FOUND`. |
|
|
382
382
|
| `CartSelectShippingMethod` | Selects a shipping method by `shippingMethodId` (typed `ID!`, a stable shipping-method UUID — NOT a per-request token). The id comes from a list of methods available for the current address + cart subtotal (queryable separately). Errors: `SHIPPING_METHOD_REQUIRED`, `ZIP_CODE_NOT_SUPPORTED`, `CART_NOT_FOUND`. |
|
|
383
|
-
| `CartSelectPaymentMethod` | Selects a payment method by `
|
|
383
|
+
| `CartSelectPaymentMethod` | Selects a payment method on the cart by category (`methodType` — BLIK, CARD, BANK_TRANSFER, ...). Optional `preferredProviderId` overrides the merchant priority when the buyer explicitly picks a gateway from `PaymentMethod.providersAvailable`. The backend resolves the gateway routing from `MerchantPaymentConfig` at `cartComplete`; the selection persisted here is the category. Errors: `PAYMENT_METHOD_REQUIRED`, `CART_NOT_FOUND`, `CART_UNAUTHENTICATED`. |
|
|
384
384
|
| `CartApplyGiftCard` | 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 at `cartComplete`. Errors: `GIFT_CARD_NOT_FOUND`, `GIFT_CARD_DEPLETED`, `GIFT_CARD_UNUSABLE`. |
|
|
385
385
|
| `CartRemoveGiftCard` | Removes a gift card from the applied list and recalculates FIFO `appliedAmount` for the remaining cards. Since gift card balances are only debited at `cartComplete`, removing before completion has no effect on the underlying gift card balance. |
|
|
386
386
|
| `CartUpdateGiftCardRecipient` | Sets per-line-item recipient details (name, email, message) for digital gift card products in the cart (line items where the variant represents a gift-card SKU). Required before `cartComplete` for any line item with a gift-card variant. Recipient details propagated to the resulting order. |
|
|
387
387
|
| `CartComplete` | Finalizes the cart — creates the `Order`, deducts gift cards, sends order-created confirmation — all atomically. **Idempotent on `idempotencyKey`** (auto-generated from cartId + minute timestamp if caller omits it). Returns `order` field after completion. Note: `paymentUrl` is intentionally NOT in payload — for hosted gateways (online providers) the storefront calls a separate `paymentCreate` mutation after this returns (check `order.canCreatePayment` first). Errors: `EMAIL_REQUIRED`, `SHIPPING_ADDRESS_REQUIRED`, `SHIPPING_METHOD_REQUIRED`, `PAYMENT_METHOD_REQUIRED`, `INSUFFICIENT_STOCK`, `ALREADY_COMPLETED`. |
|
|
388
|
-
| `PaymentCreate` | Initiates a payment session for an order created by `cartComplete` — call this when `order.canCreatePayment` is `true` (orders with an offline payment method like cash-on-delivery skip this step). `orderId` is required; `returnUrl` / `cancelUrl` are optional and, when supplied, must point to a verified domain of the shop (open-redirect protected). Branch on the returned `payment.flow`: `ONLINE_REDIRECT` → redirect to `payment.redirectUrl`, `ONLINE_EMBEDDED` → render a widget with `payment.clientSecret`, `INSTANT_DIRECT` → already settled, read `payment.status`. Public, but ownership-checked — an authenticated customer cannot pay for another customer's order. **Idempotent** — calling it again for the same order returns the existing still-valid session instead of creating a duplicate (safe to retry). Rate limit: 5 requests/minute. `userErrors[].code`: `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `INVALID_ID_FORMAT`, `PAYMENT_FAILED`. |
|
|
388
|
+
| `PaymentCreate` | Initiates a payment session for an order created by `cartComplete` — call this when `order.canCreatePayment` is `true` (orders with an offline payment method like cash-on-delivery skip this step). `orderId` is required; `returnUrl` / `cancelUrl` are optional and, when supplied, must point to a verified domain of the shop (open-redirect protected). Branch on the returned `payment.flow`: `ONLINE_REDIRECT` → redirect to `payment.redirectUrl`, `ONLINE_EMBEDDED` → render a widget with `payment.clientSecret`, `INSTANT_DIRECT` → already settled, read `payment.status`. Public, but ownership-checked — an authenticated customer cannot pay for another customer's order. **Idempotent** — calling it again for the same order returns the existing still-valid session instead of creating a duplicate (safe to retry). Rate limit: 5 requests/minute. `userErrors[].code`: `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `INVALID_ID_FORMAT`, `PAYMENT_FAILED`, `INSTRUMENT_PRESELECTION_FAILED`. `warnings[]` array zawiera `INSTRUMENT_CLEARED_FOR_RETRY` post-auto-clear instrument-specific failure (storefront retry hint: next attempt uses gateway default landing). |
|
|
389
|
+
| `CartClearPaymentSelection` | Clears all payment selection state on the cart in a single atomic operation. Use for accordion "back to method picker" flows w storefront UI. Idempotent — calling twice yields the same end state. Cart MUSI być `ACTIVE` (CONVERTED carts reject z `ALREADY_COMPLETED`). Rate limit: 30 requests/minute per IP+shop. |
|
|
389
390
|
|
|
390
391
|
#### Return Mutations
|
|
391
392
|
|
|
@@ -508,9 +509,11 @@ full executable body of each operation.
|
|
|
508
509
|
|
|
509
510
|
| Fragment | On Type | Description |
|
|
510
511
|
| --- | --- | --- |
|
|
511
|
-
| `
|
|
512
|
+
| `PaymentMethodInstrument` | `PaymentMethodInstrument` | A single concrete instrument exposed by a gateway provider (BLIK code, branded bank, wallet, card brand). Pass `instrumentCode` as `preferredInstrumentCode` in `cartSelectPaymentMethod` for direct deep-link to that instrument screen on the gateway. `displayHint` is a semantic UX hint (`PIN_ENTRY`, `WALLET_TAP`, `BANK_LIST`, `CARD_FORM`) — storefront branches rendering accordingly. `enabled: false` means the gateway reported the instrument as temporarily disabled — gray out, don't hide. |
|
|
513
|
+
| `PaymentMethod` | `PaymentMethod` | Single payment method enabled for the shop — method-centric. `type` is the category (CARD, BLIK, BANK_TRANSFER, CASH_ON_DELIVERY, OTHER) — drive iconography here. `provider`, `providersAvailable`, `preferredProvider` are `ProviderCode` enum (UPPERCASE: `PAYU`, `PRZELEWY24`, ...). `available` is `false` when the resolving gateway is temporarily unavailable or reported the method as disabled — gray-out the tile, don't hide it; `unavailableReason` carries the diagnostic. `instruments` lists concrete gateway-side instruments (BLIK code, branded banks, wallets) when the gateway exposes granular data — pass `instrumentCode` as `preferredInstrumentCode` in `cartSelectPaymentMethod` for direct deep-link to that instrument screen on the gateway. Spread on the checkout payment step. |
|
|
512
514
|
| `AvailablePaymentMethods` | `AvailablePaymentMethods` | Active payment methods list with the merchant's `defaultMethod`. Returned by the `availablePaymentMethods` query. |
|
|
513
515
|
| `PaymentSession` | `PaymentSession` | Initiated payment session for an order — returned by the `paymentCreate` mutation. Branch on `flow`: `ONLINE_REDIRECT` (redirect the browser to `redirectUrl`), `ONLINE_EMBEDDED` (render an in-page widget with `clientSecret`), `INSTANT_DIRECT` (settled with no UI — read `status`). `expiresAt` is ISO 8601, present when the gateway session has a TTL. |
|
|
516
|
+
| `PaymentWarning` | `PaymentWarning` | Non-blocking signal emitted alongside `userErrors[]` in `paymentCreate` payload — backend state change context (e.g. an auto-clear of preselected instrument after gateway rejection). Pre-translated by backend per shop locale. `code === 'INSTRUMENT_CLEARED_FOR_RETRY'` signals storefront that the next `paymentCreate` will land on the gateway default landing page (server-side cleared `Order.paymentInstrumentCode` after `INSTRUMENT_PRESELECTION_FAILED`). `retryHint` is optional context for UI dispatch — currently unused for `INSTRUMENT_CLEARED_FOR_RETRY`, reserved for future warning codes. |
|
|
514
517
|
|
|
515
518
|
#### Shipments / Tracking
|
|
516
519
|
|
package/fragments.graphql
CHANGED
|
@@ -510,6 +510,7 @@ fragment Cart on Cart {
|
|
|
510
510
|
selectedPaymentMethod {
|
|
511
511
|
...CartSelectedPaymentMethod
|
|
512
512
|
}
|
|
513
|
+
selectedPaymentInstrumentCode
|
|
513
514
|
appliedGiftCards {
|
|
514
515
|
...CartAppliedGiftCard
|
|
515
516
|
}
|
|
@@ -700,7 +701,23 @@ fragment ShopConfigFields on Shop {
|
|
|
700
701
|
# Payment Methods
|
|
701
702
|
# ============================================
|
|
702
703
|
|
|
703
|
-
#
|
|
704
|
+
# A single concrete instrument exposed by a gateway provider (BLIK code, branded bank, wallet, card brand). Pass `instrumentCode` as `preferredInstrumentCode` in `cartSelectPaymentMethod` for direct deep-link to that instrument screen on the gateway. `displayHint` is a semantic UX hint (`PIN_ENTRY`, `WALLET_TAP`, `BANK_LIST`, `CARD_FORM`) — storefront branches rendering accordingly. `enabled: false` means the gateway reported the instrument as temporarily disabled — gray out, don't hide.
|
|
705
|
+
fragment PaymentMethodInstrument on PaymentMethodInstrument {
|
|
706
|
+
providerCode
|
|
707
|
+
instrumentCode
|
|
708
|
+
type
|
|
709
|
+
displayName
|
|
710
|
+
displayHint
|
|
711
|
+
brandImageUrl
|
|
712
|
+
enabled
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
# Single payment method enabled for the shop — method-centric.
|
|
716
|
+
# `type` is the category (CARD, BLIK, BANK_TRANSFER, CASH_ON_DELIVERY, OTHER) — drive iconography here.
|
|
717
|
+
# `provider`, `providersAvailable`, `preferredProvider` are `ProviderCode` enum (UPPERCASE: `PAYU`, `PRZELEWY24`, ...).
|
|
718
|
+
# `available` is `false` when the resolving gateway is temporarily unavailable or reported the method as disabled — gray-out the tile, don't hide it; `unavailableReason` carries the diagnostic.
|
|
719
|
+
# `instruments` lists concrete gateway-side instruments (BLIK code, branded banks, wallets) when the gateway exposes granular data — pass `instrumentCode` as `preferredInstrumentCode` in `cartSelectPaymentMethod` for direct deep-link to that instrument screen on the gateway.
|
|
720
|
+
# Spread on the checkout payment step.
|
|
704
721
|
fragment PaymentMethod on PaymentMethod {
|
|
705
722
|
id
|
|
706
723
|
name
|
|
@@ -711,6 +728,13 @@ fragment PaymentMethod on PaymentMethod {
|
|
|
711
728
|
isDefault
|
|
712
729
|
supportedCurrencies
|
|
713
730
|
position
|
|
731
|
+
providersAvailable
|
|
732
|
+
preferredProvider
|
|
733
|
+
available
|
|
734
|
+
unavailableReason
|
|
735
|
+
instruments {
|
|
736
|
+
...PaymentMethodInstrument
|
|
737
|
+
}
|
|
714
738
|
}
|
|
715
739
|
|
|
716
740
|
# Active payment methods list with the merchant's `defaultMethod`. Returned by the `availablePaymentMethods` query.
|
|
@@ -735,6 +759,13 @@ fragment PaymentSession on PaymentSession {
|
|
|
735
759
|
expiresAt
|
|
736
760
|
}
|
|
737
761
|
|
|
762
|
+
# Non-blocking signal emitted alongside `userErrors[]` in `paymentCreate` payload — backend state change context (e.g. an auto-clear of preselected instrument after gateway rejection). Pre-translated by backend per shop locale. `code === 'INSTRUMENT_CLEARED_FOR_RETRY'` signals storefront that the next `paymentCreate` will land on the gateway default landing page (server-side cleared `Order.paymentInstrumentCode` after `INSTRUMENT_PRESELECTION_FAILED`). `retryHint` is optional context for UI dispatch — currently unused for `INSTRUMENT_CLEARED_FOR_RETRY`, reserved for future warning codes.
|
|
763
|
+
fragment PaymentWarning on PaymentWarning {
|
|
764
|
+
message
|
|
765
|
+
code
|
|
766
|
+
retryHint
|
|
767
|
+
}
|
|
768
|
+
|
|
738
769
|
# ============================================
|
|
739
770
|
# Discount Code Validation
|
|
740
771
|
# ============================================
|
package/llms-full.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# DoSwiftly Storefront Operations — Full Reference
|
|
2
2
|
|
|
3
|
-
> Schema version: **
|
|
4
|
-
> 52 queries ·
|
|
3
|
+
> Schema version: **17.0.0**
|
|
4
|
+
> 52 queries · 41 mutations · 104 fragments
|
|
5
5
|
|
|
6
6
|
Auto-generated from `.graphql` source files. Do not edit by hand — this file is
|
|
7
7
|
regenerated on every release to match the published schema.
|
|
@@ -1975,7 +1975,7 @@ mutation CartSelectShippingMethod($input: CartSelectShippingMethodInput!) {
|
|
|
1975
1975
|
|
|
1976
1976
|
**Section**: Cart Completion Mutations
|
|
1977
1977
|
|
|
1978
|
-
**Description**: Selects a payment method by `
|
|
1978
|
+
**Description**: Selects a payment method on the cart by category (`methodType` — BLIK, CARD, BANK_TRANSFER, ...). Optional `preferredProviderId` overrides the merchant priority when the buyer explicitly picks a gateway from `PaymentMethod.providersAvailable`. The backend resolves the gateway routing from `MerchantPaymentConfig` at `cartComplete`; the selection persisted here is the category. Errors: `PAYMENT_METHOD_REQUIRED`, `CART_NOT_FOUND`, `CART_UNAUTHENTICATED`.
|
|
1979
1979
|
|
|
1980
1980
|
**Variables**:
|
|
1981
1981
|
- `$input`: `CartSelectPaymentMethodInput!`
|
|
@@ -2115,12 +2115,12 @@ mutation CartComplete($input: CartCompleteInput!) {
|
|
|
2115
2115
|
|
|
2116
2116
|
**Section**: Cart Completion Mutations
|
|
2117
2117
|
|
|
2118
|
-
**Description**: Initiates a payment session for an order created by `cartComplete` — call this when `order.canCreatePayment` is `true` (orders with an offline payment method like cash-on-delivery skip this step). `orderId` is required; `returnUrl` / `cancelUrl` are optional and, when supplied, must point to a verified domain of the shop (open-redirect protected). Branch on the returned `payment.flow`: `ONLINE_REDIRECT` → redirect to `payment.redirectUrl`, `ONLINE_EMBEDDED` → render a widget with `payment.clientSecret`, `INSTANT_DIRECT` → already settled, read `payment.status`. Public, but ownership-checked — an authenticated customer cannot pay for another customer's order. **Idempotent** — calling it again for the same order returns the existing still-valid session instead of creating a duplicate (safe to retry). Rate limit: 5 requests/minute. `userErrors[].code`: `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `INVALID_ID_FORMAT`, `PAYMENT_FAILED`.
|
|
2118
|
+
**Description**: Initiates a payment session for an order created by `cartComplete` — call this when `order.canCreatePayment` is `true` (orders with an offline payment method like cash-on-delivery skip this step). `orderId` is required; `returnUrl` / `cancelUrl` are optional and, when supplied, must point to a verified domain of the shop (open-redirect protected). Branch on the returned `payment.flow`: `ONLINE_REDIRECT` → redirect to `payment.redirectUrl`, `ONLINE_EMBEDDED` → render a widget with `payment.clientSecret`, `INSTANT_DIRECT` → already settled, read `payment.status`. Public, but ownership-checked — an authenticated customer cannot pay for another customer's order. **Idempotent** — calling it again for the same order returns the existing still-valid session instead of creating a duplicate (safe to retry). Rate limit: 5 requests/minute. `userErrors[].code`: `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `INVALID_ID_FORMAT`, `PAYMENT_FAILED`, `INSTRUMENT_PRESELECTION_FAILED`. `warnings[]` array zawiera `INSTRUMENT_CLEARED_FOR_RETRY` post-auto-clear instrument-specific failure (storefront retry hint: next attempt uses gateway default landing).
|
|
2119
2119
|
|
|
2120
2120
|
**Variables**:
|
|
2121
2121
|
- `$input`: `PaymentCreateInput!`
|
|
2122
2122
|
|
|
2123
|
-
**Fragments used**: `PaymentSession`, `UserError`
|
|
2123
|
+
**Fragments used**: `PaymentSession`, `PaymentWarning`, `UserError`
|
|
2124
2124
|
|
|
2125
2125
|
**GraphQL**:
|
|
2126
2126
|
```graphql
|
|
@@ -2132,6 +2132,37 @@ mutation PaymentCreate($input: PaymentCreateInput!) {
|
|
|
2132
2132
|
userErrors {
|
|
2133
2133
|
...UserError
|
|
2134
2134
|
}
|
|
2135
|
+
warnings {
|
|
2136
|
+
...PaymentWarning
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
```
|
|
2141
|
+
|
|
2142
|
+
### Mutation: `CartClearPaymentSelection`
|
|
2143
|
+
|
|
2144
|
+
**Section**: Cart Completion Mutations
|
|
2145
|
+
|
|
2146
|
+
**Description**: Clears all payment selection state on the cart in a single atomic operation. Use for accordion "back to method picker" flows w storefront UI. Idempotent — calling twice yields the same end state. Cart MUSI być `ACTIVE` (CONVERTED carts reject z `ALREADY_COMPLETED`). Rate limit: 30 requests/minute per IP+shop.
|
|
2147
|
+
|
|
2148
|
+
**Variables**:
|
|
2149
|
+
- `$input`: `CartClearPaymentSelectionInput!`
|
|
2150
|
+
|
|
2151
|
+
**Fragments used**: `Cart`, `CartWarning`, `UserError`
|
|
2152
|
+
|
|
2153
|
+
**GraphQL**:
|
|
2154
|
+
```graphql
|
|
2155
|
+
mutation CartClearPaymentSelection($input: CartClearPaymentSelectionInput!) {
|
|
2156
|
+
cartClearPaymentSelection(input: $input) {
|
|
2157
|
+
cart {
|
|
2158
|
+
...Cart
|
|
2159
|
+
}
|
|
2160
|
+
userErrors {
|
|
2161
|
+
...UserError
|
|
2162
|
+
}
|
|
2163
|
+
warnings {
|
|
2164
|
+
...CartWarning
|
|
2165
|
+
}
|
|
2135
2166
|
}
|
|
2136
2167
|
}
|
|
2137
2168
|
```
|
|
@@ -3171,6 +3202,7 @@ fragment Cart on Cart {
|
|
|
3171
3202
|
selectedPaymentMethod {
|
|
3172
3203
|
...CartSelectedPaymentMethod
|
|
3173
3204
|
}
|
|
3205
|
+
selectedPaymentInstrumentCode
|
|
3174
3206
|
appliedGiftCards {
|
|
3175
3207
|
...CartAppliedGiftCard
|
|
3176
3208
|
}
|
|
@@ -3470,11 +3502,32 @@ fragment ShopConfigFields on Shop {
|
|
|
3470
3502
|
}
|
|
3471
3503
|
```
|
|
3472
3504
|
|
|
3505
|
+
### Fragment: `PaymentMethodInstrument` on `PaymentMethodInstrument`
|
|
3506
|
+
|
|
3507
|
+
**Section**: Payment Methods
|
|
3508
|
+
|
|
3509
|
+
**Description**: A single concrete instrument exposed by a gateway provider (BLIK code, branded bank, wallet, card brand). Pass `instrumentCode` as `preferredInstrumentCode` in `cartSelectPaymentMethod` for direct deep-link to that instrument screen on the gateway. `displayHint` is a semantic UX hint (`PIN_ENTRY`, `WALLET_TAP`, `BANK_LIST`, `CARD_FORM`) — storefront branches rendering accordingly. `enabled: false` means the gateway reported the instrument as temporarily disabled — gray out, don't hide.
|
|
3510
|
+
|
|
3511
|
+
**GraphQL**:
|
|
3512
|
+
```graphql
|
|
3513
|
+
fragment PaymentMethodInstrument on PaymentMethodInstrument {
|
|
3514
|
+
providerCode
|
|
3515
|
+
instrumentCode
|
|
3516
|
+
type
|
|
3517
|
+
displayName
|
|
3518
|
+
displayHint
|
|
3519
|
+
brandImageUrl
|
|
3520
|
+
enabled
|
|
3521
|
+
}
|
|
3522
|
+
```
|
|
3523
|
+
|
|
3473
3524
|
### Fragment: `PaymentMethod` on `PaymentMethod`
|
|
3474
3525
|
|
|
3475
3526
|
**Section**: Payment Methods
|
|
3476
3527
|
|
|
3477
|
-
**Description**: Single payment method enabled for the shop — type (CARD
|
|
3528
|
+
**Description**: Single payment method enabled for the shop — method-centric. `type` is the category (CARD, BLIK, BANK_TRANSFER, CASH_ON_DELIVERY, OTHER) — drive iconography here. `provider`, `providersAvailable`, `preferredProvider` are `ProviderCode` enum (UPPERCASE: `PAYU`, `PRZELEWY24`, ...). `available` is `false` when the resolving gateway is temporarily unavailable or reported the method as disabled — gray-out the tile, don't hide it; `unavailableReason` carries the diagnostic. `instruments` lists concrete gateway-side instruments (BLIK code, branded banks, wallets) when the gateway exposes granular data — pass `instrumentCode` as `preferredInstrumentCode` in `cartSelectPaymentMethod` for direct deep-link to that instrument screen on the gateway. Spread on the checkout payment step.
|
|
3529
|
+
|
|
3530
|
+
**Uses fragments**: `PaymentMethodInstrument`
|
|
3478
3531
|
|
|
3479
3532
|
**GraphQL**:
|
|
3480
3533
|
```graphql
|
|
@@ -3488,6 +3541,13 @@ fragment PaymentMethod on PaymentMethod {
|
|
|
3488
3541
|
isDefault
|
|
3489
3542
|
supportedCurrencies
|
|
3490
3543
|
position
|
|
3544
|
+
providersAvailable
|
|
3545
|
+
preferredProvider
|
|
3546
|
+
available
|
|
3547
|
+
unavailableReason
|
|
3548
|
+
instruments {
|
|
3549
|
+
...PaymentMethodInstrument
|
|
3550
|
+
}
|
|
3491
3551
|
}
|
|
3492
3552
|
```
|
|
3493
3553
|
|
|
@@ -3531,6 +3591,21 @@ fragment PaymentSession on PaymentSession {
|
|
|
3531
3591
|
}
|
|
3532
3592
|
```
|
|
3533
3593
|
|
|
3594
|
+
### Fragment: `PaymentWarning` on `PaymentWarning`
|
|
3595
|
+
|
|
3596
|
+
**Section**: Payment Methods
|
|
3597
|
+
|
|
3598
|
+
**Description**: Non-blocking signal emitted alongside `userErrors[]` in `paymentCreate` payload — backend state change context (e.g. an auto-clear of preselected instrument after gateway rejection). Pre-translated by backend per shop locale. `code === 'INSTRUMENT_CLEARED_FOR_RETRY'` signals storefront that the next `paymentCreate` will land on the gateway default landing page (server-side cleared `Order.paymentInstrumentCode` after `INSTRUMENT_PRESELECTION_FAILED`). `retryHint` is optional context for UI dispatch — currently unused for `INSTRUMENT_CLEARED_FOR_RETRY`, reserved for future warning codes.
|
|
3599
|
+
|
|
3600
|
+
**GraphQL**:
|
|
3601
|
+
```graphql
|
|
3602
|
+
fragment PaymentWarning on PaymentWarning {
|
|
3603
|
+
message
|
|
3604
|
+
code
|
|
3605
|
+
retryHint
|
|
3606
|
+
}
|
|
3607
|
+
```
|
|
3608
|
+
|
|
3534
3609
|
### Fragment: `ShipmentEvent` on `ShipmentEvent`
|
|
3535
3610
|
|
|
3536
3611
|
**Section**: Shipments / Tracking
|
package/mutations.graphql
CHANGED
|
@@ -329,7 +329,11 @@ mutation CartSelectShippingMethod($input: CartSelectShippingMethodInput!) {
|
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
-
# Selects a payment method by
|
|
332
|
+
# Selects a payment method on the cart by category (`methodType` — BLIK, CARD, BANK_TRANSFER, ...).
|
|
333
|
+
# Optional `preferredProviderId` overrides the merchant priority when the buyer explicitly picks
|
|
334
|
+
# a gateway from `PaymentMethod.providersAvailable`. The backend resolves the gateway routing
|
|
335
|
+
# from `MerchantPaymentConfig` at `cartComplete`; the selection persisted here is the category.
|
|
336
|
+
# Errors: `PAYMENT_METHOD_REQUIRED`, `CART_NOT_FOUND`, `CART_UNAUTHENTICATED`.
|
|
333
337
|
mutation CartSelectPaymentMethod($input: CartSelectPaymentMethodInput!) {
|
|
334
338
|
cartSelectPaymentMethod(input: $input) {
|
|
335
339
|
cart {
|
|
@@ -404,7 +408,7 @@ mutation CartComplete($input: CartCompleteInput!) {
|
|
|
404
408
|
}
|
|
405
409
|
}
|
|
406
410
|
|
|
407
|
-
# Initiates a payment session for an order created by `cartComplete` — call this when `order.canCreatePayment` is `true` (orders with an offline payment method like cash-on-delivery skip this step). `orderId` is required; `returnUrl` / `cancelUrl` are optional and, when supplied, must point to a verified domain of the shop (open-redirect protected). Branch on the returned `payment.flow`: `ONLINE_REDIRECT` → redirect to `payment.redirectUrl`, `ONLINE_EMBEDDED` → render a widget with `payment.clientSecret`, `INSTANT_DIRECT` → already settled, read `payment.status`. Public, but ownership-checked — an authenticated customer cannot pay for another customer's order. **Idempotent** — calling it again for the same order returns the existing still-valid session instead of creating a duplicate (safe to retry). Rate limit: 5 requests/minute. `userErrors[].code`: `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `INVALID_ID_FORMAT`, `PAYMENT_FAILED`.
|
|
411
|
+
# Initiates a payment session for an order created by `cartComplete` — call this when `order.canCreatePayment` is `true` (orders with an offline payment method like cash-on-delivery skip this step). `orderId` is required; `returnUrl` / `cancelUrl` are optional and, when supplied, must point to a verified domain of the shop (open-redirect protected). Branch on the returned `payment.flow`: `ONLINE_REDIRECT` → redirect to `payment.redirectUrl`, `ONLINE_EMBEDDED` → render a widget with `payment.clientSecret`, `INSTANT_DIRECT` → already settled, read `payment.status`. Public, but ownership-checked — an authenticated customer cannot pay for another customer's order. **Idempotent** — calling it again for the same order returns the existing still-valid session instead of creating a duplicate (safe to retry). Rate limit: 5 requests/minute. `userErrors[].code`: `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `INVALID_ID_FORMAT`, `PAYMENT_FAILED`, `INSTRUMENT_PRESELECTION_FAILED`. `warnings[]` array zawiera `INSTRUMENT_CLEARED_FOR_RETRY` post-auto-clear instrument-specific failure (storefront retry hint: next attempt uses gateway default landing).
|
|
408
412
|
mutation PaymentCreate($input: PaymentCreateInput!) {
|
|
409
413
|
paymentCreate(input: $input) {
|
|
410
414
|
payment {
|
|
@@ -413,6 +417,24 @@ mutation PaymentCreate($input: PaymentCreateInput!) {
|
|
|
413
417
|
userErrors {
|
|
414
418
|
...UserError
|
|
415
419
|
}
|
|
420
|
+
warnings {
|
|
421
|
+
...PaymentWarning
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
# Clears all payment selection state on the cart in a single atomic operation. Use for accordion "back to method picker" flows w storefront UI. Idempotent — calling twice yields the same end state. Cart MUSI być `ACTIVE` (CONVERTED carts reject z `ALREADY_COMPLETED`). Rate limit: 30 requests/minute per IP+shop.
|
|
427
|
+
mutation CartClearPaymentSelection($input: CartClearPaymentSelectionInput!) {
|
|
428
|
+
cartClearPaymentSelection(input: $input) {
|
|
429
|
+
cart {
|
|
430
|
+
...Cart
|
|
431
|
+
}
|
|
432
|
+
userErrors {
|
|
433
|
+
...UserError
|
|
434
|
+
}
|
|
435
|
+
warnings {
|
|
436
|
+
...CartWarning
|
|
437
|
+
}
|
|
416
438
|
}
|
|
417
439
|
}
|
|
418
440
|
|
package/operations.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion": "
|
|
2
|
+
"schemaVersion": "17.0.0",
|
|
3
3
|
"queries": [
|
|
4
4
|
{
|
|
5
5
|
"name": "Shop",
|
|
@@ -1518,7 +1518,7 @@
|
|
|
1518
1518
|
"name": "CartSelectPaymentMethod",
|
|
1519
1519
|
"kind": "mutation",
|
|
1520
1520
|
"section": "Cart Completion Mutations",
|
|
1521
|
-
"description": "Selects a payment method by `
|
|
1521
|
+
"description": "Selects a payment method on the cart by category (`methodType` — BLIK, CARD, BANK_TRANSFER, ...). Optional `preferredProviderId` overrides the merchant priority when the buyer explicitly picks a gateway from `PaymentMethod.providersAvailable`. The backend resolves the gateway routing from `MerchantPaymentConfig` at `cartComplete`; the selection persisted here is the category. Errors: `PAYMENT_METHOD_REQUIRED`, `CART_NOT_FOUND`, `CART_UNAUTHENTICATED`.",
|
|
1522
1522
|
"variables": [
|
|
1523
1523
|
{
|
|
1524
1524
|
"name": "input",
|
|
@@ -1613,7 +1613,7 @@
|
|
|
1613
1613
|
"name": "PaymentCreate",
|
|
1614
1614
|
"kind": "mutation",
|
|
1615
1615
|
"section": "Cart Completion Mutations",
|
|
1616
|
-
"description": "Initiates a payment session for an order created by `cartComplete` — call this when `order.canCreatePayment` is `true` (orders with an offline payment method like cash-on-delivery skip this step). `orderId` is required; `returnUrl` / `cancelUrl` are optional and, when supplied, must point to a verified domain of the shop (open-redirect protected). Branch on the returned `payment.flow`: `ONLINE_REDIRECT` → redirect to `payment.redirectUrl`, `ONLINE_EMBEDDED` → render a widget with `payment.clientSecret`, `INSTANT_DIRECT` → already settled, read `payment.status`. Public, but ownership-checked — an authenticated customer cannot pay for another customer's order. **Idempotent** — calling it again for the same order returns the existing still-valid session instead of creating a duplicate (safe to retry). Rate limit: 5 requests/minute. `userErrors[].code`: `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `INVALID_ID_FORMAT`, `PAYMENT_FAILED`.",
|
|
1616
|
+
"description": "Initiates a payment session for an order created by `cartComplete` — call this when `order.canCreatePayment` is `true` (orders with an offline payment method like cash-on-delivery skip this step). `orderId` is required; `returnUrl` / `cancelUrl` are optional and, when supplied, must point to a verified domain of the shop (open-redirect protected). Branch on the returned `payment.flow`: `ONLINE_REDIRECT` → redirect to `payment.redirectUrl`, `ONLINE_EMBEDDED` → render a widget with `payment.clientSecret`, `INSTANT_DIRECT` → already settled, read `payment.status`. Public, but ownership-checked — an authenticated customer cannot pay for another customer's order. **Idempotent** — calling it again for the same order returns the existing still-valid session instead of creating a duplicate (safe to retry). Rate limit: 5 requests/minute. `userErrors[].code`: `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `INVALID_ID_FORMAT`, `PAYMENT_FAILED`, `INSTRUMENT_PRESELECTION_FAILED`. `warnings[]` array zawiera `INSTRUMENT_CLEARED_FOR_RETRY` post-auto-clear instrument-specific failure (storefront retry hint: next attempt uses gateway default landing).",
|
|
1617
1617
|
"variables": [
|
|
1618
1618
|
{
|
|
1619
1619
|
"name": "input",
|
|
@@ -1623,9 +1623,29 @@
|
|
|
1623
1623
|
],
|
|
1624
1624
|
"fragmentRefs": [
|
|
1625
1625
|
"PaymentSession",
|
|
1626
|
+
"PaymentWarning",
|
|
1626
1627
|
"UserError"
|
|
1627
1628
|
],
|
|
1628
|
-
"body": "mutation PaymentCreate($input: PaymentCreateInput!) {\n paymentCreate(input: $input) {\n payment {\n ...PaymentSession\n }\n userErrors {\n ...UserError\n }\n }\n}"
|
|
1629
|
+
"body": "mutation PaymentCreate($input: PaymentCreateInput!) {\n paymentCreate(input: $input) {\n payment {\n ...PaymentSession\n }\n userErrors {\n ...UserError\n }\n warnings {\n ...PaymentWarning\n }\n }\n}"
|
|
1630
|
+
},
|
|
1631
|
+
{
|
|
1632
|
+
"name": "CartClearPaymentSelection",
|
|
1633
|
+
"kind": "mutation",
|
|
1634
|
+
"section": "Cart Completion Mutations",
|
|
1635
|
+
"description": "Clears all payment selection state on the cart in a single atomic operation. Use for accordion \"back to method picker\" flows w storefront UI. Idempotent — calling twice yields the same end state. Cart MUSI być `ACTIVE` (CONVERTED carts reject z `ALREADY_COMPLETED`). Rate limit: 30 requests/minute per IP+shop.",
|
|
1636
|
+
"variables": [
|
|
1637
|
+
{
|
|
1638
|
+
"name": "input",
|
|
1639
|
+
"type": "CartClearPaymentSelectionInput!",
|
|
1640
|
+
"defaultValue": null
|
|
1641
|
+
}
|
|
1642
|
+
],
|
|
1643
|
+
"fragmentRefs": [
|
|
1644
|
+
"Cart",
|
|
1645
|
+
"CartWarning",
|
|
1646
|
+
"UserError"
|
|
1647
|
+
],
|
|
1648
|
+
"body": "mutation CartClearPaymentSelection($input: CartClearPaymentSelectionInput!) {\n cartClearPaymentSelection(input: $input) {\n cart {\n ...Cart\n }\n userErrors {\n ...UserError\n }\n warnings {\n ...CartWarning\n }\n }\n}"
|
|
1629
1649
|
},
|
|
1630
1650
|
{
|
|
1631
1651
|
"name": "ReturnCreate",
|
|
@@ -2177,7 +2197,7 @@
|
|
|
2177
2197
|
"MailingAddress",
|
|
2178
2198
|
"PageInfo"
|
|
2179
2199
|
],
|
|
2180
|
-
"body": "fragment Cart on Cart {\n id\n checkoutUrl\n totalQuantity\n cost {\n ...CartCost\n }\n lines(first: 100) {\n edges {\n cursor\n node {\n ... on CartLine {\n ...CartLine\n }\n }\n }\n nodes {\n ... on CartLine {\n ...CartLine\n }\n }\n pageInfo {\n ...PageInfo\n }\n totalCount\n }\n buyerIdentity {\n ...CartBuyerIdentity\n }\n discountCodes {\n ...CartDiscountCode\n }\n discountAllocations {\n ...CartDiscountAllocation\n }\n note\n attributes {\n key\n value\n }\n email\n phone\n shippingAddress {\n ...MailingAddress\n }\n billingAddress {\n ...MailingAddress\n }\n selectedShippingMethod {\n ...CartShippingMethod\n }\n selectedPaymentMethod {\n ...CartSelectedPaymentMethod\n }\n appliedGiftCards {\n ...CartAppliedGiftCard\n }\n requiresShipping\n createdAt\n updatedAt\n status\n completedOrder {\n id\n orderNumber\n accessToken\n status\n paymentStatus\n fulfillmentStatus\n }\n}",
|
|
2200
|
+
"body": "fragment Cart on Cart {\n id\n checkoutUrl\n totalQuantity\n cost {\n ...CartCost\n }\n lines(first: 100) {\n edges {\n cursor\n node {\n ... on CartLine {\n ...CartLine\n }\n }\n }\n nodes {\n ... on CartLine {\n ...CartLine\n }\n }\n pageInfo {\n ...PageInfo\n }\n totalCount\n }\n buyerIdentity {\n ...CartBuyerIdentity\n }\n discountCodes {\n ...CartDiscountCode\n }\n discountAllocations {\n ...CartDiscountAllocation\n }\n note\n attributes {\n key\n value\n }\n email\n phone\n shippingAddress {\n ...MailingAddress\n }\n billingAddress {\n ...MailingAddress\n }\n selectedShippingMethod {\n ...CartShippingMethod\n }\n selectedPaymentMethod {\n ...CartSelectedPaymentMethod\n }\n selectedPaymentInstrumentCode\n appliedGiftCards {\n ...CartAppliedGiftCard\n }\n requiresShipping\n createdAt\n updatedAt\n status\n completedOrder {\n id\n orderNumber\n accessToken\n status\n paymentStatus\n fulfillmentStatus\n }\n}",
|
|
2181
2201
|
"onType": "Cart"
|
|
2182
2202
|
},
|
|
2183
2203
|
{
|
|
@@ -2330,13 +2350,25 @@
|
|
|
2330
2350
|
"onType": "Shop"
|
|
2331
2351
|
},
|
|
2332
2352
|
{
|
|
2333
|
-
"name": "
|
|
2353
|
+
"name": "PaymentMethodInstrument",
|
|
2334
2354
|
"kind": "fragment",
|
|
2335
2355
|
"section": "Payment Methods",
|
|
2336
|
-
"description": "
|
|
2356
|
+
"description": "A single concrete instrument exposed by a gateway provider (BLIK code, branded bank, wallet, card brand). Pass `instrumentCode` as `preferredInstrumentCode` in `cartSelectPaymentMethod` for direct deep-link to that instrument screen on the gateway. `displayHint` is a semantic UX hint (`PIN_ENTRY`, `WALLET_TAP`, `BANK_LIST`, `CARD_FORM`) — storefront branches rendering accordingly. `enabled: false` means the gateway reported the instrument as temporarily disabled — gray out, don't hide.",
|
|
2337
2357
|
"variables": [],
|
|
2338
2358
|
"fragmentRefs": [],
|
|
2339
|
-
"body": "fragment
|
|
2359
|
+
"body": "fragment PaymentMethodInstrument on PaymentMethodInstrument {\n providerCode\n instrumentCode\n type\n displayName\n displayHint\n brandImageUrl\n enabled\n}",
|
|
2360
|
+
"onType": "PaymentMethodInstrument"
|
|
2361
|
+
},
|
|
2362
|
+
{
|
|
2363
|
+
"name": "PaymentMethod",
|
|
2364
|
+
"kind": "fragment",
|
|
2365
|
+
"section": "Payment Methods",
|
|
2366
|
+
"description": "Single payment method enabled for the shop — method-centric. `type` is the category (CARD, BLIK, BANK_TRANSFER, CASH_ON_DELIVERY, OTHER) — drive iconography here. `provider`, `providersAvailable`, `preferredProvider` are `ProviderCode` enum (UPPERCASE: `PAYU`, `PRZELEWY24`, ...). `available` is `false` when the resolving gateway is temporarily unavailable or reported the method as disabled — gray-out the tile, don't hide it; `unavailableReason` carries the diagnostic. `instruments` lists concrete gateway-side instruments (BLIK code, branded banks, wallets) when the gateway exposes granular data — pass `instrumentCode` as `preferredInstrumentCode` in `cartSelectPaymentMethod` for direct deep-link to that instrument screen on the gateway. Spread on the checkout payment step.",
|
|
2367
|
+
"variables": [],
|
|
2368
|
+
"fragmentRefs": [
|
|
2369
|
+
"PaymentMethodInstrument"
|
|
2370
|
+
],
|
|
2371
|
+
"body": "fragment PaymentMethod on PaymentMethod {\n id\n name\n provider\n type\n icon\n description\n isDefault\n supportedCurrencies\n position\n providersAvailable\n preferredProvider\n available\n unavailableReason\n instruments {\n ...PaymentMethodInstrument\n }\n}",
|
|
2340
2372
|
"onType": "PaymentMethod"
|
|
2341
2373
|
},
|
|
2342
2374
|
{
|
|
@@ -2361,6 +2393,16 @@
|
|
|
2361
2393
|
"body": "fragment PaymentSession on PaymentSession {\n id\n orderId\n flow\n provider\n redirectUrl\n clientSecret\n status\n expiresAt\n}",
|
|
2362
2394
|
"onType": "PaymentSession"
|
|
2363
2395
|
},
|
|
2396
|
+
{
|
|
2397
|
+
"name": "PaymentWarning",
|
|
2398
|
+
"kind": "fragment",
|
|
2399
|
+
"section": "Payment Methods",
|
|
2400
|
+
"description": "Non-blocking signal emitted alongside `userErrors[]` in `paymentCreate` payload — backend state change context (e.g. an auto-clear of preselected instrument after gateway rejection). Pre-translated by backend per shop locale. `code === 'INSTRUMENT_CLEARED_FOR_RETRY'` signals storefront that the next `paymentCreate` will land on the gateway default landing page (server-side cleared `Order.paymentInstrumentCode` after `INSTRUMENT_PRESELECTION_FAILED`). `retryHint` is optional context for UI dispatch — currently unused for `INSTRUMENT_CLEARED_FOR_RETRY`, reserved for future warning codes.",
|
|
2401
|
+
"variables": [],
|
|
2402
|
+
"fragmentRefs": [],
|
|
2403
|
+
"body": "fragment PaymentWarning on PaymentWarning {\n message\n code\n retryHint\n}",
|
|
2404
|
+
"onType": "PaymentWarning"
|
|
2405
|
+
},
|
|
2364
2406
|
{
|
|
2365
2407
|
"name": "ShipmentEvent",
|
|
2366
2408
|
"kind": "fragment",
|
package/package.json
CHANGED
package/schema.graphql
CHANGED
|
@@ -880,7 +880,9 @@ type Cart implements Node {
|
|
|
880
880
|
"""
|
|
881
881
|
attributes: [CartAttribute!]!
|
|
882
882
|
|
|
883
|
-
"""
|
|
883
|
+
"""
|
|
884
|
+
Available payment methods dla tego carta — deduplikowane per type, sorted by merchant priority.
|
|
885
|
+
"""
|
|
884
886
|
availablePaymentMethods: [PaymentMethod!]!
|
|
885
887
|
|
|
886
888
|
"""
|
|
@@ -955,6 +957,11 @@ type Cart implements Node {
|
|
|
955
957
|
"""
|
|
956
958
|
requiresShipping: Boolean!
|
|
957
959
|
|
|
960
|
+
"""
|
|
961
|
+
Optional concrete instrument code selected within `selectedPaymentMethod` (e.g. `"blik"`, `"mb"`, `"154"`). Set gdy klient klika konkretny instrument tile na storefront (per `PaymentMethod.instruments`). Pre-payment intent: skopiowany do `Order.paymentInstrumentCode` przy `cartComplete`. Storefront może cross-reference z `availablePaymentMethods.methods[].instruments[]` żeby dostać `displayName` / `brandImageUrl`. Added by payment-instrument-preselection core sprint Req 3 AC7.
|
|
962
|
+
"""
|
|
963
|
+
selectedPaymentInstrumentCode: String
|
|
964
|
+
|
|
958
965
|
"""
|
|
959
966
|
The payment method currently selected on the cart. Null until the buyer picks a method via `cartSelectPaymentMethod`.
|
|
960
967
|
"""
|
|
@@ -982,6 +989,11 @@ type Cart implements Node {
|
|
|
982
989
|
|
|
983
990
|
"""When the cart was last modified (ISO 8601)."""
|
|
984
991
|
updatedAt: DateTime!
|
|
992
|
+
|
|
993
|
+
"""
|
|
994
|
+
Non-fatal advisories computed at query time. Currently emitted: `PAYMENT_SELECTION_STALE` when `selectedPaymentMethod` / `selectedPaymentInstrumentCode` are no longer in live gateway capabilities (storefront re-prompts the buyer). Read-only — backend state is not mutated. Added by payment-instrument-preselection-advanced sub-sprint Adv-2 Req 1.
|
|
995
|
+
"""
|
|
996
|
+
warnings: [CartWarning!]!
|
|
985
997
|
}
|
|
986
998
|
|
|
987
999
|
"""Result of `cartAddLines`."""
|
|
@@ -1171,6 +1183,30 @@ input CartBuyerIdentityInput {
|
|
|
1171
1183
|
phone: String
|
|
1172
1184
|
}
|
|
1173
1185
|
|
|
1186
|
+
"""
|
|
1187
|
+
Input for `cartClearPaymentSelection` — explicit deselect mutation. Use when the buyer goes back to the payment method picker w accordion UI bez hack typu re-selectując method. Atomic NULL na wszystkich payment selection fields (method type + provider code + instrument code + legacy method ID). Idempotent — wielokrotne wywołanie = same final state. Added by payment-instrument-preselection-advanced Adv-1 Req 3.1.
|
|
1188
|
+
"""
|
|
1189
|
+
input CartClearPaymentSelectionInput {
|
|
1190
|
+
"""ID of the cart to clear payment selection on."""
|
|
1191
|
+
cartId: ID!
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
"""
|
|
1195
|
+
Result of `cartClearPaymentSelection`. `cart` populated on success z cleared selection fields (`selectedPaymentMethod === null`, `selectedPaymentInstrumentCode === null`). `userErrors` populated gdy cart locked (CONVERTED status → `ALREADY_COMPLETED` code).
|
|
1196
|
+
"""
|
|
1197
|
+
type CartClearPaymentSelectionPayload {
|
|
1198
|
+
"""The updated cart z cleared payment selection."""
|
|
1199
|
+
cart: Cart
|
|
1200
|
+
|
|
1201
|
+
"""
|
|
1202
|
+
Business / validation errors carrying a stable `CartErrorCode` in `code` (e.g. `ALREADY_COMPLETED`).
|
|
1203
|
+
"""
|
|
1204
|
+
userErrors: [UserError!]!
|
|
1205
|
+
|
|
1206
|
+
"""Non-fatal advisories — the mutation itself succeeded."""
|
|
1207
|
+
warnings: [CartWarning!]!
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1174
1210
|
"""Input for `cartComplete` — finalises the cart into an `Order`."""
|
|
1175
1211
|
input CartCompleteInput {
|
|
1176
1212
|
"""ID of the cart to complete."""
|
|
@@ -1551,15 +1587,27 @@ type CartRemoveLinesPayload {
|
|
|
1551
1587
|
warnings: [CartWarning!]!
|
|
1552
1588
|
}
|
|
1553
1589
|
|
|
1554
|
-
"""
|
|
1590
|
+
"""
|
|
1591
|
+
Input for `cartSelectPaymentMethod` (Intelligent Payment Methods). Method-centric: the buyer picks a category (BLIK, CARD, BANK_TRANSFER, ...) and the backend resolves the preferred provider from `MerchantPaymentConfig` (priority-sorted, merchant-configurable per shop). Optional `preferredProviderCode` + `preferredInstrumentCode` enable instrument-level deep-link na gateway hosted page (skipa default landing).
|
|
1592
|
+
"""
|
|
1555
1593
|
input CartSelectPaymentMethodInput {
|
|
1556
1594
|
"""ID of the cart to update."""
|
|
1557
1595
|
cartId: ID!
|
|
1558
1596
|
|
|
1559
1597
|
"""
|
|
1560
|
-
|
|
1598
|
+
Category of the payment method the buyer picked (matches `PaymentMethod.type` from `availablePaymentMethods`).
|
|
1599
|
+
"""
|
|
1600
|
+
methodType: PaymentMethodType!
|
|
1601
|
+
|
|
1561
1602
|
"""
|
|
1562
|
-
|
|
1603
|
+
Optional gateway-specific instrument code (`blik`, `mb`, `c`, `154`, ...) z `PaymentMethod.instruments[].instrumentCode`. Wymaga ustawienia `preferredProviderCode` — instrument code jest provider-specific. Bez restrictive regex (różne bramki używają `.` / `:` / `/` w przyszłości). SQL injection chroniona przez Prisma parametrized queries. Added by payment-instrument-preselection core sprint Req 3.1.
|
|
1604
|
+
"""
|
|
1605
|
+
preferredInstrumentCode: String
|
|
1606
|
+
|
|
1607
|
+
"""
|
|
1608
|
+
Optional override of `PaymentMethod.preferredProvider`. Pass a provider code (`payu`, `przelewy24`, ...) from `providersAvailable` when the buyer explicitly picks one (rare — usually the merchant priority is enough). Format: lowercase alphanumerics + underscore + hyphen, 2-50 characters. Renamed from `preferredProviderId` — `*Code` is reserved for lowercase string identifiers, `*Id` for UUIDs.
|
|
1609
|
+
"""
|
|
1610
|
+
preferredProviderCode: String
|
|
1563
1611
|
}
|
|
1564
1612
|
|
|
1565
1613
|
"""Result of `cartSelectPaymentMethod`."""
|
|
@@ -1807,6 +1855,7 @@ enum CartWarningCode {
|
|
|
1807
1855
|
MERCHANDISE_NOT_AVAILABLE
|
|
1808
1856
|
MERCHANDISE_NOT_ENOUGH_STOCK
|
|
1809
1857
|
PAYMENTS_AMOUNT_REGION_MISMATCH
|
|
1858
|
+
PAYMENT_SELECTION_STALE
|
|
1810
1859
|
SHIPPING_METHOD_AUTO_CLEARED
|
|
1811
1860
|
}
|
|
1812
1861
|
|
|
@@ -3843,6 +3892,11 @@ type Mutation {
|
|
|
3843
3892
|
"""
|
|
3844
3893
|
cartApplyGiftCard(input: CartApplyGiftCardInput!): CartApplyGiftCardPayload!
|
|
3845
3894
|
|
|
3895
|
+
"""
|
|
3896
|
+
Clear all payment selection state on the cart in a single atomic operation. Use for accordion "back to method picker" flows w storefront UI. Idempotent — calling twice yields the same end state. Cart MUSI być `ACTIVE` (CONVERTED carts reject z `ALREADY_COMPLETED`).
|
|
3897
|
+
"""
|
|
3898
|
+
cartClearPaymentSelection(input: CartClearPaymentSelectionInput!): CartClearPaymentSelectionPayload!
|
|
3899
|
+
|
|
3846
3900
|
"""
|
|
3847
3901
|
Finalise the cart into an `Order`. The cart is locked and no longer accepts mutations. Payment is initiated separately via `paymentCreate` — check `order.canCreatePayment` to decide whether to render a "Pay now" button or send the buyer directly to the confirmation page (for offline methods such as cash on delivery). Rate-limited to 5 requests per minute per IP+shop; pass an `idempotencyKey` to guard against duplicate orders on retry.
|
|
3848
3902
|
"""
|
|
@@ -3869,7 +3923,7 @@ type Mutation {
|
|
|
3869
3923
|
cartRemoveLines(id: ID!, lineIds: [ID!]!): CartRemoveLinesPayload!
|
|
3870
3924
|
|
|
3871
3925
|
"""
|
|
3872
|
-
Select a payment method on the cart.
|
|
3926
|
+
Select a payment method on the cart by category (BLIK, CARD, BANK_TRANSFER, ...). Backend resolves the preferred provider from `MerchantPaymentConfig` at `paymentCreate` time. Optional `preferredProviderCode` overrides the merchant priority when the buyer explicitly picks a gateway from `PaymentMethod.providersAvailable`. Optional `preferredInstrumentCode` enables instrument-level deep-link na gateway hosted page (BLIK ekran, mBank flow, etc.) — wymaga `preferredProviderCode`.
|
|
3873
3927
|
"""
|
|
3874
3928
|
cartSelectPaymentMethod(input: CartSelectPaymentMethodInput!): CartSelectPaymentMethodPayload!
|
|
3875
3929
|
|
|
@@ -4337,9 +4391,14 @@ type PaymentCreatePayload {
|
|
|
4337
4391
|
payment: PaymentSession
|
|
4338
4392
|
|
|
4339
4393
|
"""
|
|
4340
|
-
Business / validation errors carrying a stable `PaymentErrorCode` in `code` (e.g. `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `PAYMENT_FAILED`).
|
|
4394
|
+
Business / validation errors carrying a stable `PaymentErrorCode` in `code` (e.g. `ORDER_NOT_FOUND`, `ORDER_ALREADY_PAID`, `ORDER_NOT_PAYABLE`, `PAYMENT_PROVIDER_NOT_CONFIGURED`, `RETURN_URL_INVALID`, `PAYMENT_FAILED`, `INSTRUMENT_PRESELECTION_FAILED`).
|
|
4341
4395
|
"""
|
|
4342
4396
|
userErrors: [UserError!]!
|
|
4397
|
+
|
|
4398
|
+
"""
|
|
4399
|
+
Non-blocking signals — backend state change context (e.g. instrument auto-cleared, server-side adjustment). Default empty array. Storefront branches per `code` for UI retry hints / analytics events. Added by payment-instrument-preselection-advanced Adv-1 Req 2.3.
|
|
4400
|
+
"""
|
|
4401
|
+
warnings: [PaymentWarning!]!
|
|
4343
4402
|
}
|
|
4344
4403
|
|
|
4345
4404
|
"""
|
|
@@ -4356,6 +4415,11 @@ enum PaymentInitiationFlow {
|
|
|
4356
4415
|
A payment method offered to the buyer at checkout — what to render in the payment picker and pass to `cartSelectPaymentMethod`.
|
|
4357
4416
|
"""
|
|
4358
4417
|
type PaymentMethod {
|
|
4418
|
+
"""
|
|
4419
|
+
True when the buyer can actually pick this method right now. False when the resolving gateway is temporarily unavailable (incident/maintenance) or reported the method as disabled. Storefront UI should gray-out the tile when false instead of hiding it — gives merchants observability into routing failures.
|
|
4420
|
+
"""
|
|
4421
|
+
available: Boolean!
|
|
4422
|
+
|
|
4359
4423
|
"""
|
|
4360
4424
|
Optional buyer-facing description shown under the name (e.g. "Pay with your bank app").
|
|
4361
4425
|
"""
|
|
@@ -4371,6 +4435,11 @@ type PaymentMethod {
|
|
|
4371
4435
|
"""
|
|
4372
4436
|
id: ID!
|
|
4373
4437
|
|
|
4438
|
+
"""
|
|
4439
|
+
Concrete instruments exposed by gateway providers w obrębie tej method (BLIK code, branded banks, wallets, card brands). Null gdy żaden provider nie expose'uje granular data dla tej method. Empty array gdy gateway expose'uje ale wszystkie instruments są disabled lub po post-filter (cross-provider leak prevention). Storefront może wyrenderować listę i pass `instrumentCode` jako `preferredInstrumentCode` w `cartSelectPaymentMethod` → gateway deep-link na ten ekran. Added by payment-instrument-preselection core sprint Req 1.
|
|
4440
|
+
"""
|
|
4441
|
+
instruments: [PaymentMethodInstrument!]
|
|
4442
|
+
|
|
4374
4443
|
"""
|
|
4375
4444
|
True when the merchant has marked this method as the default. Pre-select it in the picker.
|
|
4376
4445
|
"""
|
|
@@ -4387,9 +4456,19 @@ type PaymentMethod {
|
|
|
4387
4456
|
position: Float!
|
|
4388
4457
|
|
|
4389
4458
|
"""
|
|
4390
|
-
|
|
4459
|
+
Preferred provider code (UPPERCASE enum) that the backend will route to when the buyer picks this method type and does not specify `preferredProviderCode`. Populated only when at least one provider supports the type. Typed enum since core sprint payment-instrument-preselection (was `String` pre-v9.0).
|
|
4391
4460
|
"""
|
|
4392
|
-
|
|
4461
|
+
preferredProvider: ProviderCode
|
|
4462
|
+
|
|
4463
|
+
"""
|
|
4464
|
+
Provider code (e.g. `PAYU`, `STRIPE`, `PRZELEWY24`, `CASH_ON_DELIVERY`). Identifies the integration behind the method; do not branch UI on it — use `type` instead. Typed enum since core sprint payment-instrument-preselection (was `String` pre-v9.0).
|
|
4465
|
+
"""
|
|
4466
|
+
provider: ProviderCode!
|
|
4467
|
+
|
|
4468
|
+
"""
|
|
4469
|
+
Provider codes (UPPERCASE enum: `PAYU`, `PRZELEWY24`, ...) that can fulfil this method type for the current shop, ordered by merchant priority. Pre-select `preferredProvider`; expose the rest only when the buyer wants to choose explicitly. Single-element array when only one provider supports the type. Typed enum since core sprint payment-instrument-preselection (was `[String]` pre-v9.0).
|
|
4470
|
+
"""
|
|
4471
|
+
providersAvailable: [ProviderCode!]
|
|
4393
4472
|
|
|
4394
4473
|
"""
|
|
4395
4474
|
ISO 4217 currency codes the method accepts. Null when the method accepts the shop currency without restriction.
|
|
@@ -4400,6 +4479,72 @@ type PaymentMethod {
|
|
|
4400
4479
|
Category of the method (CARD, BLIK, BANK_TRANSFER, CASH_ON_DELIVERY, OTHER). Drives iconography and copy.
|
|
4401
4480
|
"""
|
|
4402
4481
|
type: PaymentMethodType!
|
|
4482
|
+
|
|
4483
|
+
"""
|
|
4484
|
+
When `available` is false, this enum carries the diagnostic reason (GATEWAY_DOWN, GATEWAY_DISABLED, NO_INSTRUMENTS, CREDENTIALS_INVALID). Null when `available` is true. UI can render context-aware copy ("PayU is temporarily down" vs "Method not configured").
|
|
4485
|
+
"""
|
|
4486
|
+
unavailableReason: PaymentMethodUnavailableReason
|
|
4487
|
+
}
|
|
4488
|
+
|
|
4489
|
+
"""
|
|
4490
|
+
A single concrete instrument exposed by a gateway provider (e.g. BLIK code, mBank Pay-By-Link, Apple Pay) within a broader PaymentMethod. Pass `instrumentCode` jako `preferredInstrumentCode` w `cartSelectPaymentMethod` żeby gateway deep-link prosto na ten ekran.
|
|
4491
|
+
"""
|
|
4492
|
+
type PaymentMethodInstrument {
|
|
4493
|
+
"""
|
|
4494
|
+
Optional brand image URL (bank logo, wallet icon). Storefront może użyć jako tile artwork. Null gdy gateway nie expose'uje albo instrument nie ma brand visual (BLIK code).
|
|
4495
|
+
"""
|
|
4496
|
+
brandImageUrl: String
|
|
4497
|
+
|
|
4498
|
+
"""
|
|
4499
|
+
UX rendering hint — jak storefront powinien wyrenderować ten instrument (prominent button vs branded tile vs dropdown vs radio). Backend-agnostic mapping na visual treatment.
|
|
4500
|
+
"""
|
|
4501
|
+
displayHint: PaymentMethodInstrumentDisplayHint!
|
|
4502
|
+
|
|
4503
|
+
"""
|
|
4504
|
+
Buyer-facing display name (e.g. "BLIK", "mBank", "ING Bank Śląski", "Apple Pay"). Lokalizacja zazwyczaj PL/EN — multi-language defer post-v1.
|
|
4505
|
+
"""
|
|
4506
|
+
displayName: String!
|
|
4507
|
+
|
|
4508
|
+
"""
|
|
4509
|
+
True gdy instrument jest currently enabled w gateway live capabilities. Storefront może gray-out tile gdy false zamiast hide (observability dla merchant).
|
|
4510
|
+
"""
|
|
4511
|
+
enabled: Boolean!
|
|
4512
|
+
|
|
4513
|
+
"""
|
|
4514
|
+
Gateway-specific instrument identifier (PayU: `"blik"`/`"mb"`/`"c"`, P24: numeric ID string `"154"`). Pass jako `preferredInstrumentCode` w `cartSelectPaymentMethod`. Stabilne per provider — gateway nie renumeruje.
|
|
4515
|
+
"""
|
|
4516
|
+
instrumentCode: String!
|
|
4517
|
+
|
|
4518
|
+
"""
|
|
4519
|
+
Provider obsługujący ten instrument (UPPERCASE enum). Wymagane dla cross-provider dedupe (np. BLIK code dostępny zarówno przez PayU jak P24 — różne instrumenty mimo tej samej method type).
|
|
4520
|
+
"""
|
|
4521
|
+
providerCode: ProviderCode!
|
|
4522
|
+
|
|
4523
|
+
"""
|
|
4524
|
+
Semantic type klasyfikujący instrument w obrębie method (BLIK code vs bank vs wallet vs card brand). Storefront-facing dispatch dla per-instrument UI components.
|
|
4525
|
+
"""
|
|
4526
|
+
type: PaymentMethodInstrumentType!
|
|
4527
|
+
}
|
|
4528
|
+
|
|
4529
|
+
"""
|
|
4530
|
+
UX rendering hint dla payment instrument — storefront może przełączać między prominent button / branded tile / dropdown / radio per hint. Backend-agnostic mapping na visual treatment.
|
|
4531
|
+
"""
|
|
4532
|
+
enum PaymentMethodInstrumentDisplayHint {
|
|
4533
|
+
BRANDED_TILE
|
|
4534
|
+
DROPDOWN_OPTION
|
|
4535
|
+
PROMINENT_BUTTON
|
|
4536
|
+
RADIO_OPTION
|
|
4537
|
+
}
|
|
4538
|
+
|
|
4539
|
+
"""
|
|
4540
|
+
Klasyfikacja konkretnego instrumentu w obrębie PaymentMethod (BLIK kod vs bank vs wallet vs card brand). Storefront-facing typing dla per-instrument UI dispatch.
|
|
4541
|
+
"""
|
|
4542
|
+
enum PaymentMethodInstrumentType {
|
|
4543
|
+
BANK
|
|
4544
|
+
BLIK_CODE
|
|
4545
|
+
CARD_BRAND
|
|
4546
|
+
OTHER
|
|
4547
|
+
WALLET
|
|
4403
4548
|
}
|
|
4404
4549
|
|
|
4405
4550
|
"""
|
|
@@ -4413,6 +4558,16 @@ enum PaymentMethodType {
|
|
|
4413
4558
|
OTHER
|
|
4414
4559
|
}
|
|
4415
4560
|
|
|
4561
|
+
"""
|
|
4562
|
+
Why a payment method is currently unavailable. GATEWAY_DOWN/DISABLED/NO_INSTRUMENTS are transient (gateway-side); CREDENTIALS_INVALID needs merchant action in the admin panel.
|
|
4563
|
+
"""
|
|
4564
|
+
enum PaymentMethodUnavailableReason {
|
|
4565
|
+
CREDENTIALS_INVALID
|
|
4566
|
+
GATEWAY_DISABLED
|
|
4567
|
+
GATEWAY_DOWN
|
|
4568
|
+
NO_INSTRUMENTS
|
|
4569
|
+
}
|
|
4570
|
+
|
|
4416
4571
|
"""
|
|
4417
4572
|
Payment session created for an order. Branch on `flow` to launch payment: ONLINE_REDIRECT → redirect to `redirectUrl`; ONLINE_EMBEDDED → render an in-page widget using `clientSecret`; INSTANT_DIRECT → the payment is already settled, check `status`.
|
|
4418
4573
|
"""
|
|
@@ -4471,6 +4626,33 @@ type PaymentSettings {
|
|
|
4471
4626
|
paymentProviders: [String!]!
|
|
4472
4627
|
}
|
|
4473
4628
|
|
|
4629
|
+
"""
|
|
4630
|
+
Non-blocking signal emitted alongside `userErrors` — backend state change context (e.g. an auto-clear, a server-side adjustment) that the storefront may surface as a retry hint or analytics event. Always pre-translated by backend per shop locale.
|
|
4631
|
+
"""
|
|
4632
|
+
type PaymentWarning {
|
|
4633
|
+
"""
|
|
4634
|
+
Machine-readable code — branch on this to dispatch UI retry hints. Add a new code only when there is a distinct UX response.
|
|
4635
|
+
"""
|
|
4636
|
+
code: PaymentWarningCode!
|
|
4637
|
+
|
|
4638
|
+
"""
|
|
4639
|
+
Pre-translated user-facing message describing what happened (Polish-first per shop locale).
|
|
4640
|
+
"""
|
|
4641
|
+
message: String!
|
|
4642
|
+
|
|
4643
|
+
"""
|
|
4644
|
+
Optional additional hint string for UI dispatch — currently unused for `INSTRUMENT_CLEARED_FOR_RETRY` (semantic encoded in `message`). Reserved for future warning codes (e.g. `SLOW_GATEWAY_RESPONSE` → "Retry in 30s").
|
|
4645
|
+
"""
|
|
4646
|
+
retryHint: String
|
|
4647
|
+
}
|
|
4648
|
+
|
|
4649
|
+
"""
|
|
4650
|
+
Machine-readable code for `PaymentWarning.code`. Non-blocking signals from payment mutations — branch on this to dispatch UI retry hints. `INSTRUMENT_CLEARED_FOR_RETRY` indicates backend auto-cleared a preselected payment instrument after gateway rejection; next `paymentCreate` will land on the gateway default page.
|
|
4651
|
+
"""
|
|
4652
|
+
enum PaymentWarningCode {
|
|
4653
|
+
INSTRUMENT_CLEARED_FOR_RETRY
|
|
4654
|
+
}
|
|
4655
|
+
|
|
4474
4656
|
"""
|
|
4475
4657
|
A pickup point (parcel locker or staffed collection point) attached to a delivery address. The buyer picks it in the carrier widget; it is persisted on the cart shipping address and carried through to the order.
|
|
4476
4658
|
"""
|
|
@@ -5161,6 +5343,20 @@ enum ProductVisibility {
|
|
|
5161
5343
|
PUBLIC
|
|
5162
5344
|
}
|
|
5163
5345
|
|
|
5346
|
+
"""
|
|
5347
|
+
Canonical payment provider identifier (UPPERCASE per GraphQL convention). Use for `Order.paymentMethod`, `Payment.provider`, `PaymentMethod.providersAvailable`, `PaymentMethod.preferredProvider`. Add new providers in `@doswiftly/commerce-policy/provider-codes.ts` SSOT registry.
|
|
5348
|
+
"""
|
|
5349
|
+
enum ProviderCode {
|
|
5350
|
+
BANK_TRANSFER
|
|
5351
|
+
CASH_ON_DELIVERY
|
|
5352
|
+
GIFT_CARD
|
|
5353
|
+
MANUAL_PAYMENT
|
|
5354
|
+
PAYU
|
|
5355
|
+
PRZELEWY24
|
|
5356
|
+
STRIPE
|
|
5357
|
+
TEST_GATEWAY
|
|
5358
|
+
}
|
|
5359
|
+
|
|
5164
5360
|
type Query {
|
|
5165
5361
|
"""List of all currencies supported by the system (ECB rates)"""
|
|
5166
5362
|
allSupportedCurrencies: [Currency!]!
|
|
@@ -5171,7 +5367,7 @@ type Query {
|
|
|
5171
5367
|
attributeOptionsSearch(input: AttributeOptionsSearchInput!): AttributeFilterValueConnection!
|
|
5172
5368
|
|
|
5173
5369
|
"""
|
|
5174
|
-
Payment methods active for the current shop, plus the merchant default.
|
|
5370
|
+
Payment methods active for the current shop, plus the merchant default. Returns one row per `PaymentMethodType` (BLIK, CARD, BANK_TRANSFER, ...) with `providersAvailable` (provider codes sorted by merchant priority) and `preferredProvider` (the head of the list). Shop-level — independent of cart contents.
|
|
5175
5371
|
"""
|
|
5176
5372
|
availablePaymentMethods: AvailablePaymentMethods!
|
|
5177
5373
|
|