יצירת עסקאות דיגיטליות שלא ניתנות לצריכה (Dialogflow)

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

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

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

הגבלות והנחיות לבדיקה

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

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

  • אוסטרליה
  • ברזיל
  • קנדה
  • אינדונזיה
  • יפן
  • מקסיקו
  • רוסיה
  • סינגפור
  • תאילנד
  • טורקיה
  • בריטניה
  • ארצות הברית

תהליך העסקה

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

  1. הגדרת לקוח API לרכישות דיגיטליות: במסגרת הפעולה נעשה שימוש ב-API לרכישות דיגיטליות כדי לתקשר עם מלאי שטחי הפרסום ב-Google Play ולבצע עסקאות. לפני שהפעולה מתבצעת, היא יוצרת לקוח JWT עם מפתח שירות כדי לתקשר עם ה-API לרכישות דיגיטליות.
  2. איסוף מידע: הפעולה אוספת מידע בסיסי על המשתמש ועל המלאי שלכם ב-Google Play כדי להתכונן לעסקה.
    1. אימות הדרישות לגבי טרנזקציות: בפעולה נעשה שימוש בכלי העזר בנושא דרישות לגבי עסקאות דיגיטליות בתחילת תהליך הרכישה, כדי לוודא שהמשתמשים יכולים לבצע עסקה.
    2. לאסוף מלאי זמין: הפעולה בודקת את המלאי שלכם ב-Google Play ומזהה אילו פריטים זמינים כרגע לרכישה.
  3. יוצרים את ההזמנה: הפעולה מציגה את המוצרים הדיגיטליים הזמינים למשתמשים כדי שהם יוכלו לבחור לקנות את המוצרים.
  4. השלמת הרכישה: בפעולה נעשה שימוש ב-API לרכישות דיגיטליות כדי לבצע רכישה בחנות Google Play לאחר שהמשתמש בחר.
  5. טיפול בתוצאה: הפעולה מקבלת קוד סטטוס של העסקה ומיידעת את המשתמש שהרכישה בוצעה בהצלחה (או שנדרשים שלבים נוספים).

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

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

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

  • דומיין אינטרנט שמאומת ב-Google Search Console. אין צורך לשייך את הדומיין לאתר אינטרנט שהושק באופן ציבורי, אנחנו רק צריכים להפנות לדומיין האינטרנט שלכם.

  • אפליקציה ל-Android עם ההרשאה com.android.vending.BILLING ב-Google Play Console. המוצרים הדיגיטליים שלכם יהיו "רכישות מתוך האפליקציה" שמשוייכו לאפליקציה הזו ב-Google Play Console.

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

    אם עדיין אין לכם אפליקציה ל-Android, פעלו לפי ההוראות לשיוך אפליקציה ל-Android.

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

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

שיוך אפליקציית Android

אם אין לכם כרגע ב-Google Play Console אפליקציה ל-Android עם הרשאת חיוב, תוכלו לבצע את הפעולות הבאות:

  1. יוצרים פרויקט חדש ב-Android Studio או בסביבת פיתוח משולבת (IDE) של Android. בוחרים אפשרויות בהנחיות להגדרת הפרויקט כדי ליצור אפליקציה בסיסית מאוד.
  2. נותנים לפרויקט שם חבילה, כמו com.mycompany.myapp. אל תשאירו את השם הזה כברירת מחדל, כי לא ניתן להעלות ל-Play Console חבילות שכוללות את com.example.
  3. פותחים את הקובץ AndroidManifest.xml של האפליקציה.
  4. מוסיפים את שורת הקוד הבאה לרכיב manifest:

    <uses-permission android:name="com.android.vending.BILLING" />

    הקובץ AndroidManifest.xml אמור להיראות כמו בלוק הקוד הבא:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="com.mycompany.myapp">
        <uses-permission android:name="com.android.vending.BILLING" />
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme" />
    </manifest>
    
  5. יוצרים את האפליקציה כ-APK חתום. ב-Android Studio, פועלים לפי השלבים הבאים:

    1. עוברים אל Build, יצירת חבילה / APK חתומה.
    2. לוחצים על הבא.
    3. בקטע Key store path (נתיב מאגר המפתח), לוחצים על יצירת חדש.
    4. ממלאים את כל השדות ולוחצים על אישור. רשמו את הסיסמה של מאגר המפתחות ואת הסיסמה של מפתח ושמרו אותן במקום בטוח, כי תשתמשו בהן בהמשך.
    5. לוחצים על הבא.
    6. בוחרים באפשרות פרסום.
    7. בוחרים באפשרות V1 (חתימת JAR).
    8. לוחצים על סיום.
    9. לאחר מספר שניות, מערכת Android Studio תיצור קובץ app-release.apk. אתר הקובץ הזה לשימוש במועד מאוחר יותר.
  6. במסוף Google Play, יוצרים אפליקציה חדשה.

  7. עוברים אל גרסאות של אפליקציות.

  8. בקטע מסלולים סגורים, עוברים אל ניהול ואז אל אלפא.

  9. לוחצים על הלחצן יצירת פריט תוכן.

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

  11. מעלים את קובץ ה-APK.

  12. לוחצים על שמירה.

יצירת המוצרים הדיגיטליים שלכם

אם אין לכם כרגע מוצרים דיגיטליים ב-Play Console, עליכם לפעול לפי השלבים הבאים:

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

דוגמאות למוצרים שאינם לצריכה ב-Google Play Console.

מכינים את פרויקט הפעולות

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

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

  1. במסוף הפעולות, פותחים את הפרויקט או יוצרים פרויקט חדש.
  2. עבור אל פריסה ולאחר מכן אל פרטי ספרייה.
  3. בקטעים מידע נוסף ועסקאות, מסמנים את התיבה כן בקטע Do your Actions use the Digital purchase API לביצוע טרנזקציות במוצרים דיגיטליים.
  4. לוחצים על שמירה.

יצירת מפתח API למוצרים דיגיטליים

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

כדי לאחזר את המפתח של חשבון השירות:

  1. בקונסולה ל-Actions, לוחצים על סמל שלוש הנקודות בפינה השמאלית העליונה ואז על Project settings.
  2. מאתרים את מזהה הפרויקט של הפעולה.
  3. לוחצים על הקישור הבא ומחליפים את "<project_id>" במזהה הפרויקט: https://console.developers.google.com/apis/credentials?project=project_id
  4. בתפריט הניווט הראשי, עוברים אל Credentials (פרטי כניסה).
  5. בדף שמופיע, לוחצים על Create credentials ואז על Service account key.
  6. עוברים אל Service Account (חשבון שירות) ולוחצים על New Service Account (חשבון שירות חדש).
  7. נותנים לחשבון השירות שם כמו digitaltransactions.
  8. לוחצים על יצירה.
  9. מגדירים את התפקיד בתור Project > Owner (פרויקט > בעלים).
  10. לוחצים על המשך.
  11. לוחצים על יצירת מפתח.
  12. בוחרים את סוג המפתח JSON.
  13. לוחצים על Create key ומורידים את המפתח של חשבון השירות בפורמט JSON.

יש לשמור את המפתח של חשבון השירות הזה במקום בטוח. המפתח הזה ישמש אתכם במילוי הבקשה כדי ליצור לקוח ל-API לרכישות דיגיטליות.

קישור למלאי Play

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

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

כדי לקשר את הדומיין באינטרנט והאפליקציה ב-Play Console לפרויקט Actions, צריך לבצע את השלבים הבאים:

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

    1. לחץ על הלחצן של נכס אינטרנט (</>).
    2. מזינים את כתובת ה-URL של דומיין האינטרנט ולוחצים על Connect (קישור).

    Google שולחת אימייל עם הוראות נוספות לאדם הפרטי שאימת את דומיין האינטרנט ב-Google Search Console. אחרי שהנמען של האימייל הזה יבצע את ההוראות האלה, האתר יופיע בקטע Brand verification (אימות המותג).

  3. לאחר שיש לפחות אתר מחובר אחד, מבצעים את השלבים הבאים כדי לחבר את האפליקציה ל-Android:

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

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

    4. מפעילים את האפשרות גישה לרכישות ב-Play.

תמונה שמוצגים בה אתר ואפליקציות שמקושרים לפרויקט Actions.

בניית תהליך הרכישה

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

1. הגדרת לקוח API לרכישות דיגיטליות

ב-webhook למילוי הזמנות של השיחה, יוצרים לקוח JWT עם מפתח JSON של חשבון השירות וההיקף https://www.googleapis.com/auth/actions.purchases.digital.

הקוד הבא של Node.js יוצר לקוח JWT עבור ה-API לרכישות דיגיטליות:

  const serviceAccount = {'my-file.json'};
  const request = require('request');
  const {google} = require('googleapis');

  const jwtClient = new google.auth.JWT(
    serviceAccount.client_email, null, serviceAccount.private_key,
    ['https://www.googleapis.com/auth/actions.purchases.digital'],
    null
  );

2. איסוף מידע

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

2. א. אימות הדרישות לגבי עסקאות

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

קוד Node.js הבא משתמש ב-DIGITAL_PURCHASE_CHECK בתחילת השיחה:

app.intent('Default Welcome Intent', async (conv, { SKU }) => {
  // Immediately invoke digital purchase check intent to confirm
  // purchase eligibility.
  conv.ask(new DigitalPurchaseCheck());
});

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

קוד Node.js הבא מטפל בתוצאת בדיקת הדרישות :

app.intent('Digital Purchase Check', async (conv) => {
  const arg = conv.arguments.get('DIGITAL_PURCHASE_CHECK_RESULT');
  if (!arg || !arg.resultType) {
    conv.close('Digital Purchase check failed. Please check logs.');
    return;
  }
  // User does not meet necessary conditions for completing a digital purchase
  if (arg.resultType === 'CANNOT_PURCHASE' || arg.resultType === 'RESULT_TYPE_UNSPECIFIED') {
    conv.close(`It looks like you aren't able to make digital purchases. Please check your Google Pay configuration and try again.`);
    return;
  }
  conv.ask('Welcome to the Digital Goods Sample. Would you like to see what I have for sale?');
});

2. ב. איסוף מלאי זמין

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

כל אחד מהמוצרים הדיגיטליים שלך מיוצג כמק"ט בפורמט JSON. הקוד הבא של Node.js מתאר את הפורמט הצפוי של כל מק"ט:

body = {
  skus: [
    skuId: {
      skuType: one of "APP" or "UNSPECIFIED"
      id: string,
      packageName: string
    }
    formattedPrice: string,
    title: string,
    description: string
  ]
}

יש לשלוח בקשת POST לנקודת הקצה https://actions.googleapis.com/v3/packages/{packageName}/skus:batchGet, שבה {packageName} הוא שם החבילה של האפליקציה ב-Google Play Console (לדוגמה, com.myapp.digitalgoods), ולעצב את התוצאה כמערך של אובייקטים של מק"ט.

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

הקוד הבא של Node.js מבקש רשימה של מוצרים זמינים מה-API של הרכישות הדיגיטליות, ויוצר את התוצאה כמערך של מק"טים:

return jwtClient.authorize((err, tokens) => {
    if (err) {
      throw new Error(`Auth error: ${err}`);
    }

    const packageName = 'com.example.projectname';

    request.post(`https://actions.googleapis.com/v3/packages/${packageName}/skus:batchGet`, {
      'auth': {
        'bearer': tokens.access_token,
      },
      'json': true,
      'body': {
        'conversationId': conversationId,
        'skuType': 'APP',
        // This request is filtered to only retrieve SKUs for the following product IDs
        'ids': ['nonconsumable.1']
      },
    }, (err, httpResponse, body) => {
      if (err) {
        throw new Error(`API request error: ${err}`);
      }
      console.log(`${httpResponse.statusCode}: ${httpResponse.statusMessage}`);
      console.log(JSON.stringify(body));
    });
  });
});

3. יצירת ההזמנה

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

קוד ה-Node.js הבא קורא מערך מלאי של אובייקטים של מק"ט ויוצר תגובה של רשימה עם פריט אחד ברשימה לכל אחד:

skus.forEach((sku) => {
  const key = `${sku.skuId.skuType},${sku.skuId.id}`
  list.items[key] = {
    title: sku.title,
    description: `${sku.description} | ${sku.formattedPrice}`,
  };
});

4. השלמת הרכישה

כדי להשלים את הרכישה, יש להשתמש ב-Intent המסייע COMPLETE_PURCHASE עם הפריט שהמשתמש בחר.

קוד Node.js הבא מטפל בבחירת המק"ט של המשתמש מתגובה לרשימה, ומבקש את ה-Intent COMPLETE_PURCHASE באמצעות המידע הזה:

app.intent('Send Purchase', (conv, params, option) => {
  let [skuType, id] = option.split(',');

  conv.ask(new CompletePurchase({
    skuId: {
      skuType: skuType,
      id: id,
      packageName: <PACKAGE_NAME>,
    },
  }));
});

5. טיפול בתוצאה

כשהרכישה מסתיימת, נוצר האירוע actions_intent_COMPLETE_PURCHASE Dialogflow (או actions.intent.COMPLETE_PURCHASE Actions SDK Intent) עם ארגומנט COMPLETE_PURCHASE_VALUE שמתאר את התוצאה. אפשר ליצור Intent שמופעל על ידי האירוע הזה, שמעבירה את התוצאה למשתמש.

יש לטפל בתוצאות הרכישה האפשריות הבאות:

  • PURCHASE_STATUS_OK: הרכישה בוצעה בהצלחה. העסקה הושלמה בשלב הזה, לכן יש לצאת מתהליך העסקה ולחזור לשיחה שלכם.
  • PURCHASE_STATUS_ALREADY_OWNED: העסקה נכשלה כי הפריט כבר בבעלות המשתמש. כדי להימנע מהשגיאה הזו, מומלץ לבדוק את הרכישות הקודמות של המשתמשים ולהתאים את הפריטים המוצגים כך שלא תהיה לו אפשרות לרכוש מחדש פריטים שכבר נמצאים בבעלותו.
  • PURCHASE_STATUS_ITEM_UNAVAILABLE: העסקה נכשלה כי הפריט המבוקש לא זמין. כדי להימנע מהשגיאה הזו, כדאי לבדוק את המק"טים הזמינים במועד קרוב יותר למועד הרכישה.
  • PURCHASE_STATUS_ITEM_CHANGE_REQUESTED: העסקה נכשלה כי המשתמש החליט לרכוש משהו אחר. יש להשיב על יצירת ההזמנה כדי שהמשתמשים יוכלו לקבל החלטה נוספת באופן מיידי.
  • PURCHASE_STATUS_USER_CANCELLED: העסקה נכשלה כי המשתמש ביטל את תהליך הרכישה. המשתמש יצא מהתהליך לפני כן, לכן כדאי לשאול אותו אם הוא רוצה לנסות שוב לבצע את העסקה או לצאת לגמרי מהעסקה.
  • PURCHASE_STATUS_ERROR: העסקה נכשלה מסיבה לא ידועה. מעדכנים את המשתמש אם העסקה נכשלה ושואלים אם הוא רוצה לנסות שוב.
  • PURCHASE_STATUS_UNSPECIFIED: העסקה נכשלה מסיבה לא ידועה, וכתוצאה מכך הסטטוס לא ידוע. כדי לטפל בסטטוס השגיאה, מודיעים למשתמש שהעסקה נכשלה ושואלים אם הוא רוצה לנסות שוב.

הקוד הבא של Node.js קורא את הארגומנט COMPLETE_PURCHASE_VALUE ומטפל בכל אחת מהתוצאות:

app.intent('Purchase Result', (conv) => {
  const arg = conv.arguments.get('COMPLETE_PURCHASE_VALUE');
  console.log('User Decision: ' + JSON.stringify(arg));
  if (!arg || !arg.purchaseStatus) {
    conv.close('Purchase failed. Please check logs.');
    return;
  }
  if (arg.purchaseStatus === 'PURCHASE_STATUS_OK') {
    conv.close(`Purchase completed! You're all set!`);
  } else if (arg.purchaseStatus === 'PURCHASE_STATUS_ALREADY_OWNED') {
    conv.close('Purchase failed. You already own this item.');
  } else if (arg.purchaseStatus === 'PURCHASE_STATUS_ITEM_UNAVAILABLE') {
    conv.close('Purchase failed. Item is not available.');
  } else if (arg.purchaseStatus === 'PURCHASE_STATUS_ITEM_CHANGE_REQUESTED') {
    // Reprompt with your item selection dialog
  }  else {
    conv.close('Purchase Failed:' + arg.purchaseStatus);
  }
});

לשקף את הרכישות של המשתמש

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

הקוד לדוגמה הבא מציג את אובייקט user של הבקשה, שכולל packageEntitlements מהרכישות הקודמות מתוך האפליקציה של החבילה com.digitalgoods.application:

  "user": {
    "userId": "xxxx",
    "locale": "en-US",
    "lastSeen": "2018-02-09T01:49:23Z",
    "packageEntitlements": [
      {
        "packageName": "com.digitalgoods.application",
        "entitlements": [
          {
            "sku": "non-consumable.1",
            "skuType": "APP"
          }
          {
            "sku": "consumable.2",
            "skuType": "APP"
          }
        ]
      },
      {
        "packageName": "com.digitalgoods.application",
        "entitlements": [
          {
            "sku": "annual.subscription",
            "skuType": "SUBSCRIPTION",
            "inAppDetails": {
              "inAppPurchaseData": {
                "autoRenewing": true,
                "purchaseState": 0,
                "productId": "annual.subscription",
                "purchaseToken": "12345",
                "developerPayload": "HSUSER_IW82",
                "packageName": "com.digitalgoods.application",
                "orderId": "GPA.233.2.32.3300783",
                "purchaseTime": 1517385876421
              },
              "inAppDataSignature": "V+Q=="
            }
          }
        ]
      }
    ]
  },
  "conversation": {
    "conversationId": "1518141160297",
    "type": "NEW"
  },
  "inputs": [
    {
      "intent": "actions.intent.MAIN",
      "rawInputs": [
        {
          "inputType": "VOICE",
          "query": "Talk to My Test App"
        }
      ]
    }
  ],
  ...
}