如果您的應用程式是透過 Google Play 發行,且您想銷售數位商品或提供訂閱項目,就必須使用 Google Play 結帳系統。Google Play 帳款服務提供多種工具,可用於管理目錄、價格和訂閱項目、實用報表,以及使用者熟悉的 Play 商店結帳流程。
如果應用程式是使用可信任的網頁活動建構,並透過 Google Play 商店提供,您現在可以使用Payment Request API 和 Digital Goods API 與 Google Play 結帳系統整合。適用於 Android 和 ChromeOS 的 Chrome 101 以上版本。
本指南將說明如何在 PWA 中加入 Google Play 帳款服務支援功能,並將其封裝為可在 ChromeOS 和 Play 商店中發布的應用程式。
您將使用兩個網頁平台 API,為 PWA 新增 Play 帳款服務支援功能。Digital Goods API 可用於收集 SKU 資訊,並檢查 Play 商店的購買交易和授權。Payment Request API 可用於將 Google Play 商店設為付款方式,並完成購買流程。
如何在 Play 商店中透過應用程式營利
應用程式可以透過 Google Play 帳單系統在 Play 商店營利,方法如下:
需求條件
如要設定 Google Play 帳款服務,您需要:
- Google Play 開發人員帳戶和Google 付款商家帳戶彼此連結。
- Play 商店產品資訊,且已發布至公開、封閉測試或內部測試群組。
- 如要在 Play 商店中建立及設定應用程式的產品和訂閱項目。
- Bubblewrap 產生的專案,其中包含可用的數位資產連結設定。
更新 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 目前僅在 PWA 在可信任的網路活動中執行時支援 Digital Goods API,您可以檢查 window
物件上的 getDigitalGoodsService
,藉此偵測是否可使用此 API:
if ('getDigitalGoodsService' in window) {
// Digital Goods API is supported!
}
Digital Goods API 可在任何瀏覽器中使用,並支援不同的商店。如要確認是否支援特定商店後端,您必須叫用 getDigitalGoodsService()
,並將商店 ID 做為參數傳遞。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;
}
}
擷取 SKU 的詳細資料
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 的建構函式會採用兩個參數:付款方式清單和付款詳細資料清單。
在可信任的網路活動中,您必須使用 Google Play 結帳付款方式,方法是將 https://play.google.com/billing
設為 ID,並將產品 SKU 新增為資料成員:
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 管理中心建立 SKU 時設定的值,因此可以填入假值:
const paymentDetails = {
total: {
label: `Total`,
amount: {currency: `USD`, value: `0`}
}
};
const request = new PaymentRequest(paymentMethods, paymentDetails);
請對付款要求物件呼叫 show()
,以啟動付款流程。如果 Promise 成功,表示付款可能已成功。如果失敗,使用者可能已中止付款。
如果承諾成功,您必須驗證並確認購買交易。為了防範詐欺行為,您必須使用後端實作這個步驟。請參閱 Play 帳款服務說明文件,瞭解如何在後端實作驗證機制。如果您未確認購買交易,三天後使用者會收到退款,且 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
}
...
您可以視需要在 purchaseToken 上呼叫 consume()
,將購買交易標示為已用完,並允許再次購買。
將所有內容整合後,購買方法會如下所示:
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 開發人員裝置上
您可以在開發版 Android 裝置上啟用 Digital Goods API 進行測試:
- 請確認您使用的是 Android 9 以上版本,且已啟用開發人員模式。
- 安裝 Chrome 101 以上版本。
- 前往
chrome://flags
,並依名稱搜尋標記,在 Chrome 中啟用下列標記:#enable-debug-for-store-billing
- 請確認網站是使用 https 通訊協定代管。使用 http 會導致 API
undefined
在 ChromeOS 裝置上
自 ChromeOS 89 版起,Digital Goods API 就會在 ChromeOS 穩定版中提供。在此期間,您可以測試 Digital Goods API:
- 從裝置上的 Play 商店安裝應用程式。
- 請確認網站是使用 https 通訊協定代管。使用 http 會導致 API
undefined
與測試使用者和品質保證團隊合作
Play 商店提供測試功能,包括使用者測試帳戶和測試 SKU。詳情請參閱 Google Play 帳款服務測試說明文件。
接下來要去哪裡?
如本文件所述,Play Billing API 包含由 Digital Goods API 管理的用戶端元件和伺服器端元件。
- 請參閱 Peter Conn 的範例:https://github.com/PEConn/beer
- 請參閱 Play 說明文件,瞭解購買交易驗證。
- 建議您使用其中一種 Google Play Developer API 用戶端程式庫,這些程式庫支援多種語言。
- 如果您在應用程式中導入訂閱模式,請參閱 Play 帳款服務訂閱項目說明文件。
- 實作即時開發人員通知 (RTDN) 並訂閱通知,這樣當訂閱狀態變更時,您的後端就能收到通知,而不需要在 Play 上輪詢狀態。
- 實作
linkedPurchaseToken
以避免重複訂閱。請參閱這篇網誌文章,瞭解如何正確導入這項功能。