پرش به مطلب اصلی

وب‌هوک‌های اشتراک

OrcaRail برای چرخه عمر اشتراک و صورت‌حساب رویداد وب‌هوک می‌فرستد. از همان اندپوینت وب‌هوک و بررسی امضا که برای Payment Intentها استفاده می‌کنید بهره بگیرید؛ رویدادهای اشتراک همان ساختار payload را دارند: type و data.object.

انواع رویداد​

رویدادتوضیح
subscription.createdاشتراک ساخته شد
subscription.updatedاشتراک ویرایش شد
subscription.canceledاشتراک لغو شد (فوری یا در پایان دوره)
subscription.pausedاشتراک متوقف شد
subscription.resumedاشتراک متوقف‌شده ازسر گرفته شد
subscription.trial_will_endدوره آزمایشی ۳ روز دیگر تمام می‌شود (یادآوری)
subscription.payment_link.createdلینک پرداخت یک دوره ساخته شد
subscription.payment_link.paidپرداخت دوره تأیید شد (لینک پرداخت شد یا برداشت خودکار موفق بود)
subscription.payment_link.payment_failedبرداشت خودکار این دوره ناموفق بود
subscription.past_dueاشتراک به past_due رفت (سررسیدگذشته یا پرداخت ناموفق)
subscription.completedهمه دوره‌ها کامل شدند (total_cycles رسید)

ساختار payload​

همه رویدادهای اشتراک همین ساختار را دارند:

{
"type": "subscription.payment_link.paid",
"data": {
"object": {
"id": "sub_550e8400e29b41d4a716446655440000",
"object": "subscription",
"status": "active",
"collection_method": "send_payment_link",
"amount": "10.00",
"currency": "usd",
"description": "Monthly Pro Plan",
"interval": "month",
"interval_count": 1,
"total_cycles": 12,
"completed_cycles": 3,
"current_period_start": "2025-03-01T00:00:00Z",
"current_period_end": "2025-04-01T00:00:00Z",
"payer": { "id": "...", "email": "[email protected]" },
"latest_payment_link": {
"id": "...",
"status": "completed",
"link": "..."
},
"metadata": {},
"created": "2025-01-01T00:00:00Z",
"updated": "2025-03-15T00:00:00Z"
}
}
}

data.object شیء کامل اشتراک است (نمای کلی را ببینید). برای subscription.payment_link.paid یا subscription.payment_link.created می‌توانید از data.object.latest_payment_link برای لینک دوره فعلی استفاده کنید.

نمونه پردازشگر​

const subscriptionHandlers = {
'subscription.created': (event) => {
console.log('New subscription:', event.data.object.id)
},
'subscription.updated': (event) => {
console.log('Subscription updated:', event.data.object.id)
},
'subscription.canceled': (event) => {
const sub = event.data.object
console.log('Canceled:', sub.id, sub.canceled_at)
},
'subscription.payment_link.paid': (event) => {
const sub = event.data.object
// Fulfill access for this cycle, extend license, etc.
console.log('Cycle paid:', sub.id, 'cycle', sub.completed_cycles)
},
'subscription.payment_link.payment_failed': (event) => {
const sub = event.data.object
// Notify payer, retry logic, or downgrade
console.log('Auto-charge failed:', sub.id)
},
'subscription.past_due': (event) => {
console.log('Past due:', event.data.object.id)
},
'subscription.completed': (event) => {
console.log('All cycles done:', event.data.object.id)
},
'subscription.trial_will_end': (event) => {
const sub = event.data.object
console.log('Trial ending soon:', sub.id, sub.trial_end)
},
}

// In your webhook route:
if (event.type.startsWith('subscription.')) {
const handler = subscriptionHandlers[event.type]
if (handler) await handler(event)
}

idempotency​

مانند همه وب‌هوک‌ها، رویدادها ممکن است بیش از یک بار تحویل شوند. از event.type + event.data.object.id (و در صورت تمایل شناسه دوره یا لینک) برای حذف موارد تکراری و پردازش هر رویداد فقط یک بار استفاده کنید.

قدم‌های بعدی​