Google Play を通じて配信されているアプリがデジタル商品を販売したり、定期購入を提供したりする場合は、Google Play 請求サービスを使用する必要があります。Google Play 請求サービスには、カタログ、価格、定期購入を管理するためのツール、便利なレポート、ユーザーが使い慣れている Google Play ストアの購入手続きフローが用意されています。
Trusted Web Activity を使用して作成され、Google Play ストアを通じて配信されるアプリの場合、Payment Request API と Digital Goods API を使用して Google Play 請求サービスと統合できるようになりました。Android 版と ChromeOS 版の Chrome 101 以降で利用できます。
このガイドでは、Google Play 請求サービスのサポートを PWA に追加し、ChromeOS と Play ストアの両方で Google Play ストアで配布できるようにパッケージ化する方法について説明します。
2 つのウェブ プラットフォーム API を使用して、Play 請求サービスのサポートを PWA に追加します。SKU 情報を収集し、Play ストアからの購入と利用資格を確認するために、Digital Goods API が使用されます。Payment Request API は、Google Play ストアをお支払い方法として設定し、購入フローを完了するために使用します。
Google Play ストアでアプリを収益化する方法
Play ストアの Google Play 請求サービスを使用してアプリを収益化する方法は 2 つあります。
- アプリ内購入では、追加機能など、永続性のある仮想アイテムと消費型アイテムの両方を販売したり、広告を削除したりできます。
- 定期購入。ニュースの定期購読やメンバーシップなど、定期的に料金を支払うことで、ユーザーがコンテンツやサービスに継続的にアクセ��できるようにします。
要件
Google Play 請求サービスを設定するには、以下が必要です。
- 相互にリンクされている Google Play デベロッパー アカウントと Google Payments 販売アカウント。
- 公開テストトラック、クローズド テストトラック、内部テストトラックでリリースされた 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 パッケージを生成し、このパッケージを Google Play ストアにアップロードします。
Digital Goods API と Google Play 請求サービスの提供状況を検出する機能
Digital Goods API は現在、PWA が Trusted Web Activity で実行されている場合にのみ Chrome でサポートされます。また、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 のコンストラクタは、お支払い方法のリストと���払い詳細のリストの 2 つのパラメータを受け取ります。
Trusted Web Activity 内で Google Play 請求サービスのお支払い方法を使用するには、https://play.google.com/billing
を識別子として設定し、商品の 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 請求サービスはこれらの値を無視し、Google Play Console で SKU の作成時に設定された値を使用するため、誤った値が入力される可能性があります。
const paymentDetails = {
total: {
label: `Total`,
amount: {currency: `USD`, value: `0`}
}
};
const request = new PaymentRequest(paymentMethods, paymentDetails);
支払いリクエスト オブジェクトで show()
を呼び出して、支払いフローを開始します。Promise が成功した場合、支払いが成功した可能性があります。失敗した場合、ユーザーは支払いを中止した可能性があります。
Promise が成功した場合、購入を確認して承認する必要があります。不正行為から保護するため、この手順はバックエンドを使用して実装する必要があります。バックエンドで検証を実装する方法については、Play 請求サービスのドキュメントをご覧ください。購入を承認しない場合、3 日後にユーザーに払い戻しが行われ、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 で次のフラグを有効にするには、
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
になります。
テストユーザーおよび QA チームと連携
Play ストアには、ユーザーテスト アカウントやテスト SKU など、テスト用のアフォーダンスが用意されています。詳しくは、Google Play 請求サービスのテストに関��るドキュメントをご覧ください。
次のステップ
このドキュメントで説明するように、Play Billing API には、Digital Goods API によって管理されるクライアント側のコンポーネントと、サーバー側のコンポーネントがあります。
- https://github.com/PEConn/beer で、Peter Conn のサンプルをご覧ください。
- 購入の確認については、Play のドキュメントをご覧ください。
- Google Play Developer API クライアント ライブラリのいずれかの使用を検討してください。ライブラリは複数の言語で利用可能です。
- アプリに定期購入モデルを実装する場合は、Play 請求サービスの定期購入に関するドキュメントをご覧ください。
- リアルタイム デベロッパー通知(RTDN)を実装し、通知を購読する。これによ���、Play でステータスをポーリングするのではなく、定期購入の状態が変化したときにバックエンドに通知されるようにすることができます。
linkedPurchaseToken
を実装して、サブスクリプションの重複を防ぎます。正しく実装する方法については、こちらのブログ投稿をご覧ください。