
المدفوعات هي المكان الذي تبدو فيه الشيفرة المولَّدة بالذكاء الاصطناعي مكتملة قبل أن تكون كذلك. تُفتح صفحة الدفع، وتعمل البطاقة التجريبية، وتظهر شاشة "شكرًا لك"، فيبدو أن العمل قد انتهى. لكن استلام أول دفعة هو الجزء السهل من الفوترة. أما العمل الحقيقي فهو كل ما يحدث بعد ذلك: التجديدات، والبطاقات الفاشلة، والإلغاءات، والترقيات، والمبالغ المستردة، وإعادة المحاولات، والرسائل المكررة.
يغطي هذا الدليل أخطاء Stripe التي نبحث عنها أولًا في التطبيقات المبنية بالذكاء الاصطناعي، ولماذا يكلف كل منها مالًا أو ثقة، وكيف يمكن إصلاحه. وإذا أردتم الصورة الأشمل قبل الإطلاق، فابدؤوا بـقائمة التحقق من جاهزية الإنتاج لدينا.
النموذج الذهني: Stripe هو مصدر الحقيقة
حالة فوترة عميلكم موجودة في Stripe. وتحتفظ قاعدة بياناتكم بنسخة منها، أما الـ webhooks فهي الطريقة التي يخبر بها Stripe تطبيقكم بأن شيئًا ما قد تغيّر. والـ webhook ببساطة هو طلب HTTP يرسله Stripe إلى عنوان URL على خادمكم: "نجحت هذه الدفعة"، "أُلغي هذا الاشتراك"، "فشلت هذه الفاتورة".
تنشأ معظم أخطاء الفوترة من كسر هذا النموذج: الوثوق بالمتصفح بدلًا من Stripe، أو الوثوق بالرسائل دون التحقق ممن أرسلها، أو افتراض أن كل رسالة تصل مرة واحدة تمامًا وبالترتيب. ولا يصح أي من هذه الافتراضات.
الخطأ 1: منح الوصول من صفحة النجاح
يوجّه التدفق الشائع المولَّد بالذكاء الاصطناعي المستخدم إلى /success بعد الدفع ويفتح المنتج في تلك الصفحة. لكن إعادة التوجيه مجرد تنقّل في المتصفح. فقد يغلق العميل علامة التبويب قبل تحميلها فلا يحصل على الوصول أبدًا، ويمكن لأي شخص كتابة عنوان صفحة النجاح يدويًا والحصول على الوصول دون دفع.
الإصلاح: افتحوا الوصول فقط عندما يكون خادمكم قد استلم حدث Stripe المعني وتحقق منه، ثم اقرؤوا صلاحيات المستخدم من قاعدة بياناتكم. ويمكن لصفحة النجاح أن تعرض رسالة ودية مثل "نحن نؤكد دفعتك" ريثما يصل الـ webhook.
الخطأ 2: عدم التحقق من توقيع الـ webhook
عنوان الـ webhook لديكم ليس سوى عنوان عام. فإذا كان المعالج يقبل أي طلب، يستطيع أي شخص إرسال حدث "نجحت الدفعة" مزيّف لحسابه. ويوقّع Stripe كل حدث، ويجب أن يتحقق خادمكم من هذا التوقيع باستخدام سر التوقيع الخاص بنقطة النهاية.
يحتاج التحقق إلى جسم الطلب الخام. فإذا حلّل إطار العمل الجسم إلى JSON أولًا وتحققتم من النسخة المعاد تسلسلها، يفشل التحقق، وتقوم أدوات الذكاء الاصطناعي أحيانًا بـ"إصلاح" ذلك بإيقاف التحقق. هكذا يبدو المعالج الصحيح في مسار Next.js:
export async function POST(req) {
const body = await req.text(); // raw body, not req.json()
const sig = req.headers.get("stripe-signature");
let event;
try {
event = stripe.webhooks.constructEvent(
body, sig, process.env.STRIPE_WEBHOOK_SECRET
);
} catch (err) {
return new Response("Invalid signature", { status: 400 });
}
// ...handle the event, then acknowledge it quickly
return new Response("ok", { status: 200 });
}
في Express، استخدموا محلل الجسم الخام لهذا المسار وحده. وخطأ التوقيع الذي يظهر في الإنتاج فقط يعني عادةً أن سر التوقيع غير صحيح: فلكل من نقطتي النهاية التجريبية والحية سرها الخاص.
الخطأ 3: افتراض التسليم مرة واحدة وبالترتيب
يسلّم Stripe الأحداث مرة واحدة على الأقل، لذا قد يصل الحدث نفسه مرتين، وقد تصل الأحداث بترتيب مختلف. وإذا كان معالجكم يضيف رصيدًا أو ينشئ طلبًا في كل مرة يرى فيها حدثًا، فإن إعادة المحاولة ستفعل ذلك مرتين.
الإصلاح: خزّنوا معرّف كل حدث تعالجونه وتجاهلوا المكرر. واجعلوا المعالجات تضبط الحالة (مثلًا "الحالة نشطة حتى هذا التاريخ") بدلًا من زيادة العدادات، بحيث يكون تكرارها غير ضار. وعندما يكون الترتيب مهمًا، اجلبوا الكائن الحالي من Stripe بدلًا من الوثوق بترتيب وصول الرسائل.
الخطأ 4: معالجة الدفعة الأولى فقط
للاشتراك دورة حياة، وتحتاج كل مرحلة إلى قرار في تطبيقكم. هذه هي الأحداث التي يجب على معظم المنتجات معالجتها:
| الحدث | معناه | ما ينبغي أن يفعله تطبيقكم |
|---|---|---|
checkout.session.completed | أنهى العميل عملية الدفع | ربط عميل Stripe بمستخدمكم وتسجيل الخطة |
customer.subscription.updated | تغيّرت الخطة أو الحالة أو إعدادات الإلغاء | مزامنة الحالة والخطة ونهاية الفترة الحالية |
customer.subscription.deleted | انتهى الاشتراك | إزالة الوصول المدفوع مع الاحتفاظ ببيانات العميل |
invoice.paid | دُفعت فاتورة تجديد أو فاتورة أولى | تمديد الوصول وتسجيل الدفعة |
invoice.payment_failed | فشلت عملية خصم التجديد | وسم الحساب وإشعار العميل وتطبيق سياسة المهلة لديكم |
تعتمد قائمتكم الدقيقة على نموذج التسعير لديكم، لكن "نحن نعالج الدفع فقط" نادرًا ما يكون كافيًا.
الخطأ 5: التعامل مع الإلغاء على أنه فوري
عندما يلغي العميل اشتراكه، تسمح معظم الشركات له بالاحتفاظ بالوصول حتى نهاية الفترة التي دفع مقابلها بالفعل. ويمثّل Stripe ذلك بعلامة على الاشتراك تفيد بأنه سيُلغى عند نهاية الفترة. والتطبيقات التي تزيل الوصول فورًا تتسبب في طلبات استرداد وشكاوى، أما التي تتجاهل العلامة فتستمر في خدمة عملاء غادروا.
أظهروا للعميل الحالة الحقيقية في واجهتكم ("تنتهي خطتك في 14 مارس")، وفكّروا في استخدام بوابة العملاء المستضافة من Stripe لتغيير الخطط والإلغاءات حتى لا تضطروا إلى بناء تلك الشاشات.
الخطأ 6: غياب خطة للمدفوعات الفاشلة
تنتهي صلاحية البطاقات، وترفض البنوك العمليات، وتُبلغ الحدود. فشل التجديد أمر طبيعي، والاشتراك المتأخر السداد لا يعني بعدُ أنكم فقدتم العميل. حدّدوا سياستكم مسبقًا: ما مدة فترة السماح، وماذا يرى العميل، وأي رسائل بريد إلكتروني تُرسل. يستطيع Stripe إعادة محاولة الخصومات الفاشلة وإرسال رسائل التذكير تلقائيًا، لكن تطبيقكم لا يزال عليه أن يستجيب بشكل معقول لتغيرات الحالة.
الخطأ 7: الخلط بين الوضع التجريبي والوضع الحي
الوضع التجريبي والوضع الحي عالمان منفصلان، لكل منهما مفاتيحه ومنتجاته وأسعاره وعملاؤه ونقاط نهاية الـ webhook الخاصة به. وتشمل الأخطاء المعتادة موقعًا حيًا يستخدم مفتاحًا سريًا تجريبيًا، أو نقطة نهاية webhook حية لم تُنشأ قط، أو معرّف سعر نُسخ من الوضع الخطأ. احتفظوا بمفاتيح كل وضع في متغيرات بيئة منفصلة لكل بيئة، ولا تدعوا أحدها يتسرب إلى الآخر.
وللاختبار الصحيح، استخدموا Stripe CLI لتوجيه الأحداث إلى جهازكم المحلي وتشغيل أحداث نموذجية، واستخدموا ساعات الاختبار (test clocks) من Stripe لمحاكاة شهور من التجديدات والإخفاقات والإلغاءات في دقائق.
الخطأ 8: تنفيذ العمل الثقيل داخل الـ webhook
يتوقع Stripe استجابة سريعة. فإذا كان معالجكم يرسل رسائل البريد الإلكتروني ويستدعي خدمات أخرى ويحدّث جداول كثيرة قبل الرد، فقد تنتهي مهلته وسيعتبر Stripe عملية التسليم فاشلة. وفي الوضع الحي يعيد Stripe محاولة عمليات التسليم الفاشلة بفواصل متزايدة لمدة تصل إلى ثلاثة أيام، مما يضاعف المعالجة المكررة إذا لم يكن المعالج idempotent (آمنًا عند التكرار). أكّدوا الاستلام بسرعة وادفعوا الأعمال البطيئة إلى مهمة في الخلفية.
مراجعة فوترة سريعة يمكنكم إجراؤها اليوم
- هل يُتحقق من توقيع الـ webhook باستخدام الجسم الخام؟
- هل تُخزَّن معرّفات الأحداث المعالجة بحيث يُتجاهل المكرر منها؟
- هل يعتمد الوصول على حالة الاشتراك في قاعدة بياناتكم، لا على صفحة النجاح؟
- هل اختبرتم دفعة فاشلة وإلغاءً وترقيةً واستردادًا في الوضع التجريبي؟
- هل يستخدم الوضعان التجريبي والحي مفاتيح وأسرارًا ونقاط نهاية مختلفة؟
- هل تستطيعون أن تعرفوا في دقيقة واحدة لماذا يملك عميل معين الوصول أو لا يملكه؟
إذا كانت إجابات عدة أسئلة "لا أعرف"، فالفوترة على الأرجح هي الجزء الأول الذي ينبغي مراجعته في تطبيقكم. يشمل التدقيق التقني لتطبيقات الذكاء الاصطناعي لدينا تدفقات الدفع ومعالجة الـ webhooks ضمن نطاقه، بينما تغطي خدمة إصلاح تطبيقات الذكاء الاصطناعي وإطلاقها في الإنتاج استكمال أو إصلاح عملية الدفع في Stripe وتحديثات الاشتراكات والإلغاءات والـ webhooks، مع اختبارات لكل تدفق.
الأسئلة الشائعة
لماذا تفشل Stripe webhooks لديّ؟
من الأسباب الشائعة عدم تطابق التوقيع لأن المحتوى جرى تحليله قبل التحقق، أو استخدام سر التوقيع الخاص بوضع الاختبار في الوضع الفعلي (أو العكس)، أو عنوان URL يعيد التوجيه أو غير موجود، أو معالج يستغرق وقتًا طويلًا للرد. وتُظهر محاولات التسليم في لوحة تحكم Stripe الخطأ الدقيق.
هل ينبغي أن أعتمد على صفحة نجاح الدفع لفتح الوصول؟
لا. صفحة النجاح مجرد إعادة توجيه في المتصفح، لذا يمكن تخطيها أو زيارتها يدويًا. امنح الوصول بناءً على أحداث webhook الموثّقة وحالة الاشتراك المخزّنة لديك.
كيف أختبر الاشتراكات دون انتظار شهر؟
استخدم وضع الاختبار في Stripe مع Stripe CLI لإعادة توجيه الأحداث وتشغيلها محليًا، واستخدم ساعات الاختبار (test clocks) في Stripe لمحاكاة التجديدات والمدفوعات الفاشلة والإلغاءات عبر الزمن.
ماذا يحدث عندما يلغي العميل اشتراكه؟
عادةً يحتفظ العميل بالوصول حتى نهاية الفترة التي دفع مقابلها. يضع Stripe علامة على الاشتراك ليُلغى في نهاية الفترة ويرسل حدث حذف عند انتهائه فعليًا. ينبغي أن يعرض تطبيقك تاريخ الانتهاء ولا يزيل الوصول المدفوع إلا حينها.
كيف يمكننا المساعدة
- إصلاح تطبيقات الذكاء الاصطناعي وإطلاقها في الإنتاجإصلاح مشكلات تسجيل الدخول وأذونات Supabase وStripe وAPI والنشر التي تعيق تطبيقكم المبني بالذكاء الاصطناعي، ثم إطلاق نسخة إنتاجية مضبوطة.
- تدقيق تقني لتطبيقات الذكاء الاصطناعيمراجعة بنطاق ثابت للتطبيقات المبنية بـ Lovable وCursor وBolt وReplit وv0 — المصادقة وSupabase RLS وStripe والأسرار والنشر — مع خطة إصلاح مرتبة حسب الأولوية.
- تطوير SaaS مخصصتطوير شامل لمنصات SaaS — بنية متعددة المستأجرين، وفوترة Stripe، وRBAC، وسجلات تدقيق، وجاهزية SOC 2، وميزات مبنية للذكاء الاصطناعي.
تحدثوا إلى مهندس حول مشروعكم
أخبرونا بما تبنونه. نردّ خلال يوم عمل واحد برأي صريح حول النطاق والنهج والجهد المطلوب.
احجزوا مكالمة استراتيجية مجانيةكتبه الفريق الهندسي في UnlockLive IT. تعمل UnlockLive IT Limited مع العملاء عبر مقرها الرئيسي في تورنتو، وتقدم الأعمال الهندسية من مركز التسليم في دكا. من نحن