מחזור החיים של מינוי

רכישות של מינויים יכולות לעבור כמה מצבים שונים במהלך מחזור החיים שלהן, בהתאם להרבה גורמים, כולל התנהגות החידוש האוטומטי, מצבים של דחיית תשלום ופעולות ניהול של המפתחים.

ניהול מחזור החיים של מינויים שמתחדשים אוטומטית

כשמצב המינוי של משתמש משתנה, שרת הקצה העורפי מקבל הודעה מסוג SubscriptionNotification.

subs-auto-renew-state
איור 1. מצבים במחזור החיים ואירועי מעבר לרכישות של מינויים עם חידוש אוטומטי.

כדי לעדכן את הסטטוס בקצה העורפי, קוראים ל-API‏ purchases.subscriptionsv2.get עם אסימון הרכישה שכלול בהתראה. נקודת הקצה הזו מספקת את המצב העדכני של המינוי בהינתן טוקן רכישה, והיא נחשבת למקור האמת לניהול מינויים.

אסימון הרכישה תקף ממועד ההרשמה למינוי ועד 60 יום אחרי תאריך התפוגה. אחרי התאריך הזה, אי אפשר יותר להשתמש בטוקן הרכישה כדי לבצע קריאה ל-ממשק API של Google Play למפתחים.

רכישות חדשות של מינויים שמתחדשים אוטומטית

כשמשתמש רוכש מינוי, נשלחת אל לקוח ה-RTDN שלכם הודעה מסוג SubscriptionNotification עם הערך SUBSCRIPTION_PURCHASED. בין אם קיבלתם את ההתראה הזו או רשמתם רכישה חדשה מתוך האפליקציה באמצעות PurchasesUpdatedListener או אחזור רכישות באופן ידני בשיטה onResume() של האפליקציה, עליכם לעבד את הרכישה החדשה בקצה העורפי המאובטח שלכם. לשם כך, בצע את הצעדים הבאים:

  1. שולחים שאילתה לנקודת הקצה purchases.subscriptionsv2.get כדי לקבל משאב מינוי שמכיל את מצב המינוי העדכני.
  2. מוודאים שהערך של השדה subscriptionState הוא SUBSCRIPTION_STATE_ACTIVE.
  3. מאמתים את הרכישה.
  4. נותנים למשתמש גישה לתוכן. אפשר לזהות את חשבון המשתמש שמשויך לרכישה באמצעות האובייקט 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.

סנכרון סטטוס המינוי עם ה-Backend מאפשר לכם לקבל מידע על דחיות תשלום, ונותן לכם יותר הקשר כשאתם מנסים להפחית את הנטישה הלא רצונית. האזנה להודעות מסוג SUBSCRIPTION_IN_GRACE_PERIOD של SubscriptionNotification כדי לקבל התראה כשהמשתמש נכנס לתקופת חסד. בזמן שהמשתמש נמצא בתקופת חסד, משאב המינוי מכיל את הערך 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 של הודעות בתוך האפליקציה. אם קוראים ל-API הזה כשהמשתמש פותח את האפליקציה, מוצגת לו הודעה זמנית ב-Play, שמיידעת אותו שהתשלום שלו נדחה. ההודעה הזו כוללת גם קישור עומק שמאפשר למשתמש לתקן את אמצעי התשלום שלו ב-Google Play.

ברגע שהמשתמש יתקן את אמצעי התשלום, המינוי יתחדש בתאריך החידוש המקורי, ותוכלו לטפל בחידוש כמו שמתואר בקטע חידושים.

אם המשתמש לא יתקן את אמצעי התשלום במהלך תקופת החסד, המינוי יעבור להשעיית החשבון והמשתמש יאבד את הזכאות.

גישה ושחזור בתקופת החסד

איור 2 מציג ציר זמן של מינוי שנכנס לתקופת חסד ואז חוזר לפעולה אחרי שהמשתמש מתקן את אמצעי התשלום. בתום תקופת החסד, המשתמש יאבד את ההטבות של המינוי והחשבון שלו יועבר להשהיה.

איור 2. ציר זמן של מינוי שנכנס לתקופת חסד וחוזר לפעילות לפני שהיא מסתיימת.

חשוב לזכור את הנקודות הבאות:

  • במהלך תקופת החסד, המשתמש צריך לשמור על הגישה להטבות המינוי.
  • כשמינוי מתחדש במהלך תקופת החסד, תאריך החידוש לא מתאפס.
  • אם תשנו את תקופת החסד, השינוי לא ישפיע על משתמשים שנמצאים כרגע בתקופת חסד. חידושי מינויים שיכנסו לתקופת חסד אחרי השינוי יקבלו את תקופת החסד החדשה. לדוגמה, אם משנים את תקופת החסד מ-7 ימים ל-14 ימים, משתמשים שנכנסים לתקופת החסד אחרי השינוי יקבלו את תקופת החסד החדשה של 14 ימים.
  • המינוי נשאר פעיל ולא תקבלו הודעה על תקופת חסד עד שתקופת החסד השקטה תסתיים

תקופת חסד שקטה

אפשר להגדיר תקופת חסד של 0 ימים, אבל מערכת Play תמתין לפחות יום אחד כדי לוודא שיש מספיק זמן לניסיונות חוזרים של תשלום. תקופת החסד השקטה הזו מספקת רשת ביטחון לעיבוד התשלומים. במהלך 24 השעות האלה, המינוי נשאר במצב ACTIVE.

הדרך הכי טובה להתעדכן בשינויים בסטטוס המינוי היא להאזין להתראות בזמן אמת למפתחים (RTDN) ולפעול בהתאם. כדי לקבל סטטוס מדויק יותר של המינוי, כדאי להתקשר לשיטת purchases.subscriptionsv2.get() בזמן ה-RTDN במקום במועד התפוגה.

בהתאם לסטטוס המינוי אחרי תקופת החסד השקטה של 24 שעות, תקבלו אחת מההתראות הבאות:

  • ‫SUBSCRIPTION_ON_HOLD (אם מופעל)
  • ‫SUBSCRIPTION_CANCELED (אם המינוי בוטל)
  • ‫SUBSCRIPTION_EXPIRED (אם פג התוקף)
  • ‫SUBSCRIPTION_RENEWED (אם החידוש יתבצע בהצלחה)

אפשר גם להפעיל את השיטה subscriptionV2.get() בכל שלב אחרי תקופת החסד של 24 שעות כדי לקבל את הסטטוס העדכני של המינוי.

השהיית חשבון

אם יש בעיות בתשלום על חידוש מינוי, אחרי שתקופת החסד מסתיימת, מתחילה תקופת השהיה של החשבון. כשמינוי עובר להשהיית החשבון, צריך לחסום את הגישה להרשאה של המינוי.

במהלך ההשהיה של החשבון, מומלץ להמשיך לטפל בביטולים, בשחזורים או ברכישות חוזרות של המינויים לפי הצורך, כי יכול להיות שהמשתמש יבצע את השינויים האלה בזמן שהמינוי מושהה.

התראות בזמן אמת על ניתוקים מודיעות לכם כשהמשתמש נכנס לתקופת ההשהיה של החשבון, כדי שתוכלו להודיע לו בהקדם האפשרי למה הגישה שלו למינוי הושעתה. דרך פשוטה לעשות את זה היא להשתמש ב-In-App Messaging API. אם תפעילו את ה-API הזה כשהמשתמש יפתח את האפליקציה, תוצג לו הודעה זמנית בסרגל אינטראקטיבי בתחתית המסך, שתעדכן אותו שהתשלום שלו נדחה. ההודעה כוללת גם קישור עומק שמאפשר למשתמש לתקן את אמצעי התשלום שלו ב-Google Play.

אם המשתמשים יכולים לגשת לתוכן של המינוי מחוץ לאפליקציה, הם עשויים לגלות שהם איבדו את הגישה בפלטפורמות שונות. כדאי לשלוח למשתמש התראה או אימייל כדי לעדכן אותו שהמינוי שלו כבר לא פעיל בגלל דחיית התשלום.

המינוי לא מוחזר על ידי השיטה queryPurchasesAsync() במהלך השהיית החשבון, ולכן אם האפליקציה שלכם מסתמכת על השיטה הזו כדי להציג רכישות קיימות, כדאי לתמוך בהשהיית החשבון כברירת מחדל.

באמצעות התראות בזמן אמת למפתחים, תקבלו הודעה מסוג SUBSCRIPTION_ON_HOLD עם הערך SubscriptionNotification כשמינוי עובר למצב של הקפאת החשבון. מתקשרים אל שיטת 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 שמייצג את המופע החדש הזה.

גישה לחשבון בהמתנה ושחזור החשבון

איור 3 מציג ציר זמן של מינוי שהושהה ואז חזר לפעולה אחרי שהמשתמש תיקן את אמצעי התשלום.

איור 3. ציר זמן של מינוי שהועבר להמתנה בחשבון ושוחזר לפני שהוא הסתיים.

בדומה לדוגמה הקודמת, באיור 4 מוצג ציר זמן של מינוי שנכנס לתקופת חסד לפני שהוא מושהה, ואז חוזר לפעילות בזמן ההשהיה.

איור 4. ציר זמן של מינוי שנכנס לתקופת חסד, ואז נכנס להשהיית חשבון, ולבסוף חוזר לפעילות לפני סיום השהיית החשבון.

חשוב לזכור את הנקודות הבאות:

  • לפני שהמינוי עובר להמתנה בחשבון, מערכת Google Play מנסה שוב לחייב את אמצעי התשלום במשך עד 48 שעות. במהלך התקופה הזו, המשתמש שומר על ההטבות של המינוי. אחרי שתקופת הניסיון הזו מסתיימת, המינוי עובר להשהיית החשבון והמשתמש מאבד את הגישה להטבות המינוי.
  • המינוי עובר להקפאת החשבון ישירות כשמחדשים מינוי ממצב מושהה עם אמצעי תשלום שנכשל.
  • כשמינוי חוזר לפעילות אחרי שהחשבון הושעה, תאריך החידוש מתאפס.

זמני תפוגה

כשהמינוי מסתיים, הגישה של המשתמש למינוי אמורה להיחסם. הודעה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. כשמקבלים את ההתראה הזו, השדה subscriptionState של משאב המינוי שמוחזר מ-ממשק API של Google Play למפתחים מוגדר לערך SUBSCRIPTION_STATE_CANCELED, והשדה expiryTime מכיל את התאריך שבו המשתמש יאבד את הגישה למינוי. אם התאריך הזה חלף, המשתמש יאבד את הזכאות באופן מיידי. לדוגמה, זה יכול לקרות אם משתמש מבטל מינוי בזמן שהחשבון שלו בהמתנה בגלל דחיית תשלום.

משאב המינוי של רכישה שבוטלה נראה דומה לדוגמה הבאה:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ],
}

במינויים לתשלומים, נשלחת התראה SUBSCRIPTION_CANCELLATION_SCHEDULED כשמשתמש מבטל מינוי שהתשלומים עליו עדיין לא הסתיימו במהלך תקופת ההתחייבות. הביטול בהמתנה והוא ייכנס לתוקף בסוף תקופת ההתחייבות הנוכחית. כשמקבלים את ההתראה הזו, השדה subscriptionState במשאב המינוי שמוחזר מ-ממשק API של Google Play למפתחים מוגדר לערך 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(). מומלץ להציג באפליקציה הודעה למשתמש על ביטול המינוי, כולל תאריך התפוגה.

ביטולים

יכולות להיות סיבות שונות לביטול מינוי, כולל ביטול המינוי על ידי ה-backend באמצעות purchases.subscriptionsv2.revoke או ביצוע החזר כספי על הרכישה. במצב כזה, צריך לבטל את זכאות המשתמש באופן מיידי. כשזה קורה, נשלחת הודעת SubscriptionNotification עם סוג SUBSCRIPTION_REVOKED. כשמקבלים את ההתראה הזו, הערך של השדה subscriptionState במשאב המינוי שמוחזר מ-ממשק API של Google Play למפתחים הוא SUBSCRIPTION_STATE_EXPIRED.

משאב המינוי של רכישה שבוטלה נראה דומה לדוגמה הבאה:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ]
}

מינויים שנדחו

יש מגוון סיבות שבגללן כדאי לכם להאריך את ההרשאה של משתמש. לדוגמה, יכול להיות שתרצו להציע למשתמשים גישה חינמית כקידום מכירות מיוחד, כמו שבוע חינם ברכישת סרט או גישה חינמית ללקוחות כמחווה של רצון טוב.

אפשר להשתמש ב-API‏ purchases.subscriptionsv2.defer כדי לדחות את תאריך החיוב של מינויים (כולל מינויים עם תוספים). כשדוחים מינוי עם חבילות, כל הפריטים במינוי נדחים למשך אותו פרק זמן.

כשדוחים מינוי, נשלחת הודעה מסוג SUBSCRIPTION_DEFERRED עם הערך SubscriptionNotification. במהלך תקופת הדחייה, המשתמש נרשם לתוכן שלכם עם גישה מלאה, אבל לא מחויב. תאריך חידוש המינוי מתעדכן בהתאם לתאריך החדש.

במינויים בתשלום מראש, אפשר להשתמש ב-API לדחיית החיוב כדי לדחות את מועד התפוגה.

משאב המינוי למינוי שנדחה נראה כך:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_future,
      ...
    }
  ],
}

מינויים שהושהו

כדי לצמצם את שיעור הנטישה המכוונת, אפשר לאפשר למשתמשים להשהות את המינוי שלהם. כשמפעילים את תכונת ההשהיה, המשתמשים יכולים להשהות את המינוי שלהם לתקופה של שבוע עד שלושה חודשים, בהתאם לתקופה החוזרת. הפעולה הזו תשעה את המינוי באופן זמני.

מחזור החיוב של המינוי שבועי חודשי לשלושה חודשים לשישה חודשים שנתי
משך ההשהיה האפשרי* שבוע אחד
שבועיים
3 שבועות
4 שבועות
חודש אחד
2 חודשים
3 חודשים
חודש אחד
2 חודשים
3 חודשים
חודש אחד
2 חודשים
3 חודשים
חודש אחד
2 חודשים
3 חודשים
*המכסות יכולות להשתנות בכל שלב.

ההשהיה של המינוי מתחילה רק אחרי שתקופת החיוב הנוכחית מסתיימת. בזמן שהמינוי מושהה, למשתמש אין גישה למינוי והוא לא משלם את מחיר החידוש. בסיום תקופת ההשהיה, המינוי יחודש ו-Google תנסה לחדש אותו. אם החידוש יתבצע בלי בעיות, המינוי יחזור להיות פעיל. אם החידוש נכשל בגלל בעיה בתשלום, המשתמש עובר למצב של השהיית החשבון, כמו שמוצג באיורים 5 ו-6:

איור 5. משתמש משהה את המינוי ואז מחדש אותו.
איור 6. משתמש משהה את המינוי שלו ואז מעביר את החשבון למצב של המתנה.

משתמש יכול גם לבחור להמשיך מינוי באופן ידני בכל שלב במהלך תקופת ההשהיה, כפי שמוצג באיור 6. כשמשתמש מחדש את המינוי באופן ידני, תאריך החיוב משתנה לתאריך החידוש הידני.

כשמינוי של משתמש מושהה, ספריית החיובים ב-Play לא מחזירה את המינוי דרך השיטה queryPurchasesAsync(), אלא אם הפרמטר includeSuspendedSubscriptions מוגדר כ-true ב-QueryPurchasesParams. אם המינוי מופעל מחדש, הפונקציה queryPurchasesAsync() מחזירה אותו שוב.

כדאי להאזין להודעות RTDN כדי לדעת מתי משתמש משהה את המינוי שלו. ההתראות האלה מאפשרות לכם גם להודיע למשתמשים באפליקציה שהם השהו את המינוי ואין להם גישה אליו. צריך גם לספק למשתמש דרך להפעיל מחדש את המינוי באופן ידני בכל שלב באמצעות קישור עמוק ל-Google Play.

הודעה מסוג SubscriptionNotification עם הערך SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED נשלחת כשהמשתמש מתחיל השהיה של המינוי. בשלב הזה, הגישה של המשתמש למינוי אמורה להימשך עד לתאריך החידוש הבא, ובמקור המידע של המינוי מופיע הערך autoRenewEnabled = true. הערך בשדה subscriptionState הוא SUBSCRIPTION_STATE_ACTIVE בשלב הזה.

הודעה מסוג SUBSCRIPTION_PAUSED עם סוג SubscriptionNotification נשלחת כשההשהיה נכנסת לתוקף. במקרה כזה, המשתמש אמור לאבד את הגישה למינוי שלו, ובמשאב המינוי יופיע autoRenewEnabled = true, והשדה subscriptionState יוגדר לערך SUBSCRIPTION_STATE_PAUSED. אפשר לראות מתי המינוי צפוי להתחדש שוב על ידי בדיקת האובייקט PausedStateContext.

הודעה מסוג SubscriptionNotification עם סוג SUBSCRIPTION_RECOVERED נשלחת אם המינוי מתחדש אוטומטית בסיום תקופת ההשהיה, או אם המשתמש בחר לחדש את המינוי באופן ידני.

הודעה מסוג SUBSCRIPTION_ON_HOLD עם הערך SubscriptionNotification נשלחת אם הייתה שגיאה בתשלום בזמן ניסיון לחדש את המינוי אחרי השהיה.

בשני המקרים, צריך לפעול לפי ההוראות שמתוארות במאמר בנושא השעיית חשבון.

הרשמה מחדש

במינויים בסיסיים שמתחדשים אוטומטית, יכול להיות שיוצג בחנות Google Play לחצן הרשמה מחדש. הכפתור הזה מאפשר למשתמשים לקבל שוב גישה למינוי. יכולות להיות סיבות שונות לכך שהאפשרות לא מופיעה, למשל אם תוקף המינוי פג לפני זמן רב.

איור 7. בקטע 'חשבון > מינויים' באפליקציית חנות Google Play מוצג מינוי שבוטל עם לחצן הרשמה מחדש.

למרות שהכיתוב על הלחצן הוא תמיד הרשמה מחדש, הפונקציונליות שלו תלויה במצב המינוי.

בזמן שמינוי מבוטל אבל עדיין לא פג, המשתמש עדיין מנוי ונהנה מהיתרונות של המינוי. אם המשתמש מקיש על 'חידוש המינוי', הביטול למעשה מבוטל והמינוי ממשיך להתחדש. הפעולה הזו נקראת שחזור במאמרי העזרה למפתחים ובממשקי ה-API של Play.

אחרי שמינוי שמתחדש אוטומטית פג, אתם יכולים לאפשר למשתמשים לרכוש את אותו מינוי בסיסי. הפעולה הזו נקראת הרשמה מחדש בתיעוד למפתחים ובממשקי ה-API של Play. אפשר להגדיר את האפשרות הזו לכל תוכנית בסיס ב-Play Console או באמצעות ה-API.

שחזור לפני תאריך התפוגה

אם האפליקציה שלכם מסתמכת רק על השיטה queryPurchasesAsync() כדי לקבוע אם למשתמש יש זכאות למינוי, האפליקציה צריכה לטפל בשחזורים באופן אוטומטי, כי השיטה queryPurchasesAsync() ממשיכה להחזיר רכישות שבוטלו לפני תאריכי התפוגה שלהן. מינוי ששוחזר ממשיך להתחדש כאילו הוא לא בוטל.

אם האפליקציה מסנכרנת את מצב המינוי עם שרת קצה עורפי, צריך להאזין להודעה SubscriptionNotification עם הסוג SUBSCRIPTION_RESTARTED. אחרי שמקבלים את ה-RTDN הזה, האפליקציה יכולה להגיב להתראה, לתעד שהמינוי מוגדר עכשיו לחידוש ולהפסיק להציג הודעות שחזור באפליקציה. משאב המינוי נראה בערך כמו בדוגמה הבאה:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date
      ...
    }
  ],
}

שחזור מינוי לא יוצר הזמנה חדשה. אם אתם רואים הזמנה בסך 0.00 $למינוי שהמשתמש ביטל בעבר, סביר להניח שהמשתמש נרשם מחדש דרך האפליקציה לפני שהמינוי פג. מידע נוסף זמין במאמר בנושא שדרוגים, שנמוכים וחידוש מינוי.

הרשמה מחדש אחרי שהמינוי פג

אם מינוי בסיסי שמתחדש אוטומטית מוגדר באמצעות Google Play Console או API כך שניתן להירשם מחדש, המשתמשים יכולים לרכוש מחדש מינוי שפג תוקפו ב-Google Play Store.

אלה רכישות חדשות. מערכת Google Play מנפיקה אסימון רכישה חדש לגמרי, והקצה העורפי שלכם מקבל RTDN עם סוג SUBSCRIPTION_PURCHASED. סטטוס הרכישה של סוג כזה של רכישה מחוץ לאפליקציה לא כולל linkedPurchaseToken שמשויך לרכישה המקורית במקרה הזה, כי המינוי המקורי פג לגמרי.

כדי לוודא שהמינויים שנרכשו מחדש ישויכו למשתמשים בצורה מדויקת ולמנוע החזרים כספיים אוטומטיים על רכישות שלא אושרו, אתם צריכים לאשר את הרכישה מחדש בשרת הבק-אנד:

  1. מתקשרים אל purchases.subscriptionsv2.get עם אסימון הרכישה החדש מ-RTDN. התשובה לרכישה מסוג זה מחוץ לאפליקציה כוללת את השדה outOfAppPurchaseContext, שמופיע רק ברכישות של הרשמה מחדש שלא אושרו. בשדה הזה מציינים:

    • ‫expiredExternalAccountIdentifiers: אובייקט ExternalAccountIdentifiers שמכיל את השדות obfuscatedAccountId ו-obfuscatedProfileId שהוגדרו למינוי הקודם שפג תוקפו, אם הם הוגדרו.
    • ‫expiredPurchaseToken: אסימון הרכישה של המינוי האחרון שתוקפו פג.

    אפשר להשתמש באחד מהמזהים האלה כדי לחפש את הרכישה החדשה ולקשר אותה לחשבון המשתמש הנכון בקצה העורפי.

  2. כדאי להתקשר אל purchases.subscriptions.acknowledge כדי לאשר את הרכישה.

    • אופציונלית, אתם יכולים לשלוח את obfuscatedAccountId וobfuscatedProfileId של המשתמש אם הגדרתם אותם באמצעות setObfuscatedAccountId ו-setObfuscatedProfileId במהלך רצף פעולות החיוב מתוך האפליקציה.

הגישה הזו בצד השרת מאפשרת לכם לאשר את הרכישה תוך שלושה ימים מתאריך הרכישה, גם אם המשתמש לא פותח את האפליקציה.

שדרוגים, שדרוגים לאחור וחידוש מינוי

כשמשתמש משדרג, משנמך או נרשם אחרי ביטול המינוי באפליקציה לפני שהמינוי פג, המינוי הישן הופך ללא תקף ונוצר מינוי חדש עם טוקן רכישה חדש.

בנוסף, משאב המינוי שמוחזר מ-ממשק API של Google Play למפתחים מכיל את השדה linkedPurchaseToken שמציין את הרכישה הקודמת שממנה המשתמש שדרג, הוריד את רמת המינוי או נרשם מחדש. אפשר להשתמש באסימון הרכישה בשדה הזה כדי לחפש את המינוי הישן ולזהות את חשבון המשתמש הקיים, כדי שאפשר יהיה לשייך את הרכישה החדשה לאותו חשבון.

כשמשתמש נרשם מחדש מתוך האפליקציה לאותה תוכנית בסיסית לפני שתוקף המינוי שלו פג, מערכת Google Play יוצרת הזמנה בסך 0.00 $לרכישה החדשה. המשתמש לא מחויב בזמן ההרשמה, כי הוא כבר שילם על תקופת החיוב הנוכחית. החיוב הרגיל יתחדש בתאריך החידוש המקורי. ההזמנה בסך 0.00 $מופיעה בדף ניהול הזמנות ב-Play Console ובדוחות הפיננסיים. זה לא אומר שהמשתמש קיבל תקופת ניסיון בחינם או הנחה שיווקית.

לפני שמציעים למשתמש באפליקציה אפשרויות לשדרוג, לנמוך או לחידוש המינוי, צריך לאשר את המינוי הקיים. כל שינוי בתוכנית או חידוש מינוי ייחסמו אם המינוי הקיים עדיין בהמתנה לאישור.

אם המשתמש רוכש בהצלחה שדרוג, שדרוג לאחור או מינוי מחדש, זוהי רכישה חדשה שאתם צריכים לאשר. הדרך המומלצת לעשות זאת היא באמצעות ממשק API של Google Play למפתחים. משאב המינוי אמור להיראות כך:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "linkedPurchaseToken": old_purchase_token,
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

שינויים במחירים

במדריך לשינוי מחירים אפשר לקרוא על שינוי מחירים של מינויים עם חידוש אוטומטי ועל עדכון המשתמשים כשצריך.

כשמוסיפים שינוי במחיר וכשיש עדכונים בסטטוס של השינוי במחיר, תקבלו את ה-RTDN SUBSCRIPTION_PRICE_CHANGE_UPDATED. אפשר לשלוח שאילתה לנקודת הקצה purchases.subscriptionsv2.get כדי לקבל משאב מינוי שיכיל פרטים על שינוי המחיר של כל פריט במינוי.

כששינויי מחיר מוחלים על מנויים קיימים כהסכמה, תקבלו RTDN אם המשתמש יבצע פעולה כדי לאשר או לדחות את המחיר החדש.

טיפול באישור של המשתמש לשינוי מחיר שנדרשת לגביו הסכמה

כשמשתמש מאשר את העלייה במחיר המינוי, אתם מקבלים הודעה מסוג SubscriptionNotification עם הערך SUBSCRIPTION_PRICE_CHANGE_UPDATED.

איך מטפלים בחידושים אחרי שמחילים שינוי במחיר

אם המחיר של המינוי ירד או אם המינוי יחודש במחיר גבוה יותר, תקבלו הודעה מסוג SUBSCRIPTION_RENEWED עם הערך SubscriptionNotification. התייחסו להתראה הזו כמו לכל חידוש אחר.

טיפול במקרים שבהם המשתמש לא מאשר העלאת מחיר

אם משתמש לא אישר את העלאת מחיר בכפוף להסכמה לפני שהגיע מועד החידוש במחיר הגבוה יותר, המינוי שלו יבוטל אוטומטית ותקבלו הודעת SubscriptionNotification עם סוג SUBSCRIPTION_CANCELED. מטפלים באירוע הזה כמו שמתואר בקטע ביטולים.

באותו אופן, המשתמשים יכולים לבטל את המינויים שלהם במקרה של העלאת מחיר עם אפשרות לסירוב, באותו מנגנון.

בעקבות תקנות חדשות בקוריאה הדרומית (KR), משתמשים במינוי באזור KR חייבים להביע הסכמה לכל עליית מחיר שתתרחש אחרי שתקופת הניסיון בחינם או תקופת המבצע שלהם תסתיים.

כדי לעזור לכם לעמוד בדרישות הרגולציה, מערכת Play תציג למשתמשים באזור קוריאה הדרומית הודעה על הדרישה לקבלת הסכמה, ותאחסן את תשובת המשתמשים בנוגע להסכמה. מינויים של משתמשים שלא יביעו הסכמה לפני שהמחיר הגבוה יותר ייכנס לתוקף יבוטלו באופן אוטומטי. בנוסף להתראות שנשלחות מ-Play, אתם יכולים לשלוח למשתמשים התראות מותאמות אישית על עליית מחיר, ולספק קישור לדף ניהול ספציפי בהתראות.

אחרי שתקופת ההסכמה מתחילה או שהמשתמש מספק הסכמה, תקבלו הודעה מסוג SubscriptionNotification עם הערך SUBSCRIPTION_PRICE_STEP_UP_CONSENT_UPDATED.

ההבדל בין העלאת מחיר לבין שינוי מחיר

price step-up מתייחס לעלייה במחיר המינוי, בגלל מעבר משלב אחד במבצע לשלב אחר. לדוגמה, מינוי שעובר מתקופת ניסיון בחינם למחיר רגיל. אפשר להשתמש בשדה offerPhase במשאב המינוי כדי לזהות את השלב הנוכחי של המינוי.

עם זאת, price change מתייחס לעדכוני מחירים שאתם (המפתחים) יוזמים עבור מחיר תוכנית הבסיס של מינוי. לדוגמה, העלאת מחיר בכפוף להסכמה או העלאת מחיר עם אפשרות לסירוב.

ניהול מחזור החיים של מינויים בתשלום מראש

בדומה למינויים שמתחדשים אוטומטית, צריך לאשר מינויים בתשלום מראש אחרי כל רכישה חדשה. במקרה של מינויים בתשלום מראש, אתם צריכים לעבד באופן מלא את הרכישה הראשונית ואת כל הטעינות, כי המשתמש צריך לעבור את תהליך הרכישה בכל פעם.

בגלל האפשרות לפרקי זמן קצרים של תוכניות בתשלום מראש, חשוב לאשר את הרכישה בהקדם האפשרי. צריך לאשר מינויים בתשלום מראש עם משך של שבוע אחד או יותר תוך 3 ימים. בתוכניות בתשלום מראש עם משך שימוש של פחות משבוע, צריך לאשר את התוכנית תוך מחצית ממשך השימוש. לדוגמה, למפתחים יש יום וחצי לאשר רכישה של מינוי בתשלום מראש ל-3 ימים.

איור 8. מצבים במחזור החיים ואירועי מעבר לרכישות של מינויים.

הודעה מסוג SubscriptionNotification עם הערך SUBSCRIPTION_PURCHASED נשלחת ללקוח ה-RTDN שלכם בכל פעם שנרכש מינוי לתוכנית בתשלום מראש, כולל כל טעינה. כדי לבדוק את הסטטוס העדכני של המינוי לתוכנית בתשלום מראש, מפעילים את השיטה purchases.subscriptionsv2.get.

טוקן רכישה חדש מונפק לרכישות של טעינת יתרה, ואתם מקבלים את טוקן הרכישה הקודם בשדה linkedPurchaseToken כחלק ממצב הרכישה החדש של המינוי. אסימון הרכישה תקף ממועד ההרשמה למינוי ועד 60 יום אחרי תאריך התפוגה. אחרי התאריך הזה, אי אפשר יותר להשתמש בטוקן הרכישה כדי להפעיל את ממשק API של Google Play למפתחים.

משאב המינוי לרכישה של מינוי בתשלום מראש נראה דומה לדוגמה הבאה:

{
  "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 למינויים בתשלום מראש

נוספו שדות חדשים לתמיכה במינויים בתשלום מראש, שהמשתמש מאריך אותם במקום שהם יתחדשו אוטומטית. כל השדות רלוונטיים למינויים בתשלום מראש בדיוק כמו למינויים שמתחדשים אוטומטית, למעט המקרים הבאים:

  • ‫[New field] 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 מגרסאות קודמות.