نظام الفوترة في Google Play هو خدمة تتيح لك بيع المنتجات الرقمية والمحتوى الرقمي في تطبيق Android. ومع إصدار أيار (مايو) 2022، غيّرنا طريقة تحديد المنتجات التي تتضمّن اشتراكات، ويؤثّر ذلك في طريقة بيعها داخل التطبيق وإدارتها في الخلفية. إذا كنت بصدد دمج نظام الفوترة في Google Play للمرة الأولى، يمكنك بدء عملية الدمج من خلال قراءة مقالة الاستعداد.
إذا كنت تبيع اشتراكات باستخدام "الفوترة في Google Play" قبل أيار (مايو) 2022، من المهم معرفة كيفية استخدام الميزات الجديدة مع الحفاظ على اشتراكاتك الحالية.
أول ما يجب معرفته هو أنّ جميع الاشتراكات والتطبيقات وعمليات الدمج في الخلفية الحالية تعمل كما كانت قبل إصدار أيار (مايو) 2022. ليس عليك إجراء أي تغييرات على الفور، بل يمكنك استخدام هذه الميزات الجديدة بمرور الوقت. يتوفّر الدعم لكل إصدار رئيسي من مكتبة الفوترة في Google Play لمدة عامين بعد إصداره. ستستمر عمليات الدمج الحالية مع Google Play Developer API في العمل كما كانت من قبل.
في ما يلي نظرة عامة على التحديثات التي أجريناها في أيار (مايو) 2022:
- تتيح لك Google Play Console الجديدة إنشاء الاشتراكات والخطط الأساسية والعروض وإدارتها. ويشمل ذلك كلاً من الاشتراكات الجديدة والمُنقولة.
- يتضمّن Play Developer API تحديثات تتيح استخدام وظائف جديدة في واجهة مستخدم Google Play Console في شكل واجهة برمجة تطبيقات. تجدر الإشارة إلى أنّ هناك إصدارًا جديدًا من واجهة برمجة التطبيقات Subscription Purchases API. يمكنك استخدام واجهة برمجة التطبيقات هذه للتحقّق من حالة الاشتراك وإدارة عمليات شراء الاشتراكات.
- يتيح الإصدار 5 من Play Billing Library لتطبيقك الاستفادة من جميع ميزات الاشتراك الجديدة. عندما تكون مستعدًا للترقية إلى الإصدار 5، اتّبِع الإرشادات الواردة في دليل نقل البيانات.
إعدادات الاشتراكات
إدارة الاشتراكات من خلال Google Play Console
اعتبارًا من أيار (مايو) 2022، ستلاحظ بعض الاختلافات في Google Play Console.
يمكن أن يتضمّن الاشتراك الواحد الآن عدة خطط أساسية وعروض. تظهر الآن وحدات حفظ المخزون الخاصة بالاشتراكات التي تم إنشاؤها سابقًا في Play Console على شكل عناصر جديدة للاشتراك والخطة الأساسية والعرض. إذا لم يسبق لك ذلك، يمكنك الاطّلاع على مقالة التغييرات الأخيرة على الاشتراكات في Play Console للحصول على أوصاف للعناصر الجديدة، بما في ذلك وظائفها وإعداداتها. ستظهر جميع منتجات الاشتراك الحالية في Google Play Console بهذا التنسيق الجديد. يتم الآن تمثيل كل رمز تخزين تعريفي باستخدام عنصر اشتراك يتضمّن خطة أساسية واحدة وعرضًا متوافقًا مع الإصدارات القديمة، إذا كان ذلك منطبقًا.
بما أنّ عمليات الدمج القديمة كانت تتوقّع أن يتضمّن كل اشتراك عرضًا واحدًا، يتم تمثيله بكائن SkuDetails، يمكن أن يتضمّن كل اشتراك خطة أساسية أو عرضًا واحدًا متوافقًا مع الإصدارات القديمة.
يتم عرض الخطة الأساسية أو العرض المتوافقَين مع الإصدارات القديمة كجزء من وحدة حفظ مخزون (SKU) للتطبيقات التي تستخدم الطريقة querySkuDetailsAsync() المتوقفة نهائيًا.
لمزيد من المعلومات حول إعداد العروض الترويجية المتوافقة مع الإصدارات القديمة وإدارتها، يُرجى الاطّلاع على التعرّف على الاشتراكات. بعد أن يستخدم تطبيقك queryProductDetailsAsync() فقط، وبعد أن تتوقف الإصدارات القديمة من تطبيقك عن إجراء عمليات الشراء، لن تحتاج إلى استخدام عرض ترويجي متوافق مع الإصدارات القديمة.
إدارة الاشتراكات من خلال Subscriptions Publishing API
تحتوي Play Developer API على وظائف جديدة لعمليات شراء الاشتراكات. ستستمر واجهة برمجة التطبيقات
inappproducts
لإدارة رموز التخزين التعريفية في العمل كما في السابق، بما في ذلك التعامل مع المنتجات التي يتم تحصيل سعرها مرة واحدة والاشتراكات، لذا ليس عليك إجراء أي تغييرات فورية للحفاظ على عملية الدمج.
ومع ذلك، من المهم ملاحظة أنّ Google Play Console لا يستخدم سوى عناصر الاشتراك الجديدة. بعد بدء تعديل اشتراكاتك في
Console، لن تتمكّن من استخدام
واجهة برمجة التطبيقات inappproducts
للاشتراكات.
إذا كنت قد استخدمت Publishing API قبل أيار (مايو) 2022، ولتجنُّب أي مشاكل، ستظهر أي اشتراكات حالية الآن كاشتراكات للقراءة فقط في Google Play Console. إذا حاولت إجراء تغييرات، قد يظهر لك تحذير يوضّح هذا القيد. قبل إجراء المزيد من التعديلات على الاشتراكات في Play Console، عليك تعديل عملية الدمج في الخلفية لاستخدام نقاط النهاية الجديدة لواجهة Subscription Publishing API. تتيح لك نقاط النهاية الجديدة
monetization.subscriptions وmonetization.subscriptions.baseplans وmonetization.subscriptions.offers إدارة جميع الخطط الأساسية والعروض المتاحة. يمكنك الاطّلاع على كيفية ربط الحقول المختلفة من الكيان InAppProduct بالكائنات الجديدة ضمن monetization.subscriptions في الجدول التالي:
| InAppProduct | الاشتراك |
|---|---|
packageName |
packageName |
sku |
productId |
status |
basePlans[0].state |
prices |
basePlans[0].regionalConfigs.price |
listings |
البيانات |
defaultPrice |
ما مِن مكافئ |
subscriptionPeriod |
basePlans[0].autoRenewingBasePlanType.billingPeriodDuration |
trialPeriod |
basePlans[0].offers[0].phases[0].regionalConfigs[0].free |
gracePeriod |
basePlans[0].autoRenewingBasePlanType.gracePeriodDuration |
subscriptionTaxesAndComplianceSettings |
taxAndComplianceSettings |
لا ينطبق هذا التعديل المطلوب على واجهة برمجة التطبيقات إلا على Publishing API (إدارة رموز التخزين التعريفية).
التغييرات في Play Billing Library
ولإتاحة عملية نقل البيانات التدريجية، تتضمّن "مكتبة الفوترة في Play" جميع الطرق والكائنات المتاحة في الإصدارات السابقة.
ستظلّ عناصر SkuDetails ووظائفها، مثل querySkuDetailsAsync()، متاحة، ما يتيح لك الترقية لاستخدام وظائف جديدة بدون الحاجة إلى تعديل رمز الاشتراكات الحالي على الفور.
يمكنك أيضًا التحكّم في العروض الترويجية المتاحة من خلال هذه الطرق
عن طريق وضع علامة عليها بأنّها متوافقة مع الإصدارات القديمة.
بالإضافة إلى الاحتفاظ بالطُرق القديمة، تتضمّن الإصدار 5 من مكتبة Play Billing Library الآن عنصر ProductDetails جديدًا وطريقة queryProductDetailsAsync() مقابلة للتعامل مع الكيانات والوظائف الجديدة. تتيح ProductDetails الآن أيضًا استخدام المنتجات الحالية داخل التطبيق (عمليات الشراء لمرة واحدة والمنتجات الاستهلاكية).
بالنسبة إلى الاشتراك، تعرض الدالة ProductDetails.getSubscriptionOfferDetails()
قائمة بجميع الخطط الأساسية والعروض التي يمكن للمستخدم شراؤها.
وهذا يعني أنّه يمكنك الوصول إلى جميع الخطط الأساسية والعروض المؤهّلة للمستخدم، بغض النظر عن التوافق مع الإصدارات القديمة.
getSubscriptionOfferDetails() المرتجعات null للمنتجات غير المتوفّرة باشتراك بالنسبة إلى عمليات الشراء لمرة واحدة، يمكنك استخدام
getOneTimePurchaseOfferDetails().
يتضمّن الإصدار 5 من Play Billing Library أيضًا طريقتَين جديدتَين وقديمتَين لبدء مسار الشراء. إذا تم ضبط عنصر BillingFlowParams الذي تم تمريره إلى
BillingClient.launchBillingFlow()
باستخدام عنصر SkuDetails، يستخرج النظام معلومات العرض
المراد بيعه من الخطة الأساسية أو العرض المتوافقَين مع الإصدارات القديمة
واللذين يتطابقان مع رمز التخزين التعريفي. إذا تم إعداد العنصر BillingFlowParams الذي تم تمريره إلى BillingClient.launchBillingFlow() باستخدام عناصر ProductDetailsParams، والتي تتضمّن ProductDetails وString يمثّل الرمز المميّز للعرض الذي يتم شراؤه، يستخدم النظام بعد ذلك هذه المعلومات لتحديد المنتج الذي يحصل عليه المستخدم.
تعرض queryPurchasesAsync() جميع عمليات الشراء التي يملكها المستخدم. لتحديد نوع المنتج المطلوب، يمكنك تمرير قيمة BillingClient.SkuType، كما هو الحال في الإصدارات القديمة، أو تمرير كائن QueryPurchasesParams يحتوي على قيمة BillingClient.ProductType تمثّل كيانات الاشتراك الجديدة.
ننصحك بتحديث تطبيقاتك إلى الإصدار 5 من المكتبة قريبًا حتى تتمكّن من الاستفادة من ميزات الاشتراك الجديدة هذه.
إدارة حالة الاشتراك
يوضّح هذا القسم التغييرات الأساسية التي يجب إجراؤها على مكوّنات الخلفية عند دمج نظام الفوترة في Google Play، وذلك لإتاحة الانتقال إلى الإصدار 5.
الإشعارات في الوقت الفعلي الخاصة بالمطوّرين
قريبًا، لن يحتوي الكائن SubscriptionNotification على subscriptionId. إذا كنت تعتمد على هذا الحقل لتحديد المنتج الذي يتضمّن اشتراكًا، عليك تعديله للحصول على هذه المعلومات من حالة الاشتراك باستخدام purchases.subscriptionv2:get عند تلقّي الإشعار. سيتضمّن كل عنصر SubscriptionPurchaseLineItem في المجموعة lineItems الذي يتم عرضه كجزء من حالة الشراء productId المقابل.
واجهة برمجة التطبيقات Subscriptions Purchases API: الحصول على حالة الاشتراك
في الإصدارات السابقة من واجهة برمجة التطبيقات Subscriptions Purchases API، كان بإمكانك الاستعلام عن حالة الاشتراك باستخدام purchases.subscriptions:get.
لم يتم تغيير نقطة النهاية هذه، وستظل تعمل مع عمليات شراء الاشتراكات المتوافقة مع الإصدارات القديمة. لا تتيح نقطة النهاية هذه أي وظائف جديدة تم إصدارها في أيار (مايو) 2022.
في الإصدار الجديد من واجهة برمجة التطبيقات Subscriptions Purchases API، استخدِم
purchases.subscriptionsv2:get
للحصول على حالة شراء الاشتراك. تتوافق واجهة برمجة التطبيقات هذه مع الاشتراكات التي تم نقلها والاشتراكات الجديدة (سواء كانت مدفوعة مسبقًا أو يتم تجديدها تلقائيًا) وعمليات الشراء من جميع الأنواع. يمكنك استخدام نقطة النهاية هذه للتحقّق من حالة الاشتراك عند تلقّي الإشعارات. يحتوي العنصر الذي تم عرضه، SubscriptionPurchaseV2، على حقول جديدة، ولكنّه يتضمّن أيضًا بيانات قديمة مطلوبة لمواصلة توفير الدعم للاشتراكات الحالية.
حقول SubscriptionPurchaseV2 للخطط المدفوعة مسبقًا
تمت إضافة حقول جديدة لتوفير خطط الدفع المُسبَق التي يمدّد المستخدم مدتها بدلاً من تجديدها تلقائيًا. تنطبق جميع الحقول على الخطط المدفوعة مسبقًا كما تنطبق على الاشتراكات التي يتم تجديدها تلقائيًا، باستثناء ما يلي:
- [حقل جديد] lineItems[0].prepaid_plan.allowExtendAfterTime: يشير إلى الوقت الذي سيُسمح فيه للمستخدم بشراء رصيد إضافي آخر لتمديد خطة الدفع المُسبَق، إذ يُسمح للمستخدم بالحصول على رصيد إضافي واحد فقط لم يتم استخدامه في كل مرة.
- [حقل جديد] SubscriptionState: يحدّد حالة عنصر الاشتراك.
بالنسبة إلى خطط الدفع المُسبَق، تكون هذه القيمة دائمًا
ACTIVEأوPENDINGأوCANCELED. - lineItems[0].expiryTime: يتوفّر هذا الحقل دائمًا للخطط المدفوعة مسبقًا.
- paused_state_context: لا يظهر هذا الحقل أبدًا لأنّه لا يمكن إيقاف الخطط المدفوعة مسبقًا مؤقتًا.
- lineItems[0].auto_renewing_plan: غير متوفّر لخطط الدفع المُسبَق.
- canceled_state_context: لا يظهر هذا الحقل في الخطط المدفوعة مسبقًا، لأنّه ينطبق فقط على المستخدمين الذين يلغون اشتراكًا نشطًا.
- lineItems[0].productId: يحلّ هذا الحقل محل
subscriptionIdمن الإصدارات السابقة.
حقول SubscriptionPurchaseV2 للاشتراكات المتكرّرة
يحتوي purchases.subscriptionv2 على حقول جديدة تقدّم تفاصيل أكثر
عن عناصر الاشتراك الجديدة. يوضّح الجدول التالي كيفية ربط الحقول من نقطة نهاية الاشتراك القديمة بالحقول المقابلة في purchases.subscriptionv2.
| SubscriptionPurchase | SubscriptionPurchaseV2 |
|---|---|
countryCode |
regionCode |
orderId |
latestOrderId |
| (ما مِن حقل مكافئ) | lineItems.offerPhase (تحدّد المرحلة الحالية: فترة تجريبية مجانية أو سعر تمهيدي أو تسوية أو سعر أساسي) |
| (ما مِن حقل مكافئ) | lineItems (قائمة
SubscriptionPurchaseLineItem)
التي تمثّل المنتجات التي تم الحصول عليها من خلال عملية الشراء |
| (ما مِن حقل مكافئ) | lineItems.offerDetails.basePlanId |
| (ما مِن حقل مكافئ) | lineItems.offerDetails.offerId |
| (ما مِن حقل مكافئ) | lineItems.offerDetails.offerTags |
startTimeMillis |
startTime |
expiryTimeMillis |
lineItems.expiryTime (لكل اشتراك تم الحصول عليه
في عملية الشراء expiryTime خاص به) |
| (ما مِن حقل مكافئ) | subscriptionState (تشير إلى
حالة الاشتراك) |
| (ما مِن حقل مكافئ) | pausedStateContext (تظهر فقط إذا كانت حالة الاشتراك SUBSCRIPTION_STATE_PAUSED) |
autoResumeTimeMillis |
pausedStateContext.autoResumeTime |
| (ما مِن حقل مكافئ) | canceledStateContext (يظهر فقط إذا كانت حالة الاشتراك SUBSCRIPTION_STATE_CANCELED) |
| (ما مِن حقل مكافئ) | testPurchase (يظهر فقط في عمليات الشراء التي يجريها مختبِرون مرخَّصون) |
autoRenewing |
lineItems.autoRenewingPlan.autoRenewEnabled |
priceCurrenceCode،
priceAmountMicros |
lineItems.autoRenewingPlan.recurringPrice |
introductoryPriceInfo |
lineItems.offerPhase.introductoryPriceيمكنك أيضًا العثور على هذه المعلومات في offer لكل اشتراك تم شراؤه. |
| developerPayload | تم إيقاف حمولة المطوّر (لا يوجد حقل مكافئ) نهائيًا |
| paymentState | (لا يتوفّر حقل مكافئ) يمكنك استنتاج حالة الدفع من subscriptionState:
|
cancelReason،
userCancellationTimeMillis،
cancelSurveyResult |
canceledStateContext |
linkedPurchaseToken |
linkedPurchaseToken (لم يطرأ أي تغيير) |
purchaseType |
الاختبار: من خلال testPurchaseالعرض الترويجي: signupPromotion |
priceChange |
lineItems.autoRenewingPlan.priceChangeDetails |
profileName،
emailAddress،
givenName،
familyName،
profileId |
subscribeWithGoogleInfo |
acknowledgementState |
acknowledgementState (no change) |
promotionType،
promotionCode |
signupPromotion |
externalAccountId،
obfuscatedExternalAccountId،
obfuscatedExteranlProfileId |
externalAccountIdentifiers |
وظائف أخرى لإدارة الاشتراكات
مع أنّ
purchases.subscriptions:get
تمت ترقيته إلى
purchases.subscriptionsv2:get،
ستبقى بقية وظائف إدارة اشتراكات المطوّرين
كما هي في نقطة النهاية purchases.subscriptions في الوقت الحالي،
لذا يمكنك مواصلة استخدام
purchases.subscriptions:acknowledge وpurchases.subscriptions:cancel وpurchases.subscriptions:defer وpurchases.subscriptions:refund وpurchases.subscriptions:revoke
كما كنت تفعل من قبل.
Pricing API
استخدِم نقطة النهاية
monetization.convertRegionPrices
لحساب الأسعار الإقليمية كما تفعل من خلال
Play Console. تقبل هذه الطريقة سعرًا واحدًا بأي عملة يتيحها Play، وتعرض الأسعار المحوَّلة (بما في ذلك معدّل الضريبة التلقائي حيثما ينطبق) لجميع المناطق التي يتيح فيها Google Play عمليات الشراء.