كل المقالات
Deep diveمدة القراءة 7 دقائق

واجهة Send Consumption Information من Apple تطلب الآن 5 حقول بدلاً من 12، وإليك كل حقل منها

عندما يطلب أحد العملاء استرداد الأموال من Apple، يكون payload الخاص بـ Send Consumption Information هو ردّك. خفّضت Apple عدده من 12 حقلاً إلى 5، ثلاثة إلزامية واثنان اختياريان. إليك كل حقل، والقيم التي يقبلها كل منها، ونافذة الـ 12 ساعة التي ترسله خلالها.

هاتف ذكي بجانب كومة رفيعة من نماذج ورقية مُزّق معظم صفحاتها، تجسّد payload الخاص بـ Send Consumption Information من Apple بعد خفضه من 12 حقلاً إلى 5

أهم الخلاصات

  • أصبح payload الخاص بـ Send Consumption Information من Apple يحمل الآن 5 حقول، بعد أن كان 12. ثلاثة إلزامية، customerConsented وdeliveryStatus وsampleContentProvided، واثنان اختياريان، consumptionPercentage وrefundPreference.
  • customerConsented بوابة صارمة. توجيه Apple نفسه ينص على أنه إذا لم يوافق العميل على مشاركة بيانات الاستهلاك، فلا ترسل payload على الإطلاق.
  • يحمل deliveryStatus أقوى إشارة لديك. تقول DELIVERED إن عملية الشراء نجحت، بينما تخبر قيم UNDELIVERED الأربع شركة Apple بأن العميل لم يحصل قط على منتج يعمل.
  • استبدل consumptionPercentage تعداد consumptionStatus القديم ذا الأربع خطوات برقم دقيق بوحدة milliunits، حيث تعني 100,000 milliunits أن العنصر استُهلك بالكامل.
  • أصبح refundPreference الآن نصاً string، وليس رقماً. القيم الثلاث هي DECLINE وGRANT_FULL وGRANT_PRORATED، وهو يعبّر عن تفضيل، لا عن قرار. يبقى القرار بيد Apple.
  • ترسل payload عبر PUT إلى نقطة نهاية Send Consumption Information باستخدام معرّف المعاملة transaction id، وتعيد Apple الرمز 202 Accepted بجسم فارغ. النافذة هي 12 ساعة بعد CONSUMPTION_REQUEST.
  • بالنسبة للاشتراكات التلقائية التجديد، تحسب Apple الاستهلاك بنفسها من الوقت المنقضي، لذا فإن consumptionPercentage مخصّص لعمليات الشراء الاستهلاكية وغير المتجددة.

قائمة الحقائق التي تطلبها Apple منك حين يريد العميل استرداد أمواله صارت أقصر بكثير. payload الخاص بـ Send Consumption Information، وهو الرد الوحيد الذي يستطيع المطوّر إرساله ضمن قرار استرداد في App Store، كان يضم 12 حقلاً. أما الآن فيضم 5. اختصرته Apple حول WWDC24 وطوت معظم أسئلة تصنيف الحساب القديمة في سؤالين بسيطين ورقم واحد. تقليل الحقول ليس تعديلاً صغيراً. فهو يغيّر الأدلة التي تزنها Apple، ويغيّر الحقول التي لا يمكنك تحمّل الخطأ فيها.

إليك سبب استحقاق هذا انتباهك، لا كونه مجرد ملاحظة عن schema. هذا payload هو اللحظة الوحيدة في عملية استرداد لدى Apple التي تصل فيها روايتك إلى القرار. استرداد استهلاكي يعكس إيراداً أنفقت أموالاً حقيقية بالفعل لتقديمه، والحقول الخمسة هي وسيلتك لإخبار Apple بأن المنتج سُلّم واستُخدم. إن فاتتك نافذة الـ 12 ساعة أو ملأت حقلاً بشكل خاطئ، حكمت Apple بناءً على مطالبة العميل وحدها.

ما هي Send Consumption Information

Send Consumption Information هي نقطة نهاية App Store Server API التي تستدعيها بعد أن ترسل Apple إلى خادمك إشعار CONSUMPTION_REQUEST. يعني ذلك الإشعار أن عميلاً طلب من Apple استرداد أمواله عن عملية شراء داخل التطبيق، وأن Apple تريد رأيك قبل أن تقرر. تجيب بإرسال جسم JSON صغير، وهو ConsumptionRequest، إلى نقطة النهاية عبر PUT. تقرأه Apple، وتزنه في ضوء سجل العميل، وتتخذ القرار. أنت لا تقرر الاسترداد أبداً. أنت تقدّم الحقائق.

الجسم body هو الواجهة بأكملها. لا يوجد نموذج منفصل، ولا استئناف، ولا إرسال ثانٍ يُحتسب. كل ما ترسله في ذلك payload الواحد هو قضيتك كاملة، لذا فإن معنى كل حقل يهمّ أكثر مما يوحي به عدد الحقول.

الحقول الخمسة التي تطلبها Apple الآن

يحتوي ConsumptionRequest الحالي على 5 عناصر. ثلاثة إلزامية واثنان اختياريان. كل ما كانت Apple تسأل عنه بخصوص حساب العميل، ومدته، وإجمالي إنفاقه، وإجمالي عمليات الاسترداد له، ووقت استخدامه، أُزيل مما ترسله.

الحقلإلزاميالنوعما يحمله
customerConsentedنعمBooleanهل وافق العميل على مشاركة بيانات الاستهلاك مع Apple
deliveryStatusنعمStringهل سلّم تطبيقك منتجاً يعمل
sampleContentProvidedنعمBooleanهل قدّمت عينة مجانية أو تجربة قبل الشراء
consumptionPercentageلاIntegerكم استُهلك من عملية الشراء، بوحدة milliunits
refundPreferenceلاStringالنتيجة التي تفضّلها لطلب الاسترداد

customerConsented هو البوابة

customerConsented قيمة Boolean، وهو الحقل الذي يقرر ما إذا كنت سترسل أي شيء أصلاً. يسجّل ما إذا كان العميل قد وافق على السماح لك بمشاركة بيانات الاستهلاك مع Apple. توجيه Apple مباشر، إذا لم يوافق العميل، فلا ترسل consumption information. إذاً هذا ليس حقلاً تحوّله إلى true لتقوية قضيتك. إنه يعكس إجابة نعم أو لا حقيقية يجب أن تكون بحوزتك بالفعل، وقيمة false هنا تعني أنه ينبغي عدم إرسال بقية payload.

deliveryStatus هو الحقل الذي يحرّك عمليات الاسترداد

deliveryStatus هو تعداد enum نصي، وهو أقوى أداة لديك. يخبر Apple ما إذا كان تطبيقك قد سلّم فعلاً عملية شراء داخل التطبيق تعمل. قيمة واحدة تقول نعم. والأربع الأخرى تقول لا، كلٌّ لسبب مختلف، وكل واحدة تخبر Apple بأن للعميل شكوى مشروعة.

القيمةما تخبر به Apple
DELIVEREDسلّم التطبيق عملية شراء داخل التطبيق تعمل
UNDELIVERED_QUALITY_ISSUEلم تُسلّم عملية الشراء بسبب مشكلة في الجودة
UNDELIVERED_WRONG_ITEMتلقّى العميل العنصر الخطأ
UNDELIVERED_SERVER_OUTAGEأوقف انقطاع الخادم عملية التسليم
UNDELIVERED_OTHERلم تُسلّم عملية الشراء لسبب آخر

sampleContentProvided يجيب عن سؤال إنصاف

sampleContentProvided قيمة Boolean. يسجّل ما إذا كنت قد منحت العميل عينة مجانية أو تجربة أو معلومات واضحة عمّا تفعله عملية الشراء قبل أن يشتري. قيمة true هنا إشارة إنصاف صغيرة، فقد أُتيحت للعميل فرصة معرفة ما يشتريه. لا يقرر هذا شيئاً بمفرده، لكنه أحد ثلاثة حقول إلزامية فقط، لذا تريده Apple بوضوح في كل رد.

consumptionPercentage صار الآن رقماً، لا حالة

هذا هو الحقل الذي تغيّر أكثر من غيره. كان payload القديم يضم consumptionStatus، وهو تعداد enum من أربع خطوات، UNDECLARED وNOT_CONSUMED وPARTIALLY_CONSUMED وFULLY_CONSUMED. يستبدله payload الجديد بـ consumptionPercentage، وهو عدد صحيح integer مقيس بوحدة milliunits. تعني 100,000 milliunits أن العنصر استُهلك بالكامل، فتكون 50,000 هي النصف و0 غير ممسوس. الرقم الدقيق أفضل من التصنيف رباعي الاتجاهات، لأنه يتيح لك القول إن العميل استنفد 90 بالمئة من حزمة أرصدة بدلاً من التقريب نزولاً إلى partially consumed.

تحذير واحد يُربك الناس. بالنسبة للاشتراكات التلقائية التجديد، تحسب Apple الاستهلاك بنفسها من الوقت المنقضي، لذا فإن consumptionPercentage مخصّص لعمليات الشراء الاستهلاكية وغير المتجددة. أرسله حيث ينطبق، ودع Apple تشتقّه حيث لا ينطبق.

هاتف ذكي يعرض حلقة تقدّم دائرية ممتلئة بمقدار الثلثين تقريباً، تجسّد consumptionPercentage المقيس بوحدة milliunits حيث تعني 100,000 الاستهلاك الكامل

refundPreference يعبّر عن تفضيل، لا عن حكم

refundPreference نص string اختياري، وفيه تخبر Apple بالنتيجة التي تفضّلها. وقد تغيّر شكله أيضاً. كان الحقل القديم رقماً بقيم مثل prefer-grant وprefer-decline وno-preference. أما الجديد فهو نص مُسمّى بثلاث قيم.

القيمةما تطلبه
GRANT_FULLتفضّل أن تمنح Apple استرداداً كاملاً
GRANT_PRORATEDتفضّل استرداداً جزئياً يعكس ما استُخدم
DECLINEتفضّل أن ترفض Apple الاسترداد

ما الذي أسقطته Apple، ولماذا يهمّ

كان ConsumptionRequest القديم يضم 12 حقلاً. سبعة منها اختفت مما ترسله. كانت accountTenure وlifetimeDollarsPurchased وlifetimeDollarsRefunded وplayTime وuserStatus وplatform وappAccountToken هي النصف الخاص بتصنيف الحساب من payload، وهي الحقول التي طلبت منك تصنيف العميل بحسب مدة امتلاكه لحساب، وكم أنفق، وكم استُرد له، وكم مدة استخدامه للتطبيق.

أسقطتها Apple لسبب يستحق الملاحظة. طلبت تلك الحقول من المطوّرين تسليم ملف تعريفي عن العميل، ومعظم المطوّرين إما تركوها غير معلَنة أو خمّنوها. الحقول الخمسة الباقية تتعلق بعملية الشراء والتسليم، وهي حقائق يمكنك فعلاً التحقق منها من أنظمتك الخاصة. التحوّل هو من مَن العميل إلى ما الذي حدث في عملية الشراء المحددة هذه.

payload القديمpayload الحالي
إجمالي الحقول125
الحقول الإلزاميةلا شيء مطبّق فعلياً3
إشارة الاستهلاكconsumptionStatus، أربعة تصنيفاتconsumptionPercentage، وحدات milliunits دقيقة
تفضيل الاستردادتعداد رقمينص مُسمّى، 3 قيم
تصنيف الحسابالمدة، الإنفاق الكلي، الاسترداد، وقت الاستخدام، الحالةأُزيل

نقطة النهاية والساعة

ترسل payload عبر HTTP PUT إلى نقطة نهاية Send Consumption Information، باستخدام معرّف المعاملة transaction id لعملية الشراء محل النزاع، PUT /inApps/v1/transactions/consumption/{transactionId}. يعيد النجاح الرمز 202 Accepted، ويكون جسم الاستجابة فارغاً. ذلك الرد الفارغ متوقّع، وليس خطأً. فهو يؤكد أن Apple أدرجت بياناتك في قائمة الانتظار، ولا يخبرك بشيء عن النتيجة النهائية، التي تصل لاحقاً على هيئة إشعار REFUND أو REFUND_DECLINED.

الساعة هي الجزء الذي لا يمكنك تمديده. تمنحك Apple 12 ساعة من CONSUMPTION_REQUEST للرد. يُستخدم ردّك الأول فقط، لذا يجب أن يكون payload الأول هو الكامل والصحيح. يمكن لـ Apple أن ترسل CONSUMPTION_REQUEST أكثر من مرة لعملية الشراء نفسها، لكن الموعد النهائي لكل منها ثابت، والمراجعة اليدوية نادراً ما تتّسع داخل 12 ساعة عبر المناطق الزمنية وعطلات نهاية الأسبوع.

ماذا يكلّفك حقل أُسيء التعامل معه

أُنفق المال قبل أن يأتي الاسترداد

استرداد استهلاكي ليس عكساً نظيفاً. فبحلول الوقت الذي يطلب فيه العميل استعادة أمواله عن حزمة أرصدة أو دفعة من مخرجات الذكاء الاصطناعي، تكون قد أنفقت بالفعل لتقديمها، استدلال GPU على كل طلب، واستدعاءات model API لطرف ثالث تُحتسب بحسب الرمز token، وتخزين ما أنتجته، وأي مدفوعات لمنشئ محتوى أو شريك مرتبطة بذلك الاستخدام. سعر المتجر يعود إلى العميل. أما تكلفة تسليمك فلا تعود إليك. لذا فإن استرداداً كان بإمكانك الطعن فيه ليس حدثاً متعادلاً، بل هو خسارة صافية لكل ما دفعته لخدمة الحساب.

الحقول الخمسة هي وسيلتك لتجنّب الدفع مرتين

ضبط deliveryStatus على DELIVERED مع consumptionPercentage مرتفع هما الحقيقتان اللتان تخبران Apple بأن العميل تلقّى المنتج واستخدمه. إنهما دليلك على أن الحوسبة واستدعاءات API والتخزين أدّت جميعها عملها. اترك payload دون إرسال ولن تسمع Apple ذلك أبداً. فتقرر بناءً على مطالبة العميل، ويصبح الاسترداد أكثر احتمالاً للمرور، وتتحمّل أنت الإيراد المعكوس وتكلفة التسليم خلفه معاً.

عمليات ردّ المبالغ chargebacks هي الباب الأسوأ، والصمت يشير إليه

العميل الذي لا يحصل على مبتغاه عبر مسار الاسترداد لدى Apple يظل بإمكانه الاعتراض على الرسم لدى مصرفه. ردّ المبلغ عبر البطاقة chargeback نهائي، ويحمل رسم نزاع ثابتاً، وينزع القرار من يدي Apple ومن يديك. الرد الجيد على CONSUMPTION_REQUEST يبقي النزاع داخل نظام Apple، حيث لك كلمة. تجاهله يدفع الحالات الحدّية نحو القناة الوحيدة التي لا كلمة لك فيها.

كيف تتعامل RefundHalt مع الأمر

تبدو الحقول الخمسة بسيطة إلى أن يتعيّن عليك ملؤها بشكل صحيح، خلال 12 ساعة، على كل CONSUMPTION_REQUEST، مرتبطة بالمعاملة الصحيحة. تلتقط RefundHalt الإشعار، وتقرأ سجلات التسليم والاستخدام الخاصة بك لتلك العملية، وترسل payload تلقائياً قبل أن تُغلق النافذة. يعكس deliveryStatus ما تُظهره سجلاتك فعلاً، ويأتي consumptionPercentage من استخدام حقيقي بدلاً من التخمين، ويتبع refundPreference السياسة التي ضبطتها مرة واحدة. تحصل على مراجعة الاسترداد القابل للطعن مدعومة بالأدلة، لا على موعد نهائي فائت وقرار اتُّخذ من دونك.

الأسئلة الشائعة

كم عدد الحقول التي تحتويها Send Consumption Information من Apple الآن؟
خمسة. ثلاثة إلزامية، customerConsented وdeliveryStatus وsampleContentProvided، واثنان اختياريان، consumptionPercentage وrefundPreference. كان الإصدار السابق من payload يضم 12 حقلاً، وأزالت Apple الحقول الخاصة بتصنيف الحساب مثل accountTenure وlifetimeDollarsPurchased وuserStatus.
ماذا يعني deliveryStatus في طلب استهلاك consumption request؟
يخبر deliveryStatus شركة Apple بما إذا كان تطبيقك قد سلّم عملية شراء داخل التطبيق تعمل. تعني DELIVERED أنه فعل. أما قيم UNDELIVERED الأربع، UNDELIVERED_QUALITY_ISSUE وUNDELIVERED_WRONG_ITEM وUNDELIVERED_SERVER_OUTAGE وUNDELIVERED_OTHER، فتقول كل منها إنه لم يفعل، لسبب مذكور. إنها أقوى إشارة في payload، لذا يجب أن تطابق سجلاتك الخاصة.
هل consumptionPercentage نسبة مئوية أم رقم خام؟
إنه عدد صحيح integer مقيس بوحدة milliunits، وليس نسبة مئوية بسيطة. تعني 100,000 milliunits أن العميل استهلك عملية الشراء بالكامل، فتكون 50,000 هي النصف و0 غير ممسوسة. حلّ محل تعداد consumptionStatus القديم، الذي لم يكن به سوى أربعة تصنيفات من غير المستهلك إلى المستهلك بالكامل.
هل يوقف ضبط refundPreference على DECLINE الاسترداد؟
لا. يعبّر refundPreference عن النتيجة التي تفضّلها، وهو لا يقرر شيئاً. تخبر DECLINE شركة Apple بأنك تفضّل ألا تُجري الاسترداد، وتخبرها GRANT_FULL أو GRANT_PRORATED بالعكس، لكن Apple تزن تفضيلك في مقابل سجل العميل وسياستها الخاصة وتتخذ القرار النهائي.
ماذا لو لم يوافق العميل على مشاركة بيانات الاستهلاك؟
عندئذٍ ينبغي ألا ترسل payload. customerConsented قيمة Boolean إلزامية، وتوجيه Apple هو أنه إذا لم يوافق العميل على مشاركة بيانات الاستهلاك، فلا تردّ على CONSUMPTION_REQUEST على الإطلاق. الموافقة إجابة نعم أو لا حقيقية يجب أن تكون بحوزتك بالفعل، لا قيمة تضبطها على true لمساعدة قضيتك.
كم من الوقت لديّ لإرسال consumption information؟
12 ساعة من لحظة إرسال Apple لإشعار CONSUMPTION_REQUEST. تردّ عبر PUT إلى نقطة نهاية Send Consumption Information، ويعيد النجاح الرمز 202 Accepted بجسم فارغ. يُستخدم ردّك الأول فقط، لذا يجب أن يكون payload الأول كاملاً، ونادراً ما تتّسع عملية يدوية داخل النافذة.

المصادر وقراءات إضافية

RefundHalt

الطيار الآلي للاستردادات في App Store وGoogle Play

تابع القراءة

طلب الاسترداد التالي في طريقه إليك بالفعل.

أعد RefundHalt في الوقت الذي تستغرقه لقراءة رسالة دعم أخرى عن استرداد لم تتمكن من الاعتراض عليه.