يوضّح هذا المستند كيفية التعامل مع أحداث دورة حياة الاشتراك، مثل عمليات التجديد والانتهاء. ويشرح أيضًا ميزات إضافية للاشتراك، مثل تقديم عروض ترويجية والسماح للمستخدمين بإدارة اشتراكاتهم.
إذا لم تكن قد أعددت منتجات الاشتراك في تطبيقك، يمكنك الاطّلاع على إنشاء منتجاتك وإعدادها.
نظرة عامة على الاشتراكات
الاشتراك هو معاملة متكرّرة تمنح المستخدمين امتيازات معيّنة. تمثّل أذونات الاستخدام مجموعة من المزايا التي يمكن للمستخدمين الاستفادة منها خلال فترة زمنية محدّدة. على سبيل المثال، قد يمنح الاشتراك المستخدم إذنًا بالوصول إلى محتوى متميّز.
من خلال الخطط الأساسية والعروض، يمكنك إنشاء إعدادات متعددة لمنتج الاشتراك نفسه. على سبيل المثال، يمكنك إنشاء عرض تمهيدي للمستخدمين الذين لم يسبق لهم الاشتراك في تطبيقك، أو إنشاء عرض ترقية للمستخدمين المشتركين حاليًا.
للحصول على نظرة عامة مفصّلة حول المنتجات التي تتضمّن اشتراكات والخطط الأساسية والعروض، يُرجى الاطّلاع على المستندات في مركز مساعدة Play Console.
تتيح Play Billing Library أنواع الاشتراكات التالية:
الاشتراك في منتج واحد: في هذا النوع، يكون هناك منتج واحد يتوافق مع إذن واحد. على سبيل المثال، الاشتراك في خدمة بث الموسيقى
الاشتراك مع ميزات إضافية: في هذا النوع، يمكن أن تتضمّن عملية شراء واحدة عدة استحقاقات مميّزة مجمّعة في عملية شراء واحدة. على سبيل المثال، الاشتراك في خدمة بث الموسيقى والاشتراك في خدمة بث الفيديو للحصول على معلومات خاصة بالاشتراكات التي تتضمّن ميزات إضافية، راجِع الاشتراكات التي تتضمّن ميزات إضافية.
دمج خطط الدفع المُسبق
لا يتم تجديد خطط الدفع المُسبَق تلقائيًا عند انتهاء صلاحيتها. لتمديد فترة اشتراك المستخدم بدون انقطاع، عليه إعادة شحن خطة الدفع المُسبق للاشتراك نفسه.
بالنسبة إلى عمليات إعادة الشحن، ابدأ مسار الفوترة كما تفعل عند إجراء عملية الشراء الأصلية. لست بحاجة إلى الإشارة إلى أنّ عملية الشراء هي عملية إعادة شحن.
تستخدم عمليات إضافة الرصيد إلى خطط الدفع المُسبق دائمًا وضع الاستبدال CHARGE_FULL_PRICE، ولا تحتاج إلى ضبط هذا الوضع بشكل صريح. يتم تحصيل رسوم مدة فوترة كاملة من المستخدم على الفور، ويتم تمديد فترة الاستحقاق بالمدة المحدّدة في عملية إعادة الشحن.
بعد إجراء عملية إعادة شحن، يتم تعديل الحقول التالية في عنصر النتيجة Purchase لتعكس عملية إعادة الشحن الأخيرة:
- مُعرّف الطلب
- وقت الشراء
- التوقيع
- الرمز المميز للشراء
- مواضيع تمت الموافقة عليها
تحتوي حقول Purchase التالية دائمًا على البيانات نفسها المتوفّرة في عملية الشراء الأصلية:
- اسم الحزمة
- حالة الشراء
- المنتجات
- التجديد التلقائي
إشعار باستلام عملية الشراء المُسبَقة الدفع
وكما هو الحال مع الاشتراكات التي يتم تجديدها تلقائيًا، يجب إقرار خطط الدفع المُسبَق بعد شرائها. يجب تأكيد عملية الشراء الأولية وأي عمليات إعادة شحن. لمزيد من المعلومات، يُرجى الاطّلاع على معالجة عمليات الشراء.
نظرًا إلى المدة القصيرة المحتملة لخطط الدفع المسبق، من المهم تأكيد عملية الشراء في أقرب وقت ممكن.
يجب تأكيد الخطط المدفوعة مسبقًا التي تبلغ مدتها أسبوعًا واحدًا أو أكثر في غضون ثلاثة أيام.
يجب إقرار الخطط المدفوعة مسبقًا التي تقل مدتها عن أسبوع خلال نصف مدة الخطة. على سبيل المثال، أمام المطوّرين مهلة 1.5 يوم لتأكيد خطة دفع مُسبق لمدة ثلاثة أيام.
دمج الاشتراكات بنظام الأقساط
الاشتراك بالتقسيط هو نوع من الاشتراكات يدفع فيه المستخدمون مقابل الاشتراك على دفعات متعدّدة خلال فترة زمنية محدّدة، بدلاً من دفع رسوم الاشتراك بالكامل مقدّمًا.
اعتبارات إضافية للاشتراكات بنظام الأقساط:
- التوفّر في البلدان: لا تتوفّر ميزة الاشتراكات بالتقسيط إلا في البرازيل وفرنسا وإيطاليا وإسبانيا (راجِع Play Console لمعرفة آخر المعلومات حول التوفّر).
- تحديد السعر: عند تحديد سعر اشتراك بنظام الأقساط في Play Console، يمثّل السعر مبلغ الدفعة الشهرية. ويؤدي ذلك، بالإضافة إلى فترة الالتزام المحدّدة، إلى إنشاء المبلغ الإجمالي للاشتراك في شاشة الشراء.
- مدة الالتزام: هي المدة الإجمالية للالتزام بالاشتراك الأوّلي، والتي يجب خلالها سداد الدفعات الشهرية. على سبيل المثال، إذا كانت الخطة الأساسية تتضمّن فترة اشتراك إلزامي مدتها 15 شهرًا، سيدفع المستخدم 15 دفعة شهرية خلال هذه الفترة.
- التجديدات: في سياق الاشتراكات بالتقسيط، يشير مصطلح "التجديد" إلى انتهاء مدة الالتزام، سواء كانت مدة الالتزام الأولية أو مدة الالتزام اللاحقة. بعد الاشتراك الأوّلي، يتم التجديد الأول عند اكتمال فترة الالتزام الأوّلية بالكامل. تحدث عمليات التجديد اللاحقة بعد استيفاء كل فترة التزام لاحقة. يمكن أن تكون أنواع تجديد الاشتراكات بالتقسيط "تجديد تلقائي شهريًا" أو "تجديد تلقائي للمدة نفسها". بالنسبة إلى الخيار "تجديد تلقائي شهريًا"، لا يوجد التزام لاحق وتعمل الخطة كاشتراك شهري يشكّل فيه كل رسم اشتراك شهري عملية تجديد.
- مدة الفوترة: في سياق الاشتراكات بالتقسيط، تشير هذه المدة إلى الفترة المتكرّرة التي يتم فيها إجراء الدفعات الفردية، كما هو محدّد في الخطة الأساسية.
- سلوكيات تغيير الخطة مقابل تغيير السعر: الالتزام ثابت في ما يتعلق بتغييرات الأسعار وعمليات الإلغاء. وهذا يعني أنّه إذا أراد المستخدم إلغاء الاشتراك أو أراد المطوّر تغيير السعر، فإنّ التغيير يسري بنهاية مدة الالتزام. بالنسبة إلى تغييرات الخطة، لا يكون الالتزام ثابتًا. وهذا يعني أنّه ليس عليك الانتظار حتى نهاية فترة الالتزام لإجراء تغيير في الخطة، بل سيتم تطبيق التغيير إما على الفور أو في تاريخ الدفع التالي استنادًا إلى وضع الاستبدال الذي تم ضبطه.
- تغيير الخطة في الاشتراك نفسه: لا يُسمح بتغيير الخطة من خطة أساسية بنظام الأقساط إلى خطة أساسية غير بنظام الأقساط في منتج الاشتراك نفسه.
الإشعارات في الوقت الفعلي الخاصة بالمطوّرين (RTDN): يتم إرسال
SUBSCRIPTION_CANCELLATION_SCHEDULEDإشعار RTDN فورًا عند إلغاء المستخدم للاشتراك إذا كانت هناك دفعات متبقية من فترة الالتزام. عملية الإلغاء معلّقة ولن تصبح سارية إلا في نهاية فترة الالتزام. بعد ذلك، إذا لم يستعِد المستخدمSUBSCRIPTION_CANCELEDوSUBSCRIPTION_EXPIRED، يتم إرسال أرقام التعريف المميزة القابلة لإعادة الضبط في نهاية فترة الالتزام.العائدات / تحقيق الأرباح: يحصل المطوّرون على العائدات عندما يسدد المستخدمون دفعاتهم الشهرية، ويخضع ذلك للشروط نفسها التي تنطبق على جميع الاشتراكات الأخرى. لا يحصل المطوّرون على أي مبالغ مقدمًا عندما يشترك المستخدمون في خطة الاشتراك بالتقسيط.
تحصيل الدفعات الفائتة: إذا لم يسدّد المستخدم أي دفعات من اشتراكه بنظام الأقساط، لن تحاول Google ولا المطوّر تحصيل أي دفعات فائتة أو مستحقة من المستخدم، باستثناء أنّ Google قد تعيد محاولة الدفع بشكل دوري خلال أي فترة سماح أو فترة تعليق حساب سارية وفقًا لممارساتها العادية لإعادة محاولة الدفع. لن تتحمّل Google أي مسؤولية تجاه "المطوّر" عن أي دفعات متبقية غير مدفوعة من الأقساط.
توفُّر Play Billing Library: لا يتوفّر الحقل
installmentDetailsإلا في الإصدار 7 أو إصدار أحدث من Play Billing Library. في الإصدارات 5 والإصدارات الأحدث من PBL، يتم عرض الاشتراك بالتقسيط باستخدامqueryProductDetails()، ولكن لن يتضمّن الاشتراك معلومات تفصيلية عن الأقساط، مثل عدد الدفعات الملتزم بها في الخطة.
استخدام الروابط لصفحات معيّنة في التطبيق للسماح للمستخدمين بإدارة اشتراك
يجب أن يتضمّن تطبيقك رابطًا في شاشة الإعدادات أو الإعدادات المفضّلة يتيح للمستخدمين إدارة اشتراكاتهم، ويمكنك دمج هذا الرابط في المظهر العام لتطبيقك.
يمكنك تضمين رابط لصفحة معيّنة من تطبيقك إلى مركز اشتراكات Google Play للاشتراكات غير المنتهية الصلاحية، ويمكنك تحديدها باستخدام الحقل subscriptionState في مورد الاشتراك. بناءً على ذلك، تتوفّر عدة طرق يمكنك من خلالها إنشاء رابط لصفحة معيّنة في مركز اشتراكات "متجر Play".
رابط إلى مركز الاشتراكات
استخدِم عنوان URL التالي لتوجيه المستخدمين إلى الصفحة التي تعرض جميع اشتراكاتهم، كما هو موضّح في الشكلين 1 و2:
https://play.google.com/store/account/subscriptions
قد يكون هذا الرابط لصفحة في التطبيق مفيدًا لمساعدة المستخدم في استعادة اشتراك تم إلغاؤه من مركز الاشتراكات في "متجر Play".
رابط يؤدي إلى صفحة محدّدة لإدارة الاشتراكات (خيار مُقترَح)
لربط صفحة الإدارة مباشرةً باشتراك غير منتهية صلاحيته، حدِّد اسم الحزمة وproductId المرتبطَين بالاشتراك الذي تم شراؤه. لتحديد productId لاشتراك حالي آليًا، أرسِل طلب بحث إلى الخلفية في تطبيقك أو اتّصِل بالدالة BillingClient.queryPurchasesAsync() للحصول على قائمة بالاشتراكات المرتبطة بمستخدم معيّن. يحتوي كل اشتراك على productId ذي الصلة كجزء من معلومات حالة الاشتراك.
يحتوي كل عنصر SubscriptionPurchaseLineItem مرتبط بعملية شراء اشتراك على قيمة productId المرتبطة بالاشتراك الذي اشتراه المستخدم في عنصر السطر هذا.
استخدِم عنوان URL التالي لتوجيه المستخدمين إلى شاشة معيّنة لإدارة الاشتراكات، مع استبدال "your-sub-product-id" و "your-app-package" بـ productId واسم حزمة التطبيق على التوالي:
https://play.google.com/store/account/subscriptions?sku=your-sub-product-id&package=your-app-package
وبعد ذلك، يمكن للمستخدم إدارة طرق الدفع والوصول إلى ميزات مثل الإلغاء وإعادة الاشتراك والإيقاف المؤقت.
السماح للمستخدمين بترقية اشتراكهم أو الرجوع إلى إصدار سابق أو تغييره
يمكنك تزويد المشتركين الحاليين بخيارات متنوعة لتغيير خطة اشتراكهم بما يتناسب مع احتياجاتهم بشكل أفضل:
- إذا كنت تبيع عدة فئات من الاشتراكات، مثل الاشتراكات "الأساسية" و"المميزة"، يمكنك السماح للمستخدمين بالتبديل بين الفئات من خلال شراء خطة أساسية أو عرض ترويجي مختلفين للاشتراك.
- يمكنك السماح للمستخدمين بتغيير مدة الفوترة الحالية، مثل التبديل من خطة شهرية إلى خطة سنوية.
- يمكنك أيضًا السماح للمستخدمين بالتبديل بين خطط التجديد التلقائي وخطط الدفع المُسبَق.
يمكنك تشجيع أي من هذه التغييرات من خلال تقديم عروض اشتراك تمنح خصمًا للمستخدمين المؤهّلين. على سبيل المثال، يمكنك إنشاء عرض يقدّم خصمًا بنسبة% 50 على السنة الأولى عند التبديل من خطة شهرية إلى خطة سنوية، ويمكنك حصر هذا العرض على المستخدمين المشتركين في خطة شهرية الذين لم يستفيدوا من هذا العرض. تتوفّر المزيد من المعلومات حول معايير الأهلية للاستفادة من العروض الترويجية في مركز المساعدة.
يعرض الشكل 3 مثالاً لتطبيق يتضمّن ثلاث خطط مختلفة:
يمكن أن يعرض تطبيقك شاشة مشابهة للشكل 3، ما يتيح للمستخدمين خيارات لتغيير اشتراكهم. وفي جميع الحالات، يجب أن يكون واضحًا للمستخدمين خطة الاشتراك الحالية والخيارات المتاحة لتغييرها.
عندما يقرّر المستخدمون ترقية اشتراكهم أو الرجوع إلى إصدار سابق أو تغييره، عليك تحديد وضع الاستبدال الذي يحدّد كيفية تطبيق القيمة النسبية لمدة الفوترة المدفوعة الحالية، وتحديد وقت حدوث أي تغيير في الأذونات.
أوضاع الاستبدال
يسرد الجدول التالي أوضاع الاستبدال المتاحة وأمثلة على الاستخدام، وعدد الدفعات التي تم اعتبارها مدفوعة.
وضع الاستبدال |
الوصف |
مثال على الاستخدام |
تسجيل الدفعات الملتزَم بها على أنّها مدفوعة (لاستبدال الاشتراك بنظام الأقساط) |
|
تتم ترقية المنتج أو الرجوع إلى إصدار سابق منه على الفور. ويتم تعديل أي وقت متبقٍ استنادًا إلى فرق السعر، ويُضاف إلى الاشتراك الجديد من خلال تقديم تاريخ الفوترة التالي. هذا هو السلوك التلقائي. |
الترقية إلى فئة أعلى تكلفة بدون أي دفعة إضافية فورية |
0 |
|
تتم ترقية المنتج الذي يتضمّنه الاشتراك على الفور، وتبقى دورة الفوترة كما هي. بعد ذلك، يتم تحصيل فرق السعر من المستخدم عن الفترة المتبقية. ملاحظة: لا يتوفّر هذا الخيار إلا لترقية منتج متوفّر عند الاشتراك، حيث يزداد السعر لكل وحدة زمنية. |
الترقية إلى فئة أعلى تكلفةً، بدون تغيير تاريخ الفوترة |
1 |
|
تتم ترقية أو خفض مستوى المنتج فورًا، ويتم تحصيل السعر الكامل من المستخدم مقابل إذن الاستخدام الجديد فورًا. يتم إما نقل القيمة المتبقية من الاشتراك السابق إلى الاشتراك الجديد في المنتج نفسه، أو يتم احتسابها بالتناسب مع المدة عند التبديل إلى منتج مختلف. ملاحظة: إذا كان الاشتراك الجديد يتضمّن فترة تجريبية مجانية أو عرضًا تمهيديًا، سيتم تحصيل 0 دولار أمريكي أو سعر العرض التمهيدي، أيهما ينطبق، من المستخدم عند الترقية أو الرجوع إلى إصدار أقدم. |
الترقية من مدة فوترة أقصر إلى مدة أطول |
1 (ملاحظة: 0 إذا كان الاشتراك الجديد يتضمّن فترة تجريبية مجانية) |
|
تتم ترقية المنتج أو الرجوع إلى إصدار سابق منه على الفور، ويتم تحصيل السعر الجديد عند تجديد الاشتراك. ستبقى دورة الفوترة كما هي. |
يمكنك الترقية إلى مستوى اشتراك أعلى مع الاحتفاظ بأي فترة مجانية متبقية. |
0 |
|
لا تتم ترقية عنصر الاشتراك أو الرجوع إلى إصدار سابق منه إلا عند تجديد الاشتراك، ولكن يتم إصدار عملية الشراء الجديدة على الفور مع العنصرَين التاليَين:
ملاحظة: في الاشتراكات بنظام التقسيط، يتم تغيير الخطة في بداية تاريخ الدفعة التالية. |
الرجوع إلى مستوى أقل تكلفة |
1 |
|
لن يتغيّر جدول الدفع الخاص بالمنتج الذي تم استبداله. |
إضافة أو إزالة منتج من اشتراك يتضمّن ميزات إضافية عندما لا يجب تغيير منتج معيّن |
لا ينطبق |
لمزيد من المعلومات حول التطبيقات المختلفة لعروض الترقية أو التخفيض في السعر أو استعادة الاشتراكات، يُرجى الاطّلاع على دليل العروض الترويجية.
ضبط وضع الاستبدال لعملية شراء
يمكنك استخدام أوضاع استبدال مختلفة لأنواع مختلفة من عمليات نقل الاشتراكات، وذلك استنادًا إلى تفضيلاتك ومنطق النشاط التجاري. يوضّح هذا القسم كيفية ضبط وضع الاستبدال عند تغيير الاشتراك والقيود التي تنطبق على ذلك.
إعادة الاشتراك أو التبديل بين الخطط ضمن الاشتراك نفسه
يمكنك تحديد وضع استبدال تلقائي في Google Play Console. يتيح لك هذا الإعداد اختيار الوقت الذي يتم فيه تحصيل الرسوم من المشتركين الحاليين إذا اشتروا خطة أساسية أو عرضًا ترويجيًا مختلفًا للاشتراك نفسه أو أعادوا الاشتراك بعد إلغائه. الخيارات المتاحة هي تحصيل الرسوم على الفور، أي CHARGE_FULL_PRICE، وتحصيل الرسوم في تاريخ الفوترة التالي، أي WITHOUT_PRORATION. هذه هي أوضاع الاستبدال ذات الصلة فقط عند تبديل الخطط الأساسية ضمن الاشتراك نفسه.
على سبيل المثال، إذا كنت بصدد تنفيذ عرض استعادة اشتراك للخطة نفسها بعد أن يلغي المستخدم اشتراكه ولكن قبل انتهائه، يمكنك معالجة عملية الشراء الجديدة كعملية شراء عادية بدون الإشارة إلى أي قيم في SubscriptionUpdateParams. يستخدم النظام وضع الاستبدال التلقائي الذي ضبطته في الاشتراك ويتعامل تلقائيًا مع عملية الانتقال من الخطة القديمة إلى الخطة الجديدة.
التبديل بين الخطط في الاشتراكات أو إلغاء وضع الاستبدال التلقائي
إذا كان المستخدم سيغيّر المنتجات في الاشتراك—أي سيشتري اشتراكًا مختلفًا، أو إذا أردت تجاهل وضع الاستبدال التلقائي لأي سبب، عليك تحديد معدّل التوزيع النسبي في وقت التشغيل كجزء من مَعلمات عملية الشراء.
لتقديم
ReplacementMode
بشكل صحيح في SubscriptionProductReplacementParams أو SubscriptionUpdateParams كجزء من إعدادات مسار الشراء في وقت التشغيل، يُرجى مراعاة القيود التالية:
- عند الترقية أو الرجوع إلى إصدار أقدم أو بدء التبديل إلى اشتراك مماثل من خطة دفع مُسبق إلى خطة دفع مُسبق أو خطة تتجدّد تلقائيًا أو خطة تقسيط، يكون وضع الاستبدال المسموح به الوحيد هو
CHARGE_FULL_PRICE. في حال تحديد أي وضع استبدال آخر، ستتعذّر عملية الشراء وسيظهر للمستخدم خطأ. - عند التبديل بين الخطط ضمن الاشتراك نفسه إلى خطة يتم تجديدها تلقائيًا
من خطة دفع مُسبق أو خطة يتم تجديدها تلقائيًا، يكون وضعا التناسب الصالحان هما
CHARGE_FULL_PRICEوWITHOUT_PRORATION. إذا حدّدت أي وضع آخر لتحديد السعر النسبي، ستفشل عملية الشراء وسيظهر خطأ للمستخدم. - لا يُسمح بالتبديل بين الخطط ضمن منتج الاشتراك نفسه من خطة أساسية بنظام الأقساط إلى خطة أساسية بدون نظام الأقساط.
- عند استخدام وضع الاستبدال
KEEP_EXISTINGفيSubscriptionProductReplacementParamsللحفاظ على طريقة الدفع الخاصة بالسلعة بدون تغيير أثناء الاستبدال، يجب أن يكون معرّف المنتج القديم هو نفسه معرّف المنتج الجديد. لا يتوفّر وضعKEEP_EXISTINGفيSubscriptionUpdateParams.
أمثلة على الاستبدال والسلوكيات
لفهم طريقة عمل كل وضع من أوضاع التناسب، فكِّر في السيناريو التالي:
لدى "سام" اشتراك في المحتوى على الإنترنت من تطبيق Country Gardener. لديه اشتراك شهري في إصدار المستوى 1 من المحتوى، وهو نصي فقط. تبلغ تكلفة هذا الاشتراك 2 دولار أمريكي شهريًا، ويتم تجديده في اليوم الأول من الشهر.
في 15 أبريل، اختار "سام وايز" الترقية إلى الإصدار السنوي من اشتراك المستوى 2، والذي يتضمّن تحديثات الفيديو ويكلّف $36 في السنة.
عند ترقية الاشتراك، يختار المطوّر وضعًا لتحديد السعر النسبي. توضّح القائمة التالية كيف يؤثّر كل وضع من أوضاع التسوية النسبية في اشتراك Samwise:
WITH_TIME_PRORATION
سينتهي اشتراك Samwise في المستوى 1 على الفور. لأنّه دفع مقابل شهر كامل (من 1 إلى 30 أبريل) ولكنّه رقّى مستوى اشتراكه في منتصف مدة الاشتراك، لذا تم تطبيق نصف قيمة اشتراك شهر واحد (1 دولار أمريكي) على اشتراكه الجديد. ومع ذلك، بما أنّ تكلفة الاشتراك الجديد تبلغ 36 دولارًا أمريكيًا في السنة، فإنّ رصيد الائتمان البالغ دولارًا واحدًا يتيح له الاستفادة من الاشتراك لمدة 10 أيام فقط (من 16 إلى 25 أبريل)، لذا سيتم تحصيل 36 دولارًا أمريكيًا منه في 26 أبريل مقابل الاشتراك الجديد، وسيتم تحصيل 36 دولارًا أمريكيًا أخرى منه في 26 أبريل من كل عام لاحق.
يجب استدعاء PurchasesUpdatedListener في تطبيقك فور نجاح عملية الشراء، وعندما تتمكّن من استرداد عملية الشراء الجديدة كجزء من طلب queryPurchasesAsync(). يتلقّى الخلفية على الفور
SUBSCRIPTION_PURCHASED إشعارًا في الوقت الفعلي خاصًا بالمطوّرين.
CHARGE_PRORATED_PRICE
يمكن استخدام هذا الوضع لأنّ سعر الاشتراك في المستوى 2 لكل وحدة زمنية (36 دولارًا أمريكيًا في السنة = 3 دولارات أمريكية في الشهر) أكبر من سعر الاشتراك في المستوى 1 لكل وحدة زمنية (2 دولار أمريكي في الشهر). سينتهي اشتراك Samwise في المستوى 1 على الفور. بما أنّه دفع مقابل شهر كامل ولكنّه استخدم نصفه فقط، سيتم تطبيق نصف قيمة الاشتراك الشهري (1 دولار أمريكي) على اشتراكه الجديد. ومع ذلك، بما أنّ الاشتراك الجديد يكلّف 36 دولارًا أمريكيًا في السنة، تبلغ تكلفة الأيام الـ 15 المتبقية 1.50 دولار أمريكي، لذا سيتم تحصيل فرق السعر البالغ 0.50 دولار أمريكي منه مقابل الاشتراك الجديد. في 1 مايو، يتم تحصيل 36 دولارًا أمريكيًا من "سام وايز" مقابل فئة الاشتراك الجديدة، ويتم تحصيل 36 دولارًا أمريكيًا أخرى في 1 مايو من كل عام لاحق.
يجب استدعاء PurchasesUpdatedListener في تطبيقك فور نجاح عملية الشراء، وعندما تتمكّن من استرداد عملية الشراء الجديدة كجزء من طلب queryPurchasesAsync(). يتلقّى الخلفية على الفور
SUBSCRIPTION_PURCHASED إشعارًا في الوقت الفعلي خاصًا بالمطوّرين.
WITHOUT_PRORATION
تمت ترقية اشتراك "سام وايز" في المستوى 1 على الفور إلى المستوى 2 بدون أي رسوم إضافية، وتم تحصيل 36 دولارًا أمريكيًا منه في 1 مايو مقابل مستوى الاشتراك الجديد، وسيتم تحصيل 36 دولارًا أمريكيًا أخرى منه في 1 مايو من كل عام لاحق.
يجب استدعاء PurchasesUpdatedListener في تطبيقك فور نجاح عملية الشراء، وعندما تتمكّن من استرداد عملية الشراء الجديدة كجزء من طلب queryPurchasesAsync(). يتلقّى الخلفية على الفور
SUBSCRIPTION_PURCHASED إشعارًا في الوقت الفعلي خاصًا بالمطوّرين.
DEFERRED
سيستمر اشتراك Samwise في المستوى 1 إلى أن تنتهي صلاحيته في 30 أبريل. في 1 مايو، يبدأ اشتراك المستوى 2، ويتم تحصيل 36 دولارًا أمريكيًا من "سام" مقابل مستوى الاشتراك الجديد.
يجب استدعاء PurchasesUpdatedListener في تطبيقك فور نجاح عملية الشراء، وعندما تتمكّن من استرداد عملية الشراء الجديدة كجزء من طلب queryPurchasesAsync(). يتلقّى الخلفية على الفور
SUBSCRIPTION_PURCHASED إشعارًا في الوقت الفعلي خاصًا بالمطوّرين. عليك معالجة عملية الشراء بالطريقة نفسها التي تعالج بها أي عملية شراء جديدة في تلك المرحلة. على وجه الخصوص، تأكَّد من إقرار عملية الشراء الجديدة. يُرجى العِلم أنّه يتم ملء
startTime للاشتراك الجديد في لحظة سريان الاستبدال، أي عند انتهاء صلاحية الاشتراك القديم. عندئذٍ، ستتلقّى SUBSCRIPTION_RENEWED RTDN لخطة الاشتراك الجديدة. يمكنك الاطّلاع على مزيد من المعلومات حول سلوك ReplacementMode.DEFERRED في مقالة التعامل مع الاستبدال المؤجّل.
CHARGE_FULL_PRICE
سينتهي اشتراك Samwise في المستوى 1 على الفور. يبدأ اشتراكه في المستوى 2 اليوم ويتم تحصيل 36 دولار أمريكي منه. بما أنّه دفع مقابل شهر كامل ولكنّه استخدم نصفه فقط، سيتم تطبيق نصف قيمة الاشتراك الشهري (1 دولار أمريكي) على اشتراكه الجديد. بما أنّ تكلفة الاشتراك الجديد تبلغ 36 دولار أمريكي في السنة، سيحصل على 1/36 من السنة مضافًا إلى مدة اشتراكه (أي حوالي 10 أيام). وبالتالي، ستكون الدفعة التالية المستحقة على Samwise هي 36 دولارًا أمريكيًا بعد عام و10 أيام من اليوم. بعد ذلك، سيتم تحصيل 36 دولارًا أمريكيًا منه كل عام.
عند اختيار وضع احتساب الأجزاء النسبية، احرص على مراجعة اقتراحات الاستبدال.
KEEP_EXISTING
لدى "سام وايز" اشتراك في المحتوى على الإنترنت من تطبيق Country Gardener. وهو مشترك شهريًا في "الخطة 1" للحصول على المحتوى الأساسي. تبلغ تكلفة هذا الاشتراك سعرًا تمهيديًا قدره 2 دولار أمريكي شهريًا لمدة 3 أشهر، ثم 4 دولارات أمريكية شهريًا. اشترى "سام وايز" هذا المنتج في 1 أبريل. يقدّم تطبيق Country Gardener الخطة 2 كمحتوى إضافي خاص مقابل 3 دولار أمريكي شهريًا. في 15 أبريل، أضاف "سام وايز" الخطة 2 إلى اشتراكه في تطبيق Country Gardener مع الاحتفاظ بالخطة 1 الحالية. في ما يلي جدول دفعات Samwise:
- سعر نسبي قدره 1.50 دولار أمريكي للخطة 2، مستحق الدفع في 15 أبريل
- سعر 5.00 دولار أمريكي شهريًا لمدة شهرين لاحقين يشمل السعر التمهيدي للخطة 1 والسعر العادي للخطة 2.
- بعد ذلك، سيتم تحصيل مبلغ ثابت قدره 7.00 دولار أمريكي شهريًا.
تفعيل تغييرات الاشتراك داخل التطبيق
يمكن لتطبيقك أن يتيح للمستخدمين الترقية أو الرجوع إلى إصدار سابق باستخدام الخطوات نفسها المتّبعة في بدء عملية شراء. ومع ذلك، عند الترقية أو الرجوع إلى إصدار سابق، عليك تقديم تفاصيل الاشتراك الحالي والاشتراك المستقبلي (الذي تمت ترقيته أو الرجوع إلى إصدار سابق منه) ووضع الاستبدال الذي سيتم استخدامه.
استخدام SubscriptionProductReplacementParams للاستبدال (الخيار المفضّل)
يوضّح المثال التالي كيفية تعديل اشتراك باستخدام SubscriptionProductReplacementParams.
يتضمّن الكائن
BillingFlowParams.ProductDetailsParamsالآن الطريقةsetSubscriptionProductReplacementParams()لتحديد معلومات الاستبدال على مستوى المنتج.يتضمّن
SubscriptionProductReplacementParamsطريقتَي إعداد:setOldProductId:هذا هو المنتج القديم الذي سيتم استبداله بالمنتج فيProductDetails.الحاليsetReplacementMode:هذا هو وضع الاستبدال على مستوى السلعة. تتشابه الأوضاع معSubscriptionUpdateParams، ولكن تم تعديل عملية ربط القيم.
يجب إنشاء مَعلمات تعديل مستوى الشراء الحالية
BillingFlowParams.setSubscriptionUpdateParams()باستخدامsetOldPurchaseToken().بعد استدعاء
setSubscriptionProductReplacementParams()لأي منProductDetailsParams، لن يكون لـSubscriptionUpdateParams.setSubscriptionReplacementMode()أي تأثير.
يوضّح نموذج الرمز البرمجي التالي كيفية تغيير خطة اشتراك
من (old_product_1، old_product_2) إلى (product_1، product_2،
product_3). في هذا السيناريو، يحلّ product_1 محل old_product_1،
ويحلّ product_2 محل old_product_2، ويتم إضافة product_3
إلى الاشتراك على الفور.
Kotlin
val billingClient: BillingClient = ... val replacementModeForBasePlan: Int = ... val replacementModeForAddon: Int = ... val purchaseTokenOfExistingSubscription: String = "your_old_purchase_token" // ProductDetails instances obtained from queryProductDetailsAsync(); val productDetailsParams1 = ProductDetailsParams.newBuilder() .setProductDetails(productDetails1_obj) // Required: Set the ProductDetails object .setSubscriptionProductReplacementParams( SubscriptionProductReplacementParams.newBuilder() .setOldProductId("old_product_id_1") .setReplacementMode(replacementModeForBasePlan) .build() ) .build() val productDetailsParams2 = ProductDetailsParams.newBuilder() .setProductDetails(productDetails2_obj) // Required: Set the ProductDetails object .setSubscriptionProductReplacementParams( SubscriptionProductReplacementParams.newBuilder() .setOldProductId("old_product_id_2") .setReplacementMode(replacementModeForAddon) .build() ) .build() // Example for a third item without replacement params val productDetailsParams3 = ProductDetailsParams.newBuilder() .setProductDetails(productDetails3_obj) // Required: Set the ProductDetails object .build() val newProductDetailsList = listOf( productDetailsParams1, productDetailsParams2, productDetailsParams3 ) val billingFlowParams = BillingFlowParams.newBuilder() .setSubscriptionUpdateParams( SubscriptionUpdateParams.newBuilder() .setOldPurchaseToken(purchaseTokenOfExistingSubscription) .build() ) .setProductDetailsParamsList(newProductDetailsList) .build() // To launch the billing flow: // billingClient.launchBillingFlow(activity, billingFlowParams)
Java
BillingClient billingClient = …; int replacementModeForBasePlan =…; int replacementModeForAddon =…; // ProductDetails obtained from queryProductDetailsAsync(). ProductDetailsParams productDetails1 = ProductDetailsParams.newBuilder() .setSubscriptionProductReplacementParams( SubscriptionProductReplacementParams.newBuilder() .setOldProductId("old_product_id_1") .setReplacementMode(replacementModeForBasePlan)) .build(); ProductDetailsParams productDetails2 = ProductDetailsParams.newBuilder() .setSubscriptionProductReplacementParams( SubscriptionProductReplacementParams.newBuilder() .setOldProductId("old_product_id_2") .setReplacementMode(replacementModeForAddon)) .build(); ProductDetailsParams productDetails3 = ...; ArrayListnewProductDetailsList = new ArrayList<>(); newProductDetailsList.add(productDetails1); newProductDetailsList.add(productDetails2); newProductDetailsList.add(productDetails3); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setSubscriptionUpdateParams( SubscriptionUpdateParams.newBuilder() .setOldPurchaseToken(purchaseTokenOfExistingSubscription) .build()) .setProductDetailsParamsList(productDetailsList) .build(); billingClient.launchBillingFlow(billingFlowParams);
ضبط SubscriptionUpdateParams للاستبدال (متوقّف نهائيًا)
يوضّح المثال التالي كيفية تعديل اشتراك باستخدام SubscriptionUpdateParams.
Kotlin
val offerToken = productDetails .getSubscriptionOfferDetails(selectedOfferIndex) .getOfferToken() val billingParams = BillingFlowParams.newBuilder().setProductDetailsParamsList( listOf( BillingFlowParams.ProductDetailsParams.newBuilder() .setProductDetails(productDetails) .setOfferToken(offerToken) .build() ) ).setSubscriptionUpdateParams( BillingFlowParams.SubscriptionUpdateParams.newBuilder() .setOldPurchaseToken("old_purchase_token") .setSubscriptionReplacementMode( BillingFlowParams.ReplacementMode.CHARGE_FULL_PRICE ) .build() ).build() billingClient.launchBillingFlow( activity, billingParams ) // ...
Java
String offerToken = productDetails .getSubscriptionOfferDetails(selectedOfferIndex) .getOfferToken(); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList( ImmuableList.of( ProductDetailsParams.newBuilder() // fetched via queryProductDetailsAsync .setProductDetails(productDetails) // offerToken can be found in // ProductDetails=>SubscriptionOfferDetails .setOfferToken(offerToken) .build())) .setSubscriptionUpdateParams( SubscriptionUpdateParams.newBuilder() // purchaseToken can be found in Purchase#getPurchaseToken .setOldPurchaseToken("old_purchase_token") .setSubscriptionReplacementMode(ReplacementMode.CHARGE_FULL_PRICE) .build()) .build(); BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams); // ...
اقتراحات الاستبدال
يعرض الجدول التالي سيناريوهات مختلفة لتحديد نسبة الاستخدام مع ما ننصح به لكل سيناريو:
| سيناريوهات | وضع الاستبدال المقترَح | النتيجة |
|---|---|---|
| الترقية إلى فئة أعلى تكلفة | CHARGE_PRORATED_PRICE |
يحصل المستخدم على إذن الوصول على الفور مع الاحتفاظ بفترة الفوترة نفسها. |
| الانتقال إلى مستوى أقل تكلفة | DEFERRED |
لقد دفع المستخدم مسبقًا مقابل الفئة الأعلى سعرًا، لذا سيظل بإمكانه الاستفادة من مزاياها حتى تاريخ الفوترة التالي. |
| الترقية أثناء الفترة التجريبية المجانية مع الاحتفاظ بها | WITHOUT_PRORATION |
يرقّي المستخدم إلى مستوى أعلى خلال المدة المتبقية من الفترة التجريبية بدون أي تكلفة إضافية. |
| الترقية أثناء الاستفادة من فترة تجريبية مجانية - إنهاء إمكانية الوصول إلى الفترة التجريبية المجانية | CHARGE_PRORATED_PRICE |
يحصل المستخدم على إذن الوصول إلى الفئة الجديدة على الفور، ويتم نقل القيمة المتبقية من الفترة التجريبية المجانية. يتم احتساب القيمة المرحَّلة استنادًا إلى أسعار الخطة الأساسية. |
| الحفاظ على جدول الدفع لبعض عناصر الاشتراك بدون تغيير أثناء إضافة أو إزالة عناصر اشتراك أخرى من "الاشتراك مع ميزات إضافية" | KEEP_EXISTING |
يستمر المستخدم في دفع السعر القديم مقابل السلعة التي لم يتم تغييرها. تتم إضافة العناصر الجديدة على الفور. يمكن استبدال العناصر القديمة الأخرى من خلال تحديد وضع الاستبدال أو إزالتها. |
التعامل مع عمليات شراء تغيير الاشتراك
تُعدّ تغييرات الخطة عمليات شراء جديدة لجميع الأغراض، ويجب معالجتها والإقرار بها على هذا النحو بعد اكتمال عملية الفوترة بنجاح. بالإضافة إلى معالجة عملية الشراء الجديدة بشكل مناسب، عليك إيقاف عملية الشراء التي يتم استبدالها.
ويكون السلوك داخل التطبيق هو نفسه كما هو الحال مع أي عملية شراء جديدة. يتلقّى تطبيقك نتيجة عملية الشراء الجديدة في PurchasesUpdatedListener، وتتوفّر عملية الشراء الجديدة في queryPurchasesAsync.
تعرض Google Play Developer API القيمة linkedPurchaseToken في
مصدر الاشتراك عندما تحل عملية شراء محل عملية شراء حالية. احرص على إبطال الرمز المميّز المقدَّم في linkedPurchaseToken لضمان عدم استخدام الرمز القديم للوصول إلى خدماتك. يمكنك الاطّلاع على مقالة
عمليات الترقية والرجوع إلى الإصدارات السابقة وإعادة الاشتراك للحصول على معلومات حول معالجة عمليات شراء الترقية
والرجوع إلى الإصدارات السابقة.
عندما تتلقّى الرمز المميّز الجديد الخاص بعملية الشراء، اتّبِع عملية التحقّق نفسها كما هو موضّح في مقالة التحقّق من رمز مميّز جديد خاص بعملية الشراء. احرص على إقرار عمليات الشراء هذه باستخدام BillingClient.acknowledgePurchase() من "مكتبة الفوترة في Google Play" أو Purchases.subscriptions:acknowledge من Google Play Developer API.
التعامل مع الاستبدال المؤجّل
يتيح لك وضع الاستبدال المؤجّل السماح للمستخدم بالاستفادة من الاستحقاق المتبقي في خطته القديمة قبل البدء في الخطة الجديدة.
عند استخدام ReplacementMode.DEFERRED لعملية شراء جديدة، تعرض الدالة queryPurchasesAsync() رمزًا مميزًا جديدًا لعملية الشراء بعد اكتمال مسار عملية الشراء، ويظل هذا الرمز مرتبطًا بالمنتج القديم إلى أن يتم الاستبدال المؤجّل في تاريخ التجديد التالي، وبعد ذلك يتم عرض المنتج الجديد.
في السابق، كان بإمكانك توفير تجربة المستخدم هذه باستخدام السمة ProrationMode.DEFERRED المتوقّفة نهائيًا، ولكن تم إيقاف ProrationMode.DEFERRED نهائيًا مع الإصدار 6 من Play Billing Library. اطّلِع على الجدول التالي لمعرفة الاختلافات في السلوك:
الوقت |
ProrationMode.DEFERRED (متوقّف نهائيًا) |
ReplacementMode.DEFERRED |
بعد نجاح مسار الشراء مباشرةً (التطبيق) |
يتم استدعاء يستمر الاستفادة من الخطة القديمة حتى تاريخ التجديد التالي. لضمان أن يمنح التطبيق الحقوق المناسبة، تعرض الدالة لا يظهر رمز الشراء المميّز الجديد، لذا لا يمكن معالجته في هذه المرحلة. |
يتم استدعاء تعرض يتم عرض رمز الشراء الجديد، لذا يجب معالجته في هذه المرحلة مع مراعاة وقت إجراء الاستبدال. |
بعد نجاح مسار الشراء مباشرةً (في الخلفية) |
لا يتم إرسال نوع بيانات الوقت الفعلي SUBSCRIPTION_PURCHASED بعد مسار عملية الشراء. لم يتم إعلام الخلفية بعملية الشراء الجديدة بعد. |
يتم إرسال إشعار المعاملة في الوقت الفعلي (RTDN) الذي يتضمّن رقم تعريف المنتج القديم SUBSCRIPTION_PURCHASED بعد عملية الشراء مباشرةً للحصول على رمز الشراء الجديد. يؤدي استدعاء الطريقة purchases.subscriptionsv2.get باستخدام رمز الشراء الجديد إلى عرض عملية شراء تتضمّن startTime يشير إلى وقت الشراء مع عنصرَين من عناصر السطر:
تم إرسال SUBSCRIPTION_EXPIRED لرمز الشراء القديم. عند استدعاء طريقة purchases.subscriptionsv2.get باستخدام رمز الشراء old، سيظهر على أنّه منتهي الصلاحية (يتم نقل إذن استخدام الخطة القديمة إلى عملية الشراء الجديدة للمدة المتبقية). |
عند الاستبدال - أول تجديد بعد مسار الشراء (التطبيق) |
تعرض الدالة يتم الآن عرض الرمز المميز الجديد للشراء، لذا يجب معالجته. |
تعرض من المفترض أن يكون قد تمّت معالجة عملية الشراء الجديدة عند نجاح مسار الشراء، لذا لا يجب أن يتّخذ التطبيق أي إجراء خاص بخلاف التأكّد من منح الإذن المناسب. |
عند الاستبدال - أول تجديد بعد مسار الشراء (الخادم الخلفي) |
يمكن الآن معالجة عملية الشراء الجديدة وإرسال إشعار تأكيد عند إرسال أول إشعار في الوقت الفعلي من النوع SUBSCRIPTION_RENEWED. يمكن استخدام |
تمت معالجة عملية الشراء الجديدة وتأكيدها عند إرسال إشعار RTDN SUBSCRIPTION_PURCHASED لرمز الشراء الجديد وتم تسجيله على أنّه startTime. باستخدام ReplacementMode.DEFERRED، تتبع عمليات التجديد الأولى السلوك العادي لأي عملية تجديد أخرى، ولن تحتاج إلى التعامل مع منطق خاص لعمليات الاستبدال عند حدوث هذا الحدث. عند استدعاء طريقة purchases.subscriptionsv2.get باستخدام رمز الشراء الجديد، يتم عرض عملية شراء تتضمّن عنصرَين:
|
يجب استخدام ReplacementMode.DEFERRED من الآن فصاعدًا بدلاً من ProrationMode.DEFERRED المتوقّف نهائيًا، لأنّه يقدّم السلوك نفسه فيما يتعلق بتغييرات الأذونات، ولكنّه يوفّر طريقة لإدارة عملية الشراء تكون أكثر اتساقًا مع سلوكيات عمليات الشراء الجديدة الأخرى.
إدارة العملاء
باستخدام الإشعارات في الوقت الفعلي الخاصة بالمطوّرين، يمكنك رصد قرار المستخدم بإلغاء الاشتراك في الوقت الفعلي. عندما يلغي المستخدم اشتراكه قبل انتهاء مدته، يمكنك إرسال إشعارات فورية أو رسائل داخل التطبيق إليه لتطلب منه إعادة الاشتراك.
بعد أن يلغي المستخدم اشتراكه، يمكنك محاولة استعادته إما في تطبيقك أو من خلال "متجر Play". يوضّح الجدول التالي سيناريوهات اشتراك مختلفة بالإضافة إلى إجراءات استعادة المشتركين ومتطلبات التطبيق المرتبطة بها.
| قبل انتهاء صلاحية الاشتراك | بعد انتهاء صلاحية الاشتراك | |||
| داخل التطبيق | في "متجر Play" | داخل التطبيق | في "متجر Play" | |
| ميزة استعادة العملاء | الاشتراك داخل التطبيق | استعادة | الاشتراك داخل التطبيق | إعادة الاشتراك |
| يتبع المستخدم مسار الدفع | نعم | لا | نعم | نعم |
| يظلّ اشتراك المستخدم مرتبطًا برمز التخزين التعريفي نفسه | يمكن للمستخدم الاشتراك في رمز تخزين تعريفي (SKU) نفسه أو رمز تخزين تعريفي مختلف | نعم | يمكن للمستخدم الاشتراك في رمز تخزين تعريفي (SKU) نفسه أو رمز تخزين تعريفي مختلف | نعم |
| إنشاء رمز مميّز جديد لعمليات الشراء | نعم | لا | نعم | نعم |
| مفعَّل تلقائيًا | لا | نعم، يجب توفير الدعم لجميع المطوّرين | لا |
التطبيقات التي لا تستخدم الإصدار 2.0 أو الإصدارات الأحدث من "مكتبة الفوترة": لا التطبيقات التي تستخدم الإصدار 2.0 من "مكتبة الفوترة" أو إصدارًا أحدث: نعم يمكن للمطوّرين إيقاف هذه الميزة في Play Console. |
| عند تحصيل الرسوم من المستخدم |
في حال استخدام رمز التخزين التعريفي نفسه: نهاية مدة الفوترة الحالية في حال استخدام رمز SKU مختلف: يعتمد ذلك على وضع التقسيم النسبي. |
نهاية مدة الفوترة الحالية | فورًا | فورًا |
| يجب تنفيذ الإجراء | توفير واجهة مستخدم لإعادة الاشتراك في تطبيقك |
رصد تغيير في حالة الاشتراك رابط لصفحة معيّنة في "متجر Play" |
توفير واجهة مستخدم لإعادة الاشتراك في تطبيقك | التعامل مع عمليات الشراء خارج التطبيق |
قبل انتهاء صلاحية الاشتراك - داخل التطبيق
بالنسبة إلى الاشتراكات التي تم إلغاؤها ولكن لم تنتهِ صلاحيتها بعد، يمكنك السماح للمشتركين باستعادة اشتراكهم داخل تطبيقك من خلال تطبيق مسار شراء المنتج نفسه داخل التطبيق كما هو الحال مع المشتركين الجدد. تأكَّد من أنّ واجهة المستخدم توضّح أنّ المستخدم لديه اشتراك حالي. على سبيل المثال، قد تحتاج إلى عرض تاريخ انتهاء الصلاحية الحالي والسعر المتكرّر مع زر إعادة التفعيل.
في معظم الأحيان، عليك أن تقدّم للمستخدم السعر ورمز التخزين التعريفي نفسهما اللذين اشترك فيهما سابقًا، وذلك على النحو التالي:
- ابدأ عملية شراء اشتراك جديد باستخدام رمز التخزين التعريفي نفسه.
- يحلّ الاشتراك الجديد محلّ الاشتراك القديم ويتم تجديده في تاريخ انتهاء الصلاحية نفسه. يتم وضع علامة "منتهية الصلاحية" على الاشتراك القديم على الفور.
- على سبيل المثال، لدى "أخيل" اشتراك في تطبيق Example Music App، ومن المقرر أن ينتهي الاشتراك في 1 أغسطس. في 10 يوليو، يعيد الاشتراك في الاشتراك لمدة شهر واحد بالسعر نفسه شهريًا. يتم احتساب قيمة الاشتراك الجديد بشكل نسبي مع الرصيد المتبقي، ويصبح نشطًا على الفور، ويتم تجديده في 1 أغسطس.
إذا أردت تقديم سعر مختلف، مثل فترة تجريبية مجانية جديدة أو خصم لاستعادة الاشتراك، يمكنك بدلاً من ذلك تقديم رمز تخزين تعريفي مختلف للمستخدم:
- ابدأ الترقية أو الرجوع إلى إصدار أقدم باستخدام رمز التخزين التعريفي المختلف في وضع الاستبدال
WITHOUT_PRORATION. - يحلّ الاشتراك الجديد محلّ الاشتراك القديم ويتم تجديده في تاريخ انتهاء الصلاحية نفسه. يتم تحصيل سعر رمز التخزين التعريفي الجديد من المستخدم، بما في ذلك أي أسعار تمهيدية، في تاريخ انتهاء الصلاحية الأصلي. إذا تم إنشاء الاشتراك القديم باستخدام معرّف حساب مشفَّر، يجب تمرير المعرّف نفسه إلى
BillingFlowParamsلإجراء عمليات الترقية وخفض المستوى. - على سبيل المثال، لدى "أخيل" اشتراك في تطبيق Example Music App، ومن المقرر أن ينتهي الاشتراك في 1 أغسطس. في 10 يوليو، يعيد الاشتراك في خطة سنوية بسعر تمهيدي. يصبح الاشتراك الجديد نشطًا على الفور، ويتم تحصيل السعر التمهيدي من المستخدم في 1 آب (أغسطس).
- إذا قررت تضمين فترة تجريبية مجانية أو سعر تمهيدي في رمز التخزين التعريفي الخاص باستعادة الاشتراكات، تأكَّد من أنّ المستخدم مؤهَّل من خلال إزالة العلامة من المربّع السماح بفترة تجريبية مجانية واحدة لكل تطبيق في Google Play Console، ما يمنع المستخدم من الحصول على فترة تجريبية مجانية واحدة لكل تطبيق.
عند تلقّي رمز الشراء، عالِج عملية الشراء كما تفعل مع اشتراك جديد. بالإضافة إلى ذلك، تعرض Google Play Developer API قيمة linkedPurchaseToken في مصدر الاشتراك. احرص على إبطال الرمز المميز المقدَّم في linkedPurchaseToken لضمان عدم استخدام الرمز المميز القديم للوصول إلى خدماتك.
قبل انتهاء صلاحية الاشتراك - في "متجر Play"
عند إلغاء الاشتراك مع بقائه نشطًا، يمكن للمستخدمين استعادته من مركز اشتراكات Google Play من خلال النقر على إعادة الاشتراك (استعادة سابقًا). يؤدي ذلك إلى الاحتفاظ برمز الاشتراك ورمز الشراء نفسهما.
لمزيد من المعلومات حول استعادة الاشتراكات، يُرجى الاطّلاع على عمليات الاستعادة.
بعد انتهاء صلاحية الاشتراك - داخل التطبيق
يمكنك السماح للمشتركين الذين انتهت مدة اشتراكهم بإعادة الاشتراك داخل تطبيقك من خلال تطبيق مسار شراء المنتج نفسه داخل التطبيق كما هو الحال مع المشتركين الجدد. يُرجى مراعاة ما يلي:
- لتقديم خصم للمستخدمين، يمكنك تقديم معرّف منتج بسعر خاص لاشتراكك، ويُعرف أيضًا باسم رمز التخزين التعريفي لاستعادة الاشتراكات. يمكنك تقديم العرض الترويجي في تطبيقك، أو يمكنك إرسال إشعار إلى المستخدم بشأن العرض الترويجي خارج التطبيق، مثلاً في رسالة إلكترونية.
- لبدء اشتراك استعادة، شغِّل مسار الشراء في تطبيق Android باستخدام Google Play Billing Library. وهذه العملية هي نفسها كما هو الحال مع اشتراك جديد، ولكن يمكنك تحديد رمز التخزين التعريفي المتاح للمستخدم.
- إذا قررت تضمين فترة تجريبية مجانية أو سعر تمهيدي في وحدة حفظ المخزون الخاصة باستعادة الاشتراكات، تأكَّد من أنّ المستخدم مؤهَّل من خلال إلغاء تحديد المربّع السماح بفترة تجريبية مجانية واحدة لكل تطبيق في Google Play Console، ما يمنع المستخدم من الحصول على فترة تجريبية مجانية واحدة لكل تطبيق.
- إذا أعاد المستخدم الاشتراك في رمز التخزين التعريفي نفسه، لن يكون مؤهلاً للاستفادة من الفترات التجريبية المجانية أو السعر التمهيدي. تأكَّد من أنّ واجهة المستخدم تعكس ذلك.
عند تلقّي رمز الشراء، عالِج عملية الشراء كما تفعل مع اشتراك جديد. لن تتلقّى linkedPurchaseToken في مصدر الاشتراك.
بعد انتهاء صلاحية الاشتراك - في "متجر Play"
في حال تفعيل هذه الميزة، يمكن للمستخدمين إعادة الاشتراك في رمز التخزين التعريفي نفسه لمدة تصل إلى عام واحد بعد انتهاء الصلاحية من خلال النقر على إعادة الاشتراك في مركز الاشتراكات على Google Play. يؤدي ذلك إلى إنشاء رمز مميّز جديد للاشتراك والشراء.
يُعدّ إعادة الاشتراك عملية شراء تتم خارج التطبيق، لذا احرص على اتّباع أفضل الممارسات للتعامل مع عمليات الشراء التي تتم خارج تطبيقك.
الترويج للاشتراكات
يمكنك إنشاء رموز ترويجية لمنح مستخدمين محدّدين فترة تجريبية مجانية إضافية للاشتراك الحالي. لمزيد من المعلومات، اطّلِع على الرموز الترويجية.
بالنسبة إلى الفترات التجريبية المجانية، يتحقّق Google Play من أنّ المستخدم لديه طريقة دفع صالحة قبل بدء الفترة التجريبية المجانية. قد يظهر هذا الإجراء لبعض المستخدمين على شكل تعليق مؤقت أو رسوم على طريقة الدفع. هذا التفويض أو الرسوم مؤقتة وسيتم إلغاؤها أو ردّها لاحقًا.
بعد انتهاء الفترة التجريبية، يتم تحصيل قيمة الاشتراك بالكامل من طريقة الدفع التي يختارها المستخدم.
إذا ألغى المستخدم اشتراكًا في أي وقت خلال الفترة التجريبية المجانية، يظل الاشتراك نشطًا حتى نهاية الفترة التجريبية، ولا يتم تحصيل رسوم منه عند انتهاء الفترة التجريبية المجانية.
الإلغاء أو الإبطال
يمكنك استخدام Google Play Developer API من أجل إلغاء أو إبطال اشتراك. تتوفّر هذه الوظيفة أيضًا في Google Play Console.
الإلغاء: يمكن للمستخدمين إلغاء اشتراك على Google Play. يمكنك أيضًا توفير خيار للمستخدمين لإلغاء الاشتراك في تطبيقك أو على موقعك الإلكتروني. يجب أن يتعامل تطبيقك مع عمليات الإلغاء هذه على النحو الموضّح في مقالة عمليات الإلغاء.
الإبطال: عند الإبطال، يفقد المستخدم على الفور إمكانية الوصول إلى الاشتراك. يمكن استخدام هذا السبب إذا حدث، مثلاً، خطأ فني منع المستخدم من الوصول إلى منتجك، ولم يرِد المستخدم مواصلة استخدام المنتج. يجب أن يتعامل تطبيقك مع عمليات الإلغاء هذه على النحو الموضّح في مقالة عمليات الإبطال.
يوضّح الجدول التالي الاختلافات بين الإلغاء والإبطال.
| إيقاف التجديد | إبطال إذن الوصول | |
| إلغاء | نعم | لا |
| إبطال | نعم | نعم |
تأجيل فوترة أحد المشتركين
يمكنك تقديم تاريخ الفوترة التالي للمشتركين الذين يجدّدون اشتراكاتهم تلقائيًا باستخدام
Purchases.subscriptions:defer
من Google Play Developer API. خلال فترة التأجيل، يكون المستخدم مشتركًا في المحتوى الخاص بك مع إمكانية الوصول الكامل إليه، ولكن لا يتم تحصيل رسوم منه. سيتم تعديل تاريخ تجديد الاشتراك ليوافق التاريخ الجديد.
بالنسبة إلى خطط الدفع المُسبَق، يمكنك استخدام واجهة برمجة التطبيقات الخاصة بتأجيل الفوترة لتأجيل وقت انتهاء الصلاحية.
تتيح لك الفوترة المؤجّلة إجراء ما يلي:
- يمكنك منح المستخدمين إمكانية الوصول مجانًا كعرض خاص، مثل منح أسبوع مجاني عند شراء فيلم.
- يمكنك منح العملاء إذن الوصول مجانًا كبادرة حسن نية.
يمكن تأجيل الفوترة لمدة يوم واحد على الأقل ولمدة عام واحد على الأكثر لكل طلب بيانات من واجهة برمجة التطبيقات. لتأجيل الفوترة أكثر، يمكنك استدعاء واجهة برمجة التطبيقات مرة أخرى قبل حلول تاريخ الفوترة الجديد.
على سبيل المثال، لدى "دارسي" اشتراك شهري في محتوى على الإنترنت في تطبيق Fishing Quarterly. ويتم عادةً تحصيل 1.25 جنيه إسترليني منها في اليوم الأول من كل شهر. في آذار (مارس)، شاركت في استطلاع على الإنترنت أجرته الجهة الناشرة للتطبيق. كافأ الناشر المشتركة بمنحها ستة أسابيع مجانية من خلال تأجيل الدفعة التالية إلى 15 أيار (مايو)، أي بعد ستة أسابيع من تاريخ الفوترة المحدّد سابقًا في أبريل.
- لن يتم تحصيل رسوم من "دارسي" عن شهر نيسان (أبريل) أو أوائل شهر أيار (مايو)، وسيظل بإمكانها الوصول إلى المحتوى. في 15 أيار (مايو)، يتم تحصيل رسوم الاشتراك العادية البالغة 1.25 جنيه إسترليني عن الشهر. أصبح موعد التجديد التالي في 15 يونيو.
عند تأجيل تاريخ الفوترة، قد تحتاج إلى إرسال إشعار إلى المستخدم عبر البريد الإلكتروني أو داخل التطبيق لإعلامه بأنّه تم تغيير تاريخ الفوترة.
التعامل مع حالات رفض الدفع
إذا حدثت مشاكل في الدفع عند تجديد الاشتراك، ستُعيد Google محاولة تجديد الاشتراك بشكل دوري لبعض الوقت قبل إلغائه. ويمكن أن تتألف فترة استرداد الاشتراك هذه من فترة سماح، تليها فترة تعليق الاشتراك. وخلال هذه الفترة، ترسل Google إلى المستخدم رسائل إلكترونية وإشعارات تطلب منه تعديل طريقة الدفع.
عند رفض الدفعة، يدخل الاشتراك في فترة سماح إذا تم إعدادها. خلال فترة السماح، عليك التأكّد من أنّ المستخدم لا يزال بإمكانه الوصول إلى أذونات استخدام الاشتراك.
بعد انتهاء أي فترة سماح، يدخل الاشتراك في فترة تعليق الاشتراك. خلال فترة تعليق الاشتراك، عليك التأكّد من عدم توفّر أذونات استخدام الاشتراك للمستخدم.
يمكنك تحديد مدة فترة السماح وتعليق الحساب لكل خطة أساسية تتجدّد تلقائيًا في Google Play Console. قد يؤدي تحديد مدة أقل من القيم التلقائية إلى تقليل عدد الاشتراكات التي يتم استردادها بعد رفض الدفعات.
لزيادة احتمالية استرداد الاشتراكات عند رفض الدفع، يمكنك إبلاغ المستخدم بوجود مشكلة في الدفع وطلب حلّها.
يمكنك إجراء ذلك بنفسك، كما هو موضّح في قسمَي فترة السماح وتعليق الحساب، أو يمكنك تنفيذ واجهة برمجة التطبيقات للرسائل داخل التطبيق، حيث تعرض Google رسالة للمستخدمين في تطبيقك.
المراسلة داخل التطبيق
إذا فعّلت ميزة المراسلة داخل التطبيق باستخدام
InAppMessageCategoryId.TRANSACTIONAL،
سيعرض Google Play للمستخدمين رسالة أثناء فترة السماح وفترة تعليق الاشتراك مرة واحدة في اليوم، وسيتيح لهم فرصة حلّ مشكلة الدفع بدون مغادرة التطبيق.
ننصحك باستدعاء واجهة برمجة التطبيقات هذه كلما فتح المستخدم التطبيق لتحديد ما إذا كان يجب عرض الرسالة.
إذا تمكّن المستخدم من استرداد اشتراكه بنجاح، ستتلقّى رمز استجابة
SUBSCRIPTION_STATUS_UPDATED
مع رمز مميّز للشراء. بعد ذلك، عليك استخدام رمز الشراء المميز هذا لاستدعاء Google Play Developer API وتعديل حالة الاشتراك في تطبيقك.
دمج المراسلة داخل التطبيق
لعرض رسائل داخل التطبيق للمستخدم، استخدِم
BillingClient.showInAppMessages().
في ما يلي مثال على بدء مسار الرسائل داخل التطبيق:
Kotlin
val inAppMessageParams = InAppMessageParams.newBuilder() .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL) .build() billingClient.showInAppMessages(activity, inAppMessageParams, object : InAppMessageResponseListener() { override fun onInAppMessageResponse(inAppMessageResult: InAppMessageResult) { if (inAppMessageResult.responseCode == InAppMessageResponseCode.NO_ACTION_NEEDED) { // The flow has finished and there is no action needed from developers. } else if (inAppMessageResult.responseCode == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) { // The subscription status changed. For example, a subscription // has been recovered from a suspend state. Developers should // expect the purchase token to be returned with this response // code and use the purchase token with the Google Play // Developer API. } } })
Java
InAppMessageParams inAppMessageParams = InAppMessageParams.newBuilder() .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL) .build(); billingClient.showInAppMessages(activity, inAppMessageParams, new InAppMessageResponseListener() { @Override public void onInAppMessageResponse(InAppMessageResult inAppMessageResult) { if (inAppMessageResult.responseCode == InAppMessageResponseCode.NO_ACTION_NEEDED) { // The flow has finished and there is no action needed from developers. } else if (inAppMessageResult.responseCode == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) { // The subscription status changed. For example, a subscription // has been recovered from a suspend state. Developers should // expect the purchase token to be returned with this response // code and use the purchase token with the Google Play // Developer API. } } });
التعامل مع المعاملات المعلّقة للاشتراكات
يمكن أن تحدث المعاملات المعلّقة عند إجراء عملية شراء أولية أو إضافة رصيد أو ترقية أو خفض مستوى. يبدأ شراء الاشتراك بالحالة SUBSCRIPTION_STATE_PENDING قبل الانتقال إلى الحالة SUBSCRIPTION_STATE_ACTIVE. إذا انتهت صلاحية المعاملة أو ألغاها المستخدم، سيتم نقلها إلى SUBSCRIPTION_STATE_PENDING_PURCHASE_EXPIRED. يجب عدم تعديل حالة الاستحقاق الخاصة بالمستخدم إلا بعد إكمال المعاملة.
تكون عملية تغيير حالة الاشتراك عند إجراء عملية شراء أولية مع معاملات معلّقة بسيطة. يتلقّى تطبيقك Purchase بالحالة PENDING عندما يبدأ المستخدم معاملة معلّقة. عند اكتمال المعاملة، سيتلقّى تطبيقك Purchase مرة أخرى مع تعديل الحالة إلى PURCHASED. يتم إرسال رسالة SubscriptionNotification من النوع SUBSCRIPTION_PURCHASED إلى برنامج RTDN. اتّبِع العملية العادية لتأكيد عملية الشراء ومنح المستخدم إذن الوصول إلى المحتوى وتأكيد عملية الشراء. إذا انتهت صلاحية المعاملة أو تم إلغاؤها، يتم إرسال رسالة SubscriptionNotification من النوع SUBSCRIPTION_PENDING_PURCHASE_CANCELED إلى عميل RTDN. في مثل هذه الحالات، يجب ألا يتمكّن المستخدم من الوصول إلى المحتوى.
تتضمّن عمليات التعبئة أو الترقية أو الرجوع إلى إصدار سابق مع معاملات معلّقة تغييرات في الحالة لكل من الاشتراك القديم والاشتراك الجديد. عندما يبدأ المستخدم معاملة معلّقة لإضافة رصيد أو ترقية أو خفض مستوى الاشتراك، يتلقّى تطبيقك Purchase للاشتراك القديم مع كائن PendingPurchaseUpdate. في هذه المرحلة، يكون المستخدم لا يزال يملك الاشتراك القديم ولم يحصل على الاشتراك الجديد بعد. يؤدي استدعاء getProducts() وgetPurchaseToken() على عنصر PendingPurchaseUpdate إلى عرض معرّفات المنتجات ورمز الشراء المميز للاشتراك الجديد. عند اكتمال المعاملة، يتلقّى تطبيقك
Purchase مع ضبط رمز الشراء ذي المستوى الأعلى للاشتراك الجديد
وتعيين الحالة على PURCHASED. يتم إرسال رسالة SubscriptionNotification من النوع SUBSCRIPTION_PURCHASED إلى عميل RTDN. في هذه الحالة فقط، عليك استبدال رمز الشراء القديم برمز الشراء الجديد وتعديل إذن وصول المستخدم إلى المحتوى. إذا انتهت صلاحية المعاملة أو تم إلغاؤها، يتم إرسال
SubscriptionNotification رسالة من النوع
SUBSCRIPTION_PENDING_PURCHASE_CANCELED إلى عميل RTDN. في هذه الحالات، من المفترض أن يظل بإمكان المستخدم الوصول إلى محتوى الاشتراك القديم.