Langsung ke konten utama

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.

Entitlement Grant Webhook Events

Event ini terjadi setiap kali status pemberian hak istimewa pelanggan berubah, misalnya ketika sebuah kunci lisensi dihasilkan, peran Discord diberikan, tautan unduhan disediakan, atau akses dicabut. Berlangganan ke event-event ini untuk menjaga aplikasi Anda tetap sinkron dengan apa yang dapat diakses oleh setiap pelanggan.
EventDeskripsi
entitlement_grant.createdBaris pemberian baru telah dibuat. Statusnya adalah delivered segera untuk kunci lisensi, dan pending untuk setiap integrasi lainnya.
entitlement_grant.deliveredPemberian berubah menjadi terkirim. Pelanggan sekarang memiliki akses ke platform yang ditunjuk, file, atau kunci lisensi.
entitlement_grant.failedPengiriman gagal dan tidak dicoba kembali. Periksa error_code dan error_message.
entitlement_grant.revokedAkses dicabut. Periksa revocation_reason untuk memahami alasannya.
Keempat event tersebut memiliki payload EntitlementGrantResponse yang sama seperti yang didokumentasikan dalam skema di bawah.

Pemicu Event

entitlement_grant.created

Baris pemberian baru saja dimasukkan. Pemberian selalu memiliki id yang stabil sejak saat ini, bahkan jika statusnya berubah. Gunakan event ini untuk mencatat bahwa pemenuhan sedang berlangsung. Untuk kunci lisensi baris dimasukkan langsung dengan status: "delivered" dan delivered_at terisi, sehingga satu event created diikuti tanpa perubahan status lebih lanjut kecuali pemberian dicabut kemudian. Untuk setiap integrasi lainnya baris tiba dengan status: "pending". Sebuah event delivered atau failed mengikuti setelah pengiriman selesai:
  • Integrasi berbasis OAuth (Discord, GitHub, Notion) mencakup oauth_url yang harus dikunjungi pelanggan untuk menyelesaikan persetujuan. Pemberian tetap pending hingga pelanggan memberikan otorisasi.
  • Integrasi langsung dari platform (Telegram, Framer, Digital Files) hanya berada di pending dengan singkat saat panggilan platform berjalan, kemudian berpindah ke delivered.

entitlement_grant.delivered

Pemberian berpindah dari pending ke delivered. Pelanggan sekarang memiliki akses seperti yang dijelaskan oleh pemberian tersebut. Gunakan event ini untuk membuka fitur bergantung dalam sistem Anda sendiri, misalnya untuk menyediakan workspace, mengirim email sambutan khusus, atau menandai “fulfilled”. Field delivered_at dalam payload menangkap waktu penyelesaian pengiriman. Untuk pemberian yang tiba delivered pada pembuatan, Anda akan menerima event created dan delivered secara berurutan.

entitlement_grant.failed

Pengiriman dicoba dan gagal dengan kesalahan yang tidak dapat dicoba ulang. Field error_code dan error_message menjelaskan kegagalan. Penyebab umum termasuk token OAuth dicabut, izin platform ditolak, atau target yang hilang (misalnya, komunitas Discord yang dihapus).
Perlakukan entitlement_grant.failed sebagai tindakan yang dapat dilakukan. Pelanggan membayar tetapi tidak mendapatkan akses. Tampilkan kegagalan kepada tim dukungan Anda atau picu pemberian kembali setelah masalah mendasar teratasi.

entitlement_grant.revoked

Akses ditarik di tingkat platform: peran Discord dihapus, kolaborator GitHub dihapus, kunci lisensi dinonaktifkan, URL unduhan file tidak lagi diterbitkan. Field revocation_reason mencatat pemicu.
revocation_reasonPemicu
subscription_cancelledLangganan pelanggan dibatalkan (subscription.cancelled event).
subscription_on_holdLangganan ditangguhkan karena gagal perpanjangan (subscription.on_hold). Dapat dipulihkan: percobaan ulang yang berhasil menghasilkan pemberian kembali.
subscription_expiredLangganan mencapai akhir masa berlakunya (subscription.expired).
plan_changedPaket diubah; pemberian lama dicabut sebelum yang baru dikeluarkan (subscription.plan_changed).
refundSebuah pengembalian diproses untuk pembayaran satu kali asli (refund.succeeded).
manualSeorang pedagang mencabut pemberian melalui API atau dasbor. Pencabutan manual tidak secara otomatis diberikan kembali pada pembaruan langganan.
license_key_disabledKunci lisensi di belakang pemberian kunci-lisensi dinonaktifkan. Pemberian diaktifkan kembali secara otomatis jika kunci diaktifkan kembali.
platform_externalSisi platform dari integrasi tidak sinkron (misalnya, sebuah peran Discord dihapus secara manual, Aplikasi GitHub kehilangan akses repository, atau penelusuran rekonsiliasi mendeteksi target yang hilang). Pemberian tidak diberikan kembali secara otomatis pada pembaruan langganan hingga masalah platform yang mendasar teratasi.

Variasi Payload

Field data selalu merupakan objek EntitlementGrantResponse. Dua jenis integrasi menempelkan objek bersarang tambahan:
  • license_key disertakan ketika jenis integrasi pemberian adalah license_key. Ini berisi kunci yang dihasilkan, kedaluwarsa, dan penggunaan aktivasi.
  • digital_product_delivery disertakan ketika jenis integrasi adalah digital_files. Ini berisi URL unduhan yang ditandatangani sebelumnya, instructions opsional, dan external_url opsional.
Untuk semua jenis integrasi lainnya (Discord, GitHub, Telegram, Framer, Notion) kedua field adalah null; konfigurasi yang relevan ditangkap dalam pemberian itu sendiri, bukan pemberian.

Contoh Payload

Kunci lisensi dikirim (entitlement_grant.delivered)

{
  "business_id": "bus_H4ekzPSlcg",
  "type": "entitlement_grant.delivered",
  "timestamp": "2026-05-01T10:25:33.000000Z",
  "data": {
    "id": "grant_8VbC6JDZzPEqfBPUdpj0K",
    "business_id": "bus_H4ekzPSlcg",
    "entitlement_id": "ent_9xY2bKwQn5MjRpL8d",
    "customer_id": "cus_abc123",
    "external_id": "lk_AAA111BBB222",
    "payment_id": "pay_a1b2c3d4",
    "subscription_id": null,
    "status": "delivered",
    "license_key": {
      "key": "PRO-AAAA-BBBB-CCCC-DDDD",
      "expires_at": "2027-05-01T00:00:00Z",
      "activations_used": 0,
      "activations_limit": 5
    },
    "digital_product_delivery": null,
    "delivered_at": "2026-05-01T10:25:33Z",
    "revoked_at": null,
    "revocation_reason": null,
    "error_code": null,
    "error_message": null,
    "oauth_url": null,
    "oauth_expires_at": null,
    "metadata": null,
    "created_at": "2026-05-01T10:25:33Z",
    "updated_at": "2026-05-01T10:25:33Z"
  }
}

File digital dikirim (entitlement_grant.delivered)

{
  "business_id": "bus_H4ekzPSlcg",
  "type": "entitlement_grant.delivered",
  "timestamp": "2026-05-01T10:30:12.000000Z",
  "data": {
    "id": "grant_2P9rQwYvMxTnKoCb4",
    "business_id": "bus_H4ekzPSlcg",
    "entitlement_id": "ent_files_J3kLmN4oP5",
    "customer_id": "cus_abc123",
    "external_id": "pay_a1b2c3d4",
    "payment_id": "pay_a1b2c3d4",
    "subscription_id": null,
    "status": "delivered",
    "license_key": null,
    "digital_product_delivery": {
      "files": [
        {
          "file_id": "df_a4f6c1de",
          "download_url": "https://files.dodopayments.com/.../pro-bundle.zip?Signature=...",
          "filename": "pro-bundle.zip",
          "content_type": "application/zip",
          "file_size": 18742390,
          "expires_in": 900
        }
      ],
      "instructions": "Unzip and run setup.sh from the project root.",
      "external_url": null
    },
    "delivered_at": "2026-05-01T10:30:12Z",
    "revoked_at": null,
    "revocation_reason": null,
    "error_code": null,
    "error_message": null,
    "oauth_url": null,
    "oauth_expires_at": null,
    "metadata": null,
    "created_at": "2026-05-01T10:30:12Z",
    "updated_at": "2026-05-01T10:30:12Z"
  }
}

Peran Discord dibuat dan tertunda (entitlement_grant.created)

{
  "business_id": "bus_H4ekzPSlcg",
  "type": "entitlement_grant.created",
  "timestamp": "2026-05-01T10:31:00.000000Z",
  "data": {
    "id": "grant_DiscordPending5L",
    "business_id": "bus_H4ekzPSlcg",
    "entitlement_id": "ent_discord_patrons",
    "customer_id": "cus_abc123",
    "external_id": "sub_pro_monthly_001",
    "payment_id": null,
    "subscription_id": "sub_pro_monthly_001",
    "status": "pending",
    "license_key": null,
    "digital_product_delivery": null,
    "delivered_at": null,
    "revoked_at": null,
    "revocation_reason": null,
    "error_code": null,
    "error_message": null,
    "oauth_url": "https://discord.com/oauth2/authorize?...",
    "oauth_expires_at": "2026-05-08T10:31:00Z",
    "metadata": null,
    "created_at": "2026-05-01T10:31:00Z",
    "updated_at": "2026-05-01T10:31:00Z"
  }
}

Pemberian dicabut pada pembatalan langganan (entitlement_grant.revoked)

{
  "business_id": "bus_H4ekzPSlcg",
  "type": "entitlement_grant.revoked",
  "timestamp": "2026-06-15T08:12:44.000000Z",
  "data": {
    "id": "grant_8VbC6JDZzPEqfBPUdpj0K",
    "business_id": "bus_H4ekzPSlcg",
    "entitlement_id": "ent_9xY2bKwQn5MjRpL8d",
    "customer_id": "cus_abc123",
    "external_id": "sub_pro_monthly_001",
    "payment_id": null,
    "subscription_id": "sub_pro_monthly_001",
    "status": "revoked",
    "revocation_reason": "subscription_cancelled",
    "license_key": {
      "key": "PRO-AAAA-BBBB-CCCC-DDDD",
      "expires_at": null,
      "activations_used": 1,
      "activations_limit": 5
    },
    "digital_product_delivery": null,
    "delivered_at": "2026-05-01T10:25:33Z",
    "revoked_at": "2026-06-15T08:12:44Z",
    "error_code": null,
    "error_message": null,
    "oauth_url": null,
    "oauth_expires_at": null,
    "metadata": null,
    "created_at": "2026-05-01T10:25:33Z",
    "updated_at": "2026-06-15T08:12:44Z"
  }
}

Pengiriman gagal (entitlement_grant.failed)

{
  "business_id": "bus_H4ekzPSlcg",
  "type": "entitlement_grant.failed",
  "timestamp": "2026-05-01T10:36:21.000000Z",
  "data": {
    "id": "grant_GhFailed7Z",
    "business_id": "bus_H4ekzPSlcg",
    "entitlement_id": "ent_github_repo",
    "customer_id": "cus_abc123",
    "external_id": "pay_a1b2c3d4",
    "payment_id": "pay_a1b2c3d4",
    "subscription_id": null,
    "status": "failed",
    "license_key": null,
    "digital_product_delivery": null,
    "delivered_at": null,
    "revoked_at": null,
    "revocation_reason": null,
    "error_code": "github_permission_denied",
    "error_message": "Repository access could not be granted: the GitHub App installation no longer has permission on this repository.",
    "oauth_url": null,
    "oauth_expires_at": null,
    "metadata": null,
    "created_at": "2026-05-01T10:36:00Z",
    "updated_at": "2026-05-01T10:36:21Z"
  }
}

Tips Integrasi

  • Tunggu entitlement_grant.delivered sebelum membuka fitur yang bergantung. Sebuah event payment.succeeded memberi tahu Anda bahwa pembayaran telah diterima; itu tidak memberi tahu Anda bahwa pelanggan memiliki repo GitHub atau peran Discord. Event delivered adalah sumber kebenaran untuk pemenuhan.
  • Petakan revocation_reason ke alur retensi. Pencabutan subscription_on_hold biasanya berarti kartu pelanggan gagal dan pembaruan berikutnya akan memberikan kembali akses. Pencabutan manual atau subscription_cancelled adalah disengaja. Perlakukan mereka secara berbeda dalam komunikasi pelanggan.
  • Gunakan id pemberian sebagai kunci idempoten Anda. Sebuah pemberian tunggal mengeluarkan paling banyak satu event created dan paling banyak satu event terminal (delivered atau failed), dan paling banyak satu event revoked. Pengiriman ulang dari sistem webhook dapat mengulangi acara; hapus duplikasi pada id pemberian plus type.
  • Periksa license_key dan digital_product_delivery untuk mengenali jenis integrasi. Payload pemberian itu sendiri tidak membawa jenis integrasi, tetapi tepat satu dari objek bersarang ini terisi untuk pemberian kunci-lisensi dan file digital.
  • Untuk pemberian berbasis OAuth, tampilkan oauth_url kepada pelanggan. Event entitlement_grant.created untuk alur pelanggan Discord, GitHub, atau Notion menyertakan oauth_url dan oauth_expires_at. Kirim email kepada pelanggan atau tampilkan dalam aplikasi Anda untuk membuka blokir pengiriman.

Detailed view of a single entitlement grant: who it's for, its lifecycle state, and any integration-specific delivery payload.

business_id
string
wajib

Identifier of the business that owns the grant.

created_at
string<date-time>
wajib

Timestamp when the grant was created.

customer_id
string
wajib

Identifier of the customer the grant was issued to.

entitlement_id
string
wajib

Identifier of the entitlement this grant was issued from.

id
string
wajib

Unique identifier of the grant.

metadata
object
wajib

Arbitrary key-value metadata recorded on the grant.

status
enum<string>
wajib

Lifecycle status of the grant.

Opsi yang tersedia:
Pending,
Delivered,
Failed,
Revoked
updated_at
string<date-time>
wajib

Timestamp when the grant was last modified.

delivered_at
string<date-time> | null

Timestamp when the grant transitioned to delivered, when applicable.

digital_product_delivery
Digital Product Delivery · object

Digital-product-delivery payload, present when the entitlement integration is digital_files.

error_code
string | null

Machine-readable code reported when delivery failed, when applicable.

error_message
string | null

Human-readable message reported when delivery failed, when applicable.

license_key
object

License-key delivery payload, present when the entitlement integration is license_key.

oauth_expires_at
string<date-time> | null

Timestamp when oauth_url stops being valid, when applicable.

oauth_url
string | null

Customer-facing OAuth URL for OAuth-style integrations. Populated during the customer-portal accept flow; null until the customer completes that step, and on grants for non-OAuth integrations.

payment_id
string | null

Identifier of the payment that triggered this grant, when applicable.

revocation_reason
string | null

Reason recorded when the grant was revoked, when applicable.

revoked_at
string<date-time> | null

Timestamp when the grant transitioned to revoked, when applicable.

subscription_id
string | null

Identifier of the subscription that triggered this grant, when applicable.

Last modified on May 14, 2026