# Panduan integrasi sistem lisensi kustom

Kode sumber saat ini mendukung dua penyedia lisensi: Licentivo dan `custom_http`. Pedagang memilih dan mengaktifkan salah satunya untuk seluruh produk dan lingkungan sandbox/live di **Pengaturan sistem → Sistem lisensi**; koneksi kustom dan pemetaan paket tetap dikonfigurasi per produk dan lingkungan. Fitur ini tidak mencakup pembangunan sistem lisensi sendiri; pedagang tetap menggunakan layanan lisensi dan SDK miliknya.

Pertukaran akun Licentivo, SDK sembilan bahasa, dan pengelolaan perangkat tetap menggunakan alur yang ada. Produk kustom menyinkronkan status pembelian melalui protokol ini; pelanggan membaca hasil penyampaian lisensi di pusat akun tanpa melalui alur Licentivo SDK.

## Mulai cepat

1. Implementasikan empat endpoint HTTP berikut pada layanan Anda, lalu konfigurasikan kunci penandatanganan HMAC dan pengenal terpisah untuk setiap koneksi.
2. Di ‘Sistem lisensi’, pilih ‘Layanan lisensi kustom’, tambahkan koneksi, isi alamat, lingkungan, pengenal koneksi, key ID, dan kunci Base64 standar. Setelah diverifikasi, simpan dan klik ‘Aktifkan layanan lisensi kustom’.
3. Buat draf produk dan paket penjualan. Jenis pembelian dan harga dikelola di Launch; aturan lisensi dikelola di sistem Anda sendiri.
4. Pilih produk, lingkungan, dan koneksi, lalu isi dan simpan referensi produk serta paket eksternal. Penyedia ditentukan oleh pilihan di seluruh situs; Licentivo tidak dapat diaktifkan bersamaan untuk produk lain.
5. Terbitkan versi uji di halaman paket penjualan, selesaikan penerimaan pembayaran, penyampaian, perpanjangan, peningkatan, pengembalian dana, dan pemulihan kegagalan, lalu konfigurasikan lingkungan produksi secara terpisah.

Alamat, lingkungan, pengenal koneksi, dan kebijakan akses jaringan tidak dapat diubah setelah dibuat; buat koneksi baru jika diperlukan. Kunci penandatanganan dapat dirotasi; biarkan kosong untuk mempertahankan kunci lama. Jika ada pesanan dari sistem lisensi lain, penyedia seluruh situs tidak dapat langsung diganti; migrasi harus diselesaikan terlebih dahulu. Setelah pergantian, paket lama menjadi hanya pratinjau dan harus diterbitkan ulang; kredensial koneksi dan pemetaan yang tersimpan tetap dipertahankan. Koneksi untuk produk yang sudah memiliki pesanan tidak dapat langsung diganti, begitu pula pemetaan yang sedang dijual; gunakan versi paket baru untuk harga atau pemetaan baru.

Saat mengonfigurasi melalui API, panggil `PUT /api/v1/admin/licensing/provider` terlebih dahulu dengan isi permintaan `{"provider":"custom_http"}` atau `{"provider":"licentivo"}`, lalu simpan pemetaan produk. Penyedia yang tidak diaktifkan tidak dapat menyimpan pengikatan lisensi produk atau pemetaan kebijakan paket Licentivo.

Pemeriksaan koneksi mengonfirmasi protokol, autentikasi, lingkungan, dan jenis pembelian yang didukung; pemeriksaan ini tidak membuat atau mengonfirmasi paket eksternal atas nama pedagang. Sebelum menerima pembayaran produksi, penerimaan integrasi sandbox harus diselesaikan menggunakan paket eksternal yang sebenarnya.

## 3. Alur integrasi pedagang

1. Implementasikan empat endpoint dalam dokumen ini di depan sistem lisensi yang ada; logika lisensi yang sudah ada tetap dipertahankan.
2. Buat koneksi ‘Layanan lisensi kustom’ di Launch, lalu konfigurasikan alamat HTTPS, pengenal koneksi, lingkungan, dan kunci penandatanganan.
3. Launch memanggil endpoint pemeriksaan kemampuan untuk memastikan versi protokol, dukungan pembelian permanen/berjangka, dan metode penyampaian.
4. Pilih koneksi tersebut untuk produk; petakan versi paket penjualan ke `product_ref` dan `plan_ref` eksternal. Pengenal eksternal dapat berupa string milik pedagang dan tidak harus menggunakan UUID Licentivo.
5. Selesaikan penerimaan pembayaran, perpanjangan, peningkatan, pengembalian dana, dan pemulihan kegagalan di sandbox, lalu terbitkan konfigurasi live secara terpisah.
6. Setelah memverifikasi pembayaran, Launch menyimpan pesanan, cakupan pembelian, dan tugas yang menunggu pengiriman dalam transaksi basis data yang sama.
7. Proses latar belakang mengirimkan snapshot pembelian lengkap ke layanan lisensi kustom; layanan tersebut mengonfirmasi penerimaan setelah menyimpan catatan penerimaan secara persisten.
8. Layanan lisensi memproses status tujuan. Launch memeriksa tanda terima peristiwa asli dan hanya menganggap sinkronisasi selesai ketika statusnya `applied`.
9. Launch membaca informasi penyampaian bagi pelanggan yang sudah masuk dan memiliki pembelian tersebut, lalu menampilkan kode lisensi, akses aktivasi, atau petunjuk teks biasa di pusat pelanggan. Aplikasi terhubung ke sistem lisensi milik pedagang.
10. Perpanjangan, peningkatan, pengembalian dana, pembalikan pembayaran, penangguhan, dan kedaluwarsa masing-masing menghasilkan snapshot lengkap versi baru. Layanan lisensi memprosesnya berdasarkan status tujuan terbaru.

sandbox/live untuk produk yang sama diikat ke koneksi masing-masing. Setelah ada pembelian, pergantian penyedia memerlukan proses migrasi terpisah; pesanan dan tugas lama tidak boleh diam-diam dikirim ke layanan baru mengikuti pilihan di panel administrasi.

## 4. API yang harus diimplementasikan oleh layanan lisensi kustom

Semua endpoint berikut **diterima oleh layanan lisensi pedagang dan dipanggil oleh server Launch**. `base_url` dapat berisi awalan path tetap; path dalam tabel ditambahkan setelah awalan tersebut.

| Metode dan path | Tujuan |
| --- | --- |
| `GET /launch/v1/capabilities` | Pemeriksaan koneksi serta deklarasi protokol dan kemampuan |
| `POST /launch/v1/events` | Menerima status tujuan pembelian lengkap; percobaan ulang menggunakan peristiwa asli |
| `GET /launch/v1/events/{event_id}` | Memeriksa apakah peristiwa benar-benar diterapkan dan memulihkan respons yang hilang |
| `GET /launch/v1/entitlements/{entitlement_ref}/delivery` | Membaca informasi penyampaian lisensi yang sudah ada tanpa membuat lisensi kedua |

Versi pertama menggunakan pemeriksaan tanda terima secara aktif dan tidak menambahkan endpoint callback eksternal untuk mengubah pesanan. Layanan kustom tidak berwenang mengonfirmasi pembayaran, mengubah harga, atau mengubah masa pembelian.

### 4.1 Ketentuan umum dan autentikasi

- JSON menggunakan UTF-8; waktu menggunakan UTC RFC 3339; `version` menggunakan bilangan bulat positif.
- Respons berhasil adalah `{"data": {...}, "request_id": "..."}`; respons kesalahan adalah `{"error": {"code": "...", "message": "..."}, "request_id": "..."}`.
- Setiap lingkungan dan koneksi menggunakan kunci terpisah. Kunci terdiri atas setidaknya 32 byte acak dan dirujuk dari penyimpanan kunci terenkripsi yang ada di Launch; jangan masukkan ke konfigurasi frontend, contoh, atau paket instalasi aplikasi.
- Setiap permintaan membawa `X-Launch-Key-Id`, `X-Launch-Timestamp`, `X-Launch-Nonce`, dan `X-Launch-Signature`.
- Stempel waktu berupa detik Unix desimal. nonce adalah nilai acak minimal 128 bit yang dikodekan dalam base64url tanpa padding; buat nilai baru untuk setiap percobaan jaringan.

Masukan tanda tangan adalah byte UTF-8 dari tujuh unsur berikut yang digabungkan dengan satu karakter baris baru, tanpa baris baru di akhir:

```text
v1
<key_id>
<timestamp>
<nonce>
<UPPERCASE HTTP method>
<encoded request path and raw query, including the base_url path prefix>
<lowercase hexadecimal SHA-256 digest of the exact request body>
```

`X-Launch-Signature` adalah `v1=` diikuti hasil `HMAC-SHA256` yang dikodekan dalam base64url tanpa padding. Isi permintaan GET kosong. Penerima memverifikasi tanda tangan dan rentang waktu sebelum deserialisasi; gunakan perbandingan waktu konstan, izinkan selisih plus atau minus 300 detik secara default, dan simpan nonce setidaknya 600 detik untuk mencegah replay. Jangan gunakan kembali nonce antarpercobaan, tetapi ID peristiwa dan isi permintaan bisnis harus tetap sama.

Tanda tangan tidak menggantikan HTTPS. Permintaan tidak membawa kata sandi pelanggan, kunci pembayaran, atau kunci administrasi Licentivo; secara default hanya referensi akun anonim yang dikirim, bukan email. Klien HTTP server memerlukan batas waktu, batas panjang respons, dan larangan mengikuti pengalihan dengan membawa kredensial. Validasi alamat tujuan saat mengonfigurasi alamat kustom; akses ke jaringan internal harus menjadi kemampuan deployment yang dikonfigurasi secara eksplisit oleh administrator.

### 4.2 Pemeriksaan kemampuan

`GET /launch/v1/capabilities` mengembalikan HTTP 200, misalnya:

```json
{
  "data": {
    "protocol": "launch-external-licensing-v1",
    "connection_ref": "merchant-01-sandbox",
    "environment": "sandbox",
    "purchase_types": ["perpetual", "fixed_term"],
    "delivery_types": ["license_key", "activation_url", "instructions"],
    "devices": false,
    "identity_exchange": false
  },
  "request_id": "check-001"
}
```

`protocol`, `connection_ref`, `environment`, `purchase_types`, dan `delivery_types` wajib diisi. Dua yang terakhir harus berupa array tidak kosong; jenis pembelian yang tidak didukung tidak boleh diterbitkan untuk dijual. Pada versi pertama, `devices` dan `identity_exchange` harus `false`; dukungan hanya boleh dinyatakan setelah kontrak ekstensi dan implementasinya selesai.

### 4.3 Snapshot pembelian

Contoh permintaan `POST /launch/v1/events`:

```json
{
  "schema": "launch-external-licensing-v1",
  "event_id": "7bf84b91-2749-4b01-a6a7-bd527c488ee8",
  "connection_ref": "merchant-01-sandbox",
  "environment": "sandbox",
  "type": "entitlement.snapshot",
  "change_reason": "purchase",
  "account_ref": "customer_opaque_001",
  "entitlement_ref": "purchase_opaque_001",
  "launch_product_id": "c6dd463e-50f7-4b76-8239-0a8ec6fc304b",
  "launch_plan_version_id": "5459a073-9362-4b46-949d-9b0c5d84421a",
  "product_ref": "desktop-editor",
  "plan_ref": "professional-yearly-v1",
  "version": 1,
  "desired_state": "active",
  "valid_from": "2026-10-25T00:00:00Z",
  "valid_until": "2027-10-25T00:00:00Z"
}
```

Semua bidang pada contoh di atas wajib diisi. `valid_until` bernilai `null` berarti pembelian permanen; nilai lainnya harus lebih akhir daripada `valid_from`.

| Bidang | Batasan dan arti |
| --- | --- |
| `event_id` | UUID yang dibuat oleh Launch; tetap sama pada percobaan ulang peristiwa yang sama |
| `connection_ref` / `environment` | Harus sesuai dengan koneksi dan lingkungan pemilik kunci penandatanganan |
| `account_ref` | Referensi akun anonim yang stabil; penerima mengidentifikasi pelanggan berdasarkan kombinasi koneksi, lingkungan, dan referensi ini |
| `entitlement_ref` | Referensi stabil untuk satu hubungan pembelian; pembelian ulang setelah seluruhnya dicabut menggunakan referensi baru |
| `launch_product_id` / `launch_plan_version_id` | UUID produk Launch dan versi paket yang tidak dapat diubah |
| `product_ref` / `plan_ref` | Referensi eksternal yang dikonfigurasi integrator; 1–128 karakter ASCII, dengan huruf, angka, `_`, `-`, dan `.` diperbolehkan; paket eksternal tidak dibuat secara otomatis |
| `version` | Versi tujuan yang meningkat secara monoton untuk koneksi, lingkungan, dan referensi pembelian yang sama |
| `desired_state` | `active`、`suspended`、`expired`、`revoked` |
| `change_reason` | `purchase`、`renewal`、`upgrade`、`refund`、`reversal`、`suspension`、`resumption`、`expiry`、`reconciliation` |

`account_ref` dan `entitlement_ref` menggunakan 1–128 huruf, angka, garis bawah, atau tanda hubung. `schema` dan `type` tetap menggunakan nilai dalam contoh. Penerima menerapkan hasil berdasarkan `desired_state` dan masa berlaku absolut lengkap, tanpa menambahkan hari atau mencabut seluruh lisensi sendiri berdasarkan alasan.

Khusus untuk pengembalian dana: setelah pesanan perpanjangan atau peningkatan dikembalikan, pembelian dasar yang valid mungkin masih ada. Dalam hal ini snapshot masih dapat berstatus `active`, tetapi masa berlaku dipersingkat atau paket berubah. Status penghentian yang sesuai hanya dikirim jika penghitungan ulang ledger menunjukkan tidak ada lagi cakupan pembelian yang valid.

### 4.4 Penerimaan, tanda terima, dan pemulihan

Penerima harus menyimpan ID peristiwa, digest isi permintaan asli, dan tugas yang akan dijalankan secara persisten sebelum mengembalikan HTTP 202; permintaan duplikat yang sudah selesai disinkronkan dapat mengembalikan HTTP 200. Keduanya mengembalikan struktur tanda terima berikut.

```json
{
  "data": {
    "event_id": "7bf84b91-2749-4b01-a6a7-bd527c488ee8",
    "connection_ref": "merchant-01-sandbox",
    "environment": "sandbox",
    "entitlement_ref": "purchase_opaque_001",
    "version": 1,
    "payload_sha256": "<64-character lowercase hexadecimal SHA-256 digest of the exact event body>",
    "status": "pending",
    "error_code": null
  },
  "request_id": "receipt-001"
}
```

Placeholder digest harus diganti dengan digest sebenarnya. Semua bidang tanda terima di atas wajib diisi; `error_code` bernilai `null` jika tidak ada kesalahan. Kueri `GET /launch/v1/events/{event_id}` mengembalikan struktur yang sama dengan HTTP 200; statusnya dapat berupa:

| `status` | Arti | Penanganan oleh Launch |
| --- | --- | --- |
| `pending` | Sudah disimpan secara persisten, tetapi perubahan lisensi sebenarnya belum selesai | Periksa kembali nanti; jangan tandai sinkronisasi sebagai selesai |
| `applied` | Layanan lisensi mengonfirmasi bahwa status tujuan telah benar-benar diterapkan | Konfirmasikan sinkronisasi selesai setelah memeriksa semua bidang terkait dan digest |
| `rejected` | Dipastikan tidak dapat diterapkan, misalnya paket eksternal tidak ada | Hentikan percobaan ulang otomatis dan tampilkan kesalahan yang jelas |
| `manual_review` | Hasil tidak pasti atau status bertentangan dan memerlukan pemeriksaan manual | Pertahankan tugas dan peristiwa asli sambil menunggu penanganan yang dapat diaudit |

Status penyampaian terpisah dari tanda terima sinkronisasi; `applied` tidak dapat langsung dianggap sebagai izin menjalankan aplikasi pelanggan.

Persyaratan keandalan:

- Pengiriman setidaknya sekali; penerima harus menjamin idempotensi bisnis. Tidak dapat dijanjikan bahwa jaringan ‘hanya memanggil sekali’.
- ID peristiwa yang sama dengan isi permintaan asli yang sama mengembalikan hasil yang sudah ada; ID yang sama dengan isi berbeda mengembalikan HTTP 409 `IDEMPOTENCY_CONFLICT`.
- Versi lama tidak boleh menimpa versi baru. Peristiwa atau tujuan yang berbeda untuk versi pembelian yang sama tidak boleh diterima secara diam-diam; kembalikan HTTP 409 `STATE_VERSION_CONFLICT` untuk pemeriksaan.
- Setelah respons POST hilang atau proses dimulai ulang, Launch terlebih dahulu melakukan GET terhadap peristiwa asli; kirim ulang ID dan isi permintaan asli hanya setelah `EVENT_NOT_FOUND` dikembalikan secara jelas.
- Ketika hasil penerbitan aktual di sistem jarak jauh tidak pasti, integrator juga harus memeriksanya menggunakan referensi idempotensi persisten miliknya; pengiriman ulang tidak boleh menghasilkan lisensi baru lagi.
- HTTP 429 mengikuti `Retry-After`; timeout dan 5xx dipulihkan dengan backoff; setelah batas terlampaui, lakukan pemeriksaan manual. Penolakan autentikasi, konfigurasi, dan bisnis tidak boleh dianggap sebagai sinkronisasi berhasil.

Kode kesalahan yang disarankan: `SIGNATURE_INVALID` (401), `SIGNATURE_EXPIRED` (401), `NONCE_REPLAYED` (409), `SCOPE_MISMATCH` (403), `EVENT_NOT_FOUND` (404), `IDEMPOTENCY_CONFLICT` (409), `STATE_VERSION_CONFLICT` (409), `PLAN_UNKNOWN` (422), `PURCHASE_TYPE_UNSUPPORTED` (422), `RATE_LIMITED` (429), `SERVICE_UNAVAILABLE` (503). Pesan kesalahan tidak boleh berisi kredensial.

### 4.5 Penyampaian lisensi

`GET /launch/v1/entitlements/{entitlement_ref}/delivery` hanya dapat membaca hasil penyampaian yang sudah ada pada koneksi dan lingkungan tersebut; kueri tidak boleh dianggap sebagai perintah penerbitan baru. Contoh HTTP 200:

```json
{
  "data": {
    "connection_ref": "merchant-01-sandbox",
    "environment": "sandbox",
    "entitlement_ref": "purchase_opaque_001",
    "version": 1,
    "status": "ready",
    "delivery": {
      "type": "license_key",
      "value": "EXAMPLE-ONLY-NOT-A-REAL-LICENSE",
      "expires_at": null
    }
  },
  "request_id": "delivery-001"
}
```

`status` adalah `pending`, `ready`, atau `unavailable`; ketika bukan ready, `delivery` adalah `null`. Ketika ready, `type` harus berupa `license_key`, `activation_url`, atau `instructions` yang sudah dinyatakan, `value` maksimal 4096 byte UTF-8, dan `expires_at` adalah waktu UTC atau `null`. Semua bidang terkait dalam respons harus sesuai dengan versi pembelian Launch saat ini; penyampaian versi lama tidak dapat dianggap sebagai hasil saat ini.

Kode lisensi adalah data sensitif; respons penyampaian menggunakan `Cache-Control: no-store`, isi respons tidak dicatat, dan penyimpanan terenkripsi digunakan bila persistensi diperlukan. URL aktivasi hanya menerima origin HTTPS yang diizinkan oleh konfigurasi koneksi; instructions ditampilkan sebagai teks biasa tanpa menjalankan HTML atau skrip. Akun yang dicabut, dikembalikan dananya secara penuh, atau tidak memiliki pembelian valid tidak dapat terus memperoleh informasi penyampaian melalui Launch; pembatalan aktual kredensial yang telah disampaikan dilakukan oleh sistem eksternal.

## API administrasi dan pelanggan Launch

Endpoint ini berada di origin Launch yang di-deploy oleh pedagang dan tidak menggunakan kunci HMAC layanan eksternal untuk autentikasi. Administrator menggunakan sesi situs yang ada; permintaan tulis harus membawa `X-CSRF-Token`. Pelanggan hanya dapat membaca pembeliannya sendiri.

| Metode dan path | Tujuan |
| --- | --- |
| `GET /api/v1/admin/licensing/connections` | Mengembalikan `connections`, `bindings`, `mappings`, dan `default_provider`; daftar koneksi hanya berisi koneksi kustom, sedangkan Licentivo tetap menggunakan endpoint administrasi sebelumnya |
| `POST /api/v1/admin/licensing/connections` | Memvalidasi dan menambahkan koneksi kustom |
| `PUT /api/v1/admin/licensing/connections/{id}` | Mengedit nama, origin aktivasi yang diizinkan, dan konfigurasi tanda tangan; alamat penerimaan historis tetap tidak berubah |
| `POST /api/v1/admin/licensing/connections/{id}/check` | Memeriksa ulang; `last_check_error` bukan null dalam HTTP 200 berarti pemeriksaan gagal |
| `PUT /api/v1/admin/products/{id}/licensing` | Mengonfigurasi penyedia, koneksi, dan pemetaan paket eksternal untuk lingkungan yang dipilih pada produk |
| `GET /api/v1/me/products/{id}/delivery?environment=sandbox` | Pelanggan saat ini membaca penyampaian lisensi untuk pembelian kustom yang saat ini valid; autentikasi Cookie atau desktop Bearer |
| `GET /api/v1/licensing/documentation` | Dokumen ini, tanpa perlu masuk |
| `GET /api/v1/licensing/protocol` | OpenAPI yang harus diimplementasikan oleh layanan kustom, tanpa perlu masuk |

Isi permintaan untuk menambahkan koneksi kustom:

```json
{
  "provider": "custom_http",
  "name": "My licensing service",
  "base_url": "https://licenses.example.com",
  "environment": "sandbox",
  "connection_ref": "merchant-01-sandbox",
  "key_id": "key-1",
  "signing_key": "<standard Base64 encoding of 32 to 128 random bytes>",
  "allow_private_network": false,
  "allow_local_http": false,
  "activation_origins": ["https://activate.example.com"]
}
```

Respons `data` adalah objek koneksi yang telah disamarkan dan tidak mengembalikan kunci penandatanganan atau secret ID. allow_local_http hanya mengizinkan alamat localhost/loopback di sandbox; HTTPS jaringan privat memerlukan izin eksplisit administrator. Kunci boleh dikosongkan hanya saat mengedit koneksi yang sudah ada. Licentivo tetap diatur melalui `POST /api/v1/admin/connections/licentivo`.

Isi permintaan untuk mengonfigurasi produk:

```json
{
  "provider": "custom_http",
  "environment": "sandbox",
  "connection_id": "<id returned when creating the connection>",
  "mappings": [
    {
      "version_id": "<Launch plan version UUID>",
      "product_ref": "desktop-editor",
      "plan_ref": "professional-yearly-v1"
    }
  ]
}
```

Saat memilih Licentivo, kirim `{"provider":"licentivo","environment":"sandbox","mappings":[]}`; pemetaan produk/kebijakannya tetap menggunakan endpoint sebelumnya. Pergantian pertama mengubah publikasi yang ada menjadi pratinjau dan perlu diperiksa serta diterbitkan ulang menurut penyedia baru. mappings dapat hanya berisi versi yang akan ditambahkan atau dipertahankan; penghilangan tidak menghapus pemetaan lama.

Penyampaian kepada pelanggan menggunakan envelope data standar dengan HTTP 200; tidak ada pembelian mengembalikan 404, produk Licentivo mengembalikan 409 `LICENSING_DELIVERY_UNSUPPORTED`, belum tersinkronisasi, ditangguhkan, kedaluwarsa, atau dikembalikan dananya secara penuh mengembalikan 409 `ENTITLEMENT_NOT_READY`, dan ketidaktersediaan sementara layanan eksternal atau tanda terima yang tidak cocok mengembalikan 503. ‘Lihat penyampaian lisensi’ di pusat pelanggan memvalidasi ulang kepemilikan dan status, serta tidak menulis kredensial ke URL atau log.

Endpoint identity, device, integration-check Licentivo untuk produk kustom mengembalikan 409 `CUSTOM_LICENSING_SDK_REQUIRED`. `/credential` lama tetap mengembalikan 410. Aplikasi harus menggunakan SDK milik pedagang, bukan menganggap status `ready` Launch sebagai lisensi saat berjalan.

## Contoh dan penerimaan

[Contoh adaptor tipis Python](/id/launch-documents/custom-licensing-example/) menyediakan kerangka penerima untuk tanda tangan, nonce, deduplikasi peristiwa, dan persistensi tanda terima; pemrosesan lisensi sebenarnya perlu diintegrasikan dengan sistem pedagang.

[OpenAPI](/id/assets/launch/external-licensing-openapi.json) protokol kustom dan [OpenAPI](/id/assets/launch/openapi.json) Launch masing-masing menjelaskan dua arah tersebut. Penerima tidak perlu mengimplementasikan katalog produk, katalog kebijakan, atau endpoint kepercayaan identitas Licentivo.

Verifikasi lokal menggunakan MySQL terisolasi, adaptor HTTP nyata, dan layanan lisensi/pembayaran simulasi, mencakup respons hilang, mulai ulang, perpanjangan, peningkatan, pengembalian dana, penonaktifan akun, tanda terima tidak cocok, dan isolasi penyampaian. Penerimaan produksi juga memerlukan layanan lisensi dan aplikasi milik pedagang. Kemampuan perangkat, login akun bersama, dan offline yang tidak dinyatakan tidak disediakan oleh Launch.
