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

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

הגדרה של ספריית החיובים ב-Play

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

חיבור ל-Google Play

השלבים הראשונים בתהליך השילוב זהים לאלה שמתוארים במדריך לשילוב של חיוב ב-Google Play, אבל יש כמה שינויים כשמפעילים את BillingClient:

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

בדוגמה הבאה מוצג אתחול של BillingClient כולל השינויים האלה:

Kotlin

val purchasesUpdatedListener =
   PurchasesUpdatedListener { billingResult, purchases ->
       // Handle new Google Play purchase.
   }

val userChoiceBillingListener =
   UserChoiceBillingListener { userChoiceDetails ->
       // Handle alternative billing choice.
   }

val billingClient = BillingClient.newBuilder(context)
   .setListener(purchasesUpdatedListener)
   .enablePendingPurchases()
   .enableUserChoiceBilling(userChoiceBillingListener)
   .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // Handle new Google Play purchase.
    }
};

private UserChoiceBillingListener userChoiceBillingListener = new UserChoiceBillingListener() {
    @Override
    public void userSelectedAlternativeBilling(
        UserChoiceDetails userChoiceDetails) {
        // Handle new Google Play purchase.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .enableUserChoiceBilling(userChoiceBillingListener)
    .build();

אחרי שמפעילים את BillingClient, צריך ליצור חיבור ל-Google Play כמו שמתואר במדריך השילוב.

הצגת מוצרים זמינים

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

הפעלת תהליך החיוב לבחירת המשתמש

מפעילים את תהליך החיוב לבחירת המשתמש על ידי קריאה ל-launchBillingFlow(). התהליך הזה זהה להפעלת תהליך רכישה עם שילוב של מערכת החיוב של Google Play: אתם מספקים מופע ProductDetails ו-offerToken שמתאימים למוצר ולמבצע שהמשתמש רוצה לרכוש. אם המשתמש בוחר במערכת החיוב של Google Play, המידע הזה משמש להמשך תהליך הרכישה.

כשמפתחים קוראים ל-launchBillingFlow(), מערכת החיוב של Google Play מבצעת את הבדיקה הבאה:

  • המערכת בודקת אם במדינה של המשתמש שמוגדרת ב-Google Play יש תמיכה במערכת חיוב חלופית עם אפשרות בחירה למשתמש (כלומר, מדינה נתמכת). אם המדינה נתמכת, מערכת Google Play בודקת אם הופעלה מערכת חיוב חלופית על סמך ההגדרה של BillingClient.
    • אם הפעלתם מערכת חיוב חלופית עם אפשרויות בחירה למשתמשים, בתהליך הרכישה יוצג למשתמש ממשק חוויית משתמש עם אפשרויות בחירה למשתמשים.
    • אם לא הפעלתם חיוב חלופי עם אפשרות בחירה למשתמש, בתהליך הרכישה יוצג למשתמש הממשק הרגיל של מערכת החיוב של Google Play, בלי אפשרויות לבחירה.
  • אם המדינה שמוגדרת למשתמש ב-Google Play לא נתמכת, בתהליך הרכישה מוצג ממשק המשתמש הרגיל של מערכת החיוב של Google Play, בלי אפשרויות לבחירה.

המדינה של המשתמש ב-Play היא מדינה נתמכת

המדינה של המשתמש ב-Play היא לא מדינה נתמכת

הפונקציה enableUserChoiceBilling נקראת במהלך ההגדרה של BillingClient

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

המשתמש רואה את הממשק הרגיל של מערכת החיוב של Google Play

הפונקציה enableUserChoiceBilling לא מופעלת במהלך ההגדרה של BillingClient

המשתמש רואה את הממשק הרגיל של מערכת החיוב של Google Play

המשתמש רואה את הממשק הרגיל של מערכת החיוב של Google Play

טיפול בבחירת המשתמש

האופן שבו אתם מנהלים את המשך תהליך הרכישה תלוי בבחירה של המשתמש: מערכת החיוב של Google Play או מערכת חיוב חלופית.

כשהמשתמש בוחר מערכת חיוב חלופית

אם המשתמש בוחר במערכת החיוב החלופית, ‏ Google Play קוראת ל-UserChoiceBillingListener כדי להודיע לאפליקציה שהיא צריכה להפעיל את תהליך הרכישה במערכת החיוב החלופית. בפרט, מתבצעת קריאה ל-method‏ userSelectedAlternativeBilling().

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

הUserChoiceBillingListener צריך לבצע את הפעולות הבאות:

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

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

בדוגמה הבאה אפשר לראות איך מטמיעים את UserChoiceBillingListener:

Kotlin

private val userChoiceBillingListener =
    UserChoiceBillingListener { userChoiceDetails ->
        // Get the products being purchased by the user.
        val products = userChoiceDetails.products

        // Send external transaction token to developer backend server
        // this devBackend object is for demonstration purposes,
        // developers can implement this step however best fits their
        // app to backend communication.
        devBackend.sendExternalTransactionStarted(
            userChoiceDetails.externalTransactionToken,
            user
        )

        // Launch alternative billing
        // ...
        // The developer backend handles reporting the transaction
        // to Google Play's backend once the alternative billing
        // purchase is completed.
    }

Java

private userChoiceBillingListener userChoiceBillingListener = new UserChoiceBillingListener() {
    @Override
    public void userSelectedAlternativeBilling(
           UserChoiceDetails userChoiceDetails) {
       // Get the products being purchased by the user.
       List<Product> products =
              userChoiceDetails.getProducts();

       // Send external transaction token to developer backend server
       // this devBackend object is for demonstration purposes,
       // developers can implement this step however best fits their
       // app to backend communication.
       devBackend.sendExternalTransactionStarted(
              userChoiceDetails.getExternalTransactionToken(),
              user
       );

       // Launch alternative billing
       // ...
       // The developer backend handles reporting the transaction
       // to Google Play's backend once the alternative billing
       // purchase is completed.
    }
};

כשהמשתמש בוחר במערכת החיוב של Google Play

אם המשתמש בוחר במערכת החיוב של Google Play, הוא ממשיך ברכישה דרך Google Play.

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

טיפול בשינויים במינוי

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

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

תהליכי שדרוג ושנמוך

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

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

מינויים שנרכשו דרך מערכת חיוב חלופית

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

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

Kotlin

// The external transaction ID from the current
// alternative billing subscription.
val externalTransactionId = //... ;

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        listOf(
            BillingFlowParams.ProductDetailsParams.newBuilder()
                // Fetched using queryProductDetailsAsync.
                .setProductDetails(productDetailsNewPlan)
                // offerIdToken can be found in
                // ProductDetails=>SubscriptionOfferDetails.
                .setOfferToken(offerTokenNewPlan)
                .build()
        )
    )
    .setSubscriptionUpdateParams(
        BillingFlowParams.SubscriptionUpdateParams.newBuilder()
            .setOriginalExternalTransactionId(externalTransactionId)
            .build()
        )
    .build()

val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

// When the user selects the alternative billing flow,
// the UserChoiceBillingListener is triggered.

Java

// The external transaction ID from the current
// alternative billing subscription.
String externalTransactionId = //... ;

BillingFlowParams billingFlowParams =
    BillingFlowParams.newBuilder()
        .setProductDetailsParamsList(
            ImmutableList.of(
                ProductDetailsParams.newBuilder()
                    // Fetched using queryProductDetailsAsync.
                    .setProductDetails(productDetailsNewPlan)
                    // offerIdToken can be found in
                    // ProductDetails=>SubscriptionOfferDetails
                    .setOfferToken(offerTokenNewPlan)
                    .build()
                )
            )
        .setSubscriptionUpdateParams(
            SubscriptionUpdateParams.newBuilder()
                .setOriginalExternalTransactionId(externalTransactionId)
                .build()
            )
        .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

// When the user selects the alternative billing flow,
// the UserChoiceBillingListener is triggered.

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

מינויים שנרכשו דרך מערכת החיוב של Google Play

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

  1. מזהים את offerToken של המבצע שנבחר לתוכנית החדשה:

    Kotlin

    val offerTokenNewPlan = productDetailsNewPlan
         .getSubscriptionOfferDetails(selectedOfferIndex)
         .getOfferToken()
    

    Java

    String offerTokenNewPlan = productDetailsNewPlan
            .getSubscriptionOfferDetails(selectedOfferIndex)
            .getOfferToken();
    
  2. שולחים את הפרטים הנכונים למערכת החיוב של Google Play כדי לעבד את הרכישה החדשה, כולל טוקן הרכישה של המינוי הקיים:

    Kotlin

    val billingFlowParams =
        BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(
                listOf(
                    BillingFlowParams.ProductDetailsParams.newBuilder()
                        // Fetched using queryProductDetailsAsync
                        .setProductDetails(productDetailsNewPlan)
                        // offerIdToken can be found in
                        // ProductDetails=>SubscriptionOfferDetails.
                        .setOfferToken(offerTokenNewPlan)
                        .build()
                    )
            )
            .setSubscriptionUpdateParams(
                BillingFlowParams.SubscriptionUpdateParams.newBuilder()
                    // purchaseToken can be found in
                    // Purchase#getPurchaseToken
                    .setOldPurchaseToken(oldToken)
                    .setReplaceProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
                    .build()
            )
            .build()
    
    val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)
    

    Java

    BillingFlowParams billingFlowParams =
        BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(
                ImmutableList.of(
                    ProductDetailsParams.newBuilder()
                        // Fetched using queryProductDetailsAsync
                        .setProductDetails(productDetailsNewPlan)
                        // offerIdToken can be found in
                        // ProductDetails=>SubscriptionOfferDetails.
                        .setOfferToken(offerTokenNewPlan)
                        .build()
                )
            )
            .setSubscriptionUpdateParams(
                SubscriptionUpdateParams.newBuilder()
                    // purchaseToken can be found in
                    // Purchase#getPurchaseToken
                    .setOldPurchaseToken(oldToken)
                    .setReplaceProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
                    .build()
            )
            .build();
    
    BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
    

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

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

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

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

מינויים שנרכשו דרך מערכת חיוב חלופית

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

מינויים שנרכשו דרך מערכת החיוב של Google Play

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

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

הרשמה מחדש

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

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

בדיקת מערכת חיוב חלופית

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

השלבים הבאים

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