在 Trusted Web Activity 中使用 Google Play 结算服务

本指南适用于打包为 Trusted Web Activity 的 Web 应用。对于使用 Kotlin 或 Java 编写的 Android 应用,请参阅 Google Play 结算服务文档。

在 Google Play 上销售数字商品或订阅的应用必须使用 Google Play 结算服务。在 Trusted Web Activity 中,您可以使用以下 Web API(适用于 Android 和 ChromeOS 上的 Chrome 101 及更高版本)与其集成:

要求

如需设置 Google Play 结算服务,您需要满足以下条件:

向用户收取从 Play 商店下载应用的费用。您的 PWA 仍可在网络上使用,因此付费下载不会限制访问。而是通过应用内购或订阅销售功能或内容。

在 Android 项目中启用 Play 结算服务

如果您使用 Bubblewrap 构建应用,请在项目根目录下的 twa-manifest.json 中启用 playBilling 功能:

"features": {
  "playBilling": {
    "enabled": true
  }
}

然后,依次运行 bubblewrap update 和 bubblewrap build,并将新的 Android 软件包上传到 Play 商店。

如果您在 Android Studio 中构建应用,请添加 Android 浏览器帮助程序 Play 结算库。如需了解所需的 DelegationService 和 AndroidManifest.xml 更改,请参阅 twa-play-billing 演示。

检查是否支持 Google Play 结算服务

使用 Play 商店标识符 https://play.google.com/billing 调用 getDigitalGoodsService()。如果该方法缺失或调用失败,请使用其他付款流程:

if ('getDigitalGoodsService' in window) {
  try {
    const service =
        await window.getDigitalGoodsService('https://play.google.com/billing');
    // Google Play Billing is available.
  } catch (error) {
    // Google Play Billing isn't available. Use another payment flow.
  }
}

显示商品详情

使用 getDetails() 检索商品 ID 的名称、说明和价格,以便您显示的价格与 Play 商店中的价格一致:

const details = await service.getDetails(['shiny_sword', 'gem']);
for (const item of details) {
  const localizedPrice = new Intl.NumberFormat(
      navigator.language,
      {style: 'currency', currency: item.price.currency}
  ).format(item.price.value);

  renderProductDetails(
      item.itemId, item.title, localizedPrice, item.description);
}

Digital Goods API 无法列出您的商品 ID。如需从后端查询这些信息,请使用 Google Play Developer API。

购买

在 data 中创建一个 PaymentRequest,其中 https://play.google.com/billing 为支付方式,产品 ID 为 sku。Google Play 结算服务会使用 Play 管理中心内的价格,因此 total 是必需的,但会被忽略。

show() 解析后,将购买令牌发送到您的后端,以验证并确认购买交易。如果您在三天内未确认购买交易,Google Play 会向用户退款并撤消该购买交易。

async function makePurchase(service, sku) {
  const paymentMethods = [{
    supportedMethods: 'https://play.google.com/billing',
    data: {sku},
  }];
  // Required by the Payment Request API, but ignored by Google Play Billing.
  const paymentDetails = {
    total: {label: 'Total', amount: {currency: 'USD', value: '0'}},
  };

  const request = new PaymentRequest(paymentMethods, paymentDetails);
  try {
    const response = await request.show();
    const {purchaseToken} = response.details;

    if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
      // Optional: consume the purchase so the user can buy the item again.
      await service.consume(purchaseToken);
      await response.complete('success');
    } else {
      await response.complete('fail');
    }
  } catch (error) {
    // An AbortError usually means the user canceled the purchase.
  }
}

查看用户的购买交易

使用 listPurchases() 查找用户拥有的商品,例如有效订阅、未使用的购买交易或已兑换的促销代码。在后端验证每笔购买交易,并确认您尚未确认的所有购买交易:

const purchases = await service.listPurchases();
for (const p of purchases) {
  await verifyOrAcknowledgePurchaseOnBackend(p.purchaseToken, p.itemId);
  // Update the UI with items the user is entitled to.
}

测试您的集成

如需在发布到 Play 商店之前在 Android 设备上进行测试,请按以下步骤操作:

  1. 使用 Android 9 或更高版本,并启用开发者选项。
  2. 在 Chrome 中,前往 chrome://flags 并启用 #enable-debug-for-store-billing。
  3. 通过 HTTPS 提供网站。Digital Goods API 无法通过 HTTP 使用。

如果您的应用是从 Play 商店安装的,则不需要该标志。如需使用测试账号和测试商品进行测试,请参阅测试您的 Google Play 结算库集成。

后续步骤