إنتقل إلى المحتوى الرئيسي

webhooks الاشتراكات

ترسل OrcaRail أحداث webhook لدورة حياة الاشتراك والفوترة. استخدم نقطة نهاية الـ webhook والتحقق من التوقيع نفسيهما المستخدمَين مع Payment Intents؛ إذ تستخدم أحداث الاشتراك شكل الحمولة نفسه: type وdata.object.

أنواع الأحداث​

الحدثالوصف
subscription.createdأُنشئ الاشتراك
subscription.updatedحُدّث الاشتراك
subscription.canceledأُلغي الاشتراك (فورًا أو في نهاية الفترة)
subscription.pausedأُوقف الاشتراك مؤقتًا
subscription.resumedاستُؤنف الاشتراك بعد إيقافه
subscription.trial_will_endتنتهي الفترة التجريبية خلال 3 أيام (تذكير)
subscription.payment_link.createdأُنشئ رابط دفع لدورة
subscription.payment_link.paidتأكد دفع الدورة (دُفع الرابط أو نجح الخصم التلقائي)
subscription.payment_link.payment_failedفشل سحب الخصم التلقائي لهذه الدورة
subscription.past_dueانتقل الاشتراك إلى past_due (دفعة متأخرة أو فاشلة)
subscription.completedاكتملت كل الدورات (تم بلوغ total_cycles)

بنية الحمولة​

تتبع كل أحداث الاشتراك البنية نفسها:

{
"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)​

كما في كل الـ webhooks، قد تُسلَّم الأحداث أكثر من مرة. استخدم event.type + event.data.object.id (واختياريًا معرّف الدورة أو الرابط) لإزالة التكرار ومعالجة كل حدث مرة واحدة فقط.

الخطوات التالية​