使用 Digital Goods API 和 Payment Request API 通过 Google Play 结算服务接收付款

如果您的应用通过 Google Play 分发,并且您希望销售数字商品或优惠 您必须使用 Google Play 结算服务。Google Play 结算服务提供了 您的目录、价格和订阅、实用报告以及由 Play 提供支持的结账流程 用户已经熟悉的商店。

对于使用 Trusted Web Activity 功能构建并通过 Google Play 商店交付的应用,您必须 现在可以使用 Payment Request APIDigital Goods API 来集成 Google Play 结算服务。它适用于 Android 和 ChromeOS 的 Chrome 101 及更高版本。

在本指南中,您将了解如何为 PWA 添加 Google Play 结算服务支持,以及如何将其打包用于 在 Google Play 商店中分发。

您将使用两个 Web 平台 API 向 PWA 添加 Play 结算服务支持。通过 Digital Goods API 用于收集 SKU 信息,以及检查购买交易和使用权 。Payment Request API 用于将 Google Play 商店配置为 付款方式并完成购买流程。

如何通过 Play 商店中的应用获利

您的应用可以通过两种方式在 Play 商店中利用 Google Play 结算服务变现:

  • 应用内购买允许销售耐用品和消耗性虚拟商品,例如其他 功能或移除广告。
  • 订阅:让您的用户可以定期付费,持续访问内容或服务; 例如新闻订阅或会员

要求

若要设置 Google Play 结算服务,您需要:

更新 Bubblewrap 项目

如果您尚未安装 Bubblewrap,则需要自行安装。请参阅 快速入门指南:详细了解如何开始使用。如果您已经有 Bubblewrap 请务必更新到 1.8.2 或更高版本。

Bubblewrap 还具有一个位于旗帜后面的功能。在 要启用它,您需要在 twa-manifest.json 中修改项目配置, 位于项目根目录下,并启用 alphaDependenciesplayBilling 功能:

  ...,
  "enableNotifications": true,
  "features": {
    "playBilling": {
      "enabled": true
    }
  },
  "alphaDependencies": {
    "enabled": true
  },
  ...

配置文件更新后,运行 bubblewrap update 以将配置应用于 后跟 bubblewrap build,以生成新的 Android 软件包并将此 将软件包推送到 Play 商店

检测 Digital Goods API 和 Google Play 结算服务可用性的功能

目前,仅当在 PWA 内执行 PWA 时,Chrome 才支持 Digital Goods API 可信网络活动,并且可以通过查看 针对 window 对象的 getDigitalGoodsService 权限:

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 的构造函数采用两个参数:付款方式列表和 付款信息。

在 Trusted Web 活动中,您必须通过以下操作使用 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 结算服务会忽略这些值,而使用 在 Play 管理中心内创建 SKU 时设置的值,以便填充虚假值:

const paymentDetails = {
    total: {
        label: `Total`,
        amount: {currency: `USD`, value: `0`}
    }
};

const request = new PaymentRequest(paymentMethods, paymentDetails);

对付款请求对象调用 show() 以启动付款流程。如果 Promise 成功 则表示付款成功如果付款失败,则用户可能已取消付款。

如果 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 中启用以下标记,方法是:转到 chrome://flags,然后搜索 标志: <ph type="x-smartling-placeholder">
      </ph>
    • #enable-debug-for-store-billing
  • 确保该网站使用 https 协议托管。使用 http 将导致 API 处于 undefined 状态

在 ChromeOS 设备上

从版本 89 开始,Digital Goods API 将可在 ChromeOS 稳定版中使用。在 在此期间,您可以测试 Digital Goods API:

  • 从设备上的 Play 商店安装您的应用。
  • 确保该网站使用 https 协议托管。使用 http 将导致 API 处于 undefined 状态

测试用户和质量检查团队

Play 商店提供各种测试功能,包括用户测试账号和测试 SKU。 如需了解详情,请参阅 Google Play 结算服务测试文档

下一步做什么?

如本文档中所述,Play Billing API 具有客户端组件,这些组件 由 Digital Goods API 和服务器端组件定义