SDK
기본 구현 경로에는 TypeScript SDK를 사용합니다.
SDK
프론트엔드, 서버 route, 워크플로를 01.software 규칙에 맞춰 구현할 때 SDK를 사용합니다.
설정 흐름
패키지 설치
프로젝트가 이미 사용하는 패키지 매니저로 @01.software/sdk를 추가합니다.
브라우저 클라이언트 생성
Publishable Key는 승인된 origin에서만 사용합니다. 브라우저 client는 공개 읽기와 capability 또는 customer 권한으로 승인된 Cart, Checkout, PaymentSession 작업을 지원합니다.
서버 클라이언트 생성
Secret Key는 신뢰할 수 있는 서버 코드에서 쓰기와 권한 워크플로에만 사용합니다.
검증
인계 전에 대상 프로젝트의 typecheck, lint, test, build를 실행합니다.
클라이언트 선택
| 위치 | 클라이언트 | 메모 |
|---|---|---|
| 브라우저 UI | browser client | 공개 읽기와 capability/customer 권한 commerce 작업, origin 제한 |
| 서버 route | server client | 서버 권위 작업과 권한 작업에는 @01.software/sdk/server에서 import |
| React 데이터 fetching | query helpers | 캐시와 loading 상태 명시 |
| AI 생성 코드 | 기존 프로젝트 패턴 | 새 프레임워크 계층 추가 금지 |
Collection find/count는 null 동등 조건을 보존하고, 지원하지 않는 필터는
요청 전에 거절합니다. where: {}도 ValidationError를 던지므로 조건이
남지 않으면 where를 생략하세요. 이 읽기 입력 제한은
BREAKING (0.x minor) 변경입니다. 동적으로 만든 ID 목록이 비면 조회 전에 빈 결과를
반환하세요. 읽기·bulk 공통 제한과 지원 값은 SDK README 필터 안내를
참고하세요.
Import 경계
브라우저 안전 client, commerce helper, core type에는 @01.software/sdk를
사용합니다. createServerClient는 @01.software/sdk/server에서 import하고,
React Query helper가 필요할 때만 @01.software/sdk/query를 사용합니다. 오류
가드는 client를 만드는 client/server entry에서 사용할 수 있으며, root와
@01.software/sdk/errors entry 사이에서도 동일한 오류를 판별합니다.
none으로 표시된 항목은 @01.software/sdk 외에 추가 패키지가 필요하지
않습니다.
| Import | Feature(s) | 설치할 때 |
|---|---|---|
@01.software/sdk | browser-safe createClient, commerce helpers, collection helpers, types | none |
@01.software/sdk/client | browser-safe createClient entry and SDK error guards | none |
@01.software/sdk/server | createServerClient, server-only APIs, and SDK error guards | none; secretKey 코드는 서버에 둡니다 |
@01.software/sdk/errors | SDK error classes and guards | none |
@01.software/sdk/metadata | SEO metadata extraction and generation helpers | none |
@01.software/sdk/webhook | webhook handlers, event guards, and webhook types | none |
@01.software/sdk/query | React Query hooks, cache helpers, getQueryClient | @tanstack/react-query, react, react-dom |
@01.software/sdk/realtime | RealtimeConnection, useRealtimeQuery | @tanstack/react-query, react, react-dom |
@01.software/sdk/storefront-cache | product storefront cache resource helper | none |
@01.software/sdk/embedded-admin | embedded app 브라우저 handshake와 protocol type | none |
@01.software/sdk/embedded-admin/server | assertion 검증과 JWKS 조회 | none; receiver session 생성은 서버에 둡니다 |
@01.software/sdk/ui/rich-text | RichTextContent, StyledRichTextContent | react, react-dom, @payloadcms/richtext-lexical |
@01.software/sdk/ui/form | FormRenderer | react, react-dom |
@01.software/sdk/ui/code-block | CodeBlock, highlight | react, react-dom, shiki, hast-util-to-jsx-runtime |
@01.software/sdk/ui/canvas | CanvasRenderer, CanvasFrame, useCanvas, prefetchCanvas | react, react-dom, @tanstack/react-query, @xyflow/react, quickjs-emscripten, postcss, sucrase |
@01.software/sdk/ui/canvas/server | canvas server helpers | none |
@01.software/sdk/ui/video | VideoPlayer | react, react-dom, @mux/mux-player-react |
@01.software/sdk/ui/image | Image | react, react-dom |
동영상 재생
VOD 재생은 앱 서버에서 시청자의 콘텐츠 접근 권한을 확인한 뒤
createServerClient(...).video.playback(video.id)로 URL을 발급합니다. 반환된
streamUrl을 <VideoPlayer video={video} streamUrl={streamUrl} />에 전달하고,
긴 재생이나 일시정지 뒤에는 2시간 만료 전에 갱신해야 합니다. Free 재생은 전송량을 차감하는 게이트웨이를
사용하며 월 한도 초과 시 403, 사용량 확인 불가 시 503을 반환할 수 있습니다.
기존 Mux URL 유틸리티는 전환되지 않은 유료 자산에만 사용합니다. 전환된 자산의
저장된 공개 ID는 과거 사용량 증빙용이며 재생 주소가 아닙니다.
아래 저장 비율 매핑은 SDK 0.66.3 이상이 필요하며 공개 0.65.1 배포본에는 없습니다. 저장소 소스에 존재하는 것과 패키지 게시는 별개입니다.
VideoPlayer는 저장된 aspectRatio 값 16_9, 9_16, 4_3, 1_1을
placeholder와 ready player 모두에서 CSS 비율로 표시합니다. 미설정 시 기본값은
16/9입니다. ready player는 style.aspectRatio, placeholder는
placeholderStyle.aspectRatio로 덮어쓸 수 있으며, 각 스타일은 해당 렌더 경로에만
적용됩니다.
CanvasRenderer는 예약 shape 노드(terminator, process, decision,
io, subprocess)를 워크스페이스 카탈로그 행이나 QuickJS 템플릿 없이 1st-party SVG
도형으로 렌더링합니다.
목록에 없는 feature는 별도 peer install이 필요하지 않습니다. 전체 매핑은 SDK package README에서 확인합니다.
갤러리 이미지와 영상 아이템
브라우저에서 사용할 수 있는 shaped helper로 공개 갤러리를 편집 순서대로 읽습니다.
const gallery = await client.content.galleryItems.list({
gallerySlug: 'spring-lookbook',
limit: 24,
})아이템의 mediaType: 'image' | 'video'는 선택 필드이며, 이전 응답에 값이
없으면 image로 처리합니다. 이미지 아이템은 기존 image 미디어를 유지합니다.
영상 아이템은 video.availability: 'ready' | 'processing' | 'unavailable'를
포함하며, 영상 문서 id와 안전한 업로드 thumbnail을 포함할 수 있습니다.
영상 기능이 꺼졌거나 플랜에서 차단된 경우, 대상이 없거나 삭제된 경우, 처리에
실패한 경우에는 { availability: 'unavailable' }만 반환하고 아이템 위치와
페이지 정보를 유지합니다. 이미지 관계를 영상 포스터로 사용하지 않습니다.
ready는 준비 상태이며 재생 권한을 뜻하지 않습니다. 앱 서버에서 요청한 영상이
공개 갤러리와 아이템에 속하는지 확인하고 시청자 접근 정책을 적용한 다음
server.video.playback(video.id)를 호출하세요. 반환된 streamUrl을 플레이어에
전달하면 재생 승인이 현재 워크스페이스, 영상 상태, 기능과 플랜을 다시 확인합니다.
서버 자격 증명은 앱 서버에 보관합니다. 갤러리 DTO에는 재생 URL, provider ID,
토큰, 비공개 저장소 필드가 포함되지 않습니다.
도메인과 전문 연동 참조
- Customers SDK: 고객 identity, hosted 세션과 출처 인식형 그룹 참조.
- Ecommerce SDK: 마켓, 상품 수정, 주문과 storefront 캐시 참조.
- Events SDK: 이벤트의 canonical 날짜와 유료 입장권 projection 참조.
- Community SDK: 브라우저용 게시물 읽기와 nullable 상세 결과 참조.
- Payments: 결제 action 재사용, reconcile과 서버 전용 custom bridge.
- Membership: 유료 구독 준비와 서명된 청구 결과 전달.
- Embedded Admin: 고정 origin 경계에서 embedded app 세션 수신과 검증.
- External Effects: 서버 전용 외부 작업 기록, 설치 암호문 보관과 고객 연결.
유료 Membership 구독
본문과 예제: Membership.
Embedded Admin App
본문과 예제: Embedded Admin.
오류 reason
Canonical commerce 실패는 닫힌 typed reason을 CommerceSDKError.reason에
그대로 유지합니다. 그 밖의 endpoint는 open-ended machine reason을
SDKError.apiReason에 노출합니다. 공통 오류 처리에서는
@01.software/sdk/errors의 getSDKErrorReason을 사용하면
details.reason이나 details.body.reason을 직접 검사하지 않고 두 family를
모두 읽을 수 있으며, 알 수 없는 commerce reason은 rawReason 원문으로
반환됩니다.
PortOne Standard V2 취소와 재시도
본문과 예제: Payments.
서버 전용 PortOne identity reconcile
본문과 예제: Payments.
서버 전용 커스텀 결제 bridge
본문과 예제: Payments.
멱등 mutation 응답은 exactly-once 게이트가 아닙니다
본문과 예제: Payments.
기존 품목의 기본 가격 수정
본문과 예제: Ecommerce SDK.
주문 수정 호환성
본문과 예제: Ecommerce SDK.
외부 작업 기록 (서버 전용)
본문과 예제: External Effects.
설치 자격 암호문 보관 (서버 전용)
본문과 예제: External Effects.
테넌트 컨텍스트 조회
신뢰할 수 있는 서버 워크플로에서는 서버 전용 client로 해석된 워크스페이스 feature, 활성·비활성 collection, field configuration을 조회할 수 있습니다:
import { createServerClient } from '@01.software/sdk/server'
const server = createServerClient({
publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
secretKey: process.env.SOFTWARE_SECRET_KEY!,
})
const context = await server.tenant.context()
const productSchema = await server.tenant.collectionSchema('products')Collection count와 webhook configuration이 필요할 때만
server.tenant.context({ includeCounts: true })를 사용하세요. 이 모드는 추가
읽기를 수행하므로 기본 호출보다 느립니다. 이 API와 두 credential은 신뢰할 수
있는 서버 코드에만 두세요.
productSchema.collection.customFields는 optional입니다. 값이 있으면
customData에 저장되는 active tenant-defined field를 machine key, type,
optional required marker, select option 저장값으로 설명합니다. 운영자 label과
저장된 document 값은 제외되며 실제 read/write는 기존 collection 권한을 그대로
따릅니다.
출처 인식형 고객 그룹
본문과 예제: Customers SDK.
외부 Customer 연결
본문과 예제: External Effects.
고객 인증
본문과 예제: Customers SDK.
고객 셀프 탈퇴
본문과 예제: Customers SDK.
커뮤니티 공개 읽기
본문과 예제: Community SDK.
이벤트 범위와 종일 날짜
본문과 예제: Events SDK.
이벤트 입장권
본문과 예제: Events SDK.
마켓 컨텍스트
본문과 예제: Ecommerce SDK.
Analytics
웹사이트 분석에는 GA4, Plausible, Vercel Analytics 같은 외부 도구를 직접 연동하세요. SDK는 더 이상 분석 수집 헬퍼를 제공하지 않습니다.
Storefront Cache Resources
본문과 예제: Ecommerce SDK.
Next.js 매핑
본문과 예제: Ecommerce SDK.
운영 전 확인
- 워크스페이스 플랜에서 collection과 기능 사용 가능 여부를 확인합니다.
- 키 저장 위치와 회전 담당자를 확인합니다.
- 고객 노출 흐름의 실패 처리 경로를 확인합니다.
Secret Key 값을 브라우저 bundle, public env, analytics event, 생성 예제에 넣지 않습니다.
오류, 재시도와 요청 identity
번역되는 error 문구 대신 machine reason으로 분기하고 지원용 requestId를 보존하세요. 알 수 없는 reason도 처리해야 합니다. Canonical commerce는 CommerceSDKError.reason(미지 값은 rawReason), 일반 오류는 SDKError.apiReason이며 getSDKErrorReason으로 둘 다 읽습니다. 잘못된 canonical envelope나 body/header request ID 불일치는 protocol 오류입니다.
SDK 자동 재시도는 safe method의 408/500/502/503/504에 bounded backoff로만 적용합니다. terminal 429는 자동 재시도하지 않으며 Retry-After를 따릅니다. Customer-token 401은 token_expired일 때만 refresh 재시도 1회를 허용합니다. token exchange나 unsafe mutation을 자동 재전송하지 마세요. 지원 mutation의 응답이 끊기면 원래 durable idempotencyKey를 재사용합니다. 응답 flag로 자신의 부수 효과가 중복 제거되지는 않습니다.
분할 예제는 공개 SDK 0.65.1, 필요한 곳에서 Next.js 16.3.8, Node 24.15.0을 사용합니다. workspace source의 import/peer 검사, npm artifact 컴파일, 통제된 로컬 runtime, 원격 서비스 제공 여부는 별도 관찰입니다. 완전한 앱 세션과 배포 검사는 연결된 작업 가이드를 따르세요.
다음 액션
- 정확한 HTTP 계약이 필요하면 API를 엽니다.
- shell 사용 coding agent가 필요하면 CLI를 엽니다.
- hosted·shell 없는 discovery가 필요하면 MCP를 엽니다.
- 이벤트 전달이 필요하면 웹훅을 엽니다.
- 즉시 사용 가능한 커머스 흐름이 필요하면 커머스 헬퍼를 참고합니다.
고객 혜택권
tenant-admin은 콘솔에서 혜택권 정의를 관리합니다. 혜택권은 1회용 비금전 혜택이며 Checkout 할인·적립금에 영향을 주지 않습니다. 발급 대상과 시점은 워크스페이스 서버가 결정합니다(멤버십 webhook, 자체 cron 등). source 유일성은 중복 효과만 막으며 자격이나 일정은 검증하지 않습니다.
import { createServerClient } from '@01.software/sdk/server'
const server = createServerClient({ publishableKey, secretKey })
const { voucher, created } = await server.benefitVouchers.issue({
definitionId,
customerId,
sourceNamespace: 'member-benefits',
sourceRef: 'period:2030-01:member-opaque-id',
})
const redeemed = await server.benefitVouchers.redeem({
customerId,
voucherId: voucher.id,
requestId,
actorRef: 'staff:opaque-id',
})서버 benefitVouchers.get({ customerId, voucherId }), list({ customerId, state?, definitionId?, limit?, cursor? })는 read scope, issue, redeem, voidVoucher({ customerId, voucherId, requestId, actorRef, reason })는 write scope가 필요합니다. sk01 서버 키를 사용하고 Origin을 보내지 않습니다. 무효화 사유는 issued_in_error, benefit_revoked, customer_request, other입니다. 발급·사용에는 Ecommerce와 Customers가 모두 활성화되어야 하며, 기능을 해제해도 서버 get/list·고객 본인 목록·무효화는 유지됩니다. 콘솔 패널은 고객 상세 안에 있으므로 Customers를 끄면 고객 상세와 함께 표시되지 않습니다.
발급 결과를 모르면 같은 sourceNamespace/sourceRef와 같은 요청으로 재시도합니다. 사용·무효화는 request UUID를 한 번 생성하여 재사용합니다. POST 명령은 자동 재시도하지 않습니다. 같은 식별자를 다른 요청에 쓰면 409입니다. 사용·무효화는 되돌릴 수 없고, 만료는 DB 시각으로 판단하며 expiresAt과 같으면 만료입니다. 정정은 무효화 후 새 source identity로 발급합니다.
고객은 client.benefitVouchers.listMine({ status: 'available', limit: 20 })로 본인 목록만 읽습니다. status: 'all'은 이력을 포함하며 nextCursor로 다음 페이지를 조회합니다(최대 100건). 응답은 식별자·고객 안내·상태·시각만 포함하고 private, no-store입니다. 서버 조회는 customerId가 필수이며 다른 고객·tenant 대상은 404로 처리합니다. 콘솔 고객 상세에서는 역할에 따른 사용 처리·무효화 확인도 제공합니다.
직원 앱 서버는 사용 전에 직원 권한과 고객을 확인해야 합니다. voucherId 자체는 사용 권한이 아닙니다. actorRef는 앱이 주장한 증거이며 플랫폼이 검증한 직원 신원이나 권한 입력이 아닙니다. sourceRef·actorRef에는 개인정보 없이 불투명 식별자를 사용합니다. 발급 시 이름·안내·만료 시각을 복사하므로 정의를 수정해도 기존 혜택권은 바뀌지 않습니다. 이력은 고객 개인정보 삭제 뒤에도 보존되고 tenant 영구 삭제를 차단합니다. 참조된 정의는 보관 처리합니다.