@01.software/sdk 0.46.1 → 0.49.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/CHANGELOG.md +96 -1
- package/README.md +145 -14
- package/dist/client.cjs +485 -81
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +7 -6
- package/dist/client.d.ts +7 -6
- package/dist/client.js +485 -81
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-BEGXnfQe.d.ts → collection-client-DnDt6EQz.d.ts} +4 -4
- package/dist/{collection-client-L2rEgBaR.d.cts → collection-client-XfGLPuTf.d.cts} +4 -4
- package/dist/{const-y0eipvnQ.d.cts → const-CBba4lDo.d.cts} +4 -4
- package/dist/{const-GYVwlXLr.d.ts → const-DCNV5Kq7.d.ts} +4 -4
- package/dist/errors.cjs +112 -16
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +13 -4
- package/dist/errors.d.ts +13 -4
- package/dist/errors.js +112 -16
- package/dist/errors.js.map +1 -1
- package/dist/{index-BfYL6Qb1.d.cts → index-CbKyoEzy.d.cts} +3 -3
- package/dist/{index-Bei4WlVw.d.ts → index-DUuIqUS8.d.ts} +3 -3
- package/dist/index.cjs +452 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +452 -104
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-3WNyC0gk.d.cts → payload-types-MKbx5MuJ.d.cts} +309 -17
- package/dist/{payload-types-3WNyC0gk.d.ts → payload-types-MKbx5MuJ.d.ts} +309 -17
- package/dist/query.cjs +165 -43
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.cts +5 -5
- package/dist/query.d.ts +5 -5
- package/dist/query.js +165 -43
- package/dist/query.js.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/server.cjs +566 -81
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +8 -7
- package/dist/server.d.ts +8 -7
- package/dist/server.js +566 -81
- package/dist/server.js.map +1 -1
- package/dist/storefront-cache.cjs +70 -1
- package/dist/storefront-cache.cjs.map +1 -1
- package/dist/storefront-cache.js +70 -1
- package/dist/storefront-cache.js.map +1 -1
- package/dist/{types-mIROvhhP.d.ts → types-1UeOk1Uy.d.cts} +110 -8
- package/dist/{types-CAicTn-o.d.cts → types-BKr_2avj.d.cts} +2 -2
- package/dist/{types-CDJ2M-MJ.d.cts → types-Du4s5anw.d.ts} +110 -8
- package/dist/{types-DpSyNTxy.d.ts → types-L_nh-ED7.d.ts} +2 -2
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/video.d.cts +1 -1
- package/dist/ui/video.d.ts +1 -1
- package/dist/webhook.d.cts +4 -4
- package/dist/webhook.d.ts +4 -4
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,100 @@
|
|
|
1
1
|
# @01.software/sdk
|
|
2
2
|
|
|
3
|
+
## 0.49.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- aef44ec: Fix SDK error guards across independently bundled entrypoints and expose the guards from the client and server entries.
|
|
8
|
+
- 86f74d3: Expose immutable membership subscribe-admission snapshot fields in the generated SDK types.
|
|
9
|
+
- edc790e: BREAKING (0.x minor): Checkout `paymentState.activePaymentSession.provider` can
|
|
10
|
+
now be `portone`. Consumers using `@01.software/sdk` 0.45.0, 0.46.0, or 0.46.1
|
|
11
|
+
must upgrade to the 0.49.0 release produced by this minor changeset, or later,
|
|
12
|
+
before the server exposes managed PortOne sessions; otherwise
|
|
13
|
+
`checkouts.retrieve` and `checkouts.query` throw during strict response
|
|
14
|
+
validation. SDK 0.48.0's runtime decoder already accepts `portone`, but its
|
|
15
|
+
published TypeScript `CheckoutPaymentSessionRef` remains `provider: 'toss'`, so
|
|
16
|
+
0.48.0 is not the fully compatible public-contract floor. `checkouts.create` is
|
|
17
|
+
not part of this break because the current producer does not return an active
|
|
18
|
+
PortOne session reference.
|
|
19
|
+
|
|
20
|
+
Keep custom bridge recovery on the server-only exact lookup.
|
|
21
|
+
|
|
22
|
+
- fa71a21: Add a fail-closed PortOne Standard V2 Toss Payments CARD browser action with a required redirect, PG-safe payment identity, and durable single-slot retry semantics.
|
|
23
|
+
- 5ea6348: Expose non-commerce API reasons through `SDKError.apiReason` and the family-aware `getSDKErrorReason` accessor while preserving strict commerce error typing.
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- cb2a742: Clarify that idempotent commerce mutation response fields do not provide exactly-once side-effect semantics.
|
|
28
|
+
- 15c1024: Synchronize generated Payload types for the internal payment-kernel result and owner-commit records without exposing those collections through a public SDK collection bucket.
|
|
29
|
+
|
|
30
|
+
## 0.48.0
|
|
31
|
+
|
|
32
|
+
### Minor Changes
|
|
33
|
+
|
|
34
|
+
- 715fe57: Expose active tenant custom-field structure in the optional version-1
|
|
35
|
+
collection schema response and preserve it through Agent CLI schema output.
|
|
36
|
+
- b23608d: Preserve canonical strict commerce errors through the mounted Console handlers and public Cart, Checkout, and PaymentSession facades, including the additive handler reason vocabulary.
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- 3096b74: Align the SDK build and test toolchain with the Payload release that removes
|
|
41
|
+
the vulnerable archived image parser dependency.
|
|
42
|
+
- d98f7b3: Synchronize generated Payload types for internal settlement receipt and reconciliation evidence. These collections remain absent from every public SDK collection bucket and add no public SDK API.
|
|
43
|
+
|
|
44
|
+
## 0.47.0
|
|
45
|
+
|
|
46
|
+
### Minor Changes
|
|
47
|
+
|
|
48
|
+
- 5a523e8: Add the managed PortOne Hosted v2 payment-session flow, provider-specific
|
|
49
|
+
checkout action parsing, CLI dispatch, and compatible event-template recovery
|
|
50
|
+
behavior. Expose the full current Hosted v2 payment-method vocabulary while
|
|
51
|
+
preserving per-connection allowlists.
|
|
52
|
+
- 5e68929: Add a browser-safe shaped `community.getPost({ postId })` helper while keeping
|
|
53
|
+
raw community posts server-only, and update the generated community template to
|
|
54
|
+
consume that helper without a raw collection workaround.
|
|
55
|
+
- 5a523e8: Add a server-only exact custom PaymentSession recovery lookup by provider
|
|
56
|
+
session or payment identity.
|
|
57
|
+
- 5a523e8: Expose the additive `tenantPurpose` and `testExpiresAt` fields on the generated
|
|
58
|
+
`Tenant` type for time-limited, externally fenced test tenants.
|
|
59
|
+
- d63c3c8: Reclassify `tenants` from the browser-public `COLLECTIONS` bucket to
|
|
60
|
+
`SERVER_ONLY_COLLECTIONS`. The tenant document denies reads without an
|
|
61
|
+
authenticated user, so a publishable key never reached it; the bucket promised a
|
|
62
|
+
browser surface that always failed at runtime. `tenant-metadata` remains the
|
|
63
|
+
browser-public tenant identity slug, and server (secret key) access to `tenants`
|
|
64
|
+
is unchanged because `SERVER_COLLECTIONS` still contains it.
|
|
65
|
+
|
|
66
|
+
Runtime behavior changes for one case, and the change is a narrowing.
|
|
67
|
+
`SERVER_ONLY_COLLECTIONS` is a runtime guard input, not only a type: the Console
|
|
68
|
+
REST route imports it and refuses a publishable-key raw read of any member. A
|
|
69
|
+
browser request to `/api/tenants` that previously reached Payload and was denied
|
|
70
|
+
by collection access now stops at that guard and returns **404** instead of 403.
|
|
71
|
+
Both were failures before and after; only the status and the point of denial
|
|
72
|
+
move. No caller could have succeeded on this path.
|
|
73
|
+
|
|
74
|
+
Type-level impact: `tenants` leaves the `PublicCollection` union, so a browser
|
|
75
|
+
client typed against it now fails to compile instead of failing at request time.
|
|
76
|
+
|
|
77
|
+
### Patch Changes
|
|
78
|
+
|
|
79
|
+
- 05f7b8d: Send the publishable-key raw-read safety query when listing community post
|
|
80
|
+
categories, post tags, and reaction types.
|
|
81
|
+
- 2fd5f57: Synchronize generated types for the new Discount operator field descriptions (validity window, scope target requirement, usage limit minimums, unsupported each-line allocation). Comment-only; the Discount type shape and every public wire contract are unchanged.
|
|
82
|
+
- 5a523e8: Synchronize generated types for the write-only provider-credential inputs on the SDK-hidden `commerce-payment-accounts` collection. The public SDK surface is unchanged: the collection remains internal, and the two added fields are virtual Admin-only inputs that are never persisted or returned.
|
|
83
|
+
- 07db902: Send the publishable-key raw-read safety query when listing or resolving
|
|
84
|
+
community customer profile lists.
|
|
85
|
+
- 309418a: Correct three drifted README examples. The realtime sub-path import now names
|
|
86
|
+
`RealtimeConnection`, which the package actually exports (`createRealtimeClient`
|
|
87
|
+
does not exist), and publishable-key placeholders use the real `pk01_` prefix
|
|
88
|
+
instead of `pk_xxx` / `pk_live_...`. Documentation only; no runtime or type
|
|
89
|
+
change.
|
|
90
|
+
- c5e896c: Correct the generated `ShippingPolicy` field documentation. The
|
|
91
|
+
`freeShippingMinAmount` doc comment previously pointed at the shipping rates
|
|
92
|
+
array, which owns no free-shipping condition; it now names the two surfaces
|
|
93
|
+
that do — an order-amount rate row priced at 0, or an automatic
|
|
94
|
+
`free_shipping` discount with a minimum order amount. `isActive` and
|
|
95
|
+
`isDefault` gain doc comments describing their pricing side effects. Types and
|
|
96
|
+
runtime behavior are unchanged.
|
|
97
|
+
|
|
3
98
|
## 0.46.1
|
|
4
99
|
|
|
5
100
|
### Patch Changes
|
|
@@ -993,7 +1088,7 @@ displayStatus` JSDoc comment from `Order.status`. The Console removed that
|
|
|
993
1088
|
customer auth rather than public request body input. **Breaking:** **`POST
|
|
994
1089
|
/api/event-registrations/register` rejects `body.customer` with `400
|
|
995
1090
|
bad_request`;** bind customers with `Authorization: Bearer` only. See
|
|
996
|
-
`docs/events/public-api-
|
|
1091
|
+
`docs/events/public-api-reference.md` for migration. Guest-token lookup/cancel
|
|
997
1092
|
helpers send tokens in POST bodies. Range helpers support calendar, category,
|
|
998
1093
|
and tag filters aligned with the Console public range endpoint. Exported
|
|
999
1094
|
structural `RootClient` / `RootServerClient` keep `events` optional for
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ pnpm add @01.software/sdk
|
|
|
29
29
|
import { createClient } from '@01.software/sdk'
|
|
30
30
|
|
|
31
31
|
// Server-only entry - keep Secret Key code out of browser-facing imports
|
|
32
|
-
import { createServerClient } from '@01.software/sdk/server'
|
|
32
|
+
import { createServerClient, isCommerceSDKError } from '@01.software/sdk/server'
|
|
33
33
|
|
|
34
34
|
// Webhook only - webhook handlers
|
|
35
35
|
import {
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
} from '@01.software/sdk/webhook'
|
|
39
39
|
|
|
40
40
|
// Realtime only
|
|
41
|
-
import {
|
|
41
|
+
import { RealtimeConnection } from '@01.software/sdk/realtime'
|
|
42
42
|
|
|
43
43
|
// Storefront cache resource names for SSG/ISR adapters
|
|
44
44
|
import { storefrontCacheResources } from '@01.software/sdk/storefront-cache'
|
|
@@ -61,8 +61,8 @@ entry.
|
|
|
61
61
|
| Import | Feature(s) | Install when used |
|
|
62
62
|
| ----------------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
|
|
63
63
|
| `@01.software/sdk` | browser-safe `createClient`, commerce helpers, collection helpers, types | none |
|
|
64
|
-
| `@01.software/sdk/client` | browser-safe `createClient` entry
|
|
65
|
-
| `@01.software/sdk/server` | `createServerClient`, server-only
|
|
64
|
+
| `@01.software/sdk/client` | browser-safe `createClient` entry and SDK error guards | none |
|
|
65
|
+
| `@01.software/sdk/server` | `createServerClient`, server-only APIs, and SDK error guards | none; keep `secretKey` code on the server |
|
|
66
66
|
| `@01.software/sdk/errors` | SDK error classes and guards | none |
|
|
67
67
|
| `@01.software/sdk/analytics` | browser analytics client and typed event helpers | none |
|
|
68
68
|
| `@01.software/sdk/metadata` | SEO metadata extraction and generation helpers | none |
|
|
@@ -92,6 +92,9 @@ Migration quick reference:
|
|
|
92
92
|
- `createClient` remains available from `@01.software/sdk` and
|
|
93
93
|
`@01.software/sdk/client`.
|
|
94
94
|
- `createServerClient` must be imported from `@01.software/sdk/server`.
|
|
95
|
+
- Error guards are available from the same `@01.software/sdk/client` or
|
|
96
|
+
`@01.software/sdk/server` entry as the client that throws; the root and
|
|
97
|
+
`@01.software/sdk/errors` guards also classify errors across entries.
|
|
95
98
|
- React Query hooks and cache helpers must be imported from
|
|
96
99
|
`@01.software/sdk/query`.
|
|
97
100
|
- Product storefront cache resource helpers must be imported from
|
|
@@ -109,7 +112,7 @@ Migration quick reference:
|
|
|
109
112
|
// Pageviews + custom events (browser)
|
|
110
113
|
import { createAnalytics } from '@01.software/sdk/analytics'
|
|
111
114
|
|
|
112
|
-
const analytics = createAnalytics({ publishableKey: '
|
|
115
|
+
const analytics = createAnalytics({ publishableKey: 'pk01_xxx' })
|
|
113
116
|
// auto-tracks pageviews; call analytics.pageview('/custom-path') manually if needed
|
|
114
117
|
analytics.track('signup', { plan: 'pro', trial: false })
|
|
115
118
|
```
|
|
@@ -137,7 +140,7 @@ type ShopEvents = {
|
|
|
137
140
|
checkout_start: undefined // no props
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
const analytics = createAnalytics<ShopEvents>({ publishableKey: '
|
|
143
|
+
const analytics = createAnalytics<ShopEvents>({ publishableKey: 'pk01_xxx' })
|
|
141
144
|
analytics.track('signup', { plan: 'pro', trial: false }) // ✅
|
|
142
145
|
analytics.track('checkout_start') // ✅ no props
|
|
143
146
|
// analytics.track('signpu', { plan: 'pro', trial: false }) // ❌ unknown event
|
|
@@ -145,7 +148,7 @@ analytics.track('checkout_start') // ✅ no props
|
|
|
145
148
|
|
|
146
149
|
// Bind the map once to avoid repeating the generic:
|
|
147
150
|
const create = defineAnalyticsEvents<ShopEvents>()
|
|
148
|
-
const a2 = create({ publishableKey: '
|
|
151
|
+
const a2 = create({ publishableKey: 'pk01_xxx' })
|
|
149
152
|
```
|
|
150
153
|
|
|
151
154
|
**React.** Use `AnalyticsProvider` + `useAnalytics()` to fire events from
|
|
@@ -256,10 +259,12 @@ without calling the Console endpoint directly:
|
|
|
256
259
|
|
|
257
260
|
```typescript
|
|
258
261
|
const context = await server.tenant.context()
|
|
262
|
+
const productSchema = await server.tenant.collectionSchema('products')
|
|
259
263
|
|
|
260
264
|
console.log(context.features)
|
|
261
265
|
console.log(context.collections.active)
|
|
262
266
|
console.log(context.fieldConfigs)
|
|
267
|
+
console.log(productSchema.collection.customFields)
|
|
263
268
|
```
|
|
264
269
|
|
|
265
270
|
Pass `{ includeCounts: true }` only when document counts and webhook
|
|
@@ -267,6 +272,12 @@ configuration are needed. That mode bypasses the endpoint cache and performs
|
|
|
267
272
|
additional collection reads. Tenant introspection is server-only and is not
|
|
268
273
|
exported from the browser-safe root entry.
|
|
269
274
|
|
|
275
|
+
`collection.customFields` is optional and currently applies to `customers` and
|
|
276
|
+
`products`. It exposes `storagePath: 'customData'`, active definition machine
|
|
277
|
+
keys and types, optional `required: true`, and select option storage values.
|
|
278
|
+
Operator labels and stored document values are excluded; this schema metadata
|
|
279
|
+
does not grant collection read or write access.
|
|
280
|
+
|
|
270
281
|
Server-rendered preview routes can use `server.preview.detail()` with the
|
|
271
282
|
short-lived preview token issued by Console:
|
|
272
283
|
|
|
@@ -714,7 +725,7 @@ Membership self-service is split by credential boundary:
|
|
|
714
725
|
import { createClient } from '@01.software/sdk'
|
|
715
726
|
import { createServerClient } from '@01.software/sdk/server'
|
|
716
727
|
|
|
717
|
-
const client = createClient({ publishableKey: '
|
|
728
|
+
const client = createClient({ publishableKey: 'pk01_...' })
|
|
718
729
|
|
|
719
730
|
const membership = await client.memberships.me()
|
|
720
731
|
if (
|
|
@@ -725,7 +736,7 @@ if (
|
|
|
725
736
|
}
|
|
726
737
|
|
|
727
738
|
const server = createServerClient({
|
|
728
|
-
publishableKey: '
|
|
739
|
+
publishableKey: 'pk01_...',
|
|
729
740
|
secretKey: process.env.SOFTWARE_SECRET_KEY!,
|
|
730
741
|
})
|
|
731
742
|
|
|
@@ -1317,10 +1328,8 @@ Treat a replayed Cart result as an operation receipt: never replace a newer
|
|
|
1317
1328
|
cached Cart with a lower `revision`; retrieve when response ordering is unclear.
|
|
1318
1329
|
|
|
1319
1330
|
```typescript
|
|
1320
|
-
import {
|
|
1321
|
-
|
|
1322
|
-
isCommerceSDKError,
|
|
1323
|
-
} from '@01.software/sdk'
|
|
1331
|
+
import { createCommerceIdempotencyKey } from '@01.software/sdk'
|
|
1332
|
+
import { isCommerceSDKError } from '@01.software/sdk/errors'
|
|
1324
1333
|
|
|
1325
1334
|
const checkoutIdempotencyKey = createCommerceIdempotencyKey()
|
|
1326
1335
|
const { checkout, checkoutToken } = await client.commerce.checkouts.create({
|
|
@@ -1345,12 +1354,57 @@ if (
|
|
|
1345
1354
|
// Initialize the Toss widget with the returned public client/variant fields.
|
|
1346
1355
|
}
|
|
1347
1356
|
|
|
1357
|
+
// PortOne Hosted V2 uses the same canonical lifecycle with a provider-specific
|
|
1358
|
+
// HTTPS action. Redirect completion is not payment finality; retrieve the
|
|
1359
|
+
// PaymentSession and let Console converge from PortOne's authenticated API.
|
|
1360
|
+
const portOneSession = await client.commerce.paymentSessions.createPortOne({
|
|
1361
|
+
checkoutToken,
|
|
1362
|
+
provider: 'portone',
|
|
1363
|
+
providerOptions: { profile: 'hosted_v2', paymentMethod: 'CARD_KR' },
|
|
1364
|
+
idempotencyKey: createCommerceIdempotencyKey(),
|
|
1365
|
+
})
|
|
1366
|
+
if (
|
|
1367
|
+
portOneSession.presentationStatus === 'actionable' &&
|
|
1368
|
+
portOneSession.nextAction.type === 'portone_checkout'
|
|
1369
|
+
) {
|
|
1370
|
+
window.location.assign(portOneSession.nextAction.checkoutUrl)
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
// Standard V2 is a distinct Browser SDK capability, not a Hosted fallback.
|
|
1374
|
+
// Do not treat the SDK result or mobile redirect as payment finality.
|
|
1375
|
+
const standardPortOneSession =
|
|
1376
|
+
await client.commerce.paymentSessions.createPortOne({
|
|
1377
|
+
checkoutToken,
|
|
1378
|
+
provider: 'portone',
|
|
1379
|
+
providerOptions: { profile: 'standard_v2', paymentMethod: 'CARD' },
|
|
1380
|
+
idempotencyKey: createCommerceIdempotencyKey(),
|
|
1381
|
+
})
|
|
1382
|
+
if (
|
|
1383
|
+
standardPortOneSession.presentationStatus === 'actionable' &&
|
|
1384
|
+
standardPortOneSession.nextAction.type === 'portone_sdk'
|
|
1385
|
+
) {
|
|
1386
|
+
// PortOne V2 requires its currency constant (`CURRENCY_KRW`), not ISO `KRW`.
|
|
1387
|
+
// await PortOne.requestPayment(standardPortOneSession.nextAction)
|
|
1388
|
+
// Always retrieve the session afterwards; Console lookup/webhook is authoritative.
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1348
1391
|
// Browser recovery requires the parent capability.
|
|
1349
1392
|
await client.commerce.paymentSessions.retrieve({
|
|
1350
1393
|
paymentSessionId: paymentSession.id,
|
|
1351
1394
|
checkoutToken,
|
|
1352
1395
|
})
|
|
1353
1396
|
|
|
1397
|
+
await client.commerce.paymentSessions.retrievePortOne({
|
|
1398
|
+
paymentSessionId: portOneSession.id,
|
|
1399
|
+
checkoutToken,
|
|
1400
|
+
})
|
|
1401
|
+
|
|
1402
|
+
// The server equivalent requires a write-capable credential because the
|
|
1403
|
+
// provider-authoritative lookup can converge and finalize domain state.
|
|
1404
|
+
await server.commerce.paymentSessions.retrievePortOne({
|
|
1405
|
+
paymentSessionId: portOneSession.id,
|
|
1406
|
+
})
|
|
1407
|
+
|
|
1354
1408
|
// Toss confirmation is a typed server-only adapter action. There is no generic
|
|
1355
1409
|
// `confirmVerified` or provider-paid Order creation escape hatch.
|
|
1356
1410
|
const confirmationIdempotencyKey = createCommerceIdempotencyKey()
|
|
@@ -1389,6 +1443,12 @@ authoritative API response or signed webhook, then report the exact captured
|
|
|
1389
1443
|
identity and Money. The create response is intentionally limited to
|
|
1390
1444
|
`{ id, provider, providerSessionId, money }`.
|
|
1391
1445
|
|
|
1446
|
+
Custom bridge sessions intentionally remain `null` in
|
|
1447
|
+
`checkout.paymentState.activePaymentSession`: Checkout exposes only managed
|
|
1448
|
+
adapters from its closed provider vocabulary. Persist the `providerSessionId`
|
|
1449
|
+
returned by `custom.create` and use `custom.retrieve` with that identity as the
|
|
1450
|
+
supported custom-lane settlement recovery path.
|
|
1451
|
+
|
|
1392
1452
|
```typescript
|
|
1393
1453
|
const customSession = await server.commerce.paymentSessions.custom.create({
|
|
1394
1454
|
provider: 'my-provider',
|
|
@@ -1396,6 +1456,12 @@ const customSession = await server.commerce.paymentSessions.custom.create({
|
|
|
1396
1456
|
idempotencyKey: createCommerceIdempotencyKey(),
|
|
1397
1457
|
})
|
|
1398
1458
|
|
|
1459
|
+
// A recovery path can resolve the custom session without a 01 session ID.
|
|
1460
|
+
const pending = await server.commerce.paymentSessions.custom.retrieve({
|
|
1461
|
+
provider: customSession.provider,
|
|
1462
|
+
by: { providerSessionId: customSession.providerSessionId },
|
|
1463
|
+
})
|
|
1464
|
+
|
|
1399
1465
|
const verifiedCapture = await verifyMyProviderCapture({
|
|
1400
1466
|
expectedAmount: customSession.money.amountMinor,
|
|
1401
1467
|
expectedCurrency: customSession.money.currency,
|
|
@@ -1416,8 +1482,22 @@ const customConfirmation = await server.commerce.paymentSessions.custom.confirm(
|
|
|
1416
1482
|
)
|
|
1417
1483
|
|
|
1418
1484
|
console.log(customConfirmation.orderId)
|
|
1485
|
+
|
|
1486
|
+
const recovered = await server.commerce.paymentSessions.custom.retrieve({
|
|
1487
|
+
provider: customSession.provider,
|
|
1488
|
+
by: { providerPaymentId: verifiedCapture.paymentId },
|
|
1489
|
+
})
|
|
1490
|
+
if (recovered.finalizationStatus === 'committed') {
|
|
1491
|
+
console.log(recovered.orderId)
|
|
1492
|
+
}
|
|
1419
1493
|
```
|
|
1420
1494
|
|
|
1495
|
+
`custom.retrieve` is an exact lookup by either `providerSessionId` or
|
|
1496
|
+
`providerPaymentId` (exactly one). It returns only bounded recovery state:
|
|
1497
|
+
provider identity, session/provider/finalization status, Money, and the resolved
|
|
1498
|
+
`orderId`. It does not list sessions or expose raw PaymentSession relations,
|
|
1499
|
+
provider evidence, credentials, or fingerprints.
|
|
1500
|
+
|
|
1421
1501
|
If the tenant's custom-provider policy requires HMAC, pass
|
|
1422
1502
|
`{ createProof(rawBody) }` as the second argument to `custom.confirm`. The
|
|
1423
1503
|
callback receives the exact JSON bytes the SDK sends and returns `{ timestamp,
|
|
@@ -1436,6 +1516,38 @@ Canonical commerce error envelopes become `CommerceSDKError`. Branch on its
|
|
|
1436
1516
|
stable `reason`, inspect `retryable`, and log `requestId`; a newer server reason
|
|
1437
1517
|
is preserved as `reason: 'unknown_commerce_error'` plus `rawReason`.
|
|
1438
1518
|
|
|
1519
|
+
Non-commerce endpoints preserve their open-ended machine reason separately as
|
|
1520
|
+
`SDKError.apiReason`. Use `getSDKErrorReason(error)` when shared error handling
|
|
1521
|
+
must read either family: it returns the canonical commerce reason, the verbatim
|
|
1522
|
+
unknown commerce `rawReason`, or the non-commerce `apiReason`. Existing
|
|
1523
|
+
`details` payloads remain available for compatibility, but consumers no longer
|
|
1524
|
+
need to normalize `details.reason` and `details.body.reason` themselves.
|
|
1525
|
+
|
|
1526
|
+
#### Idempotent mutation results are not exactly-once receipts
|
|
1527
|
+
|
|
1528
|
+
No commerce mutation response field is a safe exactly-once gate for a
|
|
1529
|
+
non-idempotent side effect such as an operational alert, outbound webhook, or
|
|
1530
|
+
ledger entry. Use a consumer-owned durable claim keyed by the side effect's
|
|
1531
|
+
stable logical identity. The public webhook guide's
|
|
1532
|
+
[`processOnce`](https://docs.01.software/developers/webhooks) pattern uses a
|
|
1533
|
+
database unique key, queue idempotency store, or provider-safe send ledger.
|
|
1534
|
+
|
|
1535
|
+
`custom.confirm` returns `alreadyConfirmed: true` when the session was already
|
|
1536
|
+
confirmed at observation time. It does not attribute the transition to the
|
|
1537
|
+
current call. The field is absent from the initial successful confirmation, so
|
|
1538
|
+
code that only interprets the response shape must test
|
|
1539
|
+
`'alreadyConfirmed' in result`, not `result.alreadyConfirmed === false`. That
|
|
1540
|
+
presence check is still not a side-effect gate: when the initial commit succeeds
|
|
1541
|
+
but its response is lost, a retry returns `alreadyConfirmed: true` and would
|
|
1542
|
+
otherwise silently miss the transition.
|
|
1543
|
+
|
|
1544
|
+
Likewise, the `orders.cancelOrder` fields `cancelCommitted` and
|
|
1545
|
+
`alreadyCanceled` are domain effect dispositions, not transport replay markers.
|
|
1546
|
+
A same-key retry replays the cached initial 2xx body byte-for-byte and can
|
|
1547
|
+
therefore return the original `cancelCommitted: true` again. Neither field says
|
|
1548
|
+
whether the response was replayed or whether an external side effect has already
|
|
1549
|
+
run.
|
|
1550
|
+
|
|
1439
1551
|
### Commerce Orders (post-placement operations)
|
|
1440
1552
|
|
|
1441
1553
|
Provider-paid `orders.create`, `orders.confirmPayment`, and ordinary
|
|
@@ -1693,6 +1805,25 @@ replacement API. Pass an empty list to clear codes. Singular `admission`,
|
|
|
1693
1805
|
Browser `mine()`/`merge({ guestCartToken })` derive customer identity from the
|
|
1694
1806
|
JWT; server calls require an explicit `customerToken`.
|
|
1695
1807
|
|
|
1808
|
+
### Community public reads
|
|
1809
|
+
|
|
1810
|
+
Use the shaped `community` helpers for browser/customer community screens. A
|
|
1811
|
+
publishable key is sufficient for list and detail reads; a customer JWT may be
|
|
1812
|
+
attached for the same response shape, but no secret key is needed.
|
|
1813
|
+
|
|
1814
|
+
```typescript
|
|
1815
|
+
const page = await client.community.listPosts({ limit: 20 })
|
|
1816
|
+
const post = await client.community.getPost({ postId: page.docs[0].id })
|
|
1817
|
+
|
|
1818
|
+
if (!post) {
|
|
1819
|
+
// Missing, hidden, and cross-tenant posts are intentionally indistinguishable.
|
|
1820
|
+
}
|
|
1821
|
+
```
|
|
1822
|
+
|
|
1823
|
+
`getPost()` returns the allowlisted `CommunityPost` DTO and resolves `404
|
|
1824
|
+
not_found` to `null`. Raw `client.collections.from('posts')` remains
|
|
1825
|
+
server-only; do not use it in browser or customer template code.
|
|
1826
|
+
|
|
1696
1827
|
### Community Moderation (ServerClient-only)
|
|
1697
1828
|
|
|
1698
1829
|
Available only on ServerClient via `server.community.moderation.*`.
|
|
@@ -1802,7 +1933,7 @@ Source of truth: `packages/published/sdk/src/core/collection/const.ts` (`COLLECT
|
|
|
1802
1933
|
|
|
1803
1934
|
| Category | Browser-public generic collections |
|
|
1804
1935
|
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1805
|
-
| Tenant | `
|
|
1936
|
+
| Tenant | `tenant-metadata` |
|
|
1806
1937
|
| Products | `products`, `product-variants`, `product-options`, `product-option-values`, `product-categories`, `product-tags`, `product-collections`, `markets`, `brands` |
|
|
1807
1938
|
| Customers | `customer-profiles` |
|
|
1808
1939
|
| Commerce | `discounts`, `shipping-policies`, `shipping-zones` |
|