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

# Kunci Lisensi

> Menghasilkan dan mengirimkan kunci lisensi unik dengan batas aktivasi dan kadaluarsa. Kunci lisensi adalah jenis hak Kunci Lisensi. Mereka diterbitkan secara otomatis pada saat pembayaran, terikat dengan siklus langganan, dan dicabut pada saat pembatalan atau pengembalian dana.

<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>
  Kunci lisensi adalah jenis hak Kunci Lisensi. Buat hak Kunci Lisensi sekali dengan batas aktivasi, masa berlaku, dan instruksi yang Anda inginkan, lampirkan ke produk apa pun, dan Dodo Payments menghasilkan serta mengirimkan kunci per pembelian atau kursi langganan, secara otomatis.
</Info>

## Apa itu Kunci Lisensi?

Kunci lisensi adalah token unik yang mengotorisasi akses ke produk Anda. Mereka ideal untuk:

* **Lisensi perangkat lunak**: Aplikasi desktop, plugin, dan CLI
* **Kontrol per pengguna**: Batasi aktivasi per pengguna atau perangkat
* **Barang digital**: Batasi unduhan, pembaruan, atau fitur premium

Di dalam Dodo Payments, kunci lisensi dikelola melalui sistem [Entitlements](/features/entitlements/introduction), yang berarti siklus hidup setiap kunci (pembuatan, kadaluarsa, pencabutan, pengaktifan ulang) didorong oleh peristiwa pembayaran dan langganan yang sama seperti penghantaran lainnya.

## Buat Hak Kunci Lisensi

<Steps>
  <Step title="Open Entitlements">
    Pergi ke **Entitlements** di dasbor Dodo Payments Anda dan klik **+** untuk membuat entitlements baru.
  </Step>

  <Step title="Choose License Key">
    Pilih **License Key** sebagai integrasi. Konfigurasikan bagaimana setiap kunci yang diterbitkan berperilaku:

    * **Activations Limit**: Aktivasi bersamaan maksimum per kunci (misalnya, `1` untuk pengguna tunggal, `5` untuk lisensi tim, kosongkan untuk tidak terbatas).
    * **Duration**: Berapa lama kunci tetap berlaku setelah diterbitkan (misalnya, 30 hari, 1 tahun). Untuk kunci yang diterbitkan melalui langganan, kosongkan; kunci tetap berlaku selama langganan aktif.
    * **Activation Instructions**: Instruksi yang dikirimkan kepada pelanggan bersama dengan kunci. Contoh: `Paste the key in Settings → License` atau `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="Formulir Hak Kunci Lisensi dengan batas aktivasi, durasi, dan instruksi" style={{ maxHeight: '500px', width: 'auto' }} width="2840" height="1614" data-path="images/entitlements/license-keys/create.png" />
    </Frame>
  </Step>

  <Step title="Save the entitlement">
    Simpan. Hak tersebut sekarang tersedia untuk dilampirkan pada produk apa pun.
  </Step>
</Steps>

## Lampirkan ke Produk

Buka produk, perluas **Advanced Settings → Entitlements & Credits**, dan pilih hak Kunci Lisensi Anda. Satu produk dapat mengirimkan kunci lisensi bersama dengan hak lain (akses Discord, unduhan file, akses repo GitHub, dll.) pada pembelian yang sama.

<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="Panel penghargaan produk dengan Kunci Lisensi dipilih" style={{ maxHeight: '500px', width: 'auto' }} width="2000" height="1197" data-path="images/entitlements/attach-to-product.png" />
</Frame>

***

## Bagaimana Kunci Dibagikan

Penerbitan kunci mengikuti standar [siklus hidup penghargaan](/features/entitlements/introduction#how-grants-work):

| Peristiwa                            | Perilaku                                                                                                                                                 |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `payment.succeeded` (sekali saja)    | Menghasilkan satu kunci per `quantity` yang dibeli. Kadaluarsa kunci mengikuti durasi hak.                                                               |
| `subscription.active`                | Menghasilkan satu kunci per langganan `quantity` (kursi). Kunci tidak memiliki kadaluarsa; keabsahan terkait dengan status langganan.                    |
| `subscription.renewed`               | Tidak ada operasi. Kunci yang ada tetap ada.                                                                                                             |
| `subscription.on_hold`               | Menonaktifkan kunci. Kunci akan diaktifkan kembali ketika langganan tidak lagi ditahan.                                                                  |
| `subscription.cancelled` / `expired` | Menonaktifkan kunci secara permanen.                                                                                                                     |
| `subscription.plan_changed`          | Menonaktifkan kunci lama; mengeluarkan kunci baru untuk rencana baru.                                                                                    |
| `refund.succeeded` (sekali saja)     | Menonaktifkan kunci.                                                                                                                                     |
| Pencabutan manual melalui API/dasbor | Menonaktifkan kunci dengan `revocation_reason: manual`. Ini tidak akan diterbitkan kembali secara otomatis pada pembaruan langganan.                     |
| Kunci lisensi dinonaktifkan langsung | Mencabut penghargaan dengan `revocation_reason: license_key_disabled`. Mengaktifkan kembali kunci akan mengaktifkan kembali penghargaan secara otomatis. |

### Perilaku Kuantitas

* **Produk langganan** menerbitkan satu kunci per kursi (`subscriptions.quantity`).
* **Produk satu kali** mengeluarkan satu kunci per item garis keranjang (`product_cart.quantity`).
* **Pemberian API manual** mengeluarkan tepat satu kunci.

## Aktivasi, Validasi, Penonaktifan

Endpoint API untuk aktivasi/validasi/penonaktifan bersifat **publik** dan tidak memerlukan kunci API. Gunakan secara langsung dari perangkat lunak desktop, CLI, atau klien berbasis peramban untuk memverifikasi kunci pada saat menjalankan.

<Info>
  **Public Endpoints**: Aktivasi, penonaktifan, dan validasi endpoint lisensi bersifat publik dan tidak memerlukan kunci API. Panggil secara langsung dari aplikasi klien Anda tanpa mengekspos kredensial API Anda.
</Info>

### Aktivasi lisensi

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

### Validasi lisensi

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

### Nonaktifkan instance aktivasi

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

***

## Mengelola Kunci

Ketika seorang pelanggan membeli produk mode manual, grant dibuat dalam status `pending` tanpa kunci dan webhook [`entitlement_grant.created`](/developer-resources/webhooks/intents/entitlement-grant) terpicu dengan `integration_type: "license_key"` dan `status: "pending"`. Anda dapat bereaksi terhadap webhook tersebut, atau mem-polling endpoint [List Customer Grants](/api-reference/entitlements/list-customer-grants) dengan filter `integration_type` dan `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);
}
```

## Impor Kunci Lisensi yang Ada melalui API

Sudah memiliki kunci lisensi di sistem lain? Gunakan API [Create License Key](/api-reference/licenses/create-license-key) untuk mengimpornya ke Dodo Payments. Ini memungkinkan Anda memigrasikan kunci yang ada tanpa mengganggu pelanggan Anda — mereka tetap mengaktifkan, memvalidasi, dan menonaktifkan terhadap string kunci yang sama tanpa penerbitan ulang.

<Warning>
  Kunci lisensi yang dibuat atau diperbarui melalui API tidak memberikan pemberitahuan email kepada pelanggan. Jika Anda perlu memberi tahu pelanggan tentang kunci yang diimpor, tangani secara terpisah dalam aplikasi Anda.
</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',
});
```

### Perbedaan kunci impor dari kunci yang dihasilkan otomatis

| Bidang                        | Kunci yang dihasilkan otomatis                  | Kunci impor                                |
| ----------------------------- | ----------------------------------------------- | ------------------------------------------ |
| `source`                      | `"auto"`                                        | `"import"`                                 |
| `payment_id`                  | Diatur ke pembayaran asal                       | `null` (tidak ada transaksi Dodo Payments) |
| `subscription_id`             | Diatur jika kunci diterbitkan melalui langganan | `null` kecuali secara eksplisit terhubung  |
| Pemberitahuan email pelanggan | Dikirim pada penerbitan                         | Tidak dikirim — tangani secara terpisah    |

Gunakan bidang `source` di tanggapan `GET /license_keys` untuk membedakan inventaris yang dimigrasi dari kunci yang dikeluarkan secara organik saat merekonsiliasi atau mengaudit.

<Tip>
  Migrasi dari **Polar.sh** atau **Lemon Squeezy**? [`dodo-migrate` CLI](/migrate-to-dodo) mengotomatisasi impor massal produk, pelanggan, diskon, dan kunci lisensi dalam satu perintah dan memetakan ID eksternal ke ID Dodo secara otomatis.
</Tip>

***

## Kunci Lisensi dalam URL Pengembalian

Ketika pelanggan menyelesaikan pembelian untuk produk dengan hak Kunci Lisensi, kunci yang dihasilkan secara otomatis ditambahkan ke `return_url` Anda sebagai parameter kueri. Ini memungkinkan Anda menampilkan kunci segera di halaman sukses Anda tanpa perlu memanggil API tambahan.

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

Jika pembelian menghasilkan beberapa kunci (kuantitas > 1), mereka dipisahkan dengan koma:

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

Untuk langganan, `subscription_id` digunakan sebagai pengganti `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>
  Parse parameter `license_key` di halaman pengembalian Anda untuk menampilkan kunci segera, meningkatkan pengalaman pasca pembelian.
</Tip>

***

## Manajemen API

<AccordionGroup>
  <Accordion title="Lifecycle Operations (Public Endpoints)">
    Aktivasi, penonaktifan, dan validasi bersifat publik; tidak diperlukan kunci API.

    <CardGroup cols={3}>
      <Card title="Activate License" icon="code" href="/api-reference/licenses/activate-license">
        Buat atau catat instance aktivasi untuk kunci lisensi.
      </Card>

      <Card title="Deactivate License" icon="code" href="/api-reference/licenses/deactivate-license">
        Mencabut aktivasi sebelumnya untuk membebaskan kapasitas.
      </Card>

      <Card title="Validate License" icon="code" href="/api-reference/licenses/validate-license">
        Periksa keaslian, status, dan batasan sebelum memberikan akses.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="License Key Management">
    Buat, daftar, ambil, dan perbarui catatan kunci lisensi individual. Gunakan ini untuk mengimpor kunci yang ada atau mengambil detail penggunaan.

    <CardGroup cols={2}>
      <Card title="Create License Key" icon="code" href="/api-reference/licenses/create-license-key">
        Buat kunci lisensi baru atau impor kunci yang sudah ada.
      </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">
        Ambil kunci tertentu dan metadata-nya.
      </Card>

      <Card title="Update License Key" icon="code" href="/api-reference/licenses/update-license-key">
        Modifikasi masa kadaluarsa, batas aktivasi, atau aktifkan/nonaktifkan kunci.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="Entitlement Management">
    Kelola hak Kunci Lisensi itu sendiri: batas aktivasi, durasi, dan instruksinya.

    <CardGroup cols={2}>
      <Card title="Create Entitlement" icon="plus" href="/api-reference/entitlements/create-entitlement">
        Buat hak Kunci Lisensi.
      </Card>

      <Card title="Update Entitlement" icon="pen" href="/api-reference/entitlements/update-entitlement">
        Perbarui konfigurasi hak.
      </Card>

      <Card title="List Grants" icon="users" href="/api-reference/entitlements/list-grants">
        Daftar kunci yang diterbitkan untuk hak tersebut.
      </Card>

      <Card title="Revoke Grant" icon="ban" href="/api-reference/entitlements/revoke-grant">
        Mencabut kunci pelanggan secara manual.
      </Card>
    </CardGroup>
  </Accordion>
</AccordionGroup>

***

## Webhooks

Penyampaian kunci lisensi dan pencabutan memicu empat [`entitlement_grant.*` peristiwa webhook](/developer-resources/webhooks/intents/entitlement-grant). Muatan penghargaan mencakup `license_key` objek dengan kunci, kadaluarsa, aktivasi yang digunakan, dan batas.

Acara `license_key.*` lama (`license_key.created`) terus memicu untuk siklus hidup rekaman kunci lisensi yang mendasari; lihat [halaman muatan webhook Kunci Lisensi](/developer-resources/webhooks/intents/license-key).

<Tip>
  Untuk integrasi baru, dengarkan `entitlement_grant.delivered` daripada `license_key.created`. Peristiwa hak memberitahu Anda penyampaian selesai di semua integrasi pada produk, bukan hanya kunci lisensi.
</Tip>

***

## Kunci Lisensi Lama

<Note>
  Produk yang dibuat dengan bendera lama `license_key_enabled` telah **secara otomatis dimigrasikan** ke hak Kunci Lisensi. Migrasi ini transparan: kunci pelanggan yang ada tetap bekerja tanpa perubahan, public `/licenses/activate`, `/licenses/validate`, `/licenses/deactivate` endpoint tetap berfungsi, dan `/license_keys/*` endpoint API terus membaca dan menulis ke penyimpanan kunci yang sama.

  Bagian dasbor **License Keys** yang berdiri sendiri tetap tersedia sebagai daftar datar setiap kunci yang diterbitkan, berguna untuk audit dan pencarian. Konfigurasi baru (mengubah batas aktivasi, durasi, atau instruksi) harus dilakukan dengan mengedit hak Kunci Lisensi yang dimigrasikan di bawah **Entitlements**.
</Note>

***

## Praktik Terbaik

* **Simpan batas aktivasi dengan jelas**: Pilih default yang masuk akal (1 untuk aplikasi pengguna tunggal, 3–5 untuk lisensi tim) dan dokumentasikan.
* **Berikan instruksi aktivasi yang tepat**: Pelanggan menyalin dan menempel dari email mereka, sehingga jalur dan perintah yang tepat menghemat tiket dukungan.
* **Validasi kunci sisi server**: Untuk produk yang terhubung ke jaringan, validasi melalui `/licenses/validate` alih-alih menyimpan aktivasi secara lokal.
* **Gunakan webhooks untuk pencabutan**: Dengarkan `entitlement_grant.revoked` untuk menonaktifkan fitur dalam aplikasi segera ketika pelanggan membatalkan atau mengembalikan.
* **Uji dengan langganan dan satu kali**: Perilaku kunci lisensi berbeda secara halus antara keduanya, jadi uji keduanya sebelum ditayangkan.

<Tip>
  Parse parameter `license_key` pada halaman pengembalian Anda untuk menampilkan kunci segera, meningkatkan pengalaman purna-beli.
</Tip>

***

## Manajemen API

<AccordionGroup>
  <Accordion title="Lifecycle Operations (Public Endpoints)">
    Aktivasi, deaktivasi, dan validasi bersifat publik; tidak memerlukan kunci API.

    <CardGroup cols={3}>
      <Card title="Activate License" icon="code" href="/api-reference/licenses/activate-license">
        Buat atau catat instance aktivasi untuk kunci lisensi.
      </Card>

      <Card title="Deactivate License" icon="code" href="/api-reference/licenses/deactivate-license">
        Batalkan aktivasi sebelumnya untuk membebaskan kapasitas.
      </Card>

      <Card title="Validate License" icon="code" href="/api-reference/licenses/validate-license">
        Periksa keaslian, status, dan batasan sebelum memberikan akses.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="License Key Management">
    Buat, daftarkan, ambil, dan perbarui catatan kunci lisensi individu. Gunakan ini untuk mengimpor kunci yang ada atau mengambil detail penggunaan.

    <CardGroup cols={2}>
      <Card title="Create License Key" icon="code" href="/api-reference/licenses/create-license-key">
        Buat kunci lisensi baru atau impor yang sudah ada.
      </Card>

      <Card title="List License Keys" icon="code" href="/api-reference/licenses/list-license-keys">
        Telusuri semua kunci dengan status dan detail penggunaan.
      </Card>

      <Card title="Get License Key" icon="code" href="/api-reference/licenses/get-license-key">
        Ambil kunci tertentu dan metadata-nya.
      </Card>

      <Card title="Update License Key" icon="code" href="/api-reference/licenses/update-license-key">
        Modifikasi batas kadaluarsa, aktivasi, atau aktifkan/nonaktifkan kunci.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="Entitlement Management">
    Kelola hak kunci lisensi itu sendiri: batasan aktivasi, durasi, dan instruksi.

    <CardGroup cols={2}>
      <Card title="Create Entitlement" icon="plus" href="/api-reference/entitlements/create-entitlement">
        Buat hak kunci lisensi.
      </Card>

      <Card title="Update Entitlement" icon="pen" href="/api-reference/entitlements/update-entitlement">
        Perbarui konfigurasi hak.
      </Card>

      <Card title="List Grants" icon="users" href="/api-reference/entitlements/list-grants">
        Daftarkan kunci yang diterbitkan untuk hak tersebut.
      </Card>

      <Card title="Revoke Grant" icon="ban" href="/api-reference/entitlements/revoke-grant">
        Cabut manual kunci pelanggan.
      </Card>
    </CardGroup>
  </Accordion>
</AccordionGroup>

***

## Webhooks

Pengiriman dan pencabutan kunci lisensi akan memicu empat [`entitlement_grant.*` peristiwa webhook](/developer-resources/webhooks/intents/entitlement-grant). Payload pemberian mencakup objek `license_key` yang terisi dengan kunci, kedaluwarsa, penggunaan aktivasi, dan batasan.

Peristiwa warisan `license_key.*` (`license_key.created`) tetap berjalan untuk siklus hidup catatan kunci lisensi; lihat [halaman payload webhook Kunci Lisensi](/developer-resources/webhooks/intents/license-key).

<Tip>
  Untuk integrasi baru, dengarkan `entitlement_grant.delivered` dibandingkan dengan `license_key.created`. Peristiwa hak memberi tahu Anda bahwa pengiriman selesai di semua integrasi pada produk, bukan hanya kunci lisensi.
</Tip>

***

## Kunci Lisensi Warisan

<Note>
  Produk yang dibuat dengan bendera lama `license_key_enabled` telah **di-migrasikan secara otomatis** ke hak kunci lisensi. Migrasi ini transparan: kunci pelanggan yang ada tetap berfungsi tanpa perubahan, endpoint publik `/licenses/activate`, `/licenses/validate`, `/licenses/deactivate` tetap berfungsi, dan endpoint API `/license_keys/*` terus membaca dan menulis pada penyimpanan kunci yang sama.

  Bagian dashboard **Kunci Lisensi** mandiri tetap tersedia sebagai daftar rata dari setiap kunci yang diterbitkan, berguna untuk audit dan pencarian. Konfigurasi baru (mengubah batasan aktivasi, durasi, atau instruksi) harus dilakukan dengan mengedit hak kunci lisensi yang dimigrasikan di bawah **Entitlements**.
</Note>

***

## Praktik Terbaik

* **Jaga agar batas aktivasi jelas**: Pilih default yang masuk akal (1 untuk aplikasi pengguna tunggal, 3–5 untuk lisensi tim) dan dokumentasikan.
* **Berikan instruksi aktivasi yang tepat**: Pelanggan menyalin ini dari email mereka, sehingga jalur dan perintah yang tepat menghemat tiket dukungan.
* **Validasi kunci server-side**: Untuk produk yang terhubung jaringan, validasi melalui `/licenses/validate` dibandingkan dengan menyimpan aktivasi secara lokal.
* **Gunakan webhooks untuk pencabutan**: Dengar `entitlement_grant.revoked` untuk menonaktifkan fitur dalam aplikasi segera ketika pelanggan membatalkan atau mengembalikan uang.
* **Uji dengan langganan dan pembelian satu kali**: Perilaku kunci lisensi berbeda sedikit antara keduanya, jadi uji keduanya sebelum live.
