הטמעת שדרוג/הורדת דרגת מנוי באפליקציות מובייל

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

פיתוח ותמיכה בכל סוגי היישומים הניידים:

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

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
הטמעת שדרוג/הורדת דרגת מנוי באפליקציות מובייל
בינוני
~3-5 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    868
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1288
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

שינוי תוכנית מנוי: שדרוג והורדת דרגה ב-iOS וב-Android

שינוי תוכנית מנוי הוא אחד החלקים המסובכים ביותר ברכישות בתוך האפליקציה וב-StoreKit. אפל וגוגל מטפלות במעברים בצורה שונה. "פשוט לקנות מוצר אחר" אינו שדרוג. במשך 5 שנים, יישמנו יותר מ-30 פרויקטים מבוססי מנויים בשתי הפלטפורמות. הניסיון שלנו מראה שאינטגרציה נכונה של StoreKit 2 ו-Google Play Billing מקצרת את זמן היציאה לשוק בחצי. בלעדיה, משתמש מסיים עם שני מנויים פעילים או מפסיד עד 30% מהכסף שלו בהורדת דרגה. בשדרוג, עד 40% מהיתרה הנותרת מתאדה. בואו נראה כיצד לטפל נכון בכל התרחישים: למעלה, למטה, ומעבר צדדי.

כיצד פועלים מעברים ב-iOS וב-Android

iOS: לוגיקת מעברים ו-StoreKit 2

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

  • שדרוג מיידי (לדרגה גבוהה יותר) – המנוי החדש מופעל מיד, המשתמש מקבל זיכוי יחסי עבור התקופה הנותרת (חיסכון של עד 40%)
  • מעבר צדדי בחידוש (לדרגה דומה) – המנוי החדש מתחיל במועד החידוש הבא
  • הורדת דרגה בחידוש (לדרגה נמוכה יותר) – המנוי הנוכחי נמשך עד סוף התקופה, ואז המנוי החדש מופעל

דרגת המוצר מוגדרת ב-App Store Connect → קבוצת מנויים → סדר גרירה ושחרור של המוצרים. למעלה = הגבוה ביותר.

כדי לבצע מעבר, קרא ל-product.purchase() בדיוק כמו רכישה רגילה – StoreKit קובע את סוג המעבר אוטומטית:

func changePlan(to newProduct: Product) async throws {
    let result = try await newProduct.purchase(options: [
        .appAccountToken(userAccountToken)
    ])
    switch result {
    case .success(let verification):
        if case .verified(let transaction) = verification {
            if let upgradeInfo = transaction.subscriptionGroupID {
                await handlePlanChange(transaction: transaction)
            }
            await transaction.finish()
        }
    case .pending:
        showPendingChangeNotification()
    case .userCancelled:
        break
    }
}

לאחר הרכישה, בדוק את הזכאויות הפעילות הנוכחיות באמצעות func changePlan(to newProduct: Product) async throws { let result = try await newProduct.purchase(options: [ .appAccountToken(userAccountToken) ]) switch result { case .success(let verification): if case .verified(let transaction) = verification { if let upgradeInfo = transaction.subscriptionGroupID { await handlePlanChange(transaction: transaction) } await transaction.finish() } case .pending: showPendingChangeNotification() case .userCancelled: break } } .

Android: מצבי חלוקה פרופורציונלית וטיפול בממתינים

ב-Android, שינוי מנוי דורש ציון מפורש של Transaction.currentEntitlements ב-ProrationMode:

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        listOf(
            BillingFlowParams.ProductDetailsParams.newBuilder()
                .setProductDetails(newProductDetails)
                .setOfferToken(newOfferToken)
                .build()
        )
    )
    .setSubscriptionUpdateParams(
        BillingFlowParams.SubscriptionUpdateParams.newBuilder()
            .setOldPurchaseToken(currentPurchaseToken)
            .setSubscriptionReplacementMode(
                BillingFlowParams.SubscriptionUpdateParams.ReplacementMode.CHARGE_PRORATED_PRICE
            )
            .build()
    )
    .build()

BillingFlowParams שגוי הוא טעות נפוצה (נראית בחצי מהפרויקטים). val billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList( listOf( BillingFlowParams.ProductDetailsParams.newBuilder() .setProductDetails(newProductDetails) .setOfferToken(newOfferToken) .build() ) ) .setSubscriptionUpdateParams( BillingFlowParams.SubscriptionUpdateParams.newBuilder() .setOldPurchaseToken(currentPurchaseToken) .setSubscriptionReplacementMode( BillingFlowParams.SubscriptionUpdateParams.ReplacementMode.CHARGE_PRORATED_PRICE ) .build() ) .build() עבור הורדת דרגה גורם לחיוב מיידי במחיר החדש ללא פיצוי. עבור הורדות דרגה, השתמש תמיד ב-ReplacementMode. זה מבטיח שהדרגה החדשה מתחילה רק לאחר סיום התקופה בתשלום, ומונע אובדן למשתמש. בדוק את CHARGE_PRORATED_PRICE ואל תציג את הדרגה החדשה כפעילה עד לאישור מהשרת. הגדרה נכונה מונעת הפסדים ב-95% ממקרי הורדת הדרגה.

UI/UX של מעברים

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

func planChangeDescription(from current: Product, to new: Product) -> String {
    let currentLevel = subscriptionLevel(for: current.id)
    let newLevel = subscriptionLevel(for: new.id)
    if newLevel > currentLevel {
        return "Переход на \(new.displayName) будет активирован немедленно. Остаток текущего периода будет зачтён."
    } else if newLevel == currentLevel {
        return "Переход на \(new.displayName) произойдёт при следующем продлении."
    } else {
        return "Текущий тариф \(current.displayName) останется активным до \(currentExpirationDate). Затем начнётся \(new.displayName)."
    }
}

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

השוואת מדיניויות: iOS מול Android

תרחיש מדיניות iOS מצב החלפה ב-Android
שדרוג מיידי, זיכוי יחסי CHARGE_PRORATED_PRICE
הורדת דרגה סוף התקופה WITH_TIME_PRORATION
מעבר צדדי (אותה דרגה) חידוש הבא DEFERRED

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

טעויות נפוצות וכיצד להימנע מהן

טעות השלכה פתרון
שימוש ב-CHARGE_PRORATED_PRICE עבור הורדת דרגה המשתמש מפסיד עד 30% השתמש ב-WITH_TIME_PRORATION
התעלמות מסטטוס ממתין ב-Android הדרגה החדשה מופעלת לפני אישור עקוב באמצעות PurchaseUpdatedListener
חסר appAccountToken ב-iOS לא ניתן לשחזר מנוי במכשיר אחר העבר token ברכישה
סדר מוצרים שגוי בקבוצת מנויים סוג מעבר שגוי ודא גרירה ושחרור ב-App Store Connect

מדוע שדרוג מנוי דורש טיפול מיוחד?

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

כיצד להימנע משגיאות הורדת דרגה ב-Android?

עבור הורדת דרגה, השתמש תמיד ב-purchaseState == PENDING. עקוב אחר סטטוס PENDING באמצעות func planChangeDescription(from current: Product, to new: Product) -> String { let currentLevel = subscriptionLevel(for: current.id) let newLevel = subscriptionLevel(for: new.id) if newLevel > currentLevel { return "Переход на \(new.displayName) будет активирован немедленно. Остаток текущего периода будет зачтён." } else if newLevel == currentLevel { return "Переход на \(new.displayName) произойдёт при следующем продлении." } else { return "Текущий тариф \(current.displayName) останется активным до \(currentExpirationDate). Затем начнётся \(new.displayName)." } } . אחסן את מצב המעבר בשרת והודע למשתמש על השינוי המתוכנן. אנו ממליצים גם להירשם ל-התראות מפתח בזמן אמת לסנכרון סטטוס. שלבים:

  1. בבחירת הורדת דרגה, העבר appAccountToken.
  2. ספק WITH_TIME_PRORATION של המנוי הנוכחי.
  3. טפל בסטטוס PENDING ב-PurchaseUpdatedListener.
  4. לאחר אישור השרת, הפעל את הדרגה החדשה.

דוגמה מעשית: אפליקציית כושר עם 5 דרגות

אחד הפרויקטים שלנו היה אפליקציית כושר עם 5 רמות מנוי. לאחר מעבר לטיפול נכון בשדרוג/הורדת דרגה, נטישת המשתמשים ירדה ב-15%. השינוי המרכזי היה יישום מצבי חלוקה פרופורציונלית נכונים ב-Android ושדרוג מיידי עם זיכוי ב-iOS. זה שמר על עד 40% מכספי המשתמשים בשדרוגים ומנע אובדן של עד 30% בהורדות דרגה.

מה כלול וזמני הערכה

  • הגדרת דרגות מנוי ב-App Store Connect / Google Play Console
  • לוגיקת רכישה בצד הלקוח המטפלת במיידי / ממתין
  • ממשק משתמש המסביר את התנאים לכל תרחיש (למעלה/למטה/צדדי)
  • טיפול ב-WITH_TIME_PRORATION למעקב אחר הפעלת ממתינים
  • Google Play: oldPurchaseToken נכון עבור כל סוג מעבר
  • סנכרון בצד השרת באמצעות App Store Server Notifications / RTDN
  • התאמת המנוי לכללים העסקיים שלך

זמן פיתוח משוער: 3 עד 5 ימים תלוי במספר הדרגות והפלטפורמות. העלות נקבעת באופן אישי לאחר ניתוח דרישות. קבל ייעוץ – צור קשר עם המומחים שלנו כדי לדון בפרויקט שלך מקצה לקצה. הזמן ביקורת על יישום המנוי הנוכחי שלך – זה לוקח לא יותר משעה.