خرید اشتراک میتواند درطول چرخه حیات خود، بسته به عوامل زیادی ازجمله رفتار تمدید خودکار، وضعیتهای رد پرداخت، و اقدامات مدیریت توسعهدهنده، از چندین حالت مختلف عبور کند.
مدیریت چرخه حیات برای اشتراکهای تمدید خودکار
وقتی وضعیت اشتراک کاربر تغییر میکند، سرور زیرینه شما پیام
SubscriptionNotification دریافت میکند.
برای بهروزرسانی وضعیت در پسای خود،
purchases.subscriptionsv2.get
میانای برنامهسازی کاربردی را با کد خرید موجود در اعلان فراخوانی کنید. این نقطه پایانی جدیدترین وضعیت اشتراک را با ارائه یک توکن خرید ارائه میدهد و بهعنوان منبع حقیقت برای مدیریت اشتراک درنظر گرفته میشود.
ژتون خرید از زمان ثبتنام اشتراک تا ۶۰ روز پساز انقضا معتبر است. پساز این تاریخ، کد خرید دیگر برای استفاده جهت فراخوانی Google Play Developer API معتبر نیست.
خرید اشتراک تمدید خودکار جدید
وقتی کاربری اشتراکی خریداری میکند، پیام SubscriptionNotification با نوع SUBSCRIPTION_PURCHASED به کارخواه RTDN شما ارسال میشود. چه این اعلان را دریافت کنید یا خرید جدیدی را ازطریق PurchasesUpdatedListener یا واکشی دستی خریدها در روش onResume() برنامهتان در برنامه ثبت کنید، باید خرید جدید را در پسای امن خود پردازش کنید. برای انجام این کار، این مراحل را دنبال کنید:
- نقطه پایانی
purchases.subscriptionsv2.getرا پُرسمان کنید تا منبع اشتراکی را که حاوی جدیدترین وضعیت اشتراک است دریافت کنید. - مطمئن شوید که مقدار فیلد
subscriptionStateSUBSCRIPTION_STATE_ACTIVEباشد. - خرید را درستیسنجی کنید.
- به کاربر اجازه دهید به محتوا دسترسی داشته باشد. حساب کاربری مرتبط با خرید را میتوان با شیء
ExternalAccountIdentifiersاز منبع اشتراک شناسایی کرد، اگر شناسهها در زمان خرید بااستفاده ازsetObfuscatedAccountIdوsetObfuscatedProfileIdتنظیم شده باشند.
فیلد offerPhase در SubscriptionPurchaseLineItem جزئیاتی درباره فاز فعلی اشتراک، مانند دوره آزمایشی رایگان یا قیمت آغازین، ارائه میدهد.
«کتابخانه صورتحساب Play» همچنین شامل روشی برای تأیید اشتراک،
acknowledgePurchase()،
و روشی برای بررسی وضعیت تأیید،
isAcknowledged() است.
بااینحال، توصیه میکنیم برای امنیت بهتر، پردازش خرید را در پسای خود انجام دهید.
منبع اشتراک برای خریدهای جدید شبیه به مثال زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
"startTime": "2022-04-22T18:39:58.270Z",
"regionCode": "US",
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
"latestOrderId": "GPA.3333-4137-0319-36762",
"acknowledgementState": "ACKNOWLEDGEMENT_STATE_PENDING", // need to acknowledge new purchases
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": next_renewal_date,
"autoRenewingPlan": {
"autoRenewEnabled": true
},
"offerPhase": {
"freeTrial": {}
}
}
],
}
تمدید اشتراک
برای اشتراکهای غیرقسطی و تمدید خودکار، هنگام تمدید اشتراک، SUBSCRIPTION_RENEWED
اعلان ارسال میشود. برای اشتراکهای قسطی، هر بار که هزینه اشتراک در تاریخ صورتحساب کسر میشود، اعلان SUBSCRIPTION_RENEWED ارسال میشود. مطمئن شوید که کاربر همچنان واجدشرایط اشتراک است و سپس وضعیت اشتراک را با expiryTime جدید ارائهشده در منبع اشتراک که از Google Play Developer API برگردانده شده است بهروز کنید. منبع اشتراک شبیه نمونه زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
"startTime": "2022-04-22T18:39:58.270Z",
"regionCode": "US",
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
"latestOrderId": "GPA.3333-4137-0319-36762",
"acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": next_renewal_date,
"autoRenewingPlan": {
"autoRenewEnabled": true
},
"offerPhase": {
"basePrice": {}
}
}
]
}
نیازی نیست تمدید اشتراک را تأیید کنید.
دوره مهلت
اگر مشکلی در پرداخت برای تمدید اشتراک وجود داشته باشد، Google به کاربر اطلاع میدهد و بهطور دورهای تلاش میکند اشتراک را برای مدتی قبلاز انقضای اشتراک تمدید کند. این دوره بازیابی میتواند شامل مهلت ارفاقی و بهدنبال آن دوره توقف حساب باشد. درطول مهلت ارفاقی، کاربر باید همچنان به حق استفاده اشتراک خود دسترسی داشته باشد.
روش
queryPurchasesAsync()
همچنان خریدهایی را که در مهلت ارفاقی هستند برمیگرداند. اگر برنامه شما
صرفاً به queryPurchasesAsync متکی است تا بررسی کند که آیا کاربر واجدشرایط
اشتراک است یا نه، دراینصورت برنامه شما باید بهطور خودکار مهلتهای ارفاقی را مدیریت کند، زیرا
این اشتراکها ازطریق «کتابخانه خدمات صورتحساب Play» بهعنوان فعال نشان داده میشوند.
همگامسازی وضعیت اشتراک با پسین به شما امکان میدهد از رد شدن پرداختها بیشتر مطلع شوید و هنگام تلاش برای کاهش ریزش ناخواسته، اطلاعات زمینهای بیشتری به شما میدهد. به پیامهای
SubscriptionNotification
با نوع SUBSCRIPTION_IN_GRACE_PERIOD گوش دهید تا وقتی کاربر وارد
مهلت ارفاقی میشود مطلع شوید. وقتی کاربر در مهلت ارفاقی است، منبع
اشتراک
حاوی autoRenewEnabled = true است. Google Play مقدار expiryTime را بهطور پویا تمدید میکند تا زمانی که مهلت ارفاقی منقضی شود، زیرا حق استفاده باید تا زمانی که کاربر لغو کند یا مهلت ارفاقی به حداکثر طول خود برسد، ادامه یابد. مقدار فیلد subscriptionState درطول این دوره
SUBSCRIPTION_STATE_IN_GRACE_PERIOD است. منبع اشتراک شبیه به
مثال زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_IN_GRACE_PERIOD",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": timestamp_in_future,
"autoRenewingPlan": {
"autoRenewEnabled": true
}
}
],
}
Play به کاربرانی که در مهلت ارفاقی هستند اطلاع میدهد که پرداختشان رد شده است و از آنها میخواهد مشکلات روش پرداختشان را در فروشگاه Play برطرف کنند. وقتی کاربر وارد مهلت ارفاقی میشود، باید او را تشویق کنید تا روش پرداختش را اصلاح کند تا درصورت غیرارادی بودن مشکل، برطرف شود. روش ساده برای انجام این کار استفاده از میانای برنامهسازی کاربردی پیامرسانی درونبرنامه است. اگر این API را وقتی کاربر برنامهتان را باز میکند فراخوانی کنید، پیام Play در یک نوار موقت به کاربر نشان داده میشود و به او اطلاع میدهد که پرداختش رد شده است. این پیام همچنین حاوی پیوند عمیقی است که کاربر را به Google Play هدایت میکند تا روش پرداختش را اصلاح کند.
بهمحض اینکه کاربر روش پرداخت خود را اصلاح کند، اشتراک با تاریخ تمدید اصلی خود تمدید میشود و میتوانید تمدید را همانطور که در تمدیدها توضیح داده شده است، انجام دهید.
اگر کاربر روش پرداخت خود را درطول مهلت ارفاقی اصلاح نکند، اشتراک وارد توقف حساب میشود و کاربر حق مالکیت را ازدست میدهد.
دسترسی و بازیابی مهلت ارفاقی
شکل ۲ جدول زمانی اشتراکی را نشان میدهد که وارد مهلت ارفاقی میشود و سپس وقتی کاربر روش پرداختش را اصلاح میکند، اشتراک بازیابی میشود. پساز پایان دوره ارفاقی، کاربر باید مزایای اشتراک را ازدست بدهد و حسابش تعلیق شود.
مهم است که نکات زیر را بهخاطر داشته باشید:
- درطول مهلت ارفاقی، کاربر باید همچنان به مزایای اشتراک دسترسی داشته باشد.
- وقتی اشتراکی درطول مهلت ارفاقی بازیابی میشود، تاریخ تمدید بازنشانی نمیشود.
- اگر مهلت ارفاقی را تغییر دهید، کاربرانی که درحالحاضر در مهلت ارفاقی هستند تحت تأثیر قرار نخواهند گرفت. تمدیدهای اشتراکی که پساز تغییر وارد مهلت ارفاقی میشوند، مهلت ارفاقی جدید را نشان خواهند داد. برای مثال، اگر مهلت ارفاقی را از ۷ روز به ۱۴ روز تغییر دهید، کاربرانی که پساز این تغییر وارد مهلت ارفاقی میشوند، مهلت ارفاقی جدید ۱۴ روزه خواهند داشت.
- اشتراک در حالت فعال باقی میماند و تا زمانی که مهلت ارفاقی بیصدا بهپایان نرسد، RTDN مهلت ارفاقی دریافت نخواهید کرد
مهلت ارفاقی بیصدا
میتوانید مهلت ارفاقی را ۰ روز تنظیم کنید، اما Play حداقل ۱ روز صبر میکند تا
زمان کافی برای تلاش مجدد برای پرداخت وجود داشته باشد. این دوره ارفاقی بیصدا یک
شبکه ایمنی برای پردازش پرداخت ارائه میدهد. درطول این دوره ۲۴ ساعته، اشتراک در وضعیت ACTIVE باقی میماند.
بهترین راه برای اینکه از تغییرات وضعیت اشتراک مطلع شوید این است که
به اعلانهای بیدرنگ توسعهدهنده (RTDN) گوش دهید و به آنها واکنش نشان دهید. برای دریافت وضعیت دقیقتر اشتراک، بهجای زمان انقضا، روش
purchases.subscriptionsv2.get()
را در زمان RTDN فراخوانی کنید.
بسته به وضعیت اشتراک پساز دوره ارفاقی بیصدای ۲۴ ساعته، باید یکی از اعلانهای زیر را دریافت کنید:
SUBSCRIPTION_ON_HOLD(درصورت فعال بودن)-
SUBSCRIPTION_CANCELED(درصورت لغو شدن) SUBSCRIPTION_EXPIRED(اگر منقضی شده باشد)SUBSCRIPTION_RENEWED(درصورت تمدید موفقیتآمیز)
همچنین میتوانید در هر زمانی پساز دوره مهلت اضافی ۲۴ ساعته بیصدا، روش subscriptionV2.get() را فراخوانی کنید تا جدیدترین وضعیت اشتراک را دریافت کنید.
تعلیق موقت حساب
اگر در تمدید اشتراک مشکل پرداخت وجود داشته باشد، پساز پایان مهلت ارفاقی، دوره توقف حساب شروع میشود. وقتی اشتراکی وارد وضعیت تعلیق حساب میشود، باید دسترسی به حق اشتراک را مسدود کنید.
درطول تعلیق حساب، باید همچنان به رسیدگی به هرگونه لغو، بازیابی، یا خرید مجدد اشتراکهایتان درصورت نیاز ادامه دهید، زیرا ممکن است کاربر این تغییرات را درحالیکه اشتراک در حالت تعلیق است انجام دهد.
«اعلانهای بیدرنگ حذف» زمانی که کاربر وارد دوره توقف حساب میشود به شما اطلاع میدهند تا بتوانید در اسرع وقت به او اطلاع دهید که چرا دسترسیاش به اشتراک تعلیق شده است. یک راه ساده برای انجام این کار استفاده از میانای برنامهسازی کاربردی پیامرسانی درونبرنامه است. فراخوانی این میانای برنامهسازی کاربردی هنگام باز کردن برنامه توسط کاربر، پیامی را در نوار توضیحات موقت به کاربر نشان میدهد و به او اطلاع میدهد که پرداختش رد شده است. این پیام همچنین شامل پیوند عمیقی است که کاربر میتواند ازطریق آن روش پرداختش را در Google Play اصلاح کند.
اگر کاربران شما بتوانند به محتوای اشتراک خارج از برنامه شما دسترسی داشته باشند، ممکن است متوجه شوند که دسترسی خود را در سطوح مختلف ازدست دادهاند. شاید بخواهید اعلان لحظهای یا ایمیلی برای کاربر ارسال کنید تا به او اطلاع دهید که اشتراکش بهدلیل رد شدن پرداخت دیگر فعال نیست.
اشتراک درطول دوره تعلیق حساب ازطریق روش
queryPurchasesAsync()
برگردانده نمیشود، بنابراین اگر برنامه شما برای نمایش خریدهای موجود به این روش متکی است، باید بهطور پیشفرض از تعلیق حساب پشتیبانی کنید.
با اعلانهای بیدرنگ توسعهدهنده، وقتی اشتراکی وارد وضعیت تعلیق حساب میشود، پیام SubscriptionNotification با نوع SUBSCRIPTION_ON_HOLD دریافت میکنید. روش
purchases.subscriptionsv2.get
را از سرور زیرینه امن خود فراخوانی کنید تا اطلاعات اشتراک جدید را بازیابی کنید. درطول توقف حساب، فیلد expiryTime منبع اشتراک
روی مُهر زمان گذشته تنظیم میشود و فیلد subscriptionState روی
SUBSCRIPTION_STATE_ON_HOLD تنظیم میشود:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_ON_HOLD",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": timestamp_in_past,
...
}
],
}
برای بازیابی دسترسی، کاربران باید روش پرداختشان را اصلاح کنند. Play کاربران را از رد شدن پرداختشان در حساب تعلیقشده مطلع میکند و شما نیز باید آنها را تشویق کنید روش پرداختشان را اصلاح کنند.
پساز اینکه کاربر روش پرداخت خود را اصلاح کرد، اشتراک به حالت فعال بازمیگردد و شما باید دسترسی به محتوای مشترکشده را بازیابی کنید. در این حالت،
ژتون خرید همان ژتونی است که قبلاز شروع تعلیق حساب وجود داشت، زیرا
همان خرید درحال بازیابی است و شما RTDN با نوع
SUBSCRIPTION_RECOVERED دریافت میکنید.
برای اشتراکهای قسطی، رد شدن و بازیابی پرداختها میتواند برای هر تلاش پرداخت انفرادی رخ دهد.
پساز بازیابی، «کتابخانه خدمات صورتحساب Play» اشتراک را دوباره ازطریق روش queryPurchasesAsync() برمیگرداند. اگر از این روش برای تعیین اینکه آیا کاربر واجدشرایط اشتراک است یا نه استفاده میکنید، برنامه شما باید بهطور خودکار ازسرگیری اشتراک پساز تعلیق حساب را مدیریت کند.
به پیام
SubscriptionNotification
با نوع SUBSCRIPTION_RECOVERED گوش دهید تا وقتی اشتراکی
بازیابی میشود و کاربر باید دوباره دسترسی پیدا کند، مطلع شوید. اگر پساز دریافت این اعلان، برای اشتراک پُرسمان کنید، فیلد expiryTime روی مُهر زمان آینده تنظیم میشود و فیلد subscriptionState دوباره روی SUBSCRIPTION_STATE_ACTIVE تنظیم میشود:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": next_renewal_date,
...
}
],
}
اگر کاربر روش پرداخت خود را قبلاز پایان دوره تعلیق حساب اصلاح نکند،
بهجای آن یک RTDN با نوع SUBSCRIPTION_CANCELED دریافت میکنید. برای
دستورالعملهای مربوط به رسیدگی به لغو، لغوها را ببینید. وقتی
اشتراکی را که به این روش لغو شده است جستجو میکنید، فیلد
expiryTime برگرداندهشده روی مُهر زمان گذشته تنظیم میشود:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": timestamp_in_past,
...
}
],
}
بلافاصله پساز اینکه درطول تعلیق حساب از لغو مطلع شدید،
یک RTDN با نوع SUBSCRIPTION_EXPIRED نیز دریافت خواهید کرد زیرا کاربر
دیگر حق استفاده پولی ندارد و اشتراک با لغو ریزش کرده است.
میتوانید این انقضا را مثل همیشه مدیریت کنید.
کاربر میتواند با خرید مجدد همان طرح اشتراک یا هر طرح دیگری که ازطریق برنامه درطول دوره تعلیق حساب از خرید اصلیاش ارائه میدهید، دوباره دسترسی پیدا کند. در این حالت، یک کد خرید جدید صادر میشود و مقدار جدید بهعنوان بخشی از رویداد SUBSCRIPTION_PURCHASED که نشاندهنده این نمونه جدید است برگردانده میشود.
دسترسی به تعلیق حساب و بازیابی
شکل ۳ خط زمانی اشتراکی را نشان میدهد که وارد توقف حساب میشود و سپس وقتی کاربر روش پرداختش را اصلاح میکند، بازیابی میشود.
مشابه مثال قبلی، «شکل ۴» جدول زمانی اشتراکی را نشان میدهد که ابتدا وارد دوره مهلت میشود و سپس وارد حالت تعلیق حساب میشود و درنهایت درحالیکه در حالت تعلیق است، بازیابی میشود.
مهم است که نکات زیر را بهخاطر داشته باشید:
- قبلاز اینکه اشتراک وارد حالت تعلیق حساب شود، Google Play تلاشهای بیشتری برای کسر هزینه از روش پرداخت تا ۴۸ ساعت انجام میدهد. کاربر درطول این دوره مزایای اشتراک را حفظ میکند. پساز سپری شدن این دوره تلاش مجدد، اشتراک وارد تعلیق حساب میشود و کاربر باید دسترسی به مزایای اشتراک را ازدست بدهد.
- اشتراک مستقیماً وارد حالت توقف حساب میشود وقتی اشتراک از حالت توقف موقت با روش پرداخت ناموفق ازسر گرفته شود.
- وقتی اشتراکی از توقف حساب بازیابی میشود، تاریخ تمدید بازنشانی میشود.
انقضا
پساز انقضای اشتراک، کاربر باید دسترسی به اشتراک را ازدست بدهد. در این صورت، پیام SubscriptionNotification با نوع SUBSCRIPTION_EXPIRED ارسال میشود. وقتی این اعلان را دریافت کردید، Google Play Developer API را پُرسمان کنید تا جدیدترین منبع اشتراک را دریافت کنید.
پساز اینکه تأیید کردید subscriptionState SUBSCRIPTION_STATE_EXPIRED است،
حق استفاده را بردارید و وضعیت خرید را بهعنوان نامعتبر در
بخش پشتی خود ثبت کنید. منبع اشتراک شبیه مثال زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": expiration_time_in_past,
...
}
],
}
لغو
کاربر میتواند اشتراک را بهصورت داوطلبانه از مرکز اشتراکهای Play لغو کند
یا اگر پساز قرار گرفتن در وضعیت توقف حساب بهبود نیابد، اشتراک او بهطور خودکار لغو میشود. توسعهدهندگان همچنین میتوانند بااستفاده از
purchases.subscriptionsv2.cancel
لغو را راهاندازی کنند.
وقتی اشتراکی لغو میشود، کاربر تا پایان چرخه صورتحساب فعلی دسترسی به محتوا را حفظ میکند. وقتی چرخه صورتحساب تمام میشود، دسترسی باید
لغو شود.
لغو اشتراک تمدید خودکار غیرقسطی باعث راهاندازی اعلان
SUBSCRIPTION_CANCELED میشود. وقتی
این اعلان را دریافت میکنید، منبع
اشتراک
برگرداندهشده از Google Play Developer API دارای فیلد subscriptionState
تنظیمشده روی SUBSCRIPTION_STATE_CANCELED است و فیلد expiryTime حاوی
تاریخی است که کاربر باید دسترسی به اشتراک را ازدست بدهد. اگر آن تاریخ در گذشته باشد، کاربر باید بلافاصله حق مالکیت را ازدست بدهد. برای مثال، این اتفاق زمانی میافتد که کاربر اشتراکی را درحین تعلیق حساب بهدلیل رد شدن پرداخت لغو کند.
منبع اشتراک برای خرید لغوشده شبیه به نمونه زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": expiration_time,
...
}
],
}
برای اشتراکهای قسطی، درصورت لغو ازسوی کاربر درحالیکه پرداختها برای دوره تعهد باقی مانده باشد، SUBSCRIPTION_CANCELLATION_SCHEDULED
اعلان ارسال میشود. لغو اشتراک درحال انتظار است و در پایان دوره تعهد فعلی اعمال میشود. وقتی این اعلان را دریافت میکنید، منبع اشتراک برگشتی از «میانای برنامهسازی کاربردی توسعهدهندگان Google Play» فیلد subscriptionState را روی SUBSCRIPTION_STATE_ACTIVE تنظیم کرده است زیرا اشتراک قسطی تا پایان دوره تعهد همچنان فعال است.
اما شیء pendingCancellation خالی وجود دارد.
اعلان SUBSCRIPTION_CANCELED ارسال میشود و بهدنبال آن
SUBSCRIPTION_EXPIRED در پایان دوره تعهد ارسال میشود.
منبع اشتراک برای خرید اشتراک قسطی که درانتظار لغو است شبیه به نمونه زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
...
"lineItems": [
{
"productId": "sub_plan01",
"expiryTime": expiration_time,
"autoRenewingPlan": {
"autoRenewEnabled": true,
"recurringPrice": {
"currencyCode": "USD",
"units": "1",
"nanos": 990000000
},
"installmentDetails": {
"initialCommittedPaymentsCount": 6,
"remainingCommittedPaymentsCount": 5,
"pendingCancellation": {}
...
}
}
}
],
}
میتوانید به فیلد canceledStateContext در منبع اشتراک نگاه کنید تا
دلیل لغو اشتراک را متوجه شوید (برای مثال، اینکه اشتراک توسط کاربر، سیستم، یا شما لغو شده است یا نه). اگر اشتراک توسط کاربر لغو شده باشد، میتوانید به فیلد userInitiatedCancellation نگاه کنید تا متوجه شوید چرا کاربر اشتراک را لغو کرده است. این کار میتواند به اطلاعرسانی درباره استراتژیهای
ارتباطی کمک کند.
وقتی اشتراکی لغو میشود اما هنوز منقضی نشده است، همچنان از
queryPurchasesAsync() برگردانده میشود.
شاید بخواهید پیامی در برنامهتان نمایش دهید که به کاربر اطلاع دهد اشتراکش لغو شده است و تاریخ انقضا را به او نشان دهد.
لغو کردنها
اشتراک میتواند به دلایل مختلفی لغو شود، ازجمله اینکه زیرساخت شما اشتراک را بااستفاده از purchases.subscriptionsv2.revoke لغو کند یا خرید مسترد شود. در این شرایط، فوراً حق استفاده کاربر را لغو کنید. وقتی این اتفاق میافتد، پیام SubscriptionNotification با نوع
SUBSCRIPTION_REVOKED ارسال میشود. وقتی این اعلان را دریافت میکنید، منبع اشتراک که از Google Play Developer API برگردانده شده است، فیلد subscriptionState را روی SUBSCRIPTION_STATE_EXPIRED تنظیم کرده است.
منبع اشتراک برای خرید لغوشده شبیه به نمونه زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": expiration_time,
...
}
]
}
اشتراکهای بهتعویقافتاده
دلایل مختلفی وجود دارد که ممکن است بخواهید حق مالکیت کاربر را تمدید کنید. برای مثال، ممکن است بخواهید دسترسی رایگان را بهعنوان تبلیغی ویژه به کاربران ارائه دهید، مثلاً یک هفته رایگان برای خرید فیلم ارائه دهید یا دسترسی رایگان را بهعنوان نشان دادن حسن نیت به مشتریان ارائه دهید.
میتوانید از
purchases.subscriptionsv2.defer API برای بهتعویق انداختن تاریخ صورتحساب اشتراکها (ازجمله اشتراکهای دارای برافزا) استفاده کنید. وقتی اشتراکی را با برافزاها بهتعویق میاندازید، همه موارد موجود در اشتراک برای همان مدت بهتعویق میافتند.
وقتی اشتراکی را بهتعویق میاندازید، پیام SubscriptionNotification
با نوع SUBSCRIPTION_DEFERRED ارسال میشود. درطول دوره تعویق،
کاربر با دسترسی کامل در محتوایتان مشترک میشود اما هزینهای از او کسر نمیشود. تاریخ تمدید اشتراک بهروز میشود تا تاریخ جدید را نشان دهد.
برای طرحهای پیشپرداخت، میتوانید از defer billing API برای بهتعویق انداختن زمان انقضا استفاده کنید.
منبع اشتراک برای اشتراک معوقه شبیه به مثال زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": timestamp_in_future,
...
}
],
}
اشتراکهای موقتاً متوقفشده
با فعال کردن امکان توقف موقت اشتراک برای کاربران، میتوانید ریزش داوطلبانه را کاهش دهید. وقتی ویژگی توقف موقت را فعال میکنید، کاربران میتوانند انتخاب کنند که اشتراکشان را برای مدت زمانی بین یک هفته تا سه ماه، بسته به دوره تکرار، موقتاً متوقف کنند. این کار اشتراک را موقتاً تعلیق میکند.
| تکرار اشتراک | هفتگی | ماهانه | سه ماهه | ششماهه | سالانه |
|---|---|---|---|---|---|
| طول مکثهای دردسترس* | ۱ هفته ۲ هفته ۳ هفته ۴ هفته |
۱ ماه ۲ ماه ۳ ماه |
۱ ماه ۲ ماه ۳ ماه |
۱ ماه ۲ ماه ۳ ماه |
۱ ماه ۲ ماه ۳ ماه |
توقف موقت اشتراک فقط پساز پایان دوره صورتحساب جاری اعمال میشود. وقتی اشتراک موقتاً متوقف شده است، کاربر به اشتراک دسترسی ندارد و هزینه تمدید را پرداخت نمیکند. در پایان دوره توقف، اشتراک ازسر گرفته میشود و Google تلاش میکند اشتراک را تمدید کند. اگر ازسرگیری موفقیتآمیز باشد، اشتراک دوباره فعال میشود. اگر ازسرگیری بهدلیل مشکل پرداخت ناموفق باشد، کاربر وارد وضعیت توقف حساب میشود، همانطور که در شکلهای ۵ و ۶ نشان داده شده است:
کاربر همچنین میتواند در هر زمانی درطول دوره توقف موقت، اشتراک را بهصورت دستی ازسر بگیرد، همانطور که در شکل ۶ نشان داده شده است. وقتی کاربر بهصورت دستی ازسر میگیرد، تاریخ صورتحساب به تاریخ ازسرگیری دستی تغییر میکند.
وقتی اشتراک کاربر موقتاً متوقف میشود، «کتابخانه صورتحساب Play» اشتراک را ازطریق روش queryPurchasesAsync() برنمیگرداند، مگراینکه پارامتر includeSuspendedSubscriptions در QueryPurchasesParams روی true تنظیم شده باشد. اگر اشتراک ازسر گرفته شود، روش queryPurchasesAsync() دوباره آن را برمیگرداند.
برای اطلاع از زمان توقف موقت اشتراک توسط کاربر، به RTDN گوش دهید. این اعلانها همچنین به شما امکان میدهند به کاربران خود در برنامهتان اطلاع دهید که اشتراک خود را موقتاً متوقف کردهاند و به آن دسترسی ندارند. همچنین باید راهی برای کاربر فراهم کنید تا بتواند هرزمان خواست بااستفاده از پیوند عمیق به Google Play اشتراکش را بهطور دستی ازسر بگیرد.
وقتی کاربرتان توقف موقت اشتراکش را آغاز میکند،
پیام SubscriptionNotification با نوع SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED ارسال میشود. در این زمان، کاربر باید تا تاریخ تمدید بعدی به اشتراک خود دسترسی داشته باشد و منبع اشتراک حاوی autoRenewEnabled = true باشد. مقدار فیلد subscriptionState
در این نقطه SUBSCRIPTION_STATE_ACTIVE است.
وقتی توقف موقت اعمال میشود، پیام SubscriptionNotification با نوع SUBSCRIPTION_PAUSED ارسال میشود. وقتی این اتفاق میافتد، کاربر باید دسترسی به اشتراکش را ازدست بدهد و منبع اشتراک حاوی autoRenewEnabled = true باشد و فیلد subscriptionState روی SUBSCRIPTION_STATE_PAUSED تنظیم شود. با بررسی
PausedStateContext
شیء میتوانید ببینید اشتراک چه زمانی دوباره تمدید میشود.
اگر اشتراک بهطور خودکار در پایان دوره توقف موقت ازسر گرفته شود یا اگر کاربر تصمیم بگیرد اشتراک را بهطور دستی ازسر بگیرد، پیام SubscriptionNotification با نوع SUBSCRIPTION_RECOVERED ارسال میشود.
اگر هنگام تلاش برای ازسرگیری اشتراک پساز توقف، پرداخت ناموفق باشد، پیام SubscriptionNotification با نوع SUBSCRIPTION_ON_HOLD ارسال میشود.
هر دو وضعیت باید همانطور که در تعلیق حساب شرح داده شده است مدیریت شوند.
ازسرگرفتن اشتراک
برای طرحهای پایه اشتراک با تمدید خودکار، «فروشگاه Google Play» ممکن است دکمه ازسرگرفتن اشتراک را نمایش دهد. این دکمه به کاربران امکان میدهد دوباره به اشتراک دسترسی پیدا کنند. ممکن است بهدلایل مختلفی نشان داده نشود، مثلاً وقتی اشتراکی مدتها پیش منقضی شده باشد.
اگرچه برچسب دکمه همیشه اشتراک مجدد است، عملکرد آن به وضعیت اشتراک بستگی دارد.
وقتی اشتراکی لغو شده است اما هنوز منقضی نشده است، کاربر همچنان مشترک است و مزایای اشتراک را دریافت میکند. اگر کاربر روی «ازسرگرفتن اشتراک» تکضرب بزند، لغو اشتراک بهطور مؤثری واگرد میشود و اشتراک همچنان تمدید میشود. این کنش در اسناد و میاناهای برنامهسازی کاربردی توسعهدهنده Play با عنوان بازیابی شناخته میشود.
پساز منقضی شدن اشتراک با تمدید خودکار، میتوانید به کاربران اجازه دهید همان طرح پایه اشتراک را خریداری کنند. این کنش در اسناد توسعهدهنده و میاناهای برنامهسازی کاربردی Play با عنوان ازسرگرفتن اشتراک شناخته میشود. میتوانید این گزینه را برای هر طرح پایه در کنسول Play یا بااستفاده از API پیکربندی کنید.
بازیابی قبلاز انقضا
اگر برنامه شما صرفاً به روش
queryPurchasesAsync()
برای تعیین اینکه آیا کاربر حق اشتراک دارد یا نه متکی است، دراینصورت برنامه شما
باید بهطور خودکار بازیابیها را مدیریت کند زیرا روش queryPurchasesAsync()
همچنان خریدهای لغوشده را قبلاز تاریخ انقضای آنها برمیگرداند. اشتراک بازیابیشده همچنان تمدید میشود، انگار که لغو نشده است.
اگر برنامهتان وضعیت اشتراک را با پسزمینه همگامسازی میکند، باید به پیام SubscriptionNotification با نوع SUBSCRIPTION_RESTARTED گوش دهید. پساز دریافت این RTDN،
برنامهتان میتواند به اعلان پاسخ دهد، ثبت کند که اشتراک اکنون
برای تمدید تنظیم شده است، و نمایش پیامهای بازیابی را در برنامهتان متوقف کند. منبع اشتراک شبیه به مثال زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": next_renewal_date
...
}
],
}
بازیابی اشتراک باعث ایجاد سفارش جدید نمیشود. اگر سفارش ۰٫۰۰ دلاری برای اشتراکی که کاربر قبلاً لغو کرده است میبینید، احتمالاً کاربر قبلاز منقضی شدن اشتراک دوباره ازطریق برنامه شما ثبتنام کرده است. برای اطلاعات بیشتر، به ارتقا، تنزل، و ازسر گرفتن اشتراک مراجعه کنید.
ازسرگرفتن اشتراک پساز انقضا
اگر طرح پایه تمدید خودکار بااستفاده از «کنسول Google Play» یا میانای برنامهسازی کاربردی پیکربندی شده باشد تا «ازسرگرفتن اشتراک» مجاز باشد، کاربران میتوانند اشتراک منقضیشده را در «فروشگاه Google Play» مجدداً خریداری کنند.
اینها خریدهای جدید هستند. Google Play یک کد خرید کاملاً جدید صادر میکند و
پشتیبان شما یک RTDN با نوع SUBSCRIPTION_PURCHASED دریافت میکند. وضعیت خرید
برای این نوع خرید خارج از برنامه شامل linkedPurchaseToken
مرتبط با خرید اصلی در آن مورد نمیشود، زیرا اشتراک
اصلی کاملاً منقضی شده است.
برای اطمینان از ارتباط دقیق کاربر برای اشتراکهای دوباره خریداریشده و جلوگیری از استرداد خودکار مبلغ برای خریدهای تأییدنشده، باید خرید مجدد را در سرور زیرینه خود تأیید کنید:
بااستفاده از کد خرید جدید از RTDN، با
purchases.subscriptionsv2.getتماس بگیرید. پاسخ برای این نوع خرید خارج از برنامه شامل فیلدoutOfAppPurchaseContextاست که منحصراً برای خریدهای ازسرگرفتن اشتراک تأییدنشده وجود دارد. این فیلد موارد زیر را ارائه میدهد:expiredExternalAccountIdentifiers: شیءExternalAccountIdentifiersحاوی فیلدهایobfuscatedAccountIdوobfuscatedProfileIdکه برای اشتراک منقضیشده قبلی پیکربندی شدهاند، درصورتیکه تنظیم شده باشند.-
expiredPurchaseToken: کد خرید آخرین اشتراک منقضیشده.
از یکی از این شناسهها برای جستجو و پیوند دادن خرید جدید به حساب کاربری صحیح در پسای خود استفاده کنید.
برای تأیید خرید، با
purchases.subscriptions.acknowledgeتماس بگیرید.- درصورت تمایل، میتوانید
obfuscatedAccountIdوobfuscatedProfileIdکاربر را ارسال کنید، اگر آنها را بااستفاده ازsetObfuscatedAccountIdوsetObfuscatedProfileIdدرطول جریان صورتحساب درونبرنامه پیکربندی کرده باشید.
- درصورت تمایل، میتوانید
این رویکرد سمت سرور به شما امکان میدهد خرید را ظرف سه روز از تاریخ خرید تأیید کنید، حتی اگر کاربر برنامهتان را باز نکند.
ارتقا، تنزل، و اشتراک مجدد
وقتی کاربری قبلاز منقضی شدن اشتراک از برنامه شما ارتقا میدهد، تنزل میدهد، یا پساز لغو ثبتنام میکند، اشتراک قدیمی نامعتبر میشود و اشتراک جدیدی با توکن خرید جدید ایجاد میشود.
علاوهبراین، منبع
اشتراک
برگرداندهشده از Google Play Developer API حاوی فیلد linkedPurchaseToken
است که خرید قدیمی را که کاربر از آن ارتقا داده، تنزل داده،
یا دوباره مشترک شده است نشان میدهد. میتوانید از کد خرید در آن فیلد برای جستجوی اشتراک قدیمی و شناسایی حساب کاربری موجود استفاده کنید تا بتوانید خرید جدید را با همان حساب مرتبط کنید.
وقتی کاربری قبلاز منقضی شدن اشتراکش دوباره ازطریق برنامه شما برای همان طرح پایه ثبتنام میکند، Google Play سفارشی بهمبلغ ۰٫۰۰ دلار برای خرید جدید ایجاد میکند. هنگام ثبتنام، هزینهای از کاربر کسر نمیشود، زیرا قبلاً هزینه دوره صورتحساب فعلی را پرداخت کرده است. صدور صورتحساب عادی در تاریخ تمدید اصلی ازسر گرفته میشود. سفارش ۰ دلار در مدیریت سفارش در «کنسول Play» و در گزارشهای مالی شما نشان داده میشود. این به این معنی نیست که کاربر دوره آزمایشی رایگان یا تخفیف تبلیغاتی دریافت کرده است.
قبلاز ارائه گزینههای ارتقا، تنزل، یا اشتراک مجدد به کاربر در برنامهتان، باید اشتراک موجود را تأیید کنید. اگر اشتراک موجود هنوز در انتظار تأیید باشد، هرگونه تغییر طرح یا اشتراک مجدد مسدود میشود.
اگر کاربر باموفقیت ارتقا، تنزل، یا ازسرگرفتن اشتراک را خریداری کند، این خرید جدیدی است که باید آن را تأیید کنید. روش توصیهشده برای انجام این کار استفاده از Google Play Developer API است. منبع اشتراک شبیه نمونه زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
"linkedPurchaseToken": old_purchase_token,
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": next_renewal_date,
"autoRenewingPlan": {
"autoRenewEnabled": true
}
}
],
}
قیمت تغییر میکند
برای آشنایی با نحوه تغییر قیمت اشتراک تمدیدشونده خودکار و اطلاعرسانی به کاربران در زمان مناسب، راهنمای روالهای مطلوب تغییر قیمت را ببینید.
وقتی تغییر قیمت اضافه میشود و برای هرگونه بهروزرسانی در وضعیت تغییر قیمت،
SUBSCRIPTION_PRICE_CHANGE_UPDATED RTDN را دریافت خواهید کرد. میتوانید نقطه پایانی purchases.subscriptionsv2.get را پُرسمان کنید تا منبع اشتراک را دریافت کنید که حاوی جزئیات تغییر قیمت برای هر مورد در اشتراک است.
وقتی تغییرات قیمت برای مشترکین فعلی بهصورت موافقت کردن اعمال میشود، اگر کاربر برای تأیید یا رد قیمت جدید اقدامی انجام دهد، RTDN دریافت خواهید کرد.
رسیدگی به تأیید کاربر برای تغییر قیمت با موافقت
وقتی کاربری افزایش قیمت اشتراک شما را میپذیرد، پیام
SubscriptionNotification با نوع
SUBSCRIPTION_PRICE_CHANGE_UPDATED دریافت میکنید.
رسیدگی به تمدیدها پساز اعمال تغییر قیمت
با کاهش قیمت، یا وقتی افزایش قیمت اشتراک تمدید میشود،
پیام SubscriptionNotification با نوع
SUBSCRIPTION_RENEWED دریافت خواهید کرد. این اعلان را مانند هر تمدید دیگری درنظر بگیرید.
رسیدگی به مواردی که افزایش قیمت با الزام به توافق پذیرفته نمیشود
اگر کاربری قبلاز اینکه نیاز به تمدید با قیمت بالاتر داشته باشد، افزایش قیمت اختیاری شما را نپذیرد، بهطور خودکار از اشتراک لغو میشود و پیام SubscriptionNotification با نوع SUBSCRIPTION_CANCELED دریافت میکنید. این رویداد را همانطور که در
لغوها شرح داده شده است مدیریت کنید.
کاربران همچنین میتوانند اشتراکهای خود را برای افزایش قیمت با امکان انصراف کاربر با همان سازوکار لغو کنند.
رضایت برای افزایش قیمت (فقط برای منطقه کره جنوبی قابلاعمال است)
بهدلیل مقررات جدید کره جنوبی (KR)، کاربران اشتراک در منطقه کره جنوبی باید با هرگونه افزایش قیمت که پساز پایان دوره آزمایشی رایگان یا دوره مقدماتی آنها رخ میدهد موافقت کنند.
برای کمک به شما در رعایت این مقررات، Play به کاربران ساکن منطقه کره جنوبی درباره الزامات کسب رضایت اطلاع خواهد داد و همچنین پاسخ رضایت کاربران را ذخیره خواهد کرد. اشتراک کاربرانی که قبلاز اعمال قیمت بالاتر موافقت خود را اعلام نکنند بهطور خودکار لغو میشود. علاوهبر اعلانهای ارسالشده از Play، میتوانید اعلانهای افزایش قیمت سفارشی خود را نیز به کاربران ارسال کنید و میتوانید پیوند به صفحه مدیریت خاص را در اعلانهای خود ارائه دهید.
وقتی دوره موافقت شروع شده باشد یا کاربر موافقت کرده باشد، پیام SubscriptionNotification با نوع SUBSCRIPTION_PRICE_STEP_UP_CONSENT_UPDATED دریافت خواهید کرد.
تفاوت بین افزایش قیمت تدریجی و تغییر قیمت
price step-up به افزایش قیمت اشتراک بهدلیل انتقال از یک مرحله پیشنهاد ویژه به مرحله دیگر اشاره دارد. برای مثال، اشتراکی که از دوره آزمایشی رایگان به قیمت عادی منتقل میشود. میتوانید از فیلد offerPhase در منبع اشتراک برای شناسایی فاز فعلی اشتراک استفاده کنید.
بااینحال، price change به بهروزرسانیهای قیمتی اشاره دارد که شما (توسعهدهنده) برای قیمت طرح پایه اشتراک آغاز کردهاید. برای مثال،
افزایش قیمت با الزام به توافق یا افزایش قیمت با امکان انصراف.
مدیریت چرخه حیات برای طرحهای پیشپرداخت
همانند اشتراکهای تمدید خودکار، باید طرحهای پیشپرداخت را پساز هر خرید جدید تأیید کنید. درمورد طرحهای پیشپرداخت، باید هم خرید اولیه و هم هرگونه افزایش موجودی را بهطور کامل پردازش کنید، زیرا کاربر باید هربار مراحل خرید را طی کند.
بهدلیل احتمال کوتاه بودن مدت طرح پیشپرداخت، مهم است که خرید را در اسرع وقت تأیید کنید. طرحهای پیشپرداخت با مدت یک هفته یا بیشتر باید ظرف ۳ روز تأیید شوند. طرحهای پیشپرداخت با مدت کمتر از یک هفته باید ظرف نیمی از مدت طرح تأیید شوند. برای مثال، توسعهدهندگان ۱٫۵ روز فرصت دارند تا خرید طرح پیشپرداخت سهروزه را تأیید کنند.
هرگاه اشتراک طرح پیشپرداخت خریداری شود، ازجمله هر بار افزایش موجودی، پیام SubscriptionNotification با نوع SUBSCRIPTION_PURCHASED به مشتری RTDN شما ارسال میشود. برای بررسی جدیدترین وضعیت اشتراک طرح پیشپرداخت، روش
purchases.subscriptionsv2.get
را فراخوانی کنید.
یک شناسه خرید جدید برای خریدهای افزایش موجودی صادر میشود و شما شناسه خرید قبلی را در فیلد linkedPurchaseToken بهعنوان بخشی از وضعیت خرید اشتراک جدید دریافت میکنید. رمز خرید از زمان ثبتنام اشتراک تا ۶۰ روز پساز انقضا معتبر است. پساز این تاریخ، دیگر نمیتوان از کد خرید برای فراخوانی Google Play Developer API استفاده کرد.
منبع اشتراک برای خرید طرح پیشپرداخت شبیه به مثال زیر است:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
"startTime": "2022-04-22T18:39:58.270Z",
"regionCode": "US",
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
"latestOrderId": "GPA.3333-4137-0319-36762",
"acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
"lineItems": [
{
"productId": "prepaid_plan01",
"expiryTime": expiry_date,
"prepaidPlan": {
"allowExtendAfterTime": timestamp_after_which_topups_are_allowed
}
}
]
}
میتوانید زمان پایان حق استفاده را در فیلد expiryTime ببینید. خریدهای
افزودنی زمان حق استفاده را با جمع کردن آن افزایش میدهد. یعنی اگر کاربر قبلاز پایان حق استفاده اصلیاش موجودیاش را افزایش دهد، زمان جدید به تاریخ انقضای قبلیاش اضافه میشود.
میتوانید پیامی در برنامهتان نمایش دهید که به کاربر اطلاع دهد اشتراکهای پیشپرداخت او را میتوان با افزودن موجودی تمدید کرد. برای اینکه بدانید کاربر چه زمانی میتواند
افزایش موجودی انجام دهد، فیلد allowExtendAfterTime را در منبع اشتراک
بررسی کنید.
طرحهای پیشپرداخت بهطور خودکار تمدید نمیشوند، بنابراین نمیتوان آنها را لغو کرد. اگر کاربری بخواهد طرح پیشپرداخت را لغو کند، میتواند اجازه دهد تا به تاریخ انقضایش برسد.
فیلدهای 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از نسخههای قبلی میشود.