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

# 라이센스 키

> 고유한 라이선스 키를 생성하고 전달하여 활성화 제한 및 만료일을 설정하세요. 라이선스 키는 라이선스 키 사용 권한 유형입니다. 결제가 이루어지면 자동으로 발급되며, 구독 생애 주기에 연결되고 취소 또는 환불 시 해지됩니다.

<Frame>
  <iframe className="w-full aspect-video rounded-md" src="https://www.youtube.com/embed/BNuLTXok8dQ" title="License Keys | Dodo Payments" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
</Frame>

<Info>
  라이선스 키는 라이선스 키 사용 권한 유형입니다. 원하는 활성화 제한, 만료 및 지침으로 라이선스 키 사용 권한을 한 번 생성하고, 이를 제품에 연결하면 Dodo Payments가 구매 또는 구독 자리당 키를 자동으로 생성하고 제공합니다.
</Info>

## 라이선스 키란?

라이센스 키는 제품에 대한 액세스를 승인하는 고유한 토큰입니다. 다음과 같은 경우에 적합합니다:

* **소프트웨어 라이센스**: 데스크탑 앱, 플러그인 및 CLI
* **사용자당 제어**: 사용자 또는 장치당 활성화 제한
* **디지털 상품**: 다운로드, 업데이트 또는 프리미엄 기능에 대한 접근 제한

Dodo Payments 내에서 라이선스 키는 [Entitlements](/features/entitlements/introduction) 시스템을 통해 관리되며, 각 키의 생애 주기(생성, 만료, 해지, 재부여)는 다른 제공품과 동일한 결제 및 구독 이벤트에 의해 주도됩니다.

## 라이선스 키 사용 권한 생성

<Steps>
  <Step title="Open Entitlements">
    Dodo Payments 대시보드에서 **Entitlements**로 이동하여 \*\*+\*\*를 클릭하여 새 사용 권한을 생성합니다.
  </Step>

  <Step title="Choose License Key">
    **License Key**를 통합으로 선택하십시오. 발급된 각 키가 작동하는 방식을 구성합니다:

    * **활성화 제한**: 키당 최대 동시 활성화 (예: 단일 사용자용 `1`, 팀 라이선스용 `5`, 무제한은 비워둡니다).
    * **기간**: 발급 후 키가 유효한 기간 (예: 30일, 1년). 구독용 키의 경우 비워두십시오; 구독이 활성 상태로 유지되는 한 키는 유효합니다.
    * **활성화 지침**: 키와 함께 이메일로 전송되는 고객용 지침. 예: `Paste the key in Settings → License` 또는 `Run: mycli activate <key>`.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/sZYZEc6Biy3IrQNZ/images/entitlements/license-keys/create.png?fit=max&auto=format&n=sZYZEc6Biy3IrQNZ&q=85&s=65f24596e834387d0c35278ef92d14ea" alt="라이선스 키 사용 권한 양식, 활성화 제한, 기간, 지침 포함" style={{ maxHeight: '500px', width: 'auto' }} width="2840" height="1614" data-path="images/entitlements/license-keys/create.png" />
    </Frame>
  </Step>

  <Step title="Save the entitlement">
    저장합니다. 이제 사용 권한은 모든 제품에 첨부할 수 있습니다.
  </Step>
</Steps>

## 제품에 첨부

제품을 열고 **고급 설정 → 사용 권한 및 크레딧**을 확장한 다음 라이선스 키 사용 권한을 선택하십시오. 단일 제품은 동일한 구매에서 다른 사용 권한(디스코드 접근, 파일 다운로드, GitHub 리포지토리 접근 등)과 함께 라이선스 키를 제공할 수 있습니다.

<Frame caption="Selecting the License Key entitlement in the product entitlements panel.">
  <img src="https://mintcdn.com/dodopayments/do-W-dMDGVB_xzr_/images/entitlements/attach-to-product.png?fit=max&auto=format&n=do-W-dMDGVB_xzr_&q=85&s=965ad78262791fa8dbb712b4fdf89538" alt="라이선스 키가 선택된 제품 사용 권한 패널" style={{ maxHeight: '500px', width: 'auto' }} width="2000" height="1197" data-path="images/entitlements/attach-to-product.png" />
</Frame>

***

## 키 발급 방법

키 발급은 표준 [발급 생애 주기](/features/entitlements/introduction#how-grants-work)를 따릅니다:

| 이벤트                                  | 동작                                                                                  |
| ------------------------------------ | ----------------------------------------------------------------------------------- |
| `payment.succeeded` (일회성)            | 구매한 `quantity` 당 하나의 키를 생성합니다. 키 만료는 사용 권한의 기간을 따릅니다.                               |
| `subscription.active`                | 구독 `quantity` (시트)당 하나의 키를 생성합니다. 키에 만료일이 없으며 유효성은 구독 상태에 따라 결정됩니다.                 |
| `subscription.renewed`               | 아무 작업도 하지 않습니다. 기존 키는 그대로 유지됩니다.                                                    |
| `subscription.on_hold`               | 키를 비활성화합니다. 구독이 중단에서 해제되면 다시 활성화됩니다.                                                |
| `subscription.cancelled` / `expired` | 키를 영구적으로 비활성화합니다.                                                                   |
| `subscription.plan_changed`          | 이전 키를 비활성화하고 새 플랜에 대한 새 키를 발급합니다.                                                   |
| `refund.succeeded` (일회성)             | 키를 비활성화합니다.                                                                         |
| API/대시보드를 통한 수동 해지                   | `revocation_reason: manual` 키를 비활성화합니다. 이는 구독 갱신 시 자동으로 다시 부여되지 않습니다.               |
| 라이선스 키 직접 비활성화                       | `revocation_reason: license_key_disabled`로 부여를 해지합니다. 키를 다시 활성화하면 부여가 자동으로 재활성화됩니다. |

### 수량 동작

* **구독 제품**은 시트당 하나의 키를 발급합니다 (`subscriptions.quantity`).
* **일회성 제품**은 장바구니 항목당 하나의 키를 발급합니다 (`product_cart.quantity`).
* **수동 API 부여**는 정확히 하나의 키를 발급합니다.

## 활성화, 검증, 비활성화

활성화/검증/비활성화 API 엔드포인트는 **공용**이며 API 키가 필요하지 않습니다. 데스크톱 소프트웨어, CLI 또는 브라우저 기반 클라이언트에서 이를 직접 사용하여 실행 시 키를 확인할 수 있습니다.

<Info>
  **공용 엔드포인트**: 활성화, 비활성화 및 라이선스 검증 엔드포인트는 공용이며 API 키가 필요하지 않습니다. 클라이언트 애플리케이션에서 API 자격 증명을 노출하지 않고 직접 호출하십시오.
</Info>

### 라이선스 활성화

<CodeGroup>
  ```typescript TypeScript theme={null} theme={null}
  import DodoPayments from 'dodopayments';

  // No API key needed for public license endpoints
  const client = new DodoPayments();

  const response = await client.licenses.activate({
    license_key: 'PRO-AAAA-BBBB-CCCC-DDDD',
    name: 'Device Name',
  });

  console.log(response.id);
  ```

  ```python Python theme={null} theme={null}
  client.licenses.activate(
      license_key="PRO-AAAA-BBBB-CCCC-DDDD",
      name="Device Name",
  )
  ```

  ```bash cURL theme={null} theme={null}
  curl -X POST https://test.dodopayments.com/licenses/activate \
    -H "Content-Type: application/json" \
    -d '{
      "license_key": "PRO-AAAA-BBBB-CCCC-DDDD",
      "name": "Device Name"
    }'
  ```
</CodeGroup>

### 라이선스 검증

<CodeGroup>
  ```typescript TypeScript theme={null} theme={null}
  const response = await client.licenses.validate({
    license_key: 'PRO-AAAA-BBBB-CCCC-DDDD',
  });

  console.log(response.valid);
  ```

  ```bash cURL theme={null} theme={null}
  curl -X POST https://test.dodopayments.com/licenses/validate \
    -H "Content-Type: application/json" \
    -d '{ "license_key": "PRO-AAAA-BBBB-CCCC-DDDD" }'
  ```
</CodeGroup>

### 활성화 인스턴스 비활성화

```typescript theme={null} theme={null}
await client.licenses.deactivate({
  license_key: 'PRO-AAAA-BBBB-CCCC-DDDD',
  license_key_instance_id: 'instance_abc123',
});
```

***

## 키 관리

고객이 수동 모드 제품을 구매하면, 권한 부여가 키 없이 `pending` 상태로 생성되며, [`entitlement_grant.created`](/developer-resources/webhooks/intents/entitlement-grant) 웹훅이 `integration_type: "license_key"` 및 `status: "pending"`와 함께 실행됩니다. 해당 웹훅에 반응하거나, [List Customer Grants](/api-reference/entitlements/list-customer-grants) 엔드포인트를 `integration_type` 및 `status` 필터로 폴링할 수 있습니다.

```typescript theme={null} theme={null}
const pending = await client.customers.listEntitlementGrants('customer_id', {
  integration_type: 'license_key',
  status: 'Pending',
});
```

```typescript theme={null} theme={null}
const grants = await client.entitlements.grants.list('ent_license_key_id', {
  status: 'delivered',
});

for (const grant of grants.items) {
  console.log(grant.license_key.key, grant.license_key.activations_used);
}
```

## API를 통해 기존 라이선스 키 가져오기

다른 시스템에 이미 라이선스 키가 있습니까? [Create License Key](/api-reference/licenses/create-license-key) API를 사용하여 Dodo Payments로 가져오세요. 이를 통해 고객을 방해하지 않고 기존 키를 마이그레이션할 수 있으며, 동일한 키 문자열에 대해 활성화, 검증 및 비활성화가 계속됩니다.

<Warning>
  API를 통해 생성되거나 업데이트된 라이선스 키는 고객에게 이메일 알림을 트리거하지 않습니다. 가져온 키에 대해 고객에게 알림이 필요하다면 애플리케이션에서 별도로 처리하십시오.
</Warning>

```typescript theme={null} theme={null}
const licenseKey = await client.licenseKeys.create({
  customer_id: 'cus_abc123',
  product_id: 'prod_456',
  key: 'YOUR-EXISTING-LICENSE-KEY',
  activations_limit: 5,
  expires_at: '2026-12-31T23:59:59Z',
});
```

### 가져온 키와 자동 생성 키의 차이

| 필드                | 자동 생성 키           | 가져온 키                        |
| ----------------- | ----------------- | ---------------------------- |
| `source`          | `"auto"`          | `"import"`                   |
| `payment_id`      | 원래 결제에 설정됨        | `null` (Dodo Payments 거래 없음) |
| `subscription_id` | 구독을 통해 발급된 경우 설정됨 | 명시적 연결이 없는 한 `null`          |
| 고객 이메일 알림         | 발행 시 발송           | 발송되지 않음 — 별도로 처리             |

호환 또는 감사 시 자연적으로 발급된 키와 마이그레이션된 인벤토리를 구분하기 위해 `source` 필드를 `GET /license_keys` 응답에서 사용하십시오.

<Tip>
  **Polar.sh** 또는 **Lemon Squeezy**에서 마이그레이션하시겠습니까? [`dodo-migrate` CLI](/migrate-to-dodo)는 제품, 고객, 할인 및 라이선스 키의 대량 가져오기를 단일 명령으로 자동화하며, 외부 ID를 Dodo IDs에 자동으로 매핑합니다.
</Tip>

***

## 반품 URL의 라이선스 키

라이선스 키 사용 권한이 있는 제품을 구매한 고객이 구매를 완료하면 생성된 키가 `return_url`에 쿼리 매개 변수로 자동 추가됩니다. 이렇게 하면 추가 API 호출 없이 성공 페이지에 키를 즉시 표시할 수 있습니다.

```text theme={null} theme={null}
https://yoursite.com/return?payment_id=pay_xxx&status=succeeded&license_key=LK-001&email=customer%40example.com
```

구매로 여러 키가 생성된 경우(수량 > 1), 이는 쉼표로 구분됩니다:

```text theme={null} theme={null}
https://yoursite.com/return?payment_id=pay_xxx&status=succeeded&license_key=LK-001,LK-002&email=customer%40example.com
```

구독의 경우 `subscription_id` 대신 `payment_id`를 사용합니다:

```text theme={null} theme={null}
https://yoursite.com/return?subscription_id=sub_xxx&status=active&license_key=LK-001&email=customer%40example.com
```

<Tip>
  반품 페이지에서 `license_key` 매개변수를 구문 분석하여 키를 즉시 표시하여 구매 후 경험을 향상시킵니다.
</Tip>

***

## API 관리

<AccordionGroup>
  <Accordion title="Lifecycle Operations (Public Endpoints)">
    활성화, 비활성화 및 검증은 공용입니다. API 키가 필요하지 않습니다.

    <CardGroup cols={3}>
      <Card title="Activate License" icon="code" href="/api-reference/licenses/activate-license">
        라이선스 키에 대한 활성화 인스턴스를 생성하거나 기록합니다.
      </Card>

      <Card title="Deactivate License" icon="code" href="/api-reference/licenses/deactivate-license">
        이전 활성화를 해제하여 용량을 확보합니다.
      </Card>

      <Card title="Validate License" icon="code" href="/api-reference/licenses/validate-license">
        액세스를 부여하기 전에 정품 여부, 상태 및 제약 조건을 확인합니다.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="License Key Management">
    개별 라이선스 키 레코드를 생성, 목록화, 검색 및 업데이트합니다. 기존 키를 가져오거나 사용 정보를 가져오는 데 사용할 수 있습니다.

    <CardGroup cols={2}>
      <Card title="Create License Key" icon="code" href="/api-reference/licenses/create-license-key">
        새 라이선스 키를 생성하거나 기존 키를 가져옵니다.
      </Card>

      ```typescript theme={null} theme={null}
      const grants = await client.entitlements.grants.list('ent_license_key_id', {
        status: 'Delivered',
      });

      for (const grant of grants.items) {
        console.log(grant.license_key.key, grant.license_key.activations_used);
      }
      ```

      <Card title="Get License Key" icon="code" href="/api-reference/licenses/get-license-key">
        특정 키와 해당 메타데이터를 검색합니다.
      </Card>

      <Card title="Update License Key" icon="code" href="/api-reference/licenses/update-license-key">
        만료, 활성화 제한 또는 키를 활성화/비활성화합니다.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="Entitlement Management">
    사용 권한 자체를 관리합니다: 활성화 제한, 기간 및 지침.

    <CardGroup cols={2}>
      <Card title="Create Entitlement" icon="plus" href="/api-reference/entitlements/create-entitlement">
        라이선스 키 사용 권한을 생성합니다.
      </Card>

      <Card title="Update Entitlement" icon="pen" href="/api-reference/entitlements/update-entitlement">
        사용 권한의 구성을 업데이트합니다.
      </Card>

      <Card title="List Grants" icon="users" href="/api-reference/entitlements/list-grants">
        사용 권한에 대해 발급된 키를 나열합니다.
      </Card>

      <Card title="Revoke Grant" icon="ban" href="/api-reference/entitlements/revoke-grant">
        고객의 키를 수동으로 비활성화합니다.
      </Card>
    </CardGroup>
  </Accordion>
</AccordionGroup>

***

## 웹훅

라이선스 키 전달 및 해지는 네 개의 [`entitlement_grant.*` 웹훅 이벤트](/developer-resources/webhooks/intents/entitlement-grant)를 발생시킵니다. 부여 페이로드에는 키, 만료, 사용된 활성화 및 제한이 포함된 `license_key` 객체가 포함되어 있습니다.

기존 `license_key.*` 이벤트(`license_key.created`)는 기본 라이선스 키 레코드 생애 주기에 대해 계속 발생합니다; [사용 권한 웹훅 페이로드 페이지](/developer-resources/webhooks/intents/license-key)를 참조하세요.

<Tip>
  새로운 통합의 경우 `license_key.created`가 아닌 `entitlement_grant.delivered`을 듣습니다. 사용권 이벤트는 제품의 모든 통합에서 전달이 완료되었음을 알려줍니다. 단순히 라이선스 키만이 아닙니다.
</Tip>

***

## 레거시 라이선스 키

<Note>
  이전 `license_key_enabled` 플래그로 생성된 제품은 **자동으로 마이그레이션되어** 라이선스 키 사용 권한으로 전환되었습니다. 마이그레이션은 투명하게 이루어집니다: 기존 고객의 키는 변함없이 작동하며, 공용 `/licenses/activate`, `/licenses/validate`, `/licenses/deactivate` 엔드포인트는 계속 기능하며, `/license_keys/*` API 엔드포인트는 동일한 키 저장소를 읽고 작성합니다.

  독립형 **License Keys** 대시보드 섹션은 여전히 발급된 모든 키의 평면 목록으로 이용할 수 있으며, 감사 및 검색에 유용합니다. 새 구성(활성화 제한, 기간 또는 지침 변경)은 **Entitlements** 아래의 마이그레이션된 라이선스 키 사용 권한을 편집하여 수행해야 합니다.
</Note>

***

## 모범 사례

* **활성화 제한을 명확히 유지**: 합리적인 기본값(단일 사용자 앱의 경우 1, 팀 라이선스의 경우 3–5)을 선택하고 이를 문서화합니다.
* **정확한 활성화 지침 제공**: 고객이 이메일에서 복사하여 붙여넣기 때문에 정확한 경로와 명령은 지원 티켓을 절약합니다.
* **서버 측에서 키 검증**: 네트워크 연결된 제품의 경우 로컬 활성화를 캐시하기보다는 `/licenses/validate`를 통해 검증합니다.
* **해지 시 웹훅 사용**: 고객이 취소하거나 환불할 때 즉시 앱 내 기능을 비활성화하려면 `entitlement_grant.revoked`를 듣습니다.
* **구독 및 일회성 제품을 테스트**: 라이선스 키 동작은 두 제품 간에 미묘하게 다르므로, 라이브로 전환하기 전에 둘 다 테스트합니다.

<Tip>
  구매 후 경험을 개선하기 위해 키를 즉시 표시하도록 반환 페이지에서 `license_key` 매개변수를 구문 분석합니다.
</Tip>

***

## API Management

<AccordionGroup>
  <Accordion title="Lifecycle Operations (Public Endpoints)">
    활성화, 비활성화 및 유효성 검사는 공개적이며 API 키가 필요하지 않습니다.

    <CardGroup cols={3}>
      <Card title="Activate License" icon="code" href="/api-reference/licenses/activate-license">
        라이센스 키에 대한 활성화 인스턴스를 생성하거나 기록합니다.
      </Card>

      <Card title="Deactivate License" icon="code" href="/api-reference/licenses/deactivate-license">
        용량을 확보하기 위해 이전 활성화를 취소합니다.
      </Card>

      <Card title="Validate License" icon="code" href="/api-reference/licenses/validate-license">
        액세스를 부여하기 전에 진위, 상태 및 제약 조건을 확인합니다.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="License Key Management">
    개별 라이센스 키 레코드를 생성, 나열, 검색 및 업데이트합니다. 이를 사용하여 기존 키를 가져오거나 사용 정보를 검색합니다.

    <CardGroup cols={2}>
      <Card title="Create License Key" icon="code" href="/api-reference/licenses/create-license-key">
        새 라이센스 키를 생성하거나 기존 키를 가져옵니다.
      </Card>

      <Card title="List License Keys" icon="code" href="/api-reference/licenses/list-license-keys">
        상태 및 사용 세부정보와 함께 모든 키를 탐색합니다.
      </Card>

      <Card title="Get License Key" icon="code" href="/api-reference/licenses/get-license-key">
        특정 키와 그 메타데이터를 검색합니다.
      </Card>

      <Card title="Update License Key" icon="code" href="/api-reference/licenses/update-license-key">
        만료, 활성화 제한을 수정하거나 키를 활성화/비활성화합니다.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="Entitlement Management">
    라이센스 키 권한 자체를 관리합니다: 활성화 제한, 기간 및 지침.

    <CardGroup cols={2}>
      <Card title="Create Entitlement" icon="plus" href="/api-reference/entitlements/create-entitlement">
        라이센스 키 권한을 생성합니다.
      </Card>

      <Card title="Update Entitlement" icon="pen" href="/api-reference/entitlements/update-entitlement">
        권한의 구성을 업데이트합니다.
      </Card>

      <Card title="List Grants" icon="users" href="/api-reference/entitlements/list-grants">
        권한이 부여된 키를 나열합니다.
      </Card>

      <Card title="Revoke Grant" icon="ban" href="/api-reference/entitlements/revoke-grant">
        고객의 키를 수동으로 취소합니다.
      </Card>
    </CardGroup>
  </Accordion>
</AccordionGroup>

***

## Webhooks

라이센스 키 전달 및 취소는 네 개의 [`entitlement_grant.*` webhook events](/developer-resources/webhooks/intents/entitlement-grant)를 실행합니다. 권한 부여 페이로드는 키, 만료, 사용된 활성화 및 제한이 포함된 `license_key` 객체를 포함합니다.

레거시 `license_key.*` 이벤트 (`license_key.created`)는 기본 라이센스 키 기록 수명 주기에도 계속 실행됩니다. [License Key webhook payload page](/developer-resources/webhooks/intents/license-key)를 참조하세요.

<Tip>
  새로운 통합용으로는 `entitlement_grant.delivered`를 듣고 `license_key.created`를 듣지 마십시오. 권한 부여 이벤트는 제품의 모든 통합에 대해 전달이 완료되었음을 나타내며, 단지 라이센스 키만이 아닙니다.
</Tip>

***

## Legacy License Keys

<Note>
  이전 `license_key_enabled` 플래그로 생성된 제품은 **자동으로** 라이센스 키 권한 부여로 이전되었습니다. 이전은 투명하며, 기존 고객의 키는 변경 없이 계속 작동하고, 공개 `/licenses/activate`, `/licenses/validate`, `/licenses/deactivate` 엔드포인트는 계속 작동하며, `/license_keys/*` API 엔드포인트는 동일한 키 저장소에 계속 읽고 씁니다.

  독립형 **License Keys** 대시보드 섹션은 발급된 모든 키의 평면 목록으로 제공되며, 감사 및 검색에 유용합니다. 새 구성(활성화 제한, 기간 또는 지침 변경)은 **Entitlements** 아래에서 마이그레이션된 라이센스 키 권한을 편집하여 수행해야 합니다.
</Note>

***

## Best Practices

* **활성화 제한을 명확하게 유지하세요**: 적절한 기본값을 선택하세요(단일 사용자 앱은 1, 팀 라이선스는 3–5) 그리고 이를 문서화하세요.
* **정확한 활성화 지침을 제공하세요**: 고객은 이메일에서 이를 복사하므로, 정확한 경로 및 명령은 지원 요청을 줄여줍니다.
* **서버 측에서 키를 검증하세요**: 네트워크 연결 제품의 경우, 로컬에서 활성화를 캐시하는 것보다 `/licenses/validate`를 통해 검증하세요.
* **취소를 위해 웹훅을 사용하세요**: 고객이 취소하거나 환불할 때 `entitlement_grant.revoked`를 듣고 앱 기능을 즉시 비활성화하세요.
* **구독과 일회성 테스트를 하세요**: 라이센스 키 동작은 두 경우에서 미묘하게 다르므로 라이브 전에 둘 다 테스트하세요.
