Digital Goods API と Payment Request API を使用して Google Play 請求サービス経由で支払いを受け取る

アンドレ・チプリリアニ・バンダラ
André Cipriani Bandarra

Google Play を通じて配信されているアプリがデジタル商品を販売したり、定期購入を提供したりする場合は、Google Play 請求サービスを使用する必要があります。Google Play 請求サービスには、カタログ、価格、定期購入を管理するためのツール、便利なレポート、ユーザーが使い慣れている Google Play ストアの購入手続きフローが用意されています。

Trusted Web Activity を使用して作成され、Google Play ストアを通じて配信されるアプリの場合、Payment Request APIDigital 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 請求サービスを設定するには、以下が必要です。

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 によって管理されるクライアント側のコンポーネントと、サーバー側のコンポーネントがあります。