این سند نحوه مدیریت رویدادهای چرخه حیات اشتراک، مانند تمدید و انقضا را شرح میدهد. همچنین ویژگیهای اضافی اشتراک مانند ارائه تبلیغات و اجازه دادن به کاربران برای مدیریت اشتراکهای خود را توضیح میدهد.
اگر محصولات آبونهای را برای برنامهتان پیکربندی نکردهاید، به ایجاد و پیکربندی محصولات مراجعه کنید.
نمای کلی اشتراکها
اشتراک تراکنشی تکرارشونده است که حقوق مشخصی را به کاربران اعطا میکند. حقوق استفاده مجموعهای از مزایایی است که کاربران میتوانند در یک دوره زمانی مشخص به آنها دسترسی داشته باشند. برای مثال، اشتراک ممکن است کاربر را واجدشرایط دسترسی ممتاز کند.
ازطریق طرحهای پایه و پیشنهادهای ویژه، میتوانید پیکربندیهای متعددی برای محصول اشتراک یکسان ایجاد کنید. برای مثال، میتوانید برای کاربرانی که هرگز در برنامه شما مشترک نشدهاند، پیشنهاد ویژه معرفی ایجاد کنید. به همین ترتیب، میتوانید برای کاربرانی که قبلاً مشترک شدهاند، پیشنهاد ارتقا ایجاد کنید.
برای نمای کلی دقیق محصولات اشتراک، طرحهای پایه، و پیشنهادهای ویژه، به مستندات در مرکز راهنمایی کنسول Play مراجعه کنید.
«کتابخانه خدمات صورتحساب Play» از انواع اشتراک زیر پشتیبانی میکند:
اشتراک - در این نوع، یک مورد مربوط به یک حق مالکیت. برای مثال، اشتراک سرویس جاریسازی موسیقی.
اشتراک با برافزاها - در این نوع، یک خرید میتواند چندین حق مالکیت متمایز داشته باشد که در یک خرید واحد دستهبندی شدهاند. برای مثال، اشتراک در هر دو سرویس جاریسازی موسیقی و اشتراک ویدیو. برای اطلاعات ویژه اشتراک با برافزاها، به اشتراکهای دارای برافزاها مراجعه کنید.
ادغام طرحهای پیشپرداخت
طرحهای پیشپرداخت پساز انقضا بهطور خودکار تمدید نمیشوند. برای تمدید حق اشتراک خود بدون وقفه، کاربر باید طرح پیشپرداخت را برای همان اشتراک شارژ کند.
برای افزودن موجودی، جریان صورتحساب را مانند خرید اصلی راهاندازی کنید. لازم نیست نشان دهید که خرید یک شارژ است.
افزایش اعتبار طرح پیشپرداخت همیشه از حالت جایگزینی CHARGE_FULL_PRICE استفاده میکند و
نیازی نیست این حالت را بهطور صریح تنظیم کنید. کاربر بلافاصله هزینه یک دوره صورتحساب کامل را پرداخت میکند و حق مالکیت او به مدت زمان مشخصشده در سرریز تمدید میشود.
پساز افزودن موجودی، فیلدهای زیر در
Purchase شیء نتیجه
بهروزرسانی میشوند تا جدیدترین خرید افزودن موجودی را نشان دهند:
- شناسه سفارش
- زمان خرید
- امضا
- کد خرید
- تصدیق شده
فیلدهای Purchase زیر همیشه حاوی دادههای یکسانی هستند که در خرید اصلی وجود دارد:
- نام بسته
- وضعیت خرید
- محصولات
- تمدید خودکار
تصدیق خرید پیشپرداخت
مشابه اشتراکهای با تمدید خودکار، باید طرحهای پیشپرداخت را پساز خرید تأیید کنید. هم خرید اولیه و هم هرگونه افزایش موجودی باید تأیید شوند. برای اطلاعات بیشتر، پردازش خریدها را ببینید.
بهدلیل احتمال کوتاه بودن مدت طرح پیشپرداخت، مهم است که خرید را در اسرع وقت تأیید کنید.
طرحهای پیشپرداخت با مدت یک هفته یا بیشتر باید ظرف سه روز تأیید شوند.
طرحهای پیشپرداخت با مدت کمتر از یک هفته باید در نصف مدت طرح تأیید شوند. برای مثال، توسعهدهندگان ۱٫۵ روز فرصت دارند تا طرح پیشپرداخت سهروزه را تأیید کنند.
یکپارچهسازی اشتراکهای قسطی
اشتراک قسطی نوعی اشتراک است که در آن کاربران هزینه اشتراک را بهصورت چند قسط در یک دوره زمانی پرداخت میکنند، بهجای اینکه کل هزینه اشتراک را پیشاپیش پرداخت کنند.
ملاحظات اضافی برای اشتراکهای قسطی:
- دسترسی در کشورها: ویژگی اشتراک قسطی فقط در اسپانیا، ایتالیا، برزیل، و فرانسه دردسترس است (برای اطلاع از جدیدترین دسترسی، «کنسول» را بررسی کنید).
- تنظیم قیمت: هنگام تنظیم قیمت برای اشتراک قسطی در «کنسول»، قیمت نشاندهنده مبلغ پرداخت ماهانه است. این مبلغ، همراه با دوره تعهد تعیینشده، مبلغ کل اشتراک را در صفحه خرید ایجاد میکند.
- دوره تعهد: مدت کل تعهد اشتراک اولیه که درطول آن پرداختهای ماهانه الزامی است. برای مثال، اگر طرح پایه دارای دوره تعهد ۱۵ ماهه باشد، کاربر در این دوره ۱۵ پرداخت ماهانه انجام خواهد داد.
- تمدیدها: در زمینه اشتراکهای قسطی، «تمدید» به معنای پایان دوره تعهد، چه دوره تعهد اولیه و چه دوره تعهد بعدی است. پساز ثبتنام اولیه، اولین تمدید پساز تکمیل کل دوره تعهد اولیه انجام میشود. تمدیدهای بعدی پساز تکمیل هر دوره تعهد بعدی انجام میشود. انواع تمدید برای اشتراکهای قسطی میتواند «تمدید خودکار ماهانه» یا «تمدید خودکار برای مدت یکسان» باشد. برای «تمدید خودکار ماهانه»، تعهد بعدی وجود ندارد و طرح مانند اشتراک ماهانه عمل میکند که در آن هر هزینه اشتراک ماهانه یک تمدید محسوب میشود.
- دوره صورتحساب: در زمینه اشتراکهای قسطی، این اصطلاح به فاصله تکرارشوندهای اشاره دارد که پرداختهای جداگانه در آن انجام میشود، همانطور که در طرح پایه مشخص شده است.
- رفتارهای تغییر طرح در مقابل تغییر قیمت: برای تغییرات قیمت و لغو، تعهد قطعی است. این یعنی اگر کاربری بخواهد اشتراکش را لغو کند یا توسعهدهندهای بخواهد قیمت را تغییر دهد، تغییر در پایان دوره تعهد اعمال میشود. برای تغییرات طرح، تعهد قطعی نیست. این یعنی تغییر طرح لازم نیست تا پایان دوره تعهد منتظر بماند، بلکه براساس حالت جایگزینی تنظیمشده، یا بلافاصله یا در تاریخ پرداخت بعدی اعمال میشود.
- تغییر طرح اشتراک یکسان: تغییر طرح از طرح پایه اقساطی به طرح پایه غیر اقساطی از همان محصول اشتراک مجاز نیست.
اعلانهای بیدرنگ توسعهدهنده (RTDN): A
SUBSCRIPTION_CANCELLATION_SCHEDULEDRTDN بلافاصله پساز لغو کاربر زمانی که پرداختها برای دوره تعهد باقی مانده است ارسال میشود. لغو اشتراک معلقه است و فقط در پایان دوره تعهد اعمال خواهد شد. سپس، اگر کاربر آن را بازیابی نکند، SUBSCRIPTION_CANCELEDوSUBSCRIPTION_EXPIREDپیام RTDN در پایان دوره تعهد ارسال میشود.پرداختها / تحقق درآمد: پرداختهای توسعهدهنده زمانی انجام میشود که کاربران پرداختهای ماهانه خود را انجام دهند، مشروط به همان شرایطی که برای همه اشتراکهای دیگر اعمال میشود. وقتی کاربر برای اشتراک قسطی ثبتنام میکند، توسعهدهندگان پیشاپیش پولی دریافت نمیکنند.
وصول پرداختهای معوقه: اگر کاربر نتواند پرداختهای اقساطی اشتراک را انجام دهد، نه Google و نه «توسعهدهنده» تلاش نخواهند کرد که چنین پرداختهای معوقه یا معوقی را از کاربر وصول کنند، با این تفاوت که Google ممکن است بهطور دورهای درطول هر «مهلت ارفاقی» ذیربط یا دوره «توقف حساب» مطابق با رویههای عادی خود برای تلاش مجدد برای پرداخت، پرداخت را دوباره امتحان کند. Google درقبال توسعهدهنده برای هرگونه پرداخت اقساطی معوقه مسئولیتی نخواهد داشت.
دردسترس بودن «کتابخانه خدمات صورتحساب Play»: فیلد
installmentDetailsفقط برای PBL 7 یا نسخههای جدیدتر دردسترس است. برای PBL 5 و نسخههای جدیدتر، اشتراک قسطی بااستفاده ازqueryProductDetails()برگردانده میشود، اما اشتراک شامل اطلاعات دقیق قسطی مانند تعداد پرداختهای تعهدشده طرح نخواهد بود.
از پیوندهای عمیق استفاده کنید تا به کاربران اجازه دهید اشتراک را مدیریت کنند
برنامه شما باید پیوندی در صفحه تنظیمات یا اولویتها داشته باشد که به کاربران امکان دهد اشتراکهایشان را مدیریت کنند. میتوانید این پیوند را در ظاهر و احساس طبیعی برنامه خود بگنجانید.
میتوانید پیوند عمیقی از برنامهتان به مرکز اشتراکهای Google Play برای اشتراکهای منقضینشده اضافه کنید، که میتوانید بااستفاده از فیلد subscriptionState منبع اشتراک آن را تعیین کنید. براساس این،
چندین روش وجود دارد که میتوانید به مرکز اشتراکهای «فروشگاه Play» پیوند عمیق دهید.
پیوند به مرکز اشتراکها
از نشانی وب زیر برای هدایت کاربران به صفحهای که همه اشتراکهای آنها را نشان میدهد، همانطور که در شکلهای ۱ و ۲ نشان داده شده است، استفاده کنید:
https://play.google.com/store/account/subscriptions
این پیوند عمیق میتواند برای کمک به کاربر در بازیابی اشتراک لغوشده از مرکز اشتراکهای «فروشگاه Play» مفید باشد.
پیوند به صفحه مدیریت اشتراک خاص (توصیه میشود)
برای پیوند مستقیم به صفحه مدیریت اشتراک منقضینشده، نام بسته و productId مرتبط با اشتراک خریداریشده را مشخص کنید. برای تعیین برنامهریزیشده productId برای اشتراک موجود، از زیرینه برنامهتان پُرسمان کنید یا برای دریافت فهرست اشتراکهای منسوب به کاربر خاص، BillingClient.queryPurchasesAsync() را فراخوانی کنید. هر اشتراک شامل
productId مربوطه بهعنوان بخشی از اطلاعات وضعیت اشتراک است.
هر شیء SubscriptionPurchaseLineItem مرتبط با خرید اشتراک حاوی مقدار productId مرتبط با اشتراکی است که کاربر در آن ردیف مورد خریداری کرده است.
از نشانی وب زیر برای هدایت کاربران به صفحه مدیریت اشتراک خاصی استفاده کنید و «your-sub-product-id» و «your-app-package» را بهترتیب با productId و نام بسته برنامه جایگزین کنید:
https://play.google.com/store/account/subscriptions?sku=your-sub-product-id&package=your-app-package
سپس کاربر میتواند روشهای پرداخت خود را مدیریت کند و به ویژگیها ازجمله لغو، اشتراک مجدد، و توقف موقت دسترسی داشته باشد.
به کاربران اجازه دهید اشتراک خود را ارتقا دهند، تنزل دهند یا تغییر دهند
میتوانید گزینههای مختلفی را برای مشترکین فعلی ارائه دهید تا طرح اشتراک خود را تغییر دهند و بهتر نیازهایشان را برآورده کنند:
- اگر سطوح اشتراک متعددی مثل اشتراکهای «پایه» و «ممتاز» میفروشید، میتوانید به کاربران اجازه دهید با خرید طرح پایه یا پیشنهاد اشتراک متفاوت، سطح اشتراک خود را تغییر دهند.
- میتوانید به کاربران اجازه دهید دوره صورتحساب کنونیشان را تغییر دهند، مثلاً از طرح ماهانه به طرح سالانه بروند.
- همچنین میتوانید به کاربران اجازه دهید بین طرحهای تمدید خودکار و پیشپرداخت جابهجا شوند.
میتوانید با ارائه پیشنهادهای ویژه اشتراک به کاربران واجدشرایط، این تغییرات را تشویق کنید. برای مثال، میتوانید پیشنهادی ویژه ایجاد کنید که درصورت تغییر از طرح ماهانه به طرح سالانه، تخفیف ۵۰٪ برای سال اول ارائه دهد، و این پیشنهاد ویژه را به کاربرانی که مشترک طرح ماهانه هستند و این پیشنهاد ویژه را خریداری نکردهاند محدود کنید. اطلاعات بیشتر درباره معیارهای واجدشرایط بودن برای پیشنهاد ویژه در مرکز راهنمایی دردسترس است
شکل ۳ برنامه نمونهای را با سه طرح مختلف نشان میدهد:
برنامه شما میتواند صفحهای مشابه شکل ۳ نشان دهد و به کاربران امکان دهد اشتراکشان را تغییر دهند. در همه موارد، باید برای کاربران مشخص باشد که طرح اشتراک فعلی آنها چیست و چه گزینههایی برای تغییر آن دارند.
وقتی کاربران تصمیم میگیرند ارتقا دهند، تنزل دهند، یا اشتراک خود را تغییر دهند، شما حالت جایگزینی را مشخص میکنید که تعیین میکند مقدار سرشکنشده دوره صورتحساب پولی فعلی چگونه اعمال شود و چه زمانی تغییر در حق مالکیت رخ دهد.
حالتهای جایگزینی
جدول زیر حالتهای جایگزین دردسترس و نمونه استفاده را فهرست میکند، و تعداد پرداختهایی که پرداختشده درنظر گرفته میشوند.
حالت جایگزینی |
شرح |
نمونه استفاده |
پرداختهای تعهدشده بهعنوان پرداختشده ثبت شد (برای جایگزینی اشتراک قسطی) |
|
مورد اشتراک بلافاصله ارتقا یا تنزل مییابد. زمان باقیمانده براساس تفاوت قیمت اصلاح میشود و با جلو بردن تاریخ صورتحساب بعدی، به اشتراک جدید اضافه میشود. این رفتار پیشفرض است. |
بدون پرداخت فوری هزینه اضافی، به سطح گرانتری ارتقا دهید. |
0 |
|
مورد اشتراک بلافاصله ارتقا مییابد و چرخه صورتحساب بدون تغییر باقی میماند. سپس تفاوت قیمت برای دوره باقیمانده از کاربر کسر میشود. توجه: این گزینه فقط برای ارتقای مورد اشتراک دردسترس است، جایی که قیمت بهازای واحد زمان افزایش مییابد. |
بدون تغییر تاریخ صورتحساب، به سطح گرانتری ارتقا دهید. |
1 |
|
مورد اشتراک بلافاصله ارتقا یا تنزل مییابد و کاربر بلافاصله قیمت کامل حق استفاده جدید را پرداخت میکند. مقدار باقیمانده از اشتراک قبلی یا برای همان حق استفاده منتقل میشود یا برای زمانی که به حق استفاده دیگری تغییر میدهید، سرشکن میشود. توجه: اگر اشتراک جدید دارای دوره آزمایشی رایگان یا پیشنهاد ویژه مقدماتی باشد، کاربر در زمان ارتقا یا تنزل سطح، مبلغ ۰ دلار یا قیمت پیشنهاد ویژه مقدماتی را پرداخت میکند، هرکدام که اعمال شود. |
از دوره صورتحساب کوتاهتر به دوره صورتحساب طولانیتر ارتقا دهید. |
۱ (توجه: اگر اشتراک جدید دوره آزمایشی رایگان داشته باشد، ۰) |
|
مورد اشتراک بلافاصله ارتقا یا تنزل مییابد و قیمت جدید هنگام تمدید اشتراک کسر میشود. چرخه صورتحساب بدون تغییر باقی میماند. |
به سطح اشتراک بالاتری ارتقا دهید و دوره رایگان باقیمانده را حفظ کنید. |
0 |
|
مورد اشتراک فقط هنگام تمدید اشتراک ارتقا یا تنزل مییابد، اما خرید جدید بلافاصله با دو مورد زیر صادر میشود:
توجه: برای اشتراکهای قسطی، تغییر طرح در ابتدای تاریخ پرداخت بعدی رخ میدهد. |
به سطح ارزانتری تنزل دهید. |
1 |
|
برنامه پرداخت برای محصول اشتراک در محصول جایگزین بدون تغییر باقی میماند. |
وقتی یک مورد خاص باید بدون تغییر باقی بماند، مورد اشتراک را از اشتراک دارای برافزاها اضافه یا حذف کنید. |
موجود نیست |
برای کسب اطلاعات بیشتر درباره کاربردهای مختلف ارتقا و بازگرداندن مشتری در پیشنهادهای ارتقا یا تنزل، راهنمای پیشنهادهای ویژه و تبلیغات را بخوانید.
تنظیم حالت جایگزینی برای خرید
براساس اولویتها و منطق کسبوکارتان، میتوانید از حالتهای جایگزینی مختلفی برای انواع مختلف انتقالهای اشتراک استفاده کنید. این بخش توضیح میدهد چگونه حالت جایگزینی را برای تغییر در اشتراک تنظیم کنید و محدودیتهایی که اعمال میشود.
ازسر گرفتن اشتراک یا تعویض طرح در همان اشتراک
میتوانید حالت جایگزینی پیشفرضی را در «کنسول Google Play» مشخص کنید. این
تنظیم به شما امکان میدهد انتخاب کنید اگر مشترکین فعلیْ طرح پایه یا پیشنهادی متفاوت برای اشتراک فعلیشان بخرند یا پساز
لغو اشتراک مجدداً مشترک شوند، چه زمانی هزینه از حسابشان کسر شود. گزینههای دردسترس عبارتاند از کسر هزینه فوری، معادل
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 اشتراک محتوای آنلاین دارد. او اشتراک ماهانه نسخه سطح ۱ محتوا را دارد که فقط متنی است. هزینه این اشتراک برای او ۲ دلار در ماه است و در اول ماه تمدید میشود.
در ۱۵ آوریل، «سموایز» تصمیم گرفت به نسخه سالانه اشتراک سطح ۲ ارتقا دهد که شامل بهروزرسانیهای ویدیویی است و ۳۶ دلار در سال هزینه دارد.
هنگام ارتقا دادن اشتراک، توسعهدهنده حالت سرشکن کردن را انتخاب میکند. فهرست زیر توضیح میدهد که هر حالت سرشکن چگونه بر اشتراک «ساموایز» تأثیر میگذارد:
WITH_TIME_PRORATION
اشتراک سطح ۱ Samwise بلافاصله پایان مییابد. زیرا او هزینه یک ماه کامل (۱ تا ۳۰ آوریل) را پرداخت کرده است اما در میانه دوره اشتراک ارتقا داده است، بنابراین هزینه نصف ماه اشتراک (۱ دلار) به اشتراک جدید او اعمال میشود. بااینحال، چون هزینه آن اشتراک جدید ۳۶ دلار در سال است، تراز اعتباری ۱ دلاری فقط ۱۰ روز (۱۶ تا ۲۵ آوریل) را پوشش میدهد؛ بنابراین در ۲۶ آوریل، ۳۶ دلار برای اشتراک جدید از او کسر میشود و در ۲۶ آوریل هر سال بعد هم ۳۶ دلار دیگر کسر میشود.
بهمحض اینکه خرید موفقیتآمیز بود و توانستید خرید جدید را بهعنوان بخشی از تماس queryPurchasesAsync() بازیابی کنید، باید PurchasesUpdatedListener برنامه خود را فراخوانی کنید. پشتیبان شما بلافاصله یک
SUBSCRIPTION_PURCHASED «اعلان بیدرنگ توسعهدهنده» دریافت میکند.
CHARGE_PRORATED_PRICE
از این حالت میتوان استفاده کرد زیرا قیمت اشتراک سطح ۲ در هر واحد زمان (۳۶ دلار در سال = ۳ دلار در ماه) بیشتر از قیمت اشتراک سطح ۱ در هر واحد زمان (۲ دلار در ماه) است. اشتراک سطح ۱ Samwise بلافاصله پایان مییابد. چون او هزینه یک ماه کامل را پرداخت کرده است اما فقط از نیمی از آن استفاده کرده است، هزینه نیمی از اشتراک یک ماهه (۱ دلار) به اشتراک جدید او اعمال میشود. بااینحال، چون هزینه آن اشتراک جدید ۳۶ دلار در سال است، هزینه ۱۵ روز باقیمانده ۱٫۵۰ دلار میشود؛ بنابراین تفاوت ۰٫۵۰ دلار برای اشتراک جدید از او کسر میشود. در ۱ مه، ۳۶ دلار از حساب «سموایز» برای سطح اشتراک جدیدش کسر میشود و ۳۶ دلار دیگر در ۱ مه هر سال بعد از آن کسر میشود.
بهمحض اینکه خرید موفقیتآمیز بود و توانستید خرید جدید را بهعنوان بخشی از تماس queryPurchasesAsync() بازیابی کنید، باید PurchasesUpdatedListener برنامه خود را فراخوانی کنید. پشتیبان شما بلافاصله یک
SUBSCRIPTION_PURCHASED «اعلان بیدرنگ توسعهدهنده» دریافت میکند.
WITHOUT_PRORATION
اشتراک سطح ۱ ساموایز بلافاصله به سطح ۲ ارتقا مییابد و هیچ هزینه اضافی از او کسر نمیشود، و در ۱ مه، ۳۶ دلار برای سطح اشتراک جدیدش و ۳۶ دلار دیگر در ۱ مه هر سال بعد از او کسر میشود.
بهمحض اینکه خرید موفقیتآمیز بود و توانستید خرید جدید را بهعنوان بخشی از تماس queryPurchasesAsync() بازیابی کنید، باید PurchasesUpdatedListener برنامه خود را فراخوانی کنید. پشتیبان شما بلافاصله یک
SUBSCRIPTION_PURCHASED «اعلان بیدرنگ توسعهدهنده» دریافت میکند.
DEFERRED
اشتراک سطح ۱ ساموایز تا زمان انقضای آن در ۳۰ آوریل ادامه خواهد داشت. در تاریخ ۱ مه، اشتراک سطح ۲ اعمال میشود و ۳۶ دلار از ساموایز برای سطح اشتراک جدیدش کسر میشود.
بهمحض اینکه خرید موفقیتآمیز بود و توانستید خرید جدید را بهعنوان بخشی از تماس queryPurchasesAsync() بازیابی کنید، باید PurchasesUpdatedListener برنامه خود را فراخوانی کنید. پشتیبان شما بلافاصله یک
SUBSCRIPTION_PURCHASED «اعلان بیدرنگ توسعهدهنده» دریافت میکند. باید خرید را
پردازش کنید همانگونه که هر خرید جدید دیگری را در آن
زمان پردازش میکنید. بهطور خاص، مطمئن شوید که خرید جدید را تصدیق میکنید. توجه داشته باشید که
startTime اشتراک جدید در لحظهای که جایگزینی
اعمال میشود، تکمیل میشود، که این اتفاق زمانی رخ میدهد که اشتراک قدیمی منقضی شود. در آن نقطه،
یک SUBSCRIPTION_RENEWED RTDN برای طرح اشتراک جدید دریافت میکنید. درباره رفتار ReplacementMode.DEFERRED در مدیریت جایگزینی
بهتعویقافتاده بیشتر بخوانید.
CHARGE_FULL_PRICE
اشتراک سطح ۱ Samwise بلافاصله پایان مییابد. اشتراک سطح ۲ او امروز شروع میشود و ۳۶ دلار از او کسر میشود. چون او هزینه یک ماه کامل را پرداخت کرده است اما فقط از نیمی از آن استفاده کرده است، نیمی از هزینه اشتراک یک ماهه (۱ دلار) به اشتراک جدید او اعمال میشود. چون هزینه اشتراک جدید ۳۶ دلار در سال است، او ۱/۳۶ سال به دوره اشتراک خود اضافه میکند (~۱۰ روز). بنابراین، هزینه بعدی Samwise یک سال و ۱۰ روز دیگر به مبلغ ۳۶ دلار خواهد بود. پساز آن، هر سال ۳۶ دلار از او کسر میشود.
هنگام انتخاب حالت سرشکن کردن، حتماً توصیههای جایگزینی ما را بررسی کنید.
KEEP_EXISTING
ساموایز اشتراک محتوای آنلاین از برنامه Country Gardener دارد. او اشتراک ماهانه «طرح ۱» برای محتوای پایه دارد. این اشتراک با قیمت آغازین ۲ دلار در ماه برای ۳ ماه و سپس ۴ دلار در ماه ارائه میشود. ساموایز این را در ۱ آوریل خریداری کرد. برنامه Country Gardener «طرح ۲» را بهعنوان محتوای تخصصی برافزایی با قیمت ۳ دلار در ماه ارائه میدهد. در ۱۵ آوریل، ساموایز «طرح ۲» را به اشتراک برنامه «باغبان روستایی» خود اضافه کرد و «طرح ۱» موجود را حفظ کرد. برنامه پرداخت Samwise به شرح زیر است:
- قیمت سرشکنشده ۱٫۵۰ دلار برای «طرح ۲» که باید ۱۵ آوریل پرداخت شود.
- قیمت ۵ دلار در ماه برای ۲ ماه بعدی که شامل هر دو قیمت مقدماتی برای «طرح ۱» و قیمت عادی برای «طرح ۲» میشود.
- پساز آن، پرداخت ماهانه ثابت ۷ دلار.
راهاندازی تغییرات اشتراک درونبرنامهای
برنامه شما میتواند بااستفاده از همان مراحل راهاندازی جریان خرید، به کاربران ارتقا یا تنزل پیشنهاد دهد. بااینحال، هنگام ارتقا یا تنزل، باید جزئیات اشتراک فعلی، اشتراک آینده (ارتقا یا تنزلیافته)، و حالت جایگزینی مورد استفاده را ارائه دهید.
برای جایگزینی از 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 بلافاصله به اشتراک اضافه میشود.
کاتلین
val billingClient: BillingClient = this.billingClient val replacementModeForBasePlan: Int = SubscriptionProductReplacementParams.ReplacementMode.KEEP_EXISTING val replacementModeForAddon: Int = SubscriptionProductReplacementParams.ReplacementMode.CHARGE_PRORATED_PRICE val purchaseTokenOfExistingSubscription: String = "your_old_purchase_token" // ProductDetails instances obtained from queryProductDetailsAsync(); val productDetailsParams1 = ProductDetailsParams.newBuilder() .setProductDetails(productDetails1) // Required: Set the ProductDetails object .setSubscriptionProductReplacementParams( SubscriptionProductReplacementParams.newBuilder() .setOldProductId("old_product_id_1") .setReplacementMode(replacementModeForBasePlan) .build() ) .build() val productDetailsParams2 = ProductDetailsParams.newBuilder() .setProductDetails(productDetails2) // 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) // 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)
جاوا
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 را نشان میدهد.
کاتلین
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 ) // ...
جاوا
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 را برمیگرداند. میتوانید itemReplacement را در SubscriptionPurchaseLineItem در خرید جدید بررسی کنید تا جزئیات جایگزینی سطح مورد را متوجه شوید.
علاوهبراین، میتوانید از فیلد offerPhase برای شناسایی مرحله پیشنهاد ویژه فعلی (مثل دوره سرشکن یا دوره آزمایشی رایگان) برای اشتراک جدید استفاده کنید تا تجربههای کاربری سفارشیسازیشده ارائه دهید. حتماً نشان ارائهشده در linkedPurchaseToken را نامعتبر کنید تا مطمئن شوید از نشان قدیمی برای دسترسی به سرویسهایتان استفاده نمیشود. برای اطلاعات درباره مدیریت خریدهای ارتقا و تنزل، به
ارتقا، تنزل، و ثبتنام مجدد مراجعه کنید.
وقتی کد خرید جدید را دریافت کردید، همان فرایند درستیسنجی را که برای درستیسنجی کد خرید جدید انجام میدهید دنبال کنید. حتماً این خریدها را با BillingClient.acknowledgePurchase() از «کتابخانه سیستم صورتحساب Google Play» یا Purchases.subscriptions:acknowledge از «میانای برنامهسازی کاربردی توسعهدهنده Google Play» تأیید کنید.
جایگزینی نام کاربری بهتعویق افتاد
حالت جایگزینی تعویقیافته به شما امکان میدهد به کاربر اجازه دهید قبلاز شروع طرح جدید، از حق استفاده باقیمانده در طرح قدیمیاش استفاده کند.
وقتی از ReplacementMode.DEFERRED برای خرید جدیدی استفاده میکنید،
queryPurchasesAsync() پساز جریان خرید،
یک کد خرید جدید برمیگرداند که تا زمان جایگزینی معوقه در تاریخ تمدید بعدی با محصول قدیمی مرتبط میماند و پساز آن محصول جدید برگردانده میشود.
در گذشته میتوانستید این تجربه کاربری را با
ProrationMode.DEFERRED منسوخشده بهدست آورید، اما ProrationMode.DEFERRED با «کتابخانه خدمات صورتحساب Play» نسخه ۶ منسوخ شده است. برای درک اینکه رفتار در کجا متفاوت است، جدول زیر را ببینید:
زمان |
ProrationMode.DEFERRED (منسوخ) |
ReplacementMode.DEFERRED |
بلافاصله پساز موفقیتآمیز بودن جریان خرید (برنامه) |
استحقاق طرح قدیمی تا تاریخ تمدید بعدی ادامه مییابد. برای اطمینان از اینکه برنامه حق مالکیت صحیح را ارائه میدهد، تا زمانی که جایگزینی انجام شود، دادهواحد خرید جدید نمایان نمیشود، بنابراین در این مرحله نمیتواند پردازش شود. |
نشان خرید جدید نمایان میشود، بنابراین در این نقطه باید پردازش شود و زمان جایگزینی درنظر گرفته شود. |
بلافاصله پساز موفقیتآمیز بودن جریان خرید (زیرینه) |
SUBSCRIPTION_PURCHASED RTDN پساز جریان خرید ارسال نمیشود. پشت صحنه هنوز از خرید جدید مطلع نشده است. |
SUBSCRIPTION_PURCHASED RTDN با product_id قدیمی بلافاصله پساز جریان خرید برای کد خرید جدید ارسال میشود. فراخوانی روش purchases.subscriptionsv2.get با رمز خرید جدید خریدی را برمیگرداند که دارای «startTime» است و زمان خرید را با دو مورد ردیفی نشان میدهد:
SUBSCRIPTION_EXPIRED برای کد خرید قدیمی ارسال شد. وقتی روش purchases.subscriptionsv2.get را با کد خرید قدیمی فراخوانی میکنید، این کد بهعنوان منقضیشده نشان داده میشود (استحقاق طرح قدیمی برای زمان باقیمانده به خرید جدید منتقل میشود). |
در جایگزینی - اولین تمدید پساز جریان خرید (برنامه) |
اکنون کد خرید جدید نمایان شده است، بنابراین باید پردازش شود. |
وقتی جریان خرید موفقیتآمیز باشد، خرید جدید باید قبلاً پردازش شده باشد، بنابراین برنامه نباید اقدام خاصی انجام دهد، بهجز اینکه مطمئن شود حق استفاده صحیح اعطا شده است. |
در تعویض - اولین تمدید پساز جریان خرید (زیرینه) |
اکنون میتوان خرید جدید را هنگام ارسال اولین RTDN از نوع SUBSCRIPTION_RENEWED پردازش و تأیید کرد. از |
خرید جدید زمانی پردازش و تأیید شد که RTDN «SUBSCRIPTION_PURCHASED» برای کد خرید جدید ارسال شد و بهعنوان «startTime» ثبت شد. با ReplacementMode.DEFERRED، تمدیدهای اولیه از رفتار استاندارد هر تمدید دیگری پیروی میکنند و وقتی این رویداد اتفاق میافتد، نیازی نیست منطق ویژهای برای جایگزینیها مدیریت کنید. وقتی روش purchases.subscriptionsv2.get با رمز خرید جدید فراخوانی میشود، خرید با دو مورد ردیفی برمیگرداند:
|
ازاینپس باید از ReplacementMode.DEFERRED بهجای ProrationMode.DEFERRED منسوخشده استفاده شود، زیرا این حالت رفتار یکسانی درخصوص تغییرات حق استفاده ارائه میدهد، اما روشی برای مدیریت خرید ارائه میدهد که با رفتارهای سایر خریدهای جدید سازگارتر است.
مدیریت مشتری
بااستفاده از «اعلانهای بیدرنگ توسعهدهنده»، میتوانید در زمان واقعی متوجه شوید که کاربر تصمیم به لغو گرفته است. وقتی کاربری لغو میکند، اما قبلاز اینکه اشتراک او منقضی شود، میتوانید برای او اعلانهای لحظهای یا پیامهای درونبرنامهای ارسال کنید و از او بخواهید دوباره مشترک شود.
پساز اینکه کاربر اشتراک خود را لغو کرد، میتوانید سعی کنید او را دوباره جذب کنید چه در برنامه خودتان، چه ازطریق «فروشگاه Play». جدول زیر سناریوهای مختلف اشتراک را همراه با اقدامات بازگشت مشتری مرتبط و الزامات برنامه شرح میدهد.
| قبلاز انقضای اشتراک | پساز انقضای اشتراک | |||
| درون برنامه | در «فروشگاه Play» | درون برنامه | در «فروشگاه Play» | |
| ویژگی بازگرداندن | اشتراک درونبرنامهای | بازگرداندن | اشتراک درونبرنامهای | ازسرگرفتن اشتراک |
| کاربر از جریان تسویهحساب عبور میکند | بله | نه | بله | بله |
| اشتراک کاربر همچنان با همان واحد نگهداری کالا (SKU) مرتبط میماند | کاربر میتواند برای همان «واحد نگهداری کالا» یا «واحد نگهداری کالای» دیگری ثبتنام کند | بله | کاربر میتواند برای همان «واحد نگهداری کالا» یا «واحد نگهداری کالای» دیگری ثبتنام کند | بله |
| نشان خرید جدید ایجاد میکند | بله | نه | بله | بله |
| بهطور پیشفرض فعال است | نه | بله، پشتیبانی برای همه توسعهدهندگان لازم است | نه |
برنامههای بدون «کتابخانه خدمات صورتحساب» نسخه ۲.۰ و بالاتر: خیر برنامههای دارای «کتابخانه خدمات صورتحساب» نسخه ۲.۰ و بالاتر: بله. توسعهدهندگان میتوانند در «کنسول» انصراف دهند. |
| وقتی هزینه از کاربر کسر میشود |
اگر از همان واحد نگهداری کالا استفاده میکنید: پایان دوره صورتحساب جاری. اگر از SKU دیگری استفاده میکنید: به حالت سرشکن کردن بستگی دارد. |
پایان دوره صورتحساب فعلی | بیدرنگ | بیدرنگ |
| پیادهسازی الزامی است | واسط کاربر ثبتنام مجدد در برنامهتان ارائه دهید |
تشخیص تغییر در وضعیت اشتراک پیوند عمیق به «فروشگاه Play» |
ارائه واسط کاربر ثبتنام مجدد در برنامه | مدیریت خریدهای خارج از برنامه |
قبلاز انقضای اشتراک - درونبرنامه
برای اشتراکهایی که لغو شدهاند اما هنوز منقضی نشدهاند، میتوانید به مشترکین اجازه دهید اشتراک خود را در برنامهتان با اعمال همان جریان خرید محصول درونبرنامه که برای مشترکین جدید استفاده میشود بازیابی کنند. مطمئن شوید که واسط کاربر شما نشان میدهد کاربر اشتراک موجودی دارد. برای مثال، ممکن است بخواهید تاریخ انقضای فعلی کاربر و قیمت تکرارشونده را با دکمه فعالسازی مجدد نمایش دهید.
اغلب اوقات، میخواهید همان قیمت و واحد نگهداری کالا را که کاربر قبلاً مشترک آن بوده است به او پیشنهاد دهید، به این صورت:
- خرید اشتراک جدیدی را با همان واحد نگهداری کالا آغاز کنید.
- اشتراک جدید جایگزین اشتراک قدیمی میشود و در همان تاریخ انقضا تمدید میشود. اشتراک قدیمی بلافاصله بهعنوان منقضی علامتگذاری میشود.
- بهعنوان مثال، «آشیل» در «برنامه موسیقی نمونه» اشتراک دارد و اشتراک او در تاریخ ۱ اوت منقضی میشود. در ۱۰ ژوئیه، او با همان قیمت ماهانه دوباره اشتراک یکماهه را خریداری میکند. اشتراک جدید با اعتبار باقیمانده سرشکن میشود، بلافاصله فعال میشود، و همچنان در ۱ اوت تمدید میشود.
اگر میخواهید قیمت دیگری ارائه دهید—برای مثال دوره آزمایشی رایگان جدید یا تخفیف بازگشت مشتری—میتوانید بهجای آن واحد نگهداری موجودی دیگری به کاربر ارائه دهید:
- بااستفاده از حالت جایگزینی
WITHOUT_PRORATION، ارتقا یا تنزل با «واحد نگهداری موجودی» متفاوت را شروع کنید. - اشتراک جدید جایگزین اشتراک قدیمی میشود و در همان تاریخ انقضا تمدید میشود. کاربر در تاریخ انقضای اصلی، قیمت کد محصول جدید را پرداخت میکند، ازجمله هرگونه قیمت
معرفی. اگر اشتراک قدیمی بااستفاده از شناسه حساب مبهمسازیشده ایجاد شده باشد، همان شناسه باید برای ارتقا و تنزل به
BillingFlowParamsارسال شود. - بهعنوان مثال، «آشیل» در «برنامه موسیقی نمونه» اشتراک دارد و اشتراک او در تاریخ ۱ اوت منقضی میشود. در ۱۰ ژوئیه، او دوباره برای اشتراک سالانه با قیمت آغازین ثبتنام میکند. اشتراک جدید بلافاصله فعال میشود و قیمت معرفی در تاریخ ۱ اوت از کاربر کسر میشود.
- اگر تصمیم گرفتید دوره آزمایشی رایگان یا قیمت افتتاحیه را در واحد نگهداری کالای بازگشت مشتری خود بگنجانید، با لغو انتخاب کادر اجازه یک دوره آزمایشی رایگان برای هر برنامه در «کنسول Google Play»، که کاربر را به دریافت یک دوره آزمایشی رایگان برای هر برنامه محدود میکند، مطمئن شوید کاربر واجدشرایط است.
وقتی کد خرید را دریافت کردید، خرید را پردازش کنید درست همانطور که با اشتراک جدید انجام میدهید. علاوهبراین، Google Play Developer API
linkedPurchaseToken را در منبع اشتراک برمیگرداند. حتماً
رمزه ارائهشده در
linkedPurchaseToken را نامعتبر کنید تا مطمئن شوید از رمزه قدیمی برای دسترسی به سرویسهایتان استفاده نمیشود.
قبلاز انقضای اشتراک - در «فروشگاه Play»
وقتی اشتراک لغو شده اما هنوز فعال است، کاربران میتوانند با کلیک کردن روی اشتراک مجدد (قبلاً بازیابی) اشتراک را در مرکز اشتراکهای Google Play بازیابی کنند. با این کار، همان اشتراک و رمز خرید حفظ میشود.
برای اطلاعات بیشتر درباره بازیابی اشتراکها، به بازیابیها مراجعه کنید.
پساز انقضای اشتراک - درونبرنامه
میتوانید با اعمال همان جریان خرید محصول درونبرنامه که برای مشترکان جدید استفاده میکنید، به مشترکان منقضیشده اجازه دهید در برنامهتان دوباره مشترک شوند. به موارد زیر توجه کنید:
- برای ارائه تخفیف به کاربران، ممکن است بخواهید شناسه محصولی با قیمتگذاری ویژه برای اشتراک خود ارائه دهید که به آن واحد SKU بازگشت نیز گفته میشود. میتوانید پیشنهاد ویژه را در برنامهتان ارائه دهید یا کاربر را از پیشنهاد ویژه در خارج از برنامه، مثلاً در ایمیل، مطلع کنید.
- برای شروع اشتراک بازگشت مشتری، جریان خرید را در برنامه Android خود بااستفاده از «کتابخانه خدمات صورتحساب Google Play» راهاندازی کنید. این فرایند مشابه فرایند اشتراک جدید است، اما میتوانید واحد نگهداری کالا (SKU) را که برای کاربر دردسترس است تعیین کنید.
- اگر تصمیم گرفتید دوره آزمایشی رایگان یا قیمت افتتاحیه را در واحد نگهداری کالای بازگشت مشتری خود بگنجانید، با لغو انتخاب کادر اجازه یک دوره آزمایشی رایگان برای هر برنامه در «کنسول Google Play»، که کاربر را به دریافت یک دوره آزمایشی رایگان برای هر برنامه محدود میکند، مطمئن شوید که کاربر واجدشرایط است.
- اگر کاربر دوباره در همان واحد SKU مشترک شود، دیگر واجدشرایط دوره آزمایشی رایگان یا قیمت معرفی نیست. مطمئن شوید که میانای کاربر شما این را منعکس میکند.
وقتی کد خرید را دریافت کردید، خرید را پردازش کنید درست همانطور که با اشتراک جدید انجام میدهید. linkedPurchaseToken را در منبع اشتراک دریافت نخواهید کرد.
پساز انقضای اشتراک - در «فروشگاه Play»
اگر فعال باشد، کاربران میتوانند تا یک سال پساز انقضا با کلیک کردن روی اشتراک مجدد در مرکز اشتراکهای Google Play، برای همان واحد نگهداری کالا اشتراک مجدد بگیرند. این کار باعث تولید یک کد خرید و اشتراک جدید میشود.
ازسرگرفتن اشتراک بهعنوان خرید خارج از برنامه درنظر گرفته میشود، بنابراین حتماً روالهای مطلوب را برای تأیید صحیح آنها از زیرینه خود دنبال کنید.
اشتراک خود را تبلیغ کنید
میتوانید کدهای تبلیغ ویژه ایجاد کنید تا به کاربران منتخب دوره آزمایشی رایگان طولانیتری برای اشتراک موجود بدهید. برای کسب اطلاعات بیشتر، کدهای تبلیغ ویژه را ببینید.
برای دورههای آزمایشی رایگان، Google Play قبلاز شروع دوره آزمایشی رایگان، روش پرداخت معتبر کاربر را درستیسنجی میکند. برخیاز کاربران ممکن است این درستیسنجی را بهعنوان تعلیق یا کسر هزینه در روش پرداختشان ببینند. این تعلیق یا کسر هزینه موقتی است و بعداً معکوس یا مسترد میشود.
پساز پایان دوره آزمایشی، مبلغ کامل اشتراک از روش پرداخت کاربر کسر میشود.
اگر کاربری در هر زمانی درطول دوره آزمایشی رایگان اشتراک را لغو کند، اشتراک تا پایان دوره آزمایشی فعال باقی میماند و وقتی دوره آزمایشی رایگان بهپایان میرسد هزینهای از او کسر نمیشود.
بهتعویق انداختن صورتحساب برای مشترک
بااستفاده از روش subscriptionsv2.defer میتوانید دوره حق استفاده را برای اشتراک تمدید کنید. وقتی اشتراکی را که دارای برافزاها است بهتعویق میاندازید، همه موارد موجود در اشتراک به همان مدت بهتعویق میافتند. درطول دوره تعویق، کاربر با دسترسی کامل مشترک محتوای شما میشود اما هزینهای از او کسر نمیشود. تاریخ تمدید اشتراک بهروز میشود تا تاریخ جدید را منعکس کند.
برای طرحهای پیشپرداخت، میتوانید از API تعویق صدور صورتحساب برای تعویق زمان انقضا استفاده کنید.
صورتحساب معوقه به شما امکان میدهد کارهای زیر را انجام دهید:
- بهعنوان پیشنهاد ویژه، دسترسی رایگان به کاربران بدهید، مثلاً با خرید فیلم، یک هفته رایگان دریافت کنند.
- بهعنوان نشان حسن نیت، دسترسی رایگان به مشتریان بدهید.
صورتحساب میتواند به اندازه یک روز و تا یک سال بهازای هر تماس با API بهتعویق بیفتد. برای بهتعویق انداختن بیشتر صورتحساب، میتوانید قبلاز رسیدن تاریخ صورتحساب جدید دوباره با API تماس بگیرید.
بهعنوان مثال، دارسی اشتراک ماهانهای برای محتوای آنلاین برنامه «ماهیگیری فصلی» دارد. معمولاً در اولین روز هر ماه ۱.۲۵ پوند از او کسر میشود. در ماه مارس، او در یک نظرسنجی آنلاین برای ناشر برنامه شرکت کرد. ناشر با بهتعویق انداختن پرداخت بعدی تا ۱۵ مه، که شش هفته پساز تاریخ صورتحساب برنامهریزیشده قبلی او در آوریل است، به او شش هفته رایگان پاداش میدهد.
- هزینه آوریل یا ابتدای ماه مه از دارسی کسر نمیشود و همچنان به محتوا دسترسی دارد. در ۱۵ مه، هزینه اشتراک عادی ۱.۲۵ پوند برای ماه از او کسر میشود. تاریخ تمدید بعدی او اکنون ۱۵ ژوئن است.
هنگام بهتعویق انداختن، ممکن است بخواهید ازطریق ایمیل یا درون برنامه به کاربر اطلاع دهید که تاریخ صورتحسابش تغییر کرده است.
مدیریت کردن رد شدن پرداختها
اگر در تمدید اشتراک مشکل پرداخت وجود داشته باشد، Google برای مدتی بهصورت دورهای تلاش میکند اشتراک را تمدید کند و سپس آن را لغو میکند. این دوره بازیابی میتواند شامل یک دوره مهلت ارفاقی و پساز آن یک دوره توقف حساب باشد. در این مدت، Google ایمیلها و اعلانهایی برای کاربر ارسال میکند و از او میخواهد روش پرداختش را بهروز کند.
درصورت رد شدن پرداخت، اشتراک وارد مهلت ارفاقی میشود، البته اگر مهلت ارفاقی پیکربندی شده باشد. درطول مهلت ارفاقی، باید مطمئن شوید که کاربر همچنان به حق استفاده اشتراک دسترسی دارد.
پساز پایان مهلت ارفاقی، اشتراک وارد دوره تعلیق حساب میشود. درطول توقف حساب، باید مطمئن شوید که کاربر به حق استفاده اشتراک دسترسی ندارد.
در «کنسول Google Play» میتوانید طول دوره ارفاق و نگهداری حساب هر طرح پایه تمدید خودکار را مشخص کنید. مشخص کردن طولهای کمتر از مقادیر پیشفرض ممکن است تعداد اشتراکهای بازیابیشده از پرداختهای ردشده را کاهش دهد.
برای به حداکثر رساندن احتمال بازیابی اشتراک درطول رد پرداخت، میتوانید کاربرتان را از مشکل پرداخت مطلع کنید و از او بخواهید آن را برطرف کند.
میتوانید این کار را خودتان انجام دهید، همانطور که در بخشهای دوره مهلت و تعلیق حساب توضیح داده شده است، یا میتوانید «میانای برنامهسازی کاربردی پیامرسانی درونبرنامهای» را پیادهسازی کنید، که در آن Google پیامی را به کاربران در برنامه شما نشان میدهد.
وقتی مشکل پرداخت وجود داشته باشد، Google Play میتواند اعلانی به کاربران شما نمایش دهد. برای تسهیل این امر، میتوانید از ویژگی پیامرسانی درونبرنامهای برای اطلاعرسانی به آنها درباره پرداختهای معلقه استفاده کنید. اگر پیامرسانی درونبرنامهای را فعال کرده باشید، پیام مربوط به مشکلات پرداخت درطول مهلت ارفاقی و دوره توقف حساب روزی یکبار نشان داده میشود. این کار به کاربران فرصت میدهد بدون ترک کردن برنامه، پرداختشان را اصلاح کنند. برای اطلاعات بیشتر، پیامرسانی درونبرنامهای را ببینید.
پیامرسانی درونبرنامهای
اگر پیامرسانی درونبرنامهای را با
InAppMessageCategoryId.TRANSACTIONAL فعال کرده باشید،
وقتی مشکل پرداخت یا افزایش قیمت اختیاری معوقه وجود داشته باشد،
Google Play پیامی به کاربران نشان میدهد.
توصیه میکنیم هر زمان که کاربر برنامه را باز میکند، این «میانای برنامهسازی کاربردی» را فراخوانی کنید تا مشخص شود پیام باید نشان داده شود یا نه.
اگر کاربر اشتراک خود را باموفقیت بازیابی کرد یا افزایش قیمت را تأیید کرد،
کد پاسخ SUBSCRIPTION_STATUS_UPDATED
را بههمراه کد خرید دریافت خواهید کرد. سپس باید از این کد خرید برای فراخوانی
Google Play Developer API و بازآوری وضعیت اشتراک در برنامهتان استفاده کنید.
ادغام پیامرسانی درونبرنامهای
برای نمایش پیامرسانی درونبرنامهای به کاربر، از
BillingClient.showInAppMessages() استفاده کنید.
در اینجا نمونهای از راهاندازی جریان پیامرسانی درونبرنامهای آورده شده است:
کاتلین
val inAppMessageParams = InAppMessageParams.newBuilder() .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL) .build() // Note: To display the in-app message, PBL requires an activity instance that // can provide a valid window token. This token is necessary for the Play Store // to display the message overlay correctly on top of the application's window. // The passed Activity must be in a state where its window is created and // attached to the WindowManager. 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 // is recovered from a suspended state, or a user confirms a // price increase. Developers should expect the purchase // token to be returned with this response code and use // the purchase token with the Google Play Developer API. } } } )
جاوا
InAppMessageParams inAppMessageParams = InAppMessageParams.newBuilder() .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL) .build(); // Note: To display the in-app message, PBL requires an activity instance that // can provide a valid window token. This token is necessary for the Play Store // to display the message overlay correctly on top of the application's window. // The passed Activity must be in a state where its window is created and // attached to the WindowManager. 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 // is recovered from a suspended state, or a user confirms a // price increase. Developers should expect the purchase // token to be returned with this response code and use // the purchase token with the Google Play Developer API. } } });
مدیریت لغو و وضعیتهای معلقه
این بخش توضیح میدهد که چگونه اشتراکهای لغوشده یا باطلشده را مدیریت کنید، و همچنین نحوه مدیریت اشتراکهایی که درطول فرایند خرید وارد وضعیت معلقه میشوند.
لغو یا باطل کردن
میتوانید از Google Play Developer API برای لغو یا پسگرفتن اشتراک استفاده کنید. این قابلیت در کنسول Google Play نیز دردسترس است.
لغو: کاربران میتوانند اشتراک را در Google Play لغو کنند. همچنین میتوانید گزینهای برای کاربران فراهم کنید تا در برنامه یا وبسایتتان لغو کنند. برنامه شما باید این لغوها را همانطور که در لغوها توضیح داده شده است مدیریت کند.
لغو کردن: وقتی لغو میکنید، کاربر بلافاصله دسترسی به اشتراک را ازدست میدهد. این مورد میتواند درصورتی استفاده شود که، برای مثال، خطای فنیای رخ داده باشد که مانع دسترسی کاربر به محصول شما شده باشد و کاربر نخواهد به استفاده از محصول ادامه دهد. برنامه شما باید این لغوها را همانطور که در لغو مجوزها توضیح داده شده است مدیریت کند.
جدول زیر تفاوتهای بین لغو و ابطال را نشان میدهد.
| توقف تمدید | لغو دسترسی | |
| لغو کردن | بله | نه |
| لغو کردن | بله | بله |
رسیدگی به تراکنشهای معلقه اشتراک
تراکنشهای معلقه میتواند در خرید اولیه، افزودن موجودی، ارتقا یا تنزل اتفاق بیفتد. خرید اشتراک با وضعیت
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 شما ارسال میشود. در چنین مواردی، کاربر باید همچنان به محتوای اشتراک قدیمی دسترسی داشته باشد.