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

André Cipriani Bandarra
André Cipriani Bandarra

如果您的应用通过 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 和服务器端组件定义