איך להפיק את המקסימום מהשילוב של החיוב ב-Play

1. סקירה כללית

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

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

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

דרישות מוקדמות

מה תלמדו

  • איך לנהל בצורה נכונה את מחזורי החיים של הרכישות כדי לשפר את הצמיחה באמצעות שיטות לשיפור ההמרות לרכישה ושמירה על הלקוחות
  • איך מגדירים התראות בזמן אמת למפתחים (RTDN) באמצעות Google Cloud Pub/Sub, ואיך אפשר להשתמש בהן כדי להטמיע קמפיינים לשחזור לקוחות ואסטרטגיות אחרות לניהול מחזור החיים
  • איך מגדירים מקלט בשרת הקצה העורפי כדי לטפל בהתראות בצורה מאובטחת עם מעקב מדויק והרשאות, כדי לצמצם את הסיכון להחזרים כספיים לא מכוונים או לתרמית ולשימוש לרעה
  • איך בודקים את השילוב ומבצעים סימולציה של שגיאות באמצעות Play Billing Lab כדי לשפר את חוויית המשתמש ולצמצם את עלויות הפיתוח

מה צריך בשביל להצטרף

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

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

תהליך רכישה נפוץ לרכישה חד-פעמית או למינוי כולל כמה שלבים:

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

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

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

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

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

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

3. הגדרת התראות בזמן אמת למפתחים (RTDN)

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

כדי להפעיל את RTDN, קודם צריך להגדיר את Cloud Pub/Sub באמצעות פרויקט Google Cloud Platform ‏ (GCP) משלכם, ואז להפעיל את ההתראות באפליקציה. אם אתם לא מכירים את GCP ו-Cloud Pub/Sub, כדאי לעיין במדריך למתחילים.

יצירת נושא

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

יצירת מינוי ל-Pub/Sub

כדי לקבל הודעות שפורסמו בנושא מסוים, צריך ליצור מינוי ל-Pub/Sub לאותו נושא. כדי ליצור מינוי ל-Pub/Sub:

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

הענקת זכויות פרסום בנושא

ב-Cloud Pub/Sub צריך להקצות ל-Google Play הרשאות לפרסם התראות בנושא.

  1. פותחים את מסוף Google Cloud.
  2. בוחרים את הפרויקט, מחפשים את Pub/Sub בסרגל החיפוש ועוברים לדף ההגדרות של Pub/Sub. חיפוש הדף של הגדרות Pub/Sub והתחברות אליו
  3. מחפשים את הנושא הרצוי ופותחים את הגדרת ההרשאות. פתיחת הגדרת ההרשאה
  4. לוחצים על ADD PRINCIPAL כדי להוסיף את חשבון השירות google-play-developer-notifications@system.gserviceaccount.com, ומקצים לו את התפקיד Pub/Sub Publisher. מוסיפים את חשבון השירות google-play-developer-notifications@system.gserviceaccount.com ומקצים לו את התפקיד 'פרסום הודעות ב-Pub/Sub'.
  5. לוחצים על שמירה כדי להשלים את הגדרת הנושא. לוחצים על 'שמירה' כדי להשלים את הגדרת הנושא.

הפעלת RTDN באפליקציה

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

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

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

  1. פותחים את Google Play Console.
  2. בוחרים את האפליקציה הרצויה.
  3. עוברים אל ייצור הכנסות עם Play > הגדרת מונטיזציה.
  4. גוללים לקטע התראות בזמן אמת למפתחים.
  5. מסמנים את התיבה הפעלת התראות בזמן אמת.
  6. בשדה Topic name, מזינים את שם הנושא המלא ב-Cloud Pub/Sub שהגדרתם קודם. שם הנושא צריך להיות בפורמט projects/{project_id}/topics/{topic_name}, כאשר project_id הוא המזהה הייחודי של הפרויקט ו-topic_name הוא שם הנושא שנוצר קודם.
  7. לוחצים על שליחת הודעת בדיקה כדי לשלוח הודעת בדיקה. ביצוע פרסום לבדיקה עוזר לוודא שהכול מוגדר כראוי. אם פרסום הבדיקה יצליח, תוצג הודעה על כך שפרסום הבדיקה בוצע בהצלחה. אם צירפתם מינוי לנושא הזה, אמורה להגיע אליך הודעת הבדיקה. עבור מינוי משיכה, עוברים למינוי במסוף Cloud, לוחצים על View Messages (הצגת הודעות) וממשיכים למשוך הודעות. כדי למנוע שליחה חוזרת של הודעות על ידי Cloud Pub/Sub, צריך לאשר כל הודעה שאתם מחלצים. במינוי ל-Push, בודקים אם הודעת הבדיקה נשלחת לנקודת הקצה ל-Push. קוד תגובה תקין ישמש כהודעת אישור. אם הפרסום נכשל, תוצג שגיאה. מוודאים ששם הנושא נכון ושחשבון השירות google-play-developer-notifications@system.gserviceaccount.com מוגדר עם הרשאת פרסום הודעות ב-Pub/Sub לנושא.
  8. בוחרים את סוגי ההתראות שרוצים לקבל.
  • קבלת התראות לגבי מינויים ולגבי כל הרכישות שבוטלו – קבלת התראות בזמן אמת למפתחים שקשורות למינויים ולרכישות שבוטלו. לא יתקבלו התראות על רכישות של מוצרים בחיוב חד-פעמי.
  • קבלת כל ההתראות לגבי מינויים ומוצרים בחיוב חד-פעמי – קבלת התראות על כל האירועים של מינויים ורכישות שבוטלו. בנוסף, תקבלו אירועים של רכישות חד-פעמיות של מוצרים, כמו ONE_TIME_PRODUCT_PURCHASED ו-ONE_TIME_PRODUCT_CANCELED. מידע נוסף על אירועי הרכישה האלה זמין במאמר מחזור החיים של רכישה חד-פעמית.

a266e5dec5c93cd8.png

  1. לוחצים על שמירת השינויים.

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

4. קבלת התראות

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

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

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

כל פרסום בנושא Cloud Pub/Sub מכיל שדה נתונים יחיד בקידוד base64.

{
 "message": {
   "attributes": {
     "key": "value"
   },
   "data": "eyAidmVyc2lvbiI6IHN0cmluZywgInBhY2thZ2VOYW1lIjogc3RyaW5nLCAiZXZlbnRUaW1lTWlsbGlzIjogbG9uZywgIm9uZVRpbWVQcm9kdWN0Tm90aWZpY2F0aW9uIjogT25lVGltZVByb2R1Y3ROb3RpZmljYXRpb24sICJzdWJzY3JpcHRpb25Ob3RpZmljYXRpb24iOiBTdWJzY3JpcHRpb25Ob3RpZmljYXRpb24sICJ0ZXN0Tm90aWZpY2F0aW9uIjogVGVzdE5vdGlmaWNhdGlvbiB9",
   "messageId": "136969346945"
 },
 "subscription": "projects/myproject/subscriptions/mysubscription"
}

אחרי פענוח שדה הנתונים המקודד ב-base64, ה-DeveloperNotification מכיל את השדות הבאים:

{
 "version": string,
 "packageName": string,
 "eventTimeMillis": long,
 "oneTimeProductNotification": OneTimeProductNotification,
 "subscriptionNotification": SubscriptionNotification,
 "voidedPurchaseNotification": VoidedPurchaseNotification,
 "testNotification": TestNotification
}

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

לפניכם דוגמת הקוד של NotificationReceiver לשרת הקצה העורפי המאובטח, לצורך עיבוד הודעות Pub/Sub. כדי לבצע אימות ב-Security Command Center, מגדירים את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
import java.util.Base64;
import org.json.JSONObject;

/** Real-time developer notifications receiver. */
public class NotificationReceiver {

 private NotificationReceiver() {}

 /*
  * Receive notification messages from the subscription.
  *
  * @param projectId The project ID of your Google Cloud Project.
  * @param subscriptionId The subscription ID of the subscriber to the pub/sub topic.
  */
 public static void receiveNotificationMessages(String projectId, String subscriptionId) {
   ProjectSubscriptionName subscriptionName =
       ProjectSubscriptionName.of(projectId, subscriptionId);

   try {
     Subscriber subscriber =
         Subscriber.newBuilder(subscriptionName, new NotificationMessageReceiver()).build();
     // Start the subscriber.
     subscriber.startAsync().awaitRunning();

     subscriber.awaitTerminated();
   } catch (IllegalStateException e) {
     System.out.println("Subscriber stopped: " + e);
   }
 }

 static class NotificationMessageReceiver implements MessageReceiver {

   @Override
   public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
     // Decode the data into a String from the message data field.
     String jsonString = new String(Base64.getDecoder().decode(message.getData().toStringUtf8()));
     // Parse the String into a JSON object.
     JSONObject messageJson = new JSONObject(jsonString);

     // Fetch the value for certain fields.
     String version = messageJson.getString("version");
     String packageName = messageJson.getString("packageName");
     System.out.println("version: " + version);
     System.out.println("packageName: " + packageName);

     // Validate the purchase and grant the entitlement as needed.
     // More details in the following sections.
     // ......

     // Acknowledge the message to avoid repeated delivery.
     consumer.ack();
   }
 }
}

עכשיו יש לכם מקלט התראות שמשתמש בהודעות שנשלחות לנושא Cloud Pub/Sub בשרת הקצה העורפי המאובטח. בקטעים הבאים נסקור את השיטות המומלצות לעיבוד ההודעות של RTDN בשרת הקצה העורפי.

5. צירוף מזהי משתמשים בתהליך הרכישה באפליקציה

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

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

// An activity reference from which the billing flow will be launched.
Activity activity = ...;
// A user identifier, e.g. an obfuscated user id in your system.
String obfuscatedAccountId = ...;

ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
            // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // set the offer token to specify the offer to purchase when applicable, e.g., subscription products
            // .setOfferToken(offerToken)
            .build()
    );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .setObfuscatedAccountId(obfuscatedAccountId)
    .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

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

6. אימות רכישות לפני הענקת הרשאות

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

אחרי שמשתמש רוכש מוצר בחיוב חד-פעמי, המנוי ל-Pub/Sub בשרת הקצה העורפי המאובטח יקבל הודעת Pub/Sub. צריך לבצע את הפעולות הבאות בשרת הקצה העורפי:

  1. לנתח את purchaseToken מההודעה ב-Pub/Sub. עליכם לתעד את כל הערכים של purchaseToken לכל הרכישות.
  2. מוודאים שהערך של purchaseToken ברכישה הנוכחית לא תואם לאף ערך purchaseToken קודם. הערך purchaseToken הוא ייחודי ברמת המערכת, כך שאפשר להשתמש בו בבטחה כמפתח ראשי במסד הנתונים.
  3. כדי לאמת מול Google שהרכישה חוקית, משתמשים בנקודת הקצה purchases.products:get ב-Google Play Developer API.
  1. אם הרכישה חוקית ולא הייתה בשימוש בעבר, תוכלו להעניק בבטחה את ההרשאה לפריט או למינוי באפליקציה.
  2. צריך להעניק את ההרשאה רק כשמצב הרכישה הוא PURCHASED, ולוודא שמטפלים ברכישות PENDING בצורה נכונה. מידע נוסף זמין במאמר טיפול בעסקאות בהמתנה.

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

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisherScopes;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;

/** Helper class to initialize the publisher APIs client library. */
public class AndroidPublisherHelper {
 /* Your application name */
 private static final String APPLICATION_NAME = "YourApplicationName";

 /* Load credentials from a JSON key file. Replace with the actual path to your downloaded service
  * account key file.
  */
 private static final String RESOURCES_CLIENT_SECRETS_JSON =
     "/path/to/your/service_account_key.json";

 /** Global instance of the JSON factory. */
 private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();

 /* The API client */
 private static final AndroidPublisher ANDROID_PUBLISHER = init();

 /**
  * Performs all necessary setup steps for running requests against the API.
  *
  * @return the {@link AndroidPublisher} service
  */
 private static AndroidPublisher init(){
   try {
     // Authorization.
     Credential credential =
         GoogleCredential.fromStream(
                 AndroidPublisherHelper.class.getResourceAsStream(RESOURCES_CLIENT_SECRETS_JSON))
             .createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));

     HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();

     // Set up and return API client.
     return new AndroidPublisher.Builder(httpTransport, JSON_FACTORY, credential)
         .setApplicationName(ApplicationConfig.APPLICATION_NAME)
         .build();
   } catch (GeneralSecurityException | IOException ex) {
     throw new RuntimeException("fail to initialize the publisher APIs client library", ex);
   }
 }
}

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

ב-AndroidPublisherHelper, מוסיפים את השיטה הבאה כדי לאחזר את ProductPurchase מנקודת הקצה Purchases.products:get בממשק API של Google Play למפתחים.

 /* Fetch the ProductPurchase for the one-time product purchase from
  * Purchases.products.get endpoint in the Google Play Developer API
  */
 public static ProductPurchase executeProductPurchasesGet(
     String packageName, String sku, String purchaseToken) {
   try {
     ProductPurchase productPurchase =
         ANDROID_PUBLISHER.purchases().products().get(packageName, sku, purchaseToken).execute();
     return productPurchase;
   } catch (IOException ex) {
     log.error("Exception was thrown while getting a product purchase", ex);
     // It is recommended to apply some retry mechanism, such as exponential backoff, to fetch the purchase in case of transient failures.
     return null;
   }
 }

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

 @Override
 public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
   // Decode the data into a String from the message data field.
   String jsonString = new String(Base64.getDecoder().decode(message.getData().toStringUtf8()));
   // Parse the String into a JSON object.
   JSONObject messageJson = new JSONObject(jsonString);

   // Fetch the value for certain fields.
   String version = messageJson.getString("version");
   String packageName = messageJson.getString("packageName");

   // Process notification data based on your business requirements.
   // Process oneTimeProductNotification in the message.
   JSONObject oneTimeProductNotificationJson =
       messageJson.getJSONObject("oneTimeProductNotification");
   if (oneTimeProductNotificationJson != null) {
     String purchaseToken = oneTimeProductNotificationJson.getString("purchaseToken");
     String sku = oneTimeProductNotificationJson.getString("sku");
     int notificationType = oneTimeProductNotificationJson.getInt("notificationType");

     if (notificationType == 1) {
       // ONE_TIME_PRODUCT_PURCHASED - A one-time product was successfully purchased by a user.
       // Verify that the purchaseToken value does not match any previous purchaseToken values in
       // your backend system to avoid duplicate processing.
       ......
       // Fetch the ProductPurchase from Purchases.products.get endpoint
       ProductPurchase productPurchase =
         AndroidPublisherHelper.executeProductPurchasesGet(packageName, sku, purchaseToken);
       if (productPurchase != null && productPurchase.getPurchaseState() == 0) {
         // The purchase is valid and in PURCHASED state.

         // The account Id set in the App when launching the billing flow.
         String obfuscatedExternalAccountId = productPurchase.getObfuscatedExternalAccountId();
         // Grant the entitlement to the correct account for obfuscatedExternalAccountId in your
         // system.
       ......
       }
     }
     // Process subscriptionNotification in the message.
     JSONObject subscriptionNotificationJson = messageJson.getJSONObject("subscriptionNotification");
     if (subscriptionNotificationJson != null) {
       ......
     }
     // Process other notification data in the message as needed.
     ......
   }

   // Acknowledge the message to avoid repeated delivery.
   consumer.ack();
 }

7. הודעה ל-Google על כך שהרכישה בוצעה

אחרי שמעניקים את ההרשאה, צריך להודיע ל-Google שהרכישה טופלה. לשם כך, צריך לקרוא לנקודות הקצה purchases.products:consume או purchases.products:acknowledge ב-Play Developer API משרת הקצה העורפי המאובטח כדי לצרוך מוצר שניתן לשימוש חד-פעמי או לאשר מוצר שאינו ניתן לשימוש חד-פעמי.

בקובץ AndroidPublisherHelper, מוסיפים את השיטות הבאות כדי לקרוא ל-purchases.products:consume או ל-purchases.products:acknowledge בממשק API של Google Play למפתחים.

 /* Consume the one-time product purchase by calling
  * Purchases.products.consume endpoint in the Google Play Developer API
  */
 public static void executeProductPurchasesConsume(
     String packageName, String sku, String purchaseToken) {
   try {
     ANDROID_PUBLISHER
       .purchases().products().consume(packageName, sku, purchaseToken).execute();
   } catch (IOException ex) {
     log.error("Exception was thrown while consuming a product purchase", ex);
     // It is recommended to apply some retry mechanism, such as exponential backoff, to ensure the purchase is correctly consumed in case of transient failures.
   }
 }

 /* Acknowledge the one-time product purchase by calling
  * Purchases.products.acknowledge endpoint in the Google Play Developer API
  */
 public static void executeProductPurchasesAcknowledge(
     String packageName, String sku, String purchaseToken) {
   try {
     ANDROID_PUBLISHER
       .purchases().products().acknowledge(packageName, sku, purchaseToken, new ProductPurchasesAcknowledgeRequest()).execute();
   } catch (IOException ex) {
     log.error("Exception was thrown while acknowledging a product purchase", ex);
     // It is recommended to apply some retry mechanism, such as exponential backoff, to ensure the purchase is correctly acknowledged in case of transient failures.
   }
 }

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

 @Override
 public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
   ......
       String obfuscatedExternalAccountId = productPurchase.getObfuscatedExternalAccountId();
       // Grant the entitlement to the correct account for obfuscatedExternalAccountId in your
       // system.
       ......
       // If the product is a consumable product, consume the purchase.
       AndroidPublisherHelper.executeProductPurchasesConsume(packageName, sku, purchaseToken);
       // Or if the product is a non-consumable product, acknowledge the purchase.
       // AndroidPublisherHelper.executeProductPurchasesAcknowledge(packageName, sku, purchaseToken);
  ......

 }

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

מעולה! השלמתם את השילוב עם התראות בזמן אמת למפתחים, וכך הפעלתם עיבוד רכישות מהימן, כפי שמוצג בסדנת הקוד הזו. עכשיו, כדי לוודא שהכול פועל בצורה מושלמת, נבדוק את Play Billing Lab – כלי ידידותי למשתמש שמיועד לבדוק את השילוב שלכם עם החיובים ב-Play.

8. בדיקה באמצעות Play Billing Lab

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

ב-Play Billing Lab יש תכונות בדיקה שונות שיעזרו לכם לבדוק תרחישים שונים, כולל:

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

שימוש ב-Play Billing Lab כדי לבדוק את BillingResponseCode

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

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

בדיקה באמצעות סימולטור התגובות

כשבודקים באמצעות Response Simulator, האפליקציה מתקשרת עם Play Billing Lab כדי לקבל את קוד התגובה שהגדרתם בסימולטור התגובות של Play Billing Lab.

הפעלת החיוב מבטלת את הבדיקה של ספריית החיוב ב-Play

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

<manifest ... >
  <application ... >
    ...
     <meta-data
      android:name="com.google.android.play.largest_release_audience.NONPRODUCTION"
      android:value="" />
    <meta-data
      android:name="com.google.android.play.billingclient.enableBillingOverridesTesting"
      android:value="true" />
  </application>
</manifest>

יוצרים את האפליקציה באמצעות קובץ AndroidManifest.xml המעודכן. עכשיו האפליקציה מוכנה לשימוש בסימולטור התגובות של Play Billing Lab.

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

סימולציה של שגיאות בספריית החיוב ב-Play

כדי לבדוק עם שגיאות מדומה של ספריית החיוב ב-Play, קודם צריך להגדיר את קוד התגובה באפליקציית Play Billing Lab ואז לבצע את הבדיקה באפליקציה.

הגדרת קוד תגובה

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

מרכז הבקרה של Play Billing Lab עם סימולטור התגובות

  1. לוחצים על ניהול בכרטיס של סימולטור התגובות כדי לעבור למסך של סימולטור התגובות.
  2. כשמוצגת בקשה, מאשרים לקבל התראות מ-Play Billing Lab כדי לראות את סטטוס החיבור של האפליקציה.
  3. מפעילים את המתג 'סימולציה של תגובות לספריית החיובים ב-Play', אם הוא עדיין לא מופעל.

c841baa4c96bf306.png

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

בדיקת האפליקציה

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

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

מידע נוסף על בדיקות באמצעות Play Billing Lab זמין כאן. מידע נוסף על בדיקת חיוב על רכישות באפליקציות באמצעות 'בודקי רישיונות' זמין במרכז העזרה.

9. מעולה!

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

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

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

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