אם האפליקציה שלכם מופצת דרך Google Play ואתם רוצים למכור מוצרים דיגיטליים או להציע מינויים, עליכם להשתמש בחיוב דרך Google Play. מערכת החיוב ב-Google Play כוללת כלים לניהול הקטלוג, המחירים והמינויים, דוחות שימושיים ותהליך תשלום שמבוסס על חנות Play ומוכרת למשתמשים.
באפליקציות שנוצרו באמצעות פעילויות אינטרנט מהימנות ונשלחו דרך חנות Google Play, אפשר עכשיו להשתמש ב-Payment Request API וב-Digital Goods API כדי לשלב אותן עם החיוב ב-Google Play. התכונה זמינה ב-Chrome מגרסה 101 ואילך ל-Android ול-ChromeOS.
במדריך הזה תלמדו איך להוסיף תמיכה בחיוב ב-Google Play לאפליקציית ה-PWA שלכם, ואיך לארוז אותה להפצה בחנות Google Play גם ל-ChromeOS וגם ל-Play Store.
כדי להוסיף תמיכה בחיוב ב-Play לאפליקציית ה-PWA, תשתמשו בשני ממשקי API של פלטפורמת אינטרנט. Digital Goods API משמש לאיסוף פרטי מק"ט ולבדיקת רכישות והרשאות מחנות Play. Payment Request API משמש להגדרת חנות Google Play כאמצעי התשלום ולהשלמת תהליך הרכישה.
איך לייצר הכנסות מאפליקציות בחנות Play
יש שתי דרכים לייצר הכנסות מהאפליקציה באמצעות החיוב ב-Google Play בחנות Play:
- רכישות מתוך האפליקציה מאפשרות למכור מוצרים וירטואליים עמידים ומוצרי צריכה וירטואליים, כמו תכונות נוספות או הסרת מודעות.
- מינויים, שמאפשרים למשתמשים לגשת לתוכן או לשירותים באופן קבוע תמורת תשלום קבוע, כמו מינויים לחדשות או חברויות.
דרישות
כדי להגדיר חיוב ב-Google Play, צריך:
- חשבון פיתוח ב-Google Play וחשבון מוכר ב-Google Payments שמקושרים זה לזה.
- דף האפליקציה בחנות Play עם גרסה במסלול 'בדיקה של הקהל הרחב', 'בדיקה בקבוצה מוגדרת' או 'בדיקה פנימית'.
- כדי ליצור ולהגדיר את המוצרים והמינויים של האפליקציה בחנות Play.
- פרויקט שנוצר באמצעות Bubblewrap עם הגדרה תקינה של Digital Asset Links.
עדכון הפרויקט Bubblewrap
אם לא התקנתם את Bubblewrap, תצטרכו להתקין אותה. במדריך למתחילים מוסבר איך מתחילים. אם כבר התקנתם את Bubblewrap, חשוב לעדכן אותו לגרסה 1.8.2 ואילך.
גם ב-Bubblewrap התכונה הזו מוסתרת מאחורי דגל. כדי להפעיל אותו, צריך לשנות את הגדרות הפרויקט בקובץ twa-manifest.json
שנמצא ברמה הבסיסית של הפרויקט, ולהפעיל גם את alphaDependencies
וגם את התכונה playBilling
:
...,
"enableNotifications": true,
"features": {
"playBilling": {
"enabled": true
}
},
"alphaDependencies": {
"enabled": true
},
...
אחרי שמעדכנים את קובץ התצורה, מריצים את הפקודה bubblewrap update
כדי להחיל את התצורה על הפרויקט, ואז את הפקודה bubblewrap build
כדי ליצור חבילה חדשה ל-Android ולהעלות את החבילה הזו לחנות Play.
תכונת זיהוי של Digital Goods API וזמינות של חיוב ב-Google Play
נכון לעכשיו, Chrome תומך ב-Digital Goods API רק כש-PWA מופעל בתוך פעילות אינטרנט מהימנה. אפשר לבדוק אם הוא זמין על ידי בדיקה של getDigitalGoodsService
באובייקט window
:
if ('getDigitalGoodsService' in window) {
// Digital Goods API is supported!
}
יכול להיות ש-Digital Goods API יהיה זמין בכל דפדפן וישמש בחנויות שונות. כדי לבדוק אם יש תמיכה בקצה העורפי של חנות מסוימת, צריך להפעיל את getDigitalGoodsService()
ולהעביר את מזהה החנות כפרמטר. חנות Google Play מזוהה באמצעות המחרוזת https://play.google.com/billing
:
if ('getDigitalGoodsService' in window) {
// Digital Goods API is supported!
try {
const service =
await window.getDigitalGoodsService('https://play.google.com/billing');
// Google Play Billing is supported!
} catch (error) {
// Google Play Billing is not available. Use another payment flow.
return;
}
}
אחזור פרטים של מק"ט
ב-Digital Goods API יש את השיטה getDetails()
, שמאפשרת לאחזר מידע כמו שם המוצר, התיאור והכי חשוב, המחיר, מהקצה העורפי של התשלומים.
לאחר מכן תוכלו להשתמש במידע הזה בממשק המשתמש ולספק למשתמשים פרטים נוספים:
const skuDetails = await service.getDetails(['shiny_sword', 'gem']);
for (item of skuDetails) {
// Format the price according to the user locale.
const localizedPrice = new Intl.NumberFormat(
navigator.language,
{style: 'currency', currency: item.price.currency}
).format(item.price.value);
// Render the price to the UI.
renderProductDetails(
item.itemId, item.title, localizedPrice, item.description);
}
בניית תהליך הרכישה
למבנה ה-PaymentRequest יש שני פרמטרים: רשימה של אמצעי תשלום ורשימה של פרטי תשלום.
כשמשתמשים ב-Trusted Web Activity, צריך להשתמש באמצעי התשלום לחיוב ב-Google Play. לשם כך, מגדירים את https://play.google.com/billing
כמזהה ומוסיפים את המק"ט של המוצר כחבר נתונים:
async function makePurchase(service, sku) {
// Define the preferred payment method and item ID
const paymentMethods = [{
supportedMethods: "https://play.google.com/billing",
data: {
sku: sku,
}
}];
...
}
למרות שפרטי התשלום נדרשים, מערכת החיוב ב-Play תתעלם מהערכים האלה ותשתמש בערכים שהוגדרו בזמן יצירת המק"ט ב-Play Console, כך שאפשר למלא אותם בערכים מזויפים:
const paymentDetails = {
total: {
label: `Total`,
amount: {currency: `USD`, value: `0`}
}
};
const request = new PaymentRequest(paymentMethods, paymentDetails);
כדי להתחיל את תהליך התשלום, צריך להפעיל את show()
באובייקט של בקשת התשלום. אם ה-Promise יצליח, סימן שהתשלום בוצע בהצלחה. אם הוא נכשל, סביר להניח שהמשתמש ביטל את התשלום.
אם ההתחייבות תתבצע, תצטרכו לאמת את הרכישה ולאשר אותה. כדי להגן מפני הונאות, צריך להטמיע את השלב הזה באמצעות הקצה העורפי. במסמכי התיעוד של Play Billing מוסבר איך מטמיעים את האימות בקצה העורפי. אם לא תאשרו את הרכישה, אחרי שלושה ימים המשתמש יקבל החזר כספי והרכישה ב-Google Play תבוטל.
...
const request = new PaymentRequest(paymentMethods, paymentDetails);
try {
const paymentResponse = await request.show();
const {purchaseToken} = paymentResponse.details;
// Call backend to validate and acknowledge the purchase.
if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
// Optional: tell the PaymentRequest API the validation was
// successful. The user-agent may show a "payment successful"
// message to the user.
const paymentComplete = await paymentResponse.complete('success');
} else {
// Optional: tell the PaymentRequest API the validation failed. The
// user agent may show a message to the user.
const paymentComplete = await paymentResponse.complete('fail');
}
} catch(e) {
// The purchase failed, and we can handle the failure here. AbortError
// usually means a user cancellation
}
...
אפשר גם להפעיל את consume()
על purchaseToken כדי לסמן שהרכישה נוצלה ולאפשר אותה שוב.
כשמרכזים את כל הנתונים, שיטת קנייה נראית כך:
async function makePurchase(service, sku) {
// Define the preferred payment method and item ID
const paymentMethods = [{
supportedMethods: "https://play.google.com/billing",
data: {
sku: sku,
}
}];
// The "total" member of the paymentDetails is required by the Payment
// Request API, but is not used when using Google Play Billing. We can
// set it up with bogus details.
const paymentDetails = {
total: {
label: `Total`,
amount: {currency: `USD`, value: `0`}
}
};
const request = new PaymentRequest(paymentMethods, paymentDetails);
try {
const paymentResponse = await request.show();
const {purchaseToken} = paymentResponse.details;
// Call backend to validate and acknowledge the purchase.
if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
// Optional: consume the purchase, allowing the user to purchase
// the same item again.
service.consume(purchaseToken);
// Optional: tell the PaymentRequest API the validation was
// successful. The user-agent may show a "payment successful"
// message to the user.
const paymentComplete =
await paymentResponse.complete('success');
} else {
// Optional: tell the PaymentRequest API the validation failed.
// The user agent may show a message to the user.
const paymentComplete = await paymentResponse.complete('fail');
}
} catch(e) {
// The purchase failed, and we can handle the failure here.
// AbortError usually means a user cancellation
}
}
בדיקת הסטטוס של רכישות קיימות
באמצעות Digital Goods API אפשר לבדוק אם למשתמש יש הרשאות קיימות (רכישות מתוך האפליקציה שעדיין לא נוצלו או מינויים פעילים) מרכישות קודמות שכבר בוצעו, בין אם במכשיר אחר, מהתקנה קודמת, ממקוד שובר או בפעם האחרונה שהאפליקציה נפתחה.
const service =
await window.getDigitalGoodsService('https://play.google.com/billing');
...
const existingPurchases = await service.listPurchases();
for (const p of existingPurchases) {
// Update the UI with items the user is already entitled to.
console.log(`Users has entitlement for ${p.itemId}`);
}
זה גם זמן טוב לבדוק אם יש רכישות שבוצעו בעבר אבל לא אושרו. מומלץ לאשר את הרכישות בהקדם האפשרי כדי לוודא שההרשאות של המשתמשים באפליקציה משתקפות כראוי.
const service =
await window.getDigitalGoodsService("https://play.google.com/billing");
...
const existingPurchases = await service.listPurchases();
for (const p of existingPurchases) {
await verifyOrAcknowledgePurchaseOnBackend(p.purchaseToken, p.itemId);
// Update the UI with items the user is already entitled to.
console.log(`Users has entitlement for ${p.itemId}`);
}
בדיקת השילוב
במכשיר Android לצורכי פיתוח
אפשר להפעיל את Digital Goods API במכשיר Android לפיתוח לצורך בדיקה:
- מוודאים שמשתמשים ב-Android מגרסה 9 ואילך עם מצב הפיתוח מופעל.
- מתקינים את Chrome בגרסה 101 ואילך.
- כדי להפעיל את הדגלים הבאים ב-Chrome, עוברים אל
chrome://flags
ומחפשים את הדגל לפי שם:#enable-debug-for-store-billing
- מוודאים שהאתר מתארח באמצעות פרוטוקול https. שימוש ב-http יגרום ל-API להיות
undefined
במכשיר ChromeOS
ממשק Digital Goods API יהיה זמין ב-ChromeOS בגרסה יציבה החל מגרסה 89. בינתיים, אפשר לבדוק את Digital Goods API:
- מתקינים את האפליקציה במכשיר מחנות Play.
- מוודאים שהאתר מתארח באמצעות פרוטוקול https. שימוש ב-http יגרום ל-API להיות
undefined
עם משתמשי בדיקה וצוותים של בקרת איכות
ב-Play Store יש תכונות שמאפשרות לבצע בדיקות, כולל חשבונות בדיקה של משתמשים ומק"טים לבדיקה. מידע נוסף זמין במסמכי העזרה בנושא בדיקת החיוב ב-Google Play.
לאן ממשיכים?
כפי שמתואר במסמך הזה, ל-Play Billing API יש רכיבים בצד הלקוח שמנוהלים על ידי Digital Goods API, ורכיבים בצד השרת.
- כדאי לעיין בדוגמה של Peter Conn בכתובת https://github.com/PEConn/beer
- כדאי לעיין במסמכי העזרה של Play בנושא אימות רכישות.
- מומלץ להשתמש באחת מספריות הלקוח של Google Play Developer API, שזמינות בשפות רבות.
- אם אתם מטמיעים מודל מינויים באפליקציה, כדאי לעיין במסמכי התיעוד בנושא מינויים בחיוב ב-Play.
- מטמיעים התראות בזמן אמת למפתחים (RTDN) ומירשם לקבלת התראות, כדי שהקצה העורפי יקבל התראה כשהסטטוס של המינוי ישתנה, במקום לבדוק את הסטטוס ב-Play.
- מטמיעים את
linkedPurchaseToken
כדי למנוע מינויים כפולים. בפוסט הזה בבלוג מוסבר איך מטמיעים את התכונה בצורה נכונה.