معالجة الاسترداد تتعطل بطرق صامتة، لذا اختبر استرداد المشتريات داخل التطبيق في الـ sandbox قبل أن يفعلها عميل حقيقي
معالجة الاسترداد لديك لا تعمل إلا بعد أن يكون العميل قد رحل بالفعل، لذا يبقى أي خلل فيها غير مرئي حتى يكلفك أموالاً حقيقية. كلا المتجرين يتيحان لك إطلاق استرداد في بيئة اختبار أولاً. إليك كيفية اختبار استرداد المشتريات داخل التطبيق على App Store و Google Play قبل أن يصبح أحدها حقيقياً.

أهم الخلاصات
- اختبار StoreKit في Xcode يتيح لك استرداد عملية شراء محلياً بالنقر على سهم الاسترداد في Transaction Manager، وهو ما يُطلق مستمع Transaction.updates في تطبيقك، لكنه لا يتصل بـ Apple أبداً، لذا لا يُرسَل أي App Store Server Notification.
- لاختبار جانب الخادم على Apple، وجّه رابط sandbox App Store Server Notifications V2 إلى الخادم الخلفي لديك: عندئذ يُسلّم استرداد في الـ sandbox إشعار REFUND حقيقياً، ويُسلّم طلب استرداد إشعار CONSUMPTION_REQUEST، إلى خادمك.
- نقطة نهاية Request a Test Notification من Apple تُرسل إشعاراً من نوع TEST إلى الرابط الذي أعددته وتُعيد testNotificationToken، حتى تتمكن من تأكيد أن الـ webhook لديك قابل للوصول قبل إطلاق أي حدث حقيقي.
- الـ sandbox من Apple لا يعيد أبداً محاولة إرسال إشعار فاشل، لذا فإن webhook معطلاً عند إطلاق الـ sandbox يُسقط الحدث دون محاولة ثانية، وهو نفس نوع الإخفاق الذي يكلفك لاحقاً نافذة استرداد حقيقية.
- يمنح Google Play مختبري الترخيص طريقة دفع تُسمى Test card, approves then charges back، تُطلق PendingRefundReviewNotification بعد الشراء بلحظات حتى تتمكن من التمرن على استجابة orders.reviewrefund خلال 24 ساعة.
- بالنسبة لمختبر ترخيص على Google Play، تُسترد عملية الشراء غير المُقرّة تلقائياً بعد 3 دقائق بدلاً من 3 أيام التي ينتظرها الإنتاج، لذا فإن مسار إقرار معطلاً يفشل بسرعة ووضوح في الاختبار.
- معالج الاسترداد الذي لم تختبره قط هو الذي يُبقي وصول العميل المسترد المدفوع فعّالاً، واعتباراً من 3 أغسطس 2026 يمكن أن تكلفك استجابة استرداد Google Play غير المختبرة سعر الشراء مطروحاً منه رسوم خدمة Play، إضافة إلى رسوم البنك.
معالجة الاسترداد لديك هي مسار الكود الوحيد الذي لا يعمل إلا بعد أن يكون العميل قد رحل بالفعل. لا شيء في اختبار الجودة المعتاد لديك يلمسه، لأنه للوصول إليه عليك فعلاً أن تُسترد لك الأموال. لذا يُشحن دون اختبار، ويجلس صامتاً لأشهر، ثم يفشل عند استرداد حقيقي، حيث يكلف الفشل أموالاً بدلاً من اختبار أحمر فاشل. الحل هو التوقف عن معاملة الاسترداد كشيء يحدث لك والبدء بإطلاق واحد عمداً. كل من Apple و Google يتيحان لك إطلاق استرداد في بيئة اختبار ومراقبة رد فعل خادمك. إليك كيفية اختبار استرداد المشتريات داخل التطبيق على App Store و Google Play قبل أن يثبت عميل يدفع أن معالجك كان معطلاً.
البيئات الثلاث التي يمكن أن يُطلَق فيها الاسترداد، وواحدة فقط منها هي الإنتاج
هناك ثلاثة أماكن منفصلة يمكن أن يُطلَق فيها استرداد من Apple أو Google أثناء البناء، وهي ليست قابلة للتبادل. اثنتان منها لك أن تُطلقهما عند الطلب. الثالثة هي الإنتاج، حيث لا تريد أبداً أن تلتقي بخلل استرداد لأول مرة. الفخ هو افتراض أن السهلة، الاختبار المحلي في Xcode، تُثبت خط الأنابيب بأكمله. إنها تُثبت تطبيقك. لا تقول شيئاً عن خادمك.
اختبار StoreKit في Xcode محلي، لذا يمرّن تطبيقك ولا شيء غير ذلك
اختبار StoreKit المدمج في Xcode يعمل مقابل ملف تكوين على جهاز Mac لديك، دون رحلة ذهاب وإياب إلى Apple. افتح StoreKit Transaction Manager من شريط التصحيح، اختر معاملة مشتراة، وانقر على سهم الاسترداد المنحني. تنقلب المعاملة إلى مستردة ويُطلَق مستمع Transaction.updates في تطبيقك، تماماً كما سيحدث في الواقع. يمكنك أيضاً استدعاء beginRefundRequest لعرض ورقة الاسترداد الحقيقية، وفي بيئة Xcode تُطابَق المشكلة التي تختارها واحداً لواحد مع RevocationReason، مع تطبيق الاسترداد فوراً. هذه أسرع طريقة لإثبات أن عميلك يقطع الوصول لحظة يصبح revocationDate غير فارغ. وهذا أيضاً كل ما يمكن أن يخبرك به الاختبار المحلي، لأن لا شيء هنا يصل أبداً إلى خوادم Apple، لذا لا يُرسَل أي App Store Server Notification. خادمك الخلفي لا يتعلم شيئاً.
الـ sandbox هو المكان الذي يسمع فيه خادمك أخيراً عن الاسترداد
لاختبار نصف تكاملك الذي يقرر بشأن المال، أي خادمك، تحتاج إلى sandbox من Apple. أعدّ رابط sandbox App Store Server Notifications V2 في App Store Connect، سجّل دخول sandbox tester على جهاز، واشترِ. الآن يُسلّم استرداد في الـ sandbox إشعار REFUND حقيقياً إلى خادمك الخلفي، ويُسلّم طلب استرداد على منتج استهلاكي أو تلقائي التجديد إشعار CONSUMPTION_REQUEST، نفس الحمولة الموقّعة التي سيحصل عليها خادم الإنتاج لديك. قبل أن تُطلق أي شيء، استدعِ نقطة نهاية Request a Test Notification. تُخبر خادم App Store بإرسال إشعار من نوع TEST إلى الرابط الذي أعددته وتمنحك testNotificationToken، الذي تمرره إلى Get Test Notification Status لتأكيد التسليم. إذا لم تنجح رحلة الذهاب والإياب تلك، فلن ينجح أي إشعار حقيقي أيضاً.
| البيئة | ما يمكنها إطلاقه | ما تُثبته | ما لا يمكنها فعله |
|---|---|---|---|
| اختبار StoreKit في Xcode | استرداد عبر Transaction Manager أو ورقة beginRefundRequest | تطبيقك يتفاعل مع استرداد محلياً، في ثوانٍ | لا يتصل بـ Apple أبداً، لذا لا يُرسَل أي إشعار خادم |
| Sandbox | REFUND و CONSUMPTION_REQUEST حقيقيان إلى خادمك، إضافة إلى إشعار TEST عند الطلب | خادمك الخلفي يستقبل الحمولة الموقّعة ويتحقق منها ويتصرف بناءً عليها | لا يعيد محاولة إرسال إشعار يفشل نقطة النهاية لديك في استقباله |
| Production | كل استرداد، بأموال حقيقية | لا شيء تريد أن تتعلمه هنا أولاً | لا يمكنك التراجع عن تكلفة خلل |
كيفية اختبار استرداد المشتريات داخل التطبيق على App Store
شغّله بهذا الترتيب، من فحص العميل الرخيص إلى رحلة الخادم الكاملة. كل خطوة تمرّن جزءاً مختلفاً، والخطوات المتأخرة هي التي يُحاسبك عليها الإنتاج فعلاً.
- أنشئ In-App Purchase key ضمن Users and Access، Integrations، In-App Purchase في App Store Connect، واستخدمه لتوقيع استدعاءات App Store Server API لديك.
- وجّه رابط sandbox App Store Server Notifications V2 إلى خادمك الخلفي، ثم استدعِ Request a Test Notification وأكّد أن حمولة
TESTتصل وتتحقق مقابل سلسلة شهادات Apple. - في Transaction Manager بـ Xcode، استرد عملية شراء وأكّد أن تطبيقك يُسقط الاستحقاق فور تعيين
revocationDate. - سجّل دخول sandbox tester، اشترِ منتجاً استهلاكياً، اطلب استرداداً، وأكّد أن خادمك يستقبل
CONSUMPTION_REQUESTويمكنه تجميع وإرسال رد Send Consumption Information بمهلة جيدة داخل نافذة الـ 12 ساعة. - استرد عملية شراء في الـ sandbox وأكّد أن إشعار
REFUNDيصل إلى خادمك، وأنك تلغي الوصول أو تخصم رصيد المنتج الاستهلاكي، وأن تسليماً مكرراً لنفس الإشعار لا يُطبَّق مرتين.

كيفية التمرن على استرداد ورد مبالغ على Google Play
ليس لدى Google Play وضع محلي مثل Xcode. كل شيء يعمل مقابل خوادم Google، لكن مختبري الترخيص يُبقونه مجانياً وآمناً. أضف حسابات Google الاختبارية لديك كمختبري ترخيص في Play Console فيحصلون على مجموعة من طرق الدفع الاختبارية التي لا تخصم أموالاً حقيقية أبداً. يُعلّم Google كل عملية شراء اختبارية بإشعار عبر منتصف مربع الشراء، ولا تُحسب الضرائب. ما يهم لاختبار الاسترداد هو أي أداة اختبار تختار، لأن كل واحدة تقود إلى نتيجة مختلفة.
| Test payment method | ما يحاكيه | لماذا قد تستخدمه |
|---|---|---|
| Test instrument, always approves | عملية شراء ناجحة نظيفة | إعداد طلب يمكنك بعدها استرداده أو إلغاؤه |
| Test instrument, always declines | دفعة فاشلة | تأكيد أنك لا تمنح شيئاً عند الرفض |
| Slow test card, approves after a few minutes | عملية شراء معلّقة تنجح لاحقاً | تمرين معالجة PENDING لديك قبل أن تمنح الوصول |
| Slow test card, declines after a few minutes | عملية شراء معلّقة تفشل لاحقاً | تأكيد أن رفضاً معلّقاً لا يُسرّب استحقاقاً أبداً |
| Test card, approves then charges back | رد مبالغ يبدأه المستخدم | إطلاق PendingRefundReviewNotification والتمرن على استجابتك خلال 24 ساعة |
أطلِق استرداداً، ورد مبالغ، والاسترداد التلقائي للإقرار
- اشترِ ببطاقة الاختبار approve-then-charge-back، فيصل
PendingRefundReviewNotificationإلى موضوع Real-time Developer Notifications لديك بعد لحظات. أجب عليه باستدعاءorders.reviewrefundواحد، لأن Google يحتفظ باستجابتك الأولى فقط. - استرد وألغِ طلباً اختبارياً من تبويب Orders في Play Console لإطلاق
VoidedPurchaseNotification، وأكّد أن خادمك يسحب الاستحقاق. - اترك عملية شراء مختبر ترخيص غير مُقرّة عمداً. يستردها Google تلقائياً بعد 3 دقائق بدلاً من 3 أيام التي يسمح بها الإنتاج، ويرسل إليك بريد الإلغاء، لذا يظهر مسار إقرار معطلاً في دقائق، وليس في اليوم الرابع في الإنتاج.
ما يكلفه فعلاً مسار استرداد غير مختبر
معالج الاسترداد ليس زينة. إنه الكود الذي يوقفك عن الدفع لخدمة شخص لم يعد يدفع لك. عندما يفشل بصمت، يمرّ الاسترداد رغم ذلك، لكن الوصول والرصيد والإنفاق خلفهما لا يتوقف.
تتبّع المال. عندما يسترد Apple أو Google عملية شراء، تُعيد سعر البيع ويُعيد المتجر عمولته، حتى هنا الدفتر متوازن. ما لا يعود هو كل ما أنفقته بالفعل في تسليم المنتج: الحوسبة خلف نتيجة مُولَّدة، واستدعاءات model API، والتخزين لما حفظه المستخدم، والدفعة التي أرسلتها بالفعل لصانع محتوى. معالج استرداد لا يلغي الوصول أبداً يترك مستخدماً مسترداً يواصل إنفاق تلك على ميزانيتك، دون أن يبقى في النظام ما يوقفه.
نافذتا الأدلة تجعلان الأمر أكثر حدة. CONSUMPTION_REQUEST لم تمرّنه قط في الـ sandbox هو رد ترسله مشوّهاً أو متأخراً، وغالباً ما يمنح Apple الاسترداد افتراضياً حين لا يصل ردك داخل 12 ساعة. استجابة رد مبالغ Google Play لم تُطلقها قط ببطاقة الاختبار هي نافذة 24 ساعة تتعثر فيها مباشرة، واعتباراً من 3 أغسطس 2026 يكلفك رد مبالغ Play خاسر سعر الشراء مطروحاً منه رسوم خدمة Play، إضافة إلى رسوم رد المبالغ للبنك. كل واحد من تلك الإخفاقات قابل لإعادة الإنتاج مجاناً في بيئة اختبار أولاً. لا شيء منها رخيص في الإنتاج.
| مسار غير مختبر | كيف يفشل في الإنتاج | ما يكلفك |
|---|---|---|
| REFUND handler | مستخدم مسترد يحتفظ بالوصول | الحوسبة واستدعاءات API والتخزين والدفعات التي تواصل إنفاقها عليه |
| CONSUMPTION_REQUEST reply | مشوّه، أو مُرسَل بعد 12 ساعة | يمنح Apple الاسترداد افتراضياً، فتخسر البيع والإنفاق |
| orders.reviewrefund response | فائت أو خاطئ داخل 24 ساعة | اعتباراً من 3 أغسطس 2026، سعر الشراء مطروحاً منه رسوم خدمة Play، إضافة إلى رسوم رد المبالغ للبنك |
قائمة تحقق قصيرة قبل شحن معالجة الاسترداد
لست بحاجة إلى مختبر. تحتاج أن تكون قد شاهدت كل حدث يصطدم بكودك مرة واحدة.
- تطبيقك يُسقط الوصول لحظة تُظهر معاملة StoreKit
revocationDate، مؤكداً في Transaction Manager بـ Xcode. - رابط خادم الـ sandbox لديك يستقبل إشعار
TESTويتحقق منه مقابل شهادات Apple. REFUNDفي الـ sandbox يلغي الوصول أو يخصم الرصيد، وتسليم مكرر لا يُحتسب مرتين.CONSUMPTION_REQUESTفي الـ sandbox يُنتج رد Send Consumption Information صالحاً بمهلة جيدة داخل 12 ساعة.PendingRefundReviewNotificationمن Google من بطاقة اختبار رد المبالغ يُنتج استدعاءorders.reviewrefundواحداً بالضبط.- عملية شراء اختبارية غير مُقرّة على Google Play تُسترد تلقائياً في 3 دقائق وتُلاحظها تسويتك.
شغّل تلك القائمة مرة واحدة وتتوقف معالجة الاسترداد عن كونها الكود الذي تأمل أن يعمل. تصبح الكود الذي شاهدته يعمل.
الأسئلة الشائعة
- هل يمكنني اختبار استرداد على App Store دون عملية شراء حقيقية؟
- نعم. اختبار StoreKit في Xcode يتيح لك استرداد عملية شراء محلياً عبر Transaction Manager، دون أموال حقيقية ودون حساب App Store، وهو ما يُطلق مستمع Transaction.updates في تطبيقك. لا يرسل إشعار خادم، لذا يختبر تطبيقك فقط، وليس خادمك الخلفي.
- هل يرسل اختبار StoreKit المحلي إشعارات App Store Server Notifications؟
- لا. اختبار StoreKit في Xcode يعمل بالكامل على جهاز Mac لديك مقابل تكوين محلي ولا يتصل بخوادم Apple أبداً، لذا لا يُرسَل أي App Store Server Notification، بما في ذلك REFUND أو CONSUMPTION_REQUEST. استخدم الـ sandbox لاختبار خادمك.
- كيف أختبر استجابة رد مبالغ على Google Play؟
- استخدم طريقة دفع مختبر الترخيص المسماة Test card, approves then charges back. تُطلق PendingRefundReviewNotification بعد الشراء بلحظات، نفس الإشعار الذي يرسله رد مبالغ بنكي حقيقي، حتى تتمكن من التمرن على رد orders.reviewrefund خلال 24 ساعة.
- لماذا تُسترد عملية شراء الاختبار على Google Play بعد بضع دقائق؟
- بالنسبة لمختبري الترخيص، يسترد Google عملية شراء تلقائياً بعد 3 دقائق إذا لم يُقرّها تطبيقك، ويرسل إليك بريد الإلغاء. ينتظر الإنتاج 3 أيام، لكن المختبرين يحصلون على النسخة المُسرَّعة حتى يظهر مسار إقرار معطل بسرعة.
- هل يعيد الـ sandbox من Apple محاولة إرسال إشعار استرداد فاشل؟
- لا. لا يعيد الـ sandbox محاولة إرسال App Store Server Notifications، لذا إذا كانت نقطة النهاية لديك معطلة عند إطلاق استرداد في الـ sandbox، يُسقَط الإشعار دون محاولة ثانية. أكّد أولاً أن رابطك قابل للوصول باستخدام Request a Test Notification.
المصادر وقراءات إضافية
- Apple Developer: Testing refund requests
- Apple Developer: Testing App Store server notifications
- Apple Developer: Request a Test Notification (App Store Server API)
- Apple Developer: Testing In-App Purchases with the sandbox
- Android Developers: Test your Google Play Billing Library integration
- Android Developers: Help Google dispute chargebacks (orders.reviewrefund)
- Play Console Help: Updates to refund protection and chargeback cost responsibility
RefundHalt
الطيار الآلي للاستردادات في App Store وGoogle Play
تابع القراءة
ما يكلّفه الاسترداد تطبيقك أكثر من السعر الذي تعيده
السعر المُسترَد هو أصغر بند في الفاتورة. الاسترداد يعكس عمولة المتجر أيضًا، فتخسر حصتك، وما أنفقته بالفعل من حوسبة واستدعاءات API وتخزين ومدفوعات لن يعود. أي استرداد مصرفي في Google Play بعد 3 أغسطس 2026 يضيف رسوم البنك فوق ذلك. إليك الفاتورة كاملة.
استرداد الاشتراكات لا يعمل مثل استرداد المشتريات لمرة واحدة، والمتجر الذي تعمل عليه هو من يقرّر مقدار ما لك من رأي
استرداد الاشتراك يعكس فترة فوترة كاملة، لا بيعة واحدة. على App Store تقرّر Apple ولا يعرف خادمك سوى النتيجة. على Google Play تختار أنت بنفسك استرداداً كاملاً أو تناسبياً. إليك كيف يتعامل كلّ متجر مع استرداد الاشتراكات، وكم يكلّفك استرداد واحد.