Langsung ke konten utama
Panduan ini menjelaskan langkah-langkah membangun sistem pemenuhan kunci lisensi manual dari awal hingga akhir. Alih-alih Dodo Payments yang membuat kunci otomatis saat pembayaran, setiap pembelian membuat grant pending dan menunggu Anda memasok nilai kunci dari sistem Anda sendiri, vendor pihak ketiga, atau kumpulan kode yang terbatas. Pada akhirnya Anda akan memiliki:
  • Produk dengan hak Kunci Lisensi yang diatur ke pemenuhan manual.
  • Sebuah webhook listener yang mendeteksi ketika pelanggan menunggu kunci.
  • Panggilan pemenuhan yang mengirim kunci dan memberi tahu pelanggan secara otomatis.

License Keys overview

Siklus hidup kunci lisensi lengkap dan pengaturan fulfillment_mode.

Fulfill License Key Grant API

Referensi API untuk endpoint yang Anda panggil untuk mengirim kunci.

Cara Kerjanya

Pemenuhan manual hanya mengubah langkah penerbitan. Aktivasi, validasi, deaktivasi, kadaluarsa, dan pencabutan berperilaku persis seperti kunci yang dihasilkan secara otomatis setelah dikirimkan.

Prasyarat

Untuk mengikuti panduan ini Anda memerlukan:
  • Akun pedagang Dodo Payments.
  • Kunci API Anda (DODO_PAYMENTS_API_KEY) dan kunci rahasia webhook dari dashboard. Lihat panduan pembuatan kunci API.
  • Sebuah endpoint backend yang dapat menerima webhooks.
Gunakan https://test.dodopayments.com dan kredensial test-mode saat membangun. Beralih ke https://live.dodopayments.com dan kunci live saat Anda masuk ke produksi.

Langkah 1 — Buat Hak Kunci Lisensi dalam Mode Manual

Sebuah hak adalah definisi yang dapat digunakan kembali dari apa yang Anda kirim. Buat hak Kunci Lisensi dan atur fulfillment_mode ke manual.
1

Open Entitlements

Pergi ke Hak di dashboard Anda dan klik + untuk membuat hak baru.
2

Choose License Key

Pilih License Key sebagai integrasi dan berikan Nama. Formulirnya menampilkan bidang berikut:
  • Fulfillment ModeAutomatic secara default. Ini adalah pengaturan yang memungkinkan pemenuhan manual; Anda mengubahnya di langkah berikutnya.
  • Panjang Lisensi — berapa lama setiap kunci yang diterbitkan tetap valid, atau Tanpa kadaluarsa.
  • Batas Aktivasi — maksimum aktivasi per kunci, atau Tak terbatas.
  • Pesan Aktivasi — pesan opsional yang ditampilkan kepada pelanggan ketika mereka mengaktifkan kunci.
Formulir hak Kunci Lisensi baru dengan nama, mode pemenuhan, panjang lisensi, batas aktivasi, dan pesan aktivasi
3

Set Fulfillment Mode to Manual

Buka dropdown Fulfillment Mode dan ubah dari Automatic ke Manual. Ini adalah pengaturan yang mengarahkan seluruh panduan ini — tanpanya, kunci dibuat dan dikirim secara otomatis dan tidak ada grant yang tertunda dibuat. Dengan Manual yang dipilih, setiap pembelian membuat grant pending untuk Anda penuhi. Klik Create Entitlement untuk menyimpan.
fulfillment_mode default ke auto. Mengabaikannya, atau membiarkan hak yang ada tidak berubah, mempertahankan perilaku otomatis. Hanya hak yang secara eksplisit diatur ke manual yang membuat grant yang tertunda.

Langkah 2 — Pasang Hak ke Produk

Buka produk yang ingin Anda jual, perluas Pengaturan Lanjutan → Hak & Kredit, dan pilih Hak Kunci Lisensi yang Anda atur ke Manual di Langkah 1. Satu produk dapat menyediakan kunci lisensi ini bersama hak lain pada pembelian yang sama.
Panel hak produk dengan Kunci Lisensi yang dipilih
Fulfillment mode adalah properti dari hak, bukan produk. Karena Anda mengaturnya ke Manual di Langkah 1, setiap produk yang terpasang pada hak ini menciptakan grant lisensi-kunci pending saat pembelian — tidak ada yang perlu dikonfigurasi di sini.
Jika Anda belum memiliki produk, buat terlebih dahulu (satu kali atau berlangganan). Lihat Panduan Integrasi Pembayaran Satu Kali untuk menjual produk melalui checkout.

Langkah 3 — Deteksi Grant yang Tertunda

Ketika pelanggan membeli produk, Dodo Payments membuat grant dalam status pending dengan tidak ada kunci terlampir dan menembakkan webhook entitlement_grant.created. Ini adalah sinyal Anda bahwa pelanggan menunggu kunci.

Dengarkan untuk webhook

Siapkan endpoint webhook (Pengembang → Webhook di dashboard) dan bertindaklah pada grant lisensi-kunci yang tertunda. Implementasinya mengikuti spesifikasi Standard Webhooks.
import { Webhook } from 'standardwebhooks';

const webhook = new Webhook(process.env.DODO_WEBHOOK_KEY!);

export async function POST(request: Request) {
  const rawBody = await request.text();
  const headers = {
    'webhook-id': request.headers.get('webhook-id') || '',
    'webhook-signature': request.headers.get('webhook-signature') || '',
    'webhook-timestamp': request.headers.get('webhook-timestamp') || '',
  };

  await webhook.verify(rawBody, headers);
  const event = JSON.parse(rawBody);

  // A customer bought a manual-mode license key and is waiting for it.
  if (
    event.type === 'entitlement_grant.created' &&
    event.data.integration_type === 'license_key' &&
    event.data.status === 'pending'
  ) {
    await queueLicenseKeyFulfillment({
      grantId: event.data.id,
      customerId: event.data.customer_id,
    });
  }

  return new Response('ok');
}
Payload grant membawa integration_type: "license_key", sehingga Anda dapat mengenali grant lisensi-kunci tanpa pencarian tambahan. Lihat referensi webhook Grant Hak untuk payload lengkap.

Atau polling API List Grants

Jika Anda lebih memilih untuk tidak bergantung pada webhooks, daftar grant untuk hak dan filter berdasarkan integration_type dan status:
const pending = await client.entitlements.grants.list('ent_license_key_id', {
  integration_type: 'license_key',
  status: 'pending',
});

for (const grant of pending.items) {
  console.log(`Grant ${grant.id} for customer ${grant.customer_id} needs a key`);
}

Langkah 4 — Kirim Kunci

Dapatkan nilai kunci dari sistem Anda sendiri, lalu kirimkan dengan endpoint Fulfill License Key Grant. Ini memerlukan kunci API rahasia Anda (Izin Editor); ini bukan salah satu dari endpoint lisensi publik.
async function fulfill(grantId: string, key: string) {
  const res = await fetch(
    `https://test.dodopayments.com/grants/${grantId}/license-key`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${process.env.DODO_PAYMENTS_API_KEY}`,
      },
      body: JSON.stringify({
        key,
        // Optional — fall back to the entitlement config when omitted
        activations_limit: 5,
        expires_at: '2027-05-01T00:00:00Z',
      }),
    },
  );

  if (!res.ok) {
    // See the status code table below for handling
    throw new Error(`Fulfillment failed: ${res.status}`);
  }

  return res.json(); // updated grant, now status: "delivered"
}

Bidang Permintaan

key
string
wajib
String kunci lisensi untuk dikirim ke pelanggan. Spasi dikurangi; nilai kosong atau hanya spasi ditolak.
activations_limit
integer
Batas aktivasi per kunci. Kembali ke konfigurasi hak jika tidak diisi.
expires_at
string
Kadaluarsa per kunci (ISO 8601). Kembali ke durasi konfigurasi hak jika tidak diisi. Untuk grant yang diterbitkan langganan, validitas tetap terkait dengan langganan terlepas apapun.
Pada keberhasilan, grant berpindah ke delivered, pelanggan dikirim kunci secara otomatis (email yang sama yang akan mereka terima di bawah pemenuhan otomatis), dan entitlement_grant.delivered menembak. Pelanggan menerima email dengan kunci lisensi, produk, batas aktivasi, kadaluarsa, dan instruksi aktivasi Anda:
Email kunci lisensi pelanggan yang menunjukkan kunci, produk, batas aktivasi, kadaluarsa, dan instruksi aktivasi
Anda tidak perlu mengirim email kunci sendiri — pengiriman terjadi secara otomatis ketika grant dipenuhi.

Langkah 5 — Tangani Kesalahan dan Pengulangan

Endpoint memvalidasi grant sebelum mengirimkan apapun. Tangani tanggapan berikut:
StatusArtiApa yang harus dilakukan
200Kunci terkirim, grant sekarang delivered.Selesai.
400Bukan grant kunci-lisensi, atau kuncinya kosong/hanya spasi.Perbaiki permintaan; jangan coba lagi sebagaimana adanya.
404Tidak ada grant dengan ID tersebut untuk bisnis Anda.Verifikasi grant_id.
409Grant tidak menunggu pemenuhan (sudah terkirim atau sudah memiliki kunci), atau nilai kunci sudah ada.Jika sudah dikirim, perlakukan sebagai keberhasilan. Jika duplikat kunci, berikan kunci yang berbeda.
422Body permintaan gagal validasi (mis. activations_limit < 1).Koreksi bidang dan coba lagi.
Pemenuhan aman untuk diulang pada kesalahan sementara (timeout, 5xx). Setiap grant hanya dapat dipenuhi sekali, jadi pengulangan setelah panggilan yang berhasil-tapi-belum diakui mengembalikan 409 daripada mengeluarkan kunci kedua atau mengirim email duplikat. Gunakan grant id sebagai kunci idempoten Anda.

Verifikasi Alur

  1. Beli produk dalam mode pengujian (lihat panduan checkout).
  2. Konfirmasi webhook Anda menerima entitlement_grant.created dengan status: "pending" dan integration_type: "license_key", atau bahwa grant muncul dalam respons List Grants dengan filter tersebut.
  3. Panggil endpoint pemenuhan dengan kunci pengujian.
  4. Konfirmasi tanggapan menunjukkan status: "delivered" dengan license_key yang terisi, pelanggan menerima email kunci, dan entitlement_grant.delivered menembak.
Setelah dikirim, pelanggan dapat mengaktifkan dan memvalidasi kunci terhadap endpoint lisensi publik persis seperti kunci yang dihasilkan secara otomatis.

Referensi API Terkait

Create Entitlement

Buat hak Kunci Lisensi dengan fulfillment_mode: manual.

List Grants

Filter berdasarkan integration_type dan status untuk menemukan grant yang pending.

Fulfill License Key Grant

Kirim nilai kunci dan transisikan grant ke terkirim.

Entitlement Grant Webhooks

Acara entitlement_grant.* yang menandakan grant yang tertunda dan terkirim.

Create Entitlement

Create the License Key entitlement with fulfillment_mode: manual.

List Grants

Filter by integration_type and status to find pending grants.

Fulfill License Key Grant

Deliver the key value and transition the grant to delivered.

Entitlement Grant Webhooks

The entitlement_grant.* events that signal pending and delivered grants.
Last modified on June 9, 2026