اختبار المشتريات داخل التطبيق قبل الإطلاق
ست حالات لا حالة واحدة، أربع منها لا تحدث أبدًا على جهازك وتحدث كلها عند المستخدمين — وأي بيئة اختبار تصلح لأيها.
MrBebo
الإجابة المختصرة
اختبار الشراء داخل التطبيق يغطي ست حالات: شراء ناجح، وإلغاء المستخدم للنافذة، وفشل الدفع، والاستعادة على جهاز جديد، وانقطاع الشبكة أثناء المعاملة، والشراء المؤجل الذي ينتظر موافقة ولي الأمر. طوّر بالاختبار المحلي في Xcode، وتحقق في بيئة Sandbox، وأكّد عبر TestFlight بحساب لم يشترِ من قبل.
في هذه الصفحة
أسوأ ما قد يحدث لتطبيق مدفوع أن يصل إلى المستخدمين وشاشة الشراء فيه لا تعمل. لا يظهر ذلك في اختباراتك لأنك اشتريت المنتج مرة وأصبح مفتوحًا لديك للأبد، ولا يظهر في المراجعة لأن المراجع يختبر مسارًا واحدًا، ويظهر عند أول مستخدم حقيقي — على شكل تقييم بنجمة واحدة.
اختبار الشراء هو التحقق من أن كل مسار ممكن للمعاملة ينتهي بحالة صحيحة في التطبيق، لا مجرد تشغيل الزر مرة واحدة والتأكد أنه يفتح النافذة. وهذه ست حالات مختلفة، أربع منها لا تحدث أبدًا في الاستخدام العادي على جهازك، وكلها تحدث في الاستخدام الحقيقي.
ما الذي يجب اختباره فعلًا؟
حالات اختبار الشراء الست، مرتّبة بحسب احتمال ظهورها عند المستخدمين لا بحسب سهولة اختبارها.
| الحالة | تحدث عند | تُنسى غالبًا |
|---|---|---|
| شراء ناجح | كل مستخدم يدفع | لا |
| إلغاء المستخدم للنافذة | كثيرًا جدًا | نعم |
| فشل الدفع | بطاقة مرفوضة | نعم |
| استعادة على جهاز جديد | كل تغيير هاتف | نعم |
| انقطاع الشبكة أثناء الشراء | متكرر | نعم |
| شراء مؤجل يحتاج موافقة | حسابات العائلة | نعم |
الإلغاء هو الأكثر شيوعًا على الإطلاق: كثير من المستخدمين يفتحون النافذة ثم يتراجعون. إن كان تطبيقك يعرض مؤشر تحميل لا ينتهي بعد الإلغاء، فأنت تخسر مستخدمًا كان سيشتري لاحقًا.
الشراء المؤجل هو أكثرها إهمالًا وأصعبها تشخيصًا: في حسابات العائلة يطلب الطفل الشراء فينتظر موافقة ولي الأمر، وقد تصل الموافقة بعد ساعات. التطبيق الذي يفترض نتيجة فورية يترك المستخدم في حالة معلّقة إلى الأبد، ثم يفتح المنتج فجأة في جلسة لاحقة دون أن يفهم أحد ما حدث.
المسار الذي اختبرته هو المسار الوحيد الذي لن يشتكي منه أحد.
بأي أداة تختبر كل حالة؟
لاختبار الشراء ثلاث بيئات، ولكل منها ما تصلح له وما لا تصلح له.
- اختبار محلي في Xcode عبر ملف تهيئة للمتاجر. لا يحتاج شبكة ولا حسابًا، ويسمح بمحاكاة الأخطاء والتأخير وطلبات الموافقة مباشرة من الإعدادات. هذه هي البيئة الصحيحة للاختبار اليومي أثناء التطوير، وفيها وحدها تستطيع إعادة الحالة إلى الصفر متى شئت.
- بيئة الاختبار (Sandbox) عبر حساب اختبار مرتبط بحساب المطوّر. أقرب إلى الواقع لأنها تمرّ بخوادم المتجر فعلًا، ومناسبة لاختبار الاستعادة والاشتراكات. لاحظ أن الاشتراكات فيها مسرّعة: الاشتراك الشهري قد ينتهي خلال دقائق، وهذا مفيد لاختبار التجديد لكنه مربك إن لم تكن تتوقعه.
- TestFlight يستخدم بيئة الاختبار نفسها لكن بالبناء الحقيقي وعلى أجهزة المختبرين. هذه آخر محطة قبل النشر، وفيها تكتشف مشكلات لا تظهر إلا مع أجهزة وحسابات لا تملكها.
القاعدة العملية: طوّر بالمحلي، وتحقق بالـ Sandbox، وأكّد بـ TestFlight. تخطّي الخطوة الثانية هو ما يجعل فريقًا يكتشف عطلًا في الاستعادة بعد النشر.
لماذا لا يعمل الشراء رغم صحة الكود؟
خمسة أسباب توقف اختبار الشراء قبل أن يبدأ، لا علاقة لأغلبها بالبرمجة، وكلها تنتج الأعراض نفسها: قائمة منتجات فارغة أو نافذة لا تفتح.
- المنتج غير جاهز في لوحة المطوّر. المنتج المكتمل البيانات فقط يُعاد في الاستعلام؛ الناقص يُتجاهل بصمت.
- معرّف المنتج مختلف بحرف. لا رسالة خطأ، فقط قائمة فارغة، وهذا أكثر الأسباب إهدارًا للوقت.
- الاتفاقيات المالية غير مكتملة. حتى تُوقَّع اتفاقية المدفوعات، لا تعمل المشتريات إطلاقًا حتى في بيئة الاختبار.
- معرّف الحزمة لا يطابق التطبيق في اللوحة. يحدث كثيرًا بعد إنشاء هدف جديد أو تغيير الإعدادات.
- حساب اختبار مستخدم على جهاز به حساب حقيقي. خلط الحسابين ينتج سلوكًا غير متوقع، والفصل بينهما ضروري.
السبب الثاني يستحق عادة ثابتة: عرّف معرّفات المنتجات في مكان واحد في الكود، ولا تكتبها نصًا حرًّا في أكثر من ملف. الخطأ المطبعي هنا لا يظهر كخطأ ترجمة ولا كاستثناء، بل كتطبيق يعمل بلا منتجات.
ماذا عن التحقق من الإيصال؟
التحقق هو الفرق بين قفل يمكن فتحه وقفل يمنع فعلًا، وفيه قراران يُتخذان مبكرًا ويصعب تغييرهما لاحقًا.
أين تتحقق؟ التحقق على الجهاز وحده كافٍ لتطبيق بسيط بلا خادم، وسهل التلاعب به على جهاز معدّل. التحقق على خادمك أقوى، ويصبح ضروريًا حين يفتح الشراء محتوى أو خدمة تكلّفك مالًا. تطبيقات الأعمال التي تربط الاشتراك بحساب — مثل تطبيقات الفواتير والطلبات على غرار Ordava — تحتاج التحقق الخادمي بطبيعتها، لأن الاشتراك يجب أن يتبع الحساب لا الجهاز.
متى تُنهي المعاملة؟ بعد تسليم المنتج للمستخدم لا قبله. إنهاء المعاملة مبكرًا يعني أن انقطاعًا في تلك اللحظة يترك المستخدم قد دفع ولم يحصل على شيء، بلا أي أثر يمكن استعادته.
وثلاث حالات يجب التعامل معها صراحة في أي تحقق: إيصال لاشتراك منتهٍ، وإيصال من بيئة الاختبار يصل إلى خادم الإنتاج، وإيصال مرفوض لسبب مؤقت في الشبكة. الثالثة يجب أن تعيد المحاولة لا أن تُسقط الشراء.
كيف تجعل الاختبار قابلًا للتكرار؟
اختبار الشراء اليدوي الذي يستغرق عشر دقائق سيُشغَّل مرة واحدة قبل أول إصدار ثم لن يُشغَّل مجددًا. وجعله قابلًا للتكرار هو الفرق بين تغطية حقيقية وتغطية على الورق.
ثلاثة إجراءات ترفع احتمال تشغيله فعليًا:
- افصل منطق الشراء عن الواجهة. إن كان الكود الذي يقرر «هل المستخدم يملك هذا المنتج؟» موجودًا داخل شاشة، فلا يمكن اختباره إلا يدويًا. أخرجه إلى طبقة مستقلة تقبل حالة معاملة وتعيد نتيجة، فتصبح قابلة لاختبار وحدة عادي بلا متجر أصلًا.
- استخدم بديلًا للمتجر في الاختبارات. واجهة مجرّدة أمام StoreKit تسمح بحقن نتائج جاهزة: نجاح، إلغاء، فشل، انتظار موافقة. هذه هي الطريقة الوحيدة لاختبار الحالات النادرة آليًا.
- اكتب سيناريو مكتوبًا للحالات اليدوية الباقية. بعض الحالات لا تُؤتمت، مثل الشراء الحقيقي على جهاز حقيقي. اجعلها قائمة مكتوبة في المستودع لا معرفة في رأس شخص واحد.
النقطة الأولى وحدها تغيّر الوضع أكثر من الأخريين، لأنها تحوّل أغلب المنطق إلى شيء يعمل في ثوانٍ داخل خط التكامل المستمر، فلا يبقى للاختبار اليدوي إلا المسارات التي تحتاج متجرًا حقيقيًا.
وثمة قاعدة أخيرة تستحق الالتزام: لا تشحن تغييرًا في منطق الشراء دون تشغيل القائمة كاملة. هذا الجزء من التطبيق يختلف عن غيره في أن عطبه يكلّف مالًا مباشرًا وثقة يصعب استعادتها، والتقييم الذي يقول «دفعت ولم أحصل على شيء» يبقى ظاهرًا لكل من يزور صفحتك.
وثمة تفصيل يخصّ الاشتراكات تحديدًا ويستحق اختبارًا منفصلًا: التجديد والانقطاع. الاشتراك ليس حالة ثابتة بل حالة تتغيّر مع الوقت دون أي فعل من المستخدم، وأربع لحظات فيه تنتج سلوكًا مختلفًا في تطبيقك: التجديد الناجح، والتجديد الفاشل بسبب بطاقة منتهية (وفيه مهلة سماح يبقى المشترك خلالها مشتركًا)، والإلغاء الذي يبقى فعّالًا حتى نهاية المدة المدفوعة، والاسترداد الذي يجب أن يُغلق المحتوى فورًا.
الحالة الثالثة تحديدًا يخطئ فيها كثيرون: من ألغى اشتراكه ما زال مشتركًا حتى تنتهي المدة التي دفعها، وإغلاق المحتوى لحظة الإلغاء خطأ يراه المستخدم سرقة لما دفع مقابله. وبيئة الاختبار تسرّع هذه الدورة إلى دقائق، فيمكن اختبار الأربعة في جلسة واحدة بدل انتظار شهر.
قائمة قبل الإطلاق
قائمة اختبار الشراء الكاملة تحتاج تسع دقائق على جهاز واحد.
- اشترِ بنجاح وتأكد أن المحتوى انفتح فورًا وبقي بعد إعادة تشغيل التطبيق.
- افتح النافذة وألغِها وتأكد أن الواجهة عادت إلى حالتها الطبيعية بلا مؤشر معلّق.
- اختبر فشل الدفع من إعدادات المحاكاة، وتأكد أن الرسالة مفهومة لا رمز خطأ.
- احذف التطبيق وأعد تثبيته، ثم استعِد المشتريات. هذه هي رحلة كل من غيّر هاتفه.
- اقطع الشبكة في منتصف الشراء وأعدها، وتأكد أن المعاملة تكتمل لاحقًا لا أن تضيع.
- جرّب الشراء المؤجل بمحاكاة طلب موافقة، وتأكد أن التطبيق يعرض حالة انتظار مفهومة.
- اختبر على حساب لم يشترِ من قبل، لأن حسابك أنت لم يعد يمثّل مستخدمًا جديدًا.
الخطوة الرابعة هي التي تلتقط أكثر الأعطال شيوعًا في التقييمات: مستخدم دفع على هاتفه القديم ولا يجد ما دفع مقابله على الجديد. مزيد في أدوات المطوّر والموبايل والمنتجات، وتوثيق StoreKit يغطي واجهات الاختبار المحلي بالتفصيل.
الخلاصة
اختبار الشراء داخل التطبيق يعني تغطية ست حالات لا حالة واحدة: النجاح، والإلغاء، والفشل، والاستعادة، وانقطاع الشبكة، والشراء المؤجل الذي ينتظر موافقة.
طوّر بالاختبار المحلي في Xcode، وتحقق في بيئة الاختبار، وأكّد عبر TestFlight بحساب لم يشترِ من قبل — وأنهِ المعاملة بعد تسليم المنتج لا قبله، لأن الانقطاع في تلك اللحظة بالذات هو ما يترك مستخدمًا دفع ولم يحصل على شيء.
أسئلة شائعة
- لماذا تعود قائمة المنتجات فارغة؟
- الأسباب الأشيع: معرّف منتج مختلف بحرف واحد، أو منتج غير مكتمل البيانات في لوحة المطوّر، أو اتفاقيات مالية غير موقّعة، أو معرّف حزمة لا يطابق التطبيق. لا تظهر رسالة خطأ في أي منها.
- ما الفرق بين الاختبار المحلي وبيئة Sandbox؟
- الاختبار المحلي في Xcode لا يحتاج شبكة ولا حسابًا ويسمح بمحاكاة الأخطاء وإعادة الحالة إلى الصفر، وهو للتطوير اليومي. بيئة Sandbox تمرّ بخوادم المتجر فعلًا وهي الأنسب لاختبار الاستعادة والاشتراكات.
- ما الحالة الأكثر إهمالًا في الاختبار؟
- الشراء المؤجل الذي ينتظر موافقة ولي الأمر في حسابات العائلة. قد تصل الموافقة بعد ساعات، والتطبيق الذي يفترض نتيجة فورية يترك المستخدم في حالة معلّقة.
- متى أُنهي المعاملة؟
- بعد تسليم المنتج للمستخدم لا قبله. الإنهاء المبكر يعني أن انقطاعًا في تلك اللحظة يترك المستخدم قد دفع ولم يحصل على شيء، دون أثر يمكن استعادته.
المصادر
- StoreKit documentation — Apple Developer
- Testing in-app purchases with sandbox — Apple Developer
- Ordava: Invoice & Order Maker — Tecno Blocks

MrBebo
محتوى تقني عربي يقدمه بهاء طه حول البرمجة، الذكاء الاصطناعي، Web2 وWeb3، تطوير التطبيقات، بناء المنتجات وأدوات المطورين.
عن المدوّنة