> ## 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.

# License Keys

> Tạo và phân phối các mã giấy phép độc nhất với giới hạn kích hoạt và hết hạn. Mã giấy phép thuộc loại quyền được cấp phép License Key. Chúng được cấp tự động khi thanh toán, gắn liền với vòng đời đăng ký, và bị thu hồi khi hủy hoặc hoàn tiền.

<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>
  Mã giấy phép thuộc loại quyền được cấp phép License Key. Tạo một quyền cấp phép License Key một lần với giới hạn kích hoạt, thời hạn hết hạn và hướng dẫn bạn muốn, gắn nó vào bất kỳ sản phẩm nào, và Dodo Payments sẽ tạo và phân phối một mã mỗi lần mua hoặc mỗi chỗ trong đăng ký, tự động.
</Info>

## Mã Giấy Phép là gì?

License keys are unique tokens that authorize access to your product. They're ideal for:

* **Software licensing**: Desktop apps, plugins, and CLIs
* **Per-seat controls**: Limit activations per user or device
* **Digital goods**: Gate downloads, updates, or premium features

Trong Dodo Payments, mã giấy phép được quản lý thông qua hệ thống [Entitlements](/features/entitlements/introduction), có nghĩa là vòng đời của mỗi mã (tạo, hết hạn, thu hồi, cấp lại) được điều khiển bởi cùng các sự kiện thanh toán và đăng ký như các sản phẩm khác của bạn.

## Tạo một Quyền cấp phép License Key

<Steps>
  <Step title="Open Entitlements">
    Đi đến **Entitlements** trong bảng điều khiển Dodo Payments của bạn và nhấp **+** để tạo một quyền mới.
  </Step>

  <Step title="Choose License Key">
    Chọn **License Key** làm tích hợp. Cấu hình cách mà mỗi mã được cấp phát hành xử lý:

    * **Giới hạn Kích hoạt**: Số lượng kích hoạt đồng thời tối đa cho mỗi mã (ví dụ, `1` cho ứng dụng một người dùng, `5` cho giấy phép nhóm, để trống cho không giới hạn).
    * **Thời Gian**: Thời gian mã duy trì hiệu lực sau khi phát hành (ví dụ, 30 ngày, 1 năm). Đối với mã được cấp phát hành thông qua đăng ký, để trống; mã vẫn có hiệu lực miễn là đăng ký còn hoạt động.
    * **Hướng Dẫn Kích Hoạt**: Các hướng dẫn dành cho khách hàng được gửi kèm với mã qua email. Ví dụ: `Paste the key in Settings → License` hoặc `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="New License Key entitlement form with name, fulfillment mode, license length, activations limit, and activation message" style={{ maxHeight: '500px', width: 'auto' }} width="2840" height="1614" data-path="images/entitlements/license-keys/create.png" />
    </Frame>
  </Step>

  <Step title="Save the entitlement">
    Lưu. Quyền cấp phát hành giờ có sẵn để gắn vào bất kỳ sản phẩm nào.
  </Step>
</Steps>

## Gắn vào Sản Phẩm

Mở một sản phẩm, mở rộng **Cài Đặt Nâng Cao → Entitlements & Credits**, và chọn quyền cấp phép License Key của bạn. Một sản phẩm đơn có thể cấp một mã giấy phép cùng với các quyền khác (truy cập Discord, tải tệp, truy cập kho GitHub, v.v.) trong cùng một lần mua.

<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="Product entitlements panel with License Key selected" style={{ maxHeight: '500px', width: 'auto' }} width="2000" height="1197" data-path="images/entitlements/attach-to-product.png" />
</Frame>

***

## Cách Mã Được Phát Hành

Việc phát hành mã theo chuẩn [vòng đời cấp phát](/features/entitlements/introduction#how-grants-work):

| Sự Kiện                                  | Hành Vi                                                                                                                        |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `payment.succeeded` (một lần)            | Tạo một mã cho mỗi `quantity` đã mua. Thời hạn mã tôn trọng thời gian của quyền cấp phát hành.                                 |
| `subscription.active`                    | Tạo một mã cho mỗi chỗ trong đăng ký `quantity`. Mã không có thời hạn; hiệu lực được gắn với tình trạng đăng ký.               |
| `subscription.renewed`                   | Không hành động. Các mã đã có vẫn tồn tại.                                                                                     |
| `subscription.on_hold`                   | Vô hiệu hóa mã. Chúng sẽ được kích hoạt lại khi đăng ký thoát khỏi chế độ tạm dừng.                                            |
| `subscription.cancelled` / `expired`     | Vô hiệu hóa permanent mã.                                                                                                      |
| `subscription.plan_changed`              | Vô hiệu hóa mã cũ; phát hành mã mới cho kế hoạch mới.                                                                          |
| `refund.succeeded` (một lần)             | Vô hiệu hóa mã.                                                                                                                |
| Thu hồi thủ công qua API/bảng điều khiển | Vô hiệu hóa mã với `revocation_reason: manual`. Các mã này không tự cấp phát lại khi đăng ký được gia hạn.                     |
| Mã giấy phép bị vô hiệu hóa trực tiếp    | Thu hồi quyền cấp phát với `revocation_reason: license_key_disabled`. Kích hoạt lại mã sẽ tự động kích hoạt việc cấp phát lại. |

### Hành vi với Số lượng

* **Sản phẩm đăng ký** cấp một mã cho mỗi chỗ (`subscriptions.quantity`).
* **Sản phẩm một lần** cấp một mã cho mỗi dòng sản phẩm trong giỏ hàng (`product_cart.quantity`).
* **Cấp phát thủ công qua API** chỉ cấp đúng một mã.

### Chế độ thực hiện

Mỗi quyền cấp License Key có một `fulfillment_mode` để kiểm soát ai cung cấp mã:

* **`auto`** (mặc định): Dodo Payments tự động tạo và gửi qua email mã khi thanh toán hoặc đăng ký. Đây là hành vi đã mô tả trước đó và áp dụng khi `fulfillment_mode` bị bỏ qua.
* **`manual`**: Việc mua tạo ra một quyền cấp `pending` không có mã, và bạn tự cung cấp từng giá trị mã. Xem [Thực hiện thủ công](#manual-fulfillment) dưới đây.

***

## Thực hiện thủ công

Theo mặc định, Dodo Payments tạo và gửi qua email một mã license ngay khi khách hàng thanh toán. Với **thực hiện thủ công** bạn tự cung cấp mã: việc mua tạo ra một quyền cấp `pending` không có mã, thông báo cho bạn, và chờ bạn gửi giá trị mã. Sử dụng điều này khi mã đến từ hệ thống của bạn, nhà cung cấp bên thứ ba, hoặc một nhóm mã đã in sẵn.

<Info>
  Tìm kiếm hướng dẫn từng bước để xây dựng? Xem [Hướng dẫn tích hợp thực hiện thủ công mã License](/developer-resources/manual-license-key-fulfillment) để có hướng dẫn chi tiết từ việc tạo sản phẩm đến cung cấp mã.
</Info>

### Khi nào sử dụng

Thực hiện tự động là lựa chọn mặc định đúng cho hầu hết các giấy phép phần mềm. Chọn thực hiện thủ công khi Dodo Payments không thể phát hành mã:

* **Mang theo mã của bạn**: Mã được tạo bởi ứng dụng của bạn, một sản phẩm desktop, hoặc máy chủ cấp phép của bạn.
* **Nhà cung cấp bên thứ ba**: Bạn bán lại các mã được cấp bởi nhà cung cấp thượng nguồn (một mã game, thông tin xác thực API, nền tảng đối tác).
* **Tồn kho hữu hạn**: Bạn cung cấp mã từ một nhóm đã phân bổ trước và muốn chỉ định chúng từng cái một.
* **Đánh giá con người**: Bạn muốn xem xét một giao dịch mua trước khi phát hành quyền truy cập.

### Kích hoạt thực hiện thủ công

Đặt `fulfillment_mode: "manual"` trên cấu hình tích hợp quyền cấp License Key:

<CodeGroup>
  ```typescript Node.js theme={null} theme={null}
  const entitlement = await client.entitlements.create({
    name: 'Pro License (Manual)',
    integration_type: 'license_key',
    integration_config: {
      fulfillment_mode: 'manual',
      activations_limit: 5,
      duration_count: 1,
      duration_interval: 'Year',
    },
  });
  ```

  ```bash cURL theme={null} theme={null}
  curl -X POST https://test.dodopayments.com/entitlements \
    -H "Authorization: Bearer $DODO_PAYMENTS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Pro License (Manual)",
      "integration_type": "license_key",
      "integration_config": {
        "fulfillment_mode": "manual",
        "activations_limit": 5,
        "duration_count": 1,
        "duration_interval": "Year"
      }
    }'
  ```
</CodeGroup>

<Note>
  `fulfillment_mode` tương thích ngược. Các quyền cấp được tạo ra trước khi thiết lập này tồn tại không có `fulfillment_mode` và tiếp tục hoạt động như `auto`. Chuyển sang `manual` chỉ ảnh hưởng đến các quyền cấp được tạo **sau** thay đổi này; các mã đã được phát hành sẽ không bị ảnh hưởng.
</Note>

### Tìm quyền cấp chờ thực hiện

Khi khách hàng mua một sản phẩm chế độ thủ công, quyền cấp được tạo ở trạng thái `pending` mà không có khóa và một [`entitlement_grant.created`](/developer-resources/webhooks/intents/entitlement-grant) webhook được kích hoạt với `integration_type: "license_key"` và `status: "pending"`. Bạn có thể phản hồi lại webhook đó, hoặc truy vấn điểm cuối [List Customer Grants](/api-reference/entitlements/list-customer-grants) với các bộ lọc `integration_type` và `status`:

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

### Cung cấp mã

Gửi mã với endpoint [Fulfill License Key Grant](/api-reference/entitlements/fulfill-license-key). Quyền cấp di chuyển sang `delivered` và khách hàng sẽ tự động nhận được mã — cùng email mà họ sẽ nhận được trong chế độ thực hiện tự động.

```bash cURL theme={null} theme={null}
curl -X POST https://test.dodopayments.com/grants/grant_8VbC6JDZ/license-key \
  -H "Authorization: Bearer $DODO_PAYMENTS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "PRO-AAAA-BBBB-CCCC-DDDD",
    "activations_limit": 5,
    "expires_at": "2027-05-01T00:00:00Z"
  }'
```

`activations_limit` và `expires_at` là tùy chọn và mặc định theo cấu hình quyền cấp khi bị bỏ qua. Mỗi quyền cấp chỉ được thực hiện một lần; thử lại một quyền cấp đã được thực hiện sẽ trả về `409` thay vì cấp phát mã thứ hai.

<Check>
  Bạn không cần phải gửi email mã tự mình — việc cung cấp xảy ra tự động khi quyền cấp được thực hiện. Điều này khác với [nhập các mã](#import-existing-license-keys-via-api) qua `POST /license_keys`, mà cố ý **không** thông báo cho khách hàng.
</Check>

***

## Kích hoạt, Xác nhận, Hủy kích hoạt

Các điểm cuối kích hoạt/xác nhận/hủy kích hoạt API là **công khai** và không yêu cầu mã API. Sử dụng chúng trực tiếp từ phần mềm desktop, CLIs hoặc khách hàng dựa trên trình duyệt để xác minh các mã trong thời gian chạy.

<Info>
  **Điểm cuối công khai**: Các điểm cuối kích hoạt, hủy kích hoạt và xác nhận license là công khai và không yêu cầu mã API. Gọi chúng trực tiếp từ ứng dụng của bạn mà không làm lộ thông tin xác thực API của bạn.
</Info>

### Kích hoạt một license

<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>

### Xác nhận một license

<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>

### Hủy kích hoạt một phiên bản kích hoạt

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

***

## Quản lý Mã

Mở quyền cấp License Key từ bảng điều khiển của bạn để xem mọi quyền cấp (một hàng mỗi mã khách hàng) với ngày giao hàng, số lượng kích hoạt, và hành động thu hồi. Mỗi chi tiết quyền cấp sẽ xuất hiện mã license cơ bản, hạn sử dụng, số lần kích hoạt đã sử dụng, và giới hạn kích hoạt.

Bạn cũng có thể liệt kê quyền cấp theo cách lập trình:

```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);
}
```

## Nhập Mã License Hiện Tại qua API

Đã có mã license trong hệ thống khác? Sử dụng API [Tạo Mã License](/api-reference/licenses/create-license-key) để nhập chúng vào Dodo Payments. Điều này cho phép bạn di chuyển các mã hiện có mà không làm gián đoạn khách hàng của bạn — họ tiếp tục kích hoạt, xác nhận, và hủy kích hoạt các chuỗi mã như cũ mà không cần cấp lại.

<Warning>
  Mã license được tạo hoặc cập nhật qua API không kích hoạt thông báo email đến khách hàng. Nếu bạn cần thông báo khách hàng về một mã đã nhập, hãy xử lý điều đó một cách riêng biệt trong ứng dụng của bạn.
</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',
});
```

### Sự Khác Biệt của Mã theo Nguồn

| Trường                     | Mã tự động tạo                            | Mã thực hiện thủ công                                                    | Mã nhập khẩu                                  |
| -------------------------- | ----------------------------------------- | ------------------------------------------------------------------------ | --------------------------------------------- |
| `source`                   | `"auto"`                                  | `"manual"`                                                               | `"import"`                                    |
| Nguồn gốc                  | Được tạo bởi Dodo Payments khi thanh toán | [Cung cấp bởi bạn](#manual-fulfillment) chống lại một quyền cấp đang chờ | Được tạo/di chuyển qua `POST /license_keys`   |
| `payment_id`               | Đặt vào thanh toán gốc                    | Giải quyết từ quyền cấp hoặc đăng ký của nó                              | `null` (không có giao dịch của Dodo Payments) |
| `subscription_id`          | Đặt nếu phát hành qua đăng ký             | Đặt nếu quyền cấp đến từ một đăng ký                                     | `null` trừ khi được liên kết rõ ràng          |
| Thông báo email khách hàng | Gửi khi phát hành                         | Gửi khi thực hiện                                                        | Không gửi — xử lý riêng                       |

Sử dụng trường `source` trên các phản hồi `GET /license_keys` để phân biệt di chuyển tồn kho và mã thực hiện thủ công từ các mã cấp phát tự nhiên khi đối chiếu hoặc kiểm toán.

<Tip>
  Di chuyển từ **Polar.sh** hoặc **Lemon Squeezy**? [`dodo-migrate` CLI](/migrate-to-dodo) tự động hóa việc nhập hàng loạt sản phẩm, khách hàng, chiết khấu và mã license trong một lệnh duy nhất và ánh xạ ID ngoài sang ID Dodo tự động.
</Tip>

***

## Mã License trong URL Trả về

Khi một khách hàng hoàn tất quá trình mua cho một sản phẩm với quyền cấp License Key, mã được tạo ra tự động sẽ được thêm vào `return_url` của bạn dưới dạng tham số truy vấn. Điều này cho phép bạn hiển thị mã ngay lập tức trên trang thành công của mình mà không cần thực hiện thêm yêu cầu API.

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

Nếu giao dịch mua tạo ra nhiều mã (số lượng > 1), chúng sẽ được ngăn cách bằng dấu phẩy:

```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
```

Đối với đăng ký, `subscription_id` được sử dụng thay vì `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>
  Phân tích tham số `license_key` trên trang trả về của bạn để hiển thị mã ngay lập tức, cải thiện trải nghiệm sau mua hàng.
</Tip>

***

## Quản lý API

<AccordionGroup>
  <Accordion title="Lifecycle Operations (Public Endpoints)">
    Kích hoạt, hủy kích hoạt, và xác nhận là công khai; không yêu cầu mã API.

    <CardGroup cols={3}>
      <Card title="Activate License" icon="code" href="/api-reference/licenses/activate-license">
        Tạo hoặc ghi lại một phiên bản kích hoạt cho một mã license.
      </Card>

      <Card title="Deactivate License" icon="code" href="/api-reference/licenses/deactivate-license">
        Thu hồi một lần kích hoạt trước đó để giải phóng dung lượng.
      </Card>

      <Card title="Validate License" icon="code" href="/api-reference/licenses/validate-license">
        Kiểm tra tính xác thực, trạng thái, và giới hạn trước khi cấp quyền truy cập.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="License Key Management">
    Tạo, liệt kê, truy xuất, và cập nhật các bản ghi mã license riêng lẻ. Sử dụng chúng để nhập các mã hiện tại hoặc lấy thông tin sử dụng.

    <CardGroup cols={2}>
      <Card title="Create License Key" icon="code" href="/api-reference/licenses/create-license-key">
        Tạo một mã license mới hoặc nhập một mã hiện tại.
      </Card>

      <Card title="List License Keys" icon="code" href="/api-reference/licenses/list-license-keys">
        Duyệt tất cả mã với các chi tiết trạng thái và sử dụng.
      </Card>

      <Card title="Get License Key" icon="code" href="/api-reference/licenses/get-license-key">
        Truy xuất một mã cụ thể và siêu dữ liệu của nó.
      </Card>

      <Card title="Update License Key" icon="code" href="/api-reference/licenses/update-license-key">
        Điều chỉnh hạn sử dụng, giới hạn kích hoạt, hoặc bật/tắt mã.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="Entitlement Management">
    Quản lý quyền cấp License Key: giới hạn kích hoạt của nó, thời gian và hướng dẫn.

    <CardGroup cols={2}>
      <Card title="Create Entitlement" icon="plus" href="/api-reference/entitlements/create-entitlement">
        Tạo một quyền cấp License Key.
      </Card>

      <Card title="Update Entitlement" icon="pen" href="/api-reference/entitlements/update-entitlement">
        Cập nhật cấu hình của quyền cấp.
      </Card>

      <Card title="List Grants" icon="users" href="/api-reference/entitlements/list-grants">
        Liệt kê các mã đã phát hành cho một quyền cấp.
      </Card>

      <Card title="Revoke Grant" icon="ban" href="/api-reference/entitlements/revoke-grant">
        Thu hồi mã của khách hàng một cách thủ công.
      </Card>
    </CardGroup>
  </Accordion>
</AccordionGroup>

***

## Webhooks

Việc cấp mã và thu hồi mã kích hoạt bốn [sự kiện webhook `entitlement_grant.*`](/developer-resources/webhooks/intents/entitlement-grant). Payload quyền cấp bao gồm một đối tượng `license_key` với mã, hạn sử dụng, số lần kích hoạt đã sử dụng, và giới hạn.

Các sự kiện `license_key.*` cũ (`license_key.created`) tiếp tục kích hoạt cho vòng đời ghi chép mã license cơ bản; xem [trang payload webhook License Key](/developer-resources/webhooks/intents/license-key).

<Tip>
  Đối với tích hợp mới, lắng nghe `entitlement_grant.delivered` thay vì `license_key.created`. Sự kiện quyền cấp cho bạn biết rằng việc cấp đã hoàn tất trên tất cả tích hợp trên sản phẩm, không chỉ mã license.
</Tip>

***

## Mã License Cũ

<Note>
  Các sản phẩm được tạo với cờ `license_key_enabled` cũ đã được **tự động di chuyển** sang quyền cấp License Key. Việc di chuyển là trong suốt: các mã khách hàng hiện tại tiếp tục hoạt động không thay đổi, các điểm cuối công khai `/licenses/activate`, `/licenses/validate`, `/licenses/deactivate` tiếp tục hoạt động, và các điểm cuối API `/license_keys/*` tiếp tục đọc và ghi vào cùng kho mã.

  Phần **Mã License** độc lập trong bảng điều khiển vẫn có sẵn dưới dạng danh sách phẳng của mọi mã đã phát hành, hữu ích cho kiểm toán và tìm kiếm. Cấu hình mới (thay đổi giới hạn kích hoạt, thời gian, hoặc hướng dẫn) nên được thực hiện bằng cách chỉnh sửa quyền cấp License Key đã di chuyển trong **Quyền cấp**.
</Note>

***

## Thực hành Tốt nhất

* **Giữ giới hạn kích hoạt rõ ràng**: Chọn các giá trị mặc định hợp lý (1 cho ứng dụng đơn người dùng, 3–5 cho giấy phép nhóm) và tài liệu hóa chúng.
* **Cung cấp hướng dẫn kích hoạt chính xác**: Khách hàng dán những hướng dẫn này từ email của họ, vì vậy các đường dẫn và lệnh chính xác sẽ tiết kiệm các yêu cầu hỗ trợ.
* **Xác nhận mã phía máy chủ**: Đối với các sản phẩm kết nối mạng, xác nhận qua `/licenses/validate` thay vì lưu trữ dữ liệu kích hoạt cục bộ.
* **Sử dụng webhooks để thu hồi**: Lắng nghe `entitlement_grant.revoked` để vô hiệu hóa các tính năng trong ứng dụng ngay lập tức khi khách hàng hủy hoặc hoàn tiền.
* **Kiểm tra với đăng ký và một lần**: Hành vi mã license khác biệt nhẹ giữa hai hình thức, vì vậy hãy kiểm tra cả hai trước khi đưa vào thực tế.
