> ## Documentation Index
> Fetch the complete documentation index at: https://docs.headlesscommerce.io/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK

> Headless Commerce API 공식 TypeScript 및 Python 클라이언트

# SDK

타입 안전하고 프로덕션에 바로 사용할 수 있는 Headless Commerce API 클라이언트입니다.

## 설치

<Tabs>
  <Tab title="TypeScript / Node.js">
    <CodeGroup>
      ```bash npm theme={null}
      npm install @headless-commerce/sdk
      ```

      ```bash pnpm theme={null}
      pnpm add @headless-commerce/sdk
      ```

      ```bash yarn theme={null}
      yarn add @headless-commerce/sdk
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    <CodeGroup>
      ```bash pip theme={null}
      pip install headless-commerce
      ```

      ```bash poetry theme={null}
      poetry add headless-commerce
      ```

      ```bash uv theme={null}
      uv add headless-commerce
      ```
    </CodeGroup>

    **요구 사항:** Python 3.10 이상. 유일한 런타임 의존성은 [httpx](https://www.python-httpx.org/)입니다.
  </Tab>
</Tabs>

## 빠른 시작

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { HeadlessCommerce } from '@headless-commerce/sdk';

    // Admin 클라이언트 (서버 사이드)
    const admin = new HeadlessCommerce({
      secretKey: 'sk_test_your_key',
    });

    // Storefront 클라이언트 (클라이언트 사이드에서 안전하게 사용 가능)
    const storefront = new HeadlessCommerce({
      publishableKey: 'pk_test_your_key',
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from headless_commerce import HeadlessCommerce

    # 컨텍스트 매니저로 리소스를 안전하게 정리합니다
    with HeadlessCommerce(api_key="sk_test_your_key") as client:
        products = client.products.list({"limit": 10})
        print(products["data"])
    ```

    비동기 애플리케이션(FastAPI, Django async 등)의 경우:

    ```python theme={null}
    from headless_commerce import AsyncHeadlessCommerce

    async with AsyncHeadlessCommerce(api_key="sk_test_your_key") as client:
        products = await client.products.list({"limit": 10})
    ```
  </Tab>
</Tabs>

## 사용 예시

### 상품 목록 조회

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const { data, has_more } = await storefront.products.list({
      status: 'active',
      limit: 20,
    });
    // data: Product[] — 자동 완성이 지원되는 완전한 타입
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    result = client.products.list({
        "q": "shirt",
        "limit": 20,
    })
    # result["data"] — 상품 목록
    # result["has_more"] — 추가 페이지 존재 여부
    ```
  </Tab>
</Tabs>

### 장바구니 플로우

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    // 장바구니 생성
    const cart = await storefront.carts.create({
      session_id: 'guest-session-123',
    });

    // 상품 추가
    await storefront.carts.addItem(cart.id, {
      variant_id: 'var_001',
      quantity: 2,
    });

    // 계산된 합계가 포함된 장바구니 조회
    const updated = await storefront.carts.get(cart.id);
    console.log(updated.summary.total);
    // { amount: 78000, currency: "KRW" }

    // 체크아웃
    const order = await storefront.carts.checkout(cart.id, {
      email: 'customer@example.com',
      payment_provider: 'stripe',
      payment_method_id: 'pm_xxx',
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # 장바구니 생성
    cart = client.carts.create()

    # 상품 추가
    cart = client.carts.add_item(cart["id"], {
        "variant_id": "var_001",
        "quantity": 2,
    })

    # 합계 확인
    print(cart["summary"]["total"])
    # {"amount": 78000, "currency": "KRW"}

    # 체크아웃
    order = client.checkout.create(cart["id"], {
        "email": "customer@example.com",
        "payment_provider": "stripe",
        "payment_method_id": "pm_xxx",
    })
    ```
  </Tab>
</Tabs>

### 관리자 작업

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    // 옵션이 포함된 상품 생성
    const product = await admin.products.create({
      name: 'Classic T-Shirt',
      type: 'physical',
      status: 'draft',
      options: [
        { name: 'Size', values: ['S', 'M', 'L'] },
        { name: 'Color', values: ['Black', 'White'] },
      ],
    });

    // 자동 페이지네이션
    for await (const order of admin.orders.listAll({ status: 'confirmed' })) {
      console.log(order.number);
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # 상품 생성
    product = client.products.admin_create({
        "name": "Classic T-Shirt",
        "type": "physical",
        "status": "draft",
        "options": [
            {"name": "Size", "values": ["S", "M", "L"]},
            {"name": "Color", "values": ["Black", "White"]},
        ],
    })

    # 자동 페이지네이션 (모든 페이지의 항목을 순회)
    for product in client.products.admin_list_auto_paginate():
        print(product["name"])
    ```
  </Tab>
</Tabs>

## 오류 처리

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { HeadlessCommerceError } from '@headless-commerce/sdk';

    try {
      const product = await storefront.products.get('nonexistent');
    } catch (error) {
      if (error instanceof HeadlessCommerceError) {
        console.log(`API 오류 ${error.status}: ${error.code} — ${error.message}`);
      }
    }
    ```
  </Tab>

  <Tab title="Python">
    SDK는 HTTP 상태 코드에 매핑되는 타입 지정 예외를 발생시킵니다:

    ```python theme={null}
    from headless_commerce import (
        HeadlessCommerceError,  # 기본 클래스 — 모든 오류를 포착
        NotFoundError,          # 404
        ValidationError,        # 400 / 422
        AuthenticationError,    # 401
        RateLimitError,         # 429
        InternalServerError,    # 500+
    )

    try:
        product = client.products.get("nonexistent")
    except NotFoundError as e:
        print(f"찾을 수 없음: {e}")
    except HeadlessCommerceError as e:
        print(f"API 오류 {e.status}: {e.code} — {e}")
        print(f"요청 ID: {e.request_id}")
    ```

    모든 하위 클래스는 `HeadlessCommerceError`를 상속하므로, 특정 오류를 개별적으로 처리하거나 한꺼번에 처리할 수 있습니다.
  </Tab>
</Tabs>

## 웹훅 검증

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import crypto from 'node:crypto';

    function verifyWebhook(payload: string, signature: string, secret: string): boolean {
      const expected = crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');
      return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
    }
    ```

    전체 통합 패턴은 [웹훅 가이드](/ko/webhooks)를 참고하세요.
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from headless_commerce import verify_webhook_signature

    is_valid = verify_webhook_signature(
        payload=request.body,
        signature=request.headers["x-webhook-signature"],
        secret="whsec_your_secret",
    )
    ```

    타임스탬프 재전송 공격 방지:

    ```python theme={null}
    verify_webhook_signature(
        payload=request.body,
        signature=request.headers["x-webhook-signature"],
        secret="whsec_your_secret",
        timestamp=request.headers["x-webhook-timestamp"],
        tolerance=300,  # 5분 이상 경과한 요청 거부
    )
    ```
  </Tab>
</Tabs>

## 설정

<Tabs>
  <Tab title="TypeScript">
    | 옵션 | 타입 | 필수 | 설명 |
    | - | - | - | - |
    | `secretKey` | string | \* | 서버 사이드용 비밀 API 키 |
    | `publishableKey` | string | \* | 클라이언트 사이드용 공개 키 |
    | `baseUrl` | string | 아니오 | 커스텀 API 기본 URL (기본값: `https://api.headlesscommerce.io/v1`) |

    <Info>
      `secretKey` 또는 `publishableKey` 중 하나가 필수입니다.
    </Info>
  </Tab>

  <Tab title="Python">
    | 옵션 | 타입 | 필수 | 설명 |
    | - | - | - | - |
    | `api_key` | str | 예 | API 키 (관리자용 `sk_*`, 스토어프론트용 `pk_*`) |
    | `base_url` | str | 아니오 | 커스텀 API 기본 URL (기본값: `https://api.headlesscommerce.io/v1`) |
    | `max_retries` | int | 아니오 | 429/5xx 오류 시 최대 재시도 횟수 (기본값: `2`) |
    | `timeout` | float | 아니오 | 요청 타임아웃(초) (기본값: `30`) |
    | `http_client` | httpx.Client | 아니오 | 프록시/mTLS/전송용 커스텀 httpx 클라이언트 |

    ### 재시도 동작

    SDK는 다음 상황에서 자동으로 재시도합니다:

    * **429** Too Many Requests (`Retry-After` 헤더를 준수)
    * **5xx** 서버 오류
    * 네트워크 오류 및 타임아웃

    재시도는 지터가 적용된 지수 백오프를 사용합니다. 재시도 불가능한 오류(400, 401, 404, 422)는 즉시 실패합니다.
  </Tab>
</Tabs>

## 리소스

총 23개의 API 리소스를 사용할 수 있습니다:

| 리소스 | 스토어프론트 | 관리자 |
| - | - | - |
| `products` | list, get, get\_by\_slug | CRUD, images, bundles |
| `categories` | list, tree | CRUD |
| `collections` | list, get | CRUD |
| `carts` | create, get, items, discounts | — |
| `checkout` | create | — |
| `orders` | list, get, lookup | CRUD, confirm, cancel, complete |
| `customers` | me, addresses | CRUD, tokens |
| `variants` | — | CRUD |
| `inventory` | — | get, adjust, set |
| `fulfillments` | — | create, ship, deliver |
| `discounts` | validate | CRUD |
| `shipping_methods` | list | CRUD |
| `payments` | — | record, complete |
| `returns` | request, list, get | CRUD, approve, reject, receive |
| `refunds` | — | create |
| `regions` | — | CRUD, prices, currencies, locales, translations |
| `webhooks` | — | CRUD, test |
| `api_keys` | — | CRUD, rotate |
| `organization` | — | get, update, members |
| `store` | — | get, update |
| `logs` | — | list, get, stats |
| `dashboard` | — | stats |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.