Skip to main content

أحداث منح الاستحقاق عبر webhook

يتم إطلاق هذه الأحداث كلما تغيرت حالة منحة استحقاق العميل، على سبيل المثال عند إنشاء مفتاح ترخيص، أو تعيين دور Discord، أو توفير رابط تنزيل، أو سحب الوصول. اشترك في هذه الأحداث للحفاظ على توافق تطبيقك مع ما يمكن لكل عميل الوصول إليه. تشترك جميع الأحداث الأربعة في نفس الحمولة EntitlementGrantResponse الموثقة في المخطط أدناه.

محفزات الأحداث

entitlement_grant.created

تم إدراج صف منح. يملك المنح دائمًا id ثابتًا اعتبارًا من هذه النقطة، حتى إذا تغيرت حالته. استخدم هذا الحدث لتسجيل أن عملية الاستيفاء قيد التنفيذ. بالنسبة إلى مفاتيح الترخيص التي يتم استيفاؤها تلقائيًا ورايات الميزات، يُدرج الصف مباشرةً مع تعبئة status: "Delivered" وdelivered_at، لذلك يتبع حدث created واحد دون أي تغييرات لاحقة في الحالة، ما لم يتم إلغاء المنح لاحقًا. بالنسبة إلى مفاتيح الترخيص التي يتم تنفيذها يدويًا (الاستحقاقات التي تحتوي على fulfillment_mode: manual)، يصل الصف مع status: "Pending" ومن دون كائن license_key — إذ لا يوجد مفتاح بعد. يشير هذا الحدث إلى أن مفتاحًا بانتظار التنفيذ؛ وفّره عبر POST /grants/{grant_id}/license-key، ما يؤدي بعد ذلك إلى إطلاق entitlement_grant.delivered. راجع التنفيذ اليدوي. بالنسبة إلى كل عمليات التكامل الأخرى، يصل الصف مع status: "Pending". يتبع ذلك حدث delivered أو failed عند اكتمال التسليم:
  • التكاملات المستندة إلى OAuth (Discord وGitHub وNotion) تستخدم oauth_url الذي يجب على العميل زيارته لإكمال الموافقة. يحاول Dodo Payments إنشاءه عند إنشاء المنح، لذلك قد يتضمنه entitlement_grant.created؛ وإذا كان null، فستتم تعبئته عندما يبدأ العميل تدفق القبول من Customer Portal. تظل المنحة في حالة Pending حتى يمنح العميل التفويض.
  • التكاملات المباشرة مع المنصة (Telegram وFramer وDigital Files) تبقى في حالة Pending لفترة وجيزة فقط أثناء تنفيذ استدعاء المنصة، ثم تنتقل إلى Delivered.

entitlement_grant.delivered

انتقل المنح إلى Delivered، وعادةً من Pending. أصبح لدى العميل الآن الوصول الموضح في الاستحقاق. استخدم هذا الحدث لفتح الميزات التابعة في أنظمتك، مثل تهيئة مساحة عمل، أو إرسال رسالة ترحيب مخصصة عبر البريد الإلكتروني، أو تعيين علامة “fulfilled”. يلتقط الحقل delivered_at في الحمولة وقت اكتمال التسليم. يتم إطلاق delivered كلما تغيرت حالة منح موجودة إلى Delivered: من Pending، أو عند نجاح منح OAuth فاشل لاحقًا، أو عند استعادة منح مُلغى. أما المنح الذي يصل إلى Delivered عند إنشائه، مثل مفتاح الترخيص المستوفى تلقائيًا، فيُطلق created فقط.

entitlement_grant.failed

تمت محاولة التسليم وفشلت مع خطأ غير ممكن إعادة المحاولة. يوضح الحقل error_code وerror_message الفشل. تشمل الأسباب الشائعة إلغاء رمز OAuth، أو رفض إذن منصة، أو هدف مفقود (مثل، تم حذف خادم Discord).
اعتبر entitlement_grant.failed قابلا للتنفيذ. دفع العميل ولكن لم يحصل على الوصول. أظهر الفشل لفريق الدعم الخاص بك أو قم بإعادة المنح بمجرد حل المشكلة الأساسية.

entitlement_grant.revoked

تم سحب الوصول على مستوى المنصة: تم إزالة دور Discord، تم إزالة المتعاون في GitHub، تم تعطيل مفتاح الترخيص، لم يعد يتم إصدار روابط تحميل الملفات. يسجل حقل revocation_reason المُحرك.

أنواع الحمولة

يكون الحقل data دائمًا كائنًا من نوع EntitlementGrantResponse. تحمل الحمولة حقل integration_type (مثل license_key وdigital_files وdiscord) حتى تتمكن من التعرّف مباشرةً على نوع المنح. كما تُرفق ثلاثة أنواع من عمليات التكامل كائنات متداخلة إضافية:
  • يُضمَّن license_key عندما يكون integration_type هو license_key ويكون قد تم إصدار مفتاح. ويحتوي على المفتاح المُنشأ وتاريخ الانتهاء واستخدام التفعيل. وبالنسبة إلى منح يتم تنفيذها يدويًا ولا تزال في حالة Pending، يكون هذا الكائن null إلى أن تنفذ المنح.
  • يُضمَّن digital_product_delivery عندما يكون integration_type هو digital_files. ويحتوي على عناوين URL لتنزيلات موقعة مسبقًا، وinstructions الاختياري، وexternal_url الاختياري.
  • يُضمَّن feature عندما يكون integration_type هو feature_flag. ويحتوي على feature_type وfeature_id للقدرة التي يمنحها المنح.
بالنسبة إلى جميع أنواع عمليات التكامل الأخرى (Discord وGitHub وTelegram وFigma وFramer وNotion)، تكون هذه الحقول المتداخلة null؛ إذ يتم تسجيل الإعدادات ذات الصلة في الاستحقاق نفسه، وليس في المنح.

عينات الحمولة

تم تسليم مفتاح الترخيص (entitlement_grant.delivered)

مفتاح الترخيص بانتظار الاستيفاء اليدوي (entitlement_grant.created)

يتم إطلاقه عندما يشتري العميل منتجًا يستخدم استحقاق مفتاح الترخيص الخاص به fulfillment_mode: manual. يكون المنح في حالة Pending ومن دون كائن license_key بعد — يجب على التاجر توفير المفتاح.

تم تسليم الملفات الرقمية (entitlement_grant.delivered)

تم إنشاء دور Discord وهو قيد الانتظار (entitlement_grant.created)

تم إلغاء المنح عند إلغاء الاشتراك (entitlement_grant.revoked)

فشل التسليم (entitlement_grant.failed)


نصائح للتكامل

  • فعّل الميزات التابعة عندما تصل المنحة إلى Delivered. يخبرك حدث payment.succeeded بأن الأموال قد تمت تسويتها؛ لكنه لا يخبرك بأن العميل حصل بالفعل على مستودع GitHub أو دور Discord. تعامل مع entitlement_grant.delivered، وكذلك مع entitlement_grant.created باستخدام status: "Delivered"، لأن المنحة التي يتم تسليمها عند الإنشاء لا تطلق أي حدث delivered.
  • اربط revocation_reason بتدفقات الاحتفاظ. يعني إلغاء subscription_on_hold عادةً فشل بطاقة العميل، وستعيد عملية التجديد التالية منح الوصول. أما إلغاء manual أو subscription_cancelled فيكون مقصودًا. تعامل معها بشكل مختلف في رسائل العملاء.
  • اكتشف التكرارات باستخدام الترويسة webhook-id، وليس id الخاص بالمنحة. تُصدر المنحة created مرة واحدة، لكن يمكن أن يُطلق كل من delivered وrevoked أكثر من مرة، لأن المنحة الملغاة يمكن استعادتها ثم إلغاؤها مرة أخرى. ولا يكون failed نهائيًا دائمًا: إذ لا يزال من الممكن تسليم منحة OAuth الفاشلة. كما يمكن لإعادة التسليم من نظام webhook أن تكرر حدثًا ما. تخطَّ التكرارات باستخدام webhook-id، واجعل سجلات المنح الخاصة بك تعتمد على id الخاص بالمنحة.
  • اقرأ integration_type للتعرف على نوع المنحة. تحمل الحمولة integration_type مباشرةً (مثل license_key وdigital_files وdiscord). تتم تعبئة الكائنين المتداخلين license_key وdigital_product_delivery بعد تسليم المنحتين المعنيتين؛ بينما تظل منحة مفتاح الترخيص التي تم تنفيذها يدويًا في حالة Pending مع integration_type: "license_key" وnull license_key إلى أن تنفذها.
  • بالنسبة إلى المنح المستندة إلى OAuth، اعرض oauth_url للعميل. قد يتضمن حدث entitlement_grant.created لتدفقات المشتركين في Discord أو GitHub أو Notion كلاً من oauth_url وoauth_expires_at. وإذا كان null، فانتظر حدثًا لاحقًا أو وجّه العميل إلى Customer Portal. أرسل عنوان URL بالبريد الإلكتروني إلى العميل أو اعرضه في تطبيقك لإتاحة التسليم.

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

brand_id
string
مطلوب

Brand id this grant belongs to.

business_id
string
مطلوب

Identifier of the business that owns the grant.

created_at
string<date-time>
مطلوب

Timestamp when the grant was created.

customer_id
string
مطلوب

Identifier of the customer the grant was issued to.

entitlement_id
string
مطلوب

Identifier of the entitlement this grant was issued from.

id
string
مطلوب

Unique identifier of the grant.

integration_type
enum<string>
مطلوب

The integration type of the grant's entitlement (e.g. license_key).

الخيارات المتاحة:
discord,
telegram,
github,
figma,
framer,
notion,
digital_files,
license_key,
feature_flag
metadata
Metadata · object
مطلوب

Arbitrary key-value metadata recorded on the grant.

status
enum<string>
مطلوب

Lifecycle status of the grant.

الخيارات المتاحة:
Pending,
Delivered,
Failed,
Revoked
updated_at
string<date-time>
مطلوب

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

feature
null | object

Typed feature payload, present only when the entitlement integration is feature_flag; null for every other integration type.

license_key
null | 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.

آخر تعديل في ٢٦ سبتمبر ٢٠٢٦