应用内集成指南(适用于外部支付)

本文档介绍了如何集成 Play 结算库 API,以便在符合条件的应用中提供外部付款方式。如需详细了解此计划,请参阅计划要求

Play 结算库设置

向您的 Android 应用添加 Play 结算库依赖项。如需使用外部付款 API,您需要使用 8.3 或更高版本。如果您需要从较早版本迁移,请先按照迁移指南中的说明升级,然后再开始集成。

初始化结算客户端

集成流程的最初步骤与 Google Play 结算服务集成指南中所述的一些步骤相同,在初始化您的 BillingClient 时需进行一些调整:

以下示例演示了如何通过这些调整来初始化 BillingClient:

Kotlin

val purchasesUpdatedListener =
    PurchasesUpdatedListener { billingResult, purchases ->
        // Handle new Google Play purchase.
    }

val developerProvidedBillingListener =
    DeveloperProvidedBillingListener { details ->
        // Handle user selection for developer provided billing option.
    }

val billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .enableBillingProgram(
        EnableBillingProgramParams.newBuilder()
            .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
            .setDeveloperProvidedBillingListener(developerProvidedBillingListener)
            .build())
    .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // Handle new Google Play purchase.
    }
};

private DeveloperProvidedBillingListener developerProvidedBillingListener =
    new DeveloperProvidedBillingListener() {
        @Override
        public void onUserSelectedDeveloperBilling(
            DeveloperProvidedBillingDetails details) {
            // Handle user selection for developer provided billing option.
        }
    };

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .enableBillingProgram(
        EnableBillingProgramParams.newBuilder()
            .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
            .setDeveloperProvidedBillingListener(developerProvidedBillingListener)
            .build())
    .build();

连接到 Google Play

初始化 BillingClient 后,请按照与 Google Play 建立连接中的说明与 Google Play 建立连接。

检查用户资格

连接到 Google Play 后,您可以通过调用 isBillingProgramAvailableAsync() 方法来检查用户是否符合外部付款计划的条件。如果用户符合条件,此方法会返回 BillingResponseCode.OK。以下示例演示了如何检查资格条件:

Kotlin

billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_PAYMENTS,
  object : BillingProgramAvailabilityListener {
    override fun onBillingProgramAvailabilityResponse(
      billingProgram: Int, billingResult: BillingResult) {
        if (billingResult.responseCode != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external payments unavailable, etc.
            return
        }

        // External payments are available. Can proceed with generating an
        // external transaction token.
})

Java

billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_PAYMENTS,
  new BillingProgramAvailabilityListener() {
    @Override
    public void onBillingProgramAvailabilityResponse(
      int billingProgram, BillingResult billingResult) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external payments unavailable, etc.
            return;
        }

        // External payments are available. Can proceed with generating an external transaction token.
      }

    });

如需详细了解您的应用应如何响应其他响应代码,请参阅响应处理部分。如果您使用 Kotlin 扩展,则可以使用 Kotlin 协程,因此无需定义单独的监听器。

显示可购买的商品

您可以采用集成 Google Play 结算系统的相同方式向用户显示可购买的商品。当用户看到可供购买的商品并选择购买时,请启动外部付款流程(如启动外部付款流程部分中所述)。

准备外部交易令牌

如需向 Google Play 报告外部交易,您必须拥有通过 Play 结算库生成的外部交易令牌。每次用户通过外部支付 API 访问外部网站或应用时,都必须生成新的外部交易令牌。您可以通过调用 createBillingProgramReportingDetailsAsync API 来完成此操作。令牌应在调用 launchBillingFlow 之前立即生成。

Kotlin

val params =
    BillingProgramReportingDetailsParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .build()

billingClient.createBillingProgramReportingDetailsAsync(
  params,
  object : BillingProgramReportingDetailsListener {
    override fun onCreateBillingProgramReportingDetailsResponse(
      billingResult: BillingResult,
      billingProgramReportingDetails: BillingProgramReportingDetails?) {
        if (billingResult.responseCode != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors.
            return
        }
        val externalTransactionToken =
            billingProgramReportingDetails?.externalTransactionToken
        // Persist the external transaction token locally. Pass it to
        // the external website using DeveloperBillingOptionParams when
        // launchBillingFlow is called.
    }
})

Java

BillingProgramReportingDetailsParams params =
    BillingProgramReportingDetailsParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .build();

billingClient.createBillingProgramReportingDetailsAsync(
  params,
  new BillingProgramReportingDetailsListener() {
    @Override
    public void onCreateBillingProgramReportingDetailsResponse(
      BillingResult billingResult,
      @Nullable BillingProgramReportingDetails
        billingProgramReportingDetails) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors.
            return;
        }

        String transactionToken =
          billingProgramReportingDetails.getExternalTransactionToken();

        // Persist the external transaction token locally. Pass it to
        // the external website using DeveloperBillingOptionParams when
        // launchBillingFlow is called.
      }
});

如果您使用 Kotlin 扩展,则可以使用 Kotlin 协程,因此无需定义单独的监听器。

启动外部支付流程

通过调用 launchBillingFlow() 启动外部付款流程,这与通过集成 Google Play 结算系统来启动购买流程类似,但需要额外提供一个参数 DeveloperBillingOptionParams,用于指明您的应用希望为此购买交易启用外部付款流程。

DeveloperBillingOptionParams 必须包含以下内容:

当您的应用调用 launchBillingFlow() 并提供 DeveloperBillingOptionParams 时,Google Play 结算系统会执行以下检查:

  • 系统会检查用户的 Google Play 国家/地区是否支持外部付款(即是否是受支持的国家/地区)。如果用户的 Google Play 国家/地区是受支持的国家/地区,Google Play 会根据 BillingClient 的配置检查是否已启用外部付款,以及是否提供了 DeveloperBillingOptionParams
    • 如果已启用外部付款,购买流程会显示用户选择体验。
    • 如果未启用外部付款,购买流程会显示标准的 Google Play 结算系统用户体验,无需用户选择。
  • 如果用户的 Google Play 国家/地区不是受支持的国家/地区,购买流程会显示标准的 Google Play 结算系统用户体验,无需用户选择。

用户的 Play 国家/地区受支持

用户的 Play 国家/地区不受支持

已启用外部支付(BillingClient 设置launchBillingFlow

用户会看到用户选择体验

用户会看到标准的 Google Play 结算系统用户体验

未启用外部付款(在 BillingClient 设置期间未启用,或未向 launchBillingFlow 提供 DeveloperBillingOptionParams)

用户会看到标准的 Google Play 结算系统用户体验

用户会看到标准的 Google Play 结算系统用户体验

以下代码段演示了如何构造 DeveloperBillingOptionParams

Kotlin

val developerBillingOptionParams =
    DeveloperBillingOptionParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .setLinkUri("https://www.example.com/external/purchase")
        .setLaunchMode(
            DeveloperBillingOptionParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
        .build()

Java

DeveloperBillingOptionParams developerBillingOptionParams =
    DeveloperBillingOptionParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .setLinkUri("https://www.example.com/external/purchase")
        .setLaunchMode(
            DeveloperBillingOptionParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
        .build();

处理用户选择

购买流程其余部分的处理方式不尽相同,具体取决于用户选择的是 Google Play 结算系统还是在您的网站上付款。

当用户选择在您的网站上或在付款应用中付款时

如果用户选择在您的网站上付款,Google Play 会调用 DeveloperProvidedBillingListener 来通知应用用户选择在您的网站上或在付款应用中付款。具体来说,系统会调用 onUserSelectedDeveloperBilling() 方法。

如果您的应用将 launchMode 设置为 LAUNCH_IN_EXTERNAL_BROWSER_OR_APP,则 Google Play 将启动该链接。如果 launchMode 设置为 CALLER_WILL_LAUNCH_LINK,则您的应用负责启动链接。 将用户链接到付款应用时,您有责任检查用户是否已在其设备上安装付款应用。

后端集成指南中所述,使用此令牌可报告这一选择产生的任何交易。

当用户选择 Google Play 结算系统时

如果用户选择 Google Play 结算系统,则可以继续通过 Google Play 进行购买交易。

  • 如需详细了解如何通过 Google Play 结算系统处理新的应用内购买交易,请参阅库集成指南中的处理购买交易
  • 如需获得关于订阅购买交易的更多指南,请参阅订阅管理指南中的新订阅

处理订阅变更

如果开发者使用外部付款方式,则需要通过 Google Play 结算系统处理购买交易或使用 externalTransactionId 报告购买交易,具体取决于用户的选择。在订阅到期之前,通过开发者网站来处理的对现有订阅的变更可通过同一结算系统实现。

本部分介绍了如何处理一些常见的订阅变更场景。

升级和降级流程

订阅方案变更(包括升级和降级流程)的处理方式应有所不同,具体取决于订阅最初是通过 Google Play 结算系统购买的,还是通过开发者的网站购买的。

依赖于现有订阅、共用相同付款方式且定期扣款时间一致的加购项将作为升级处理。对于其他加购项,用户应该能够选择要使用的结算系统。使用 launchBillingFlow() 启动新的购买体验,如启动外部付款流程中所述。

通过开发者的网站或支付应用购买的订阅

对于最初在用户选择后通过开发者的网站或支付应用购买的订阅,请求升级或降级的用户应通过开发者的网站或支付应用继续操作,无需用户再次选择。

为此,当用户请求升级或降级时,请调用 launchBillingFlow()。请使用 setOriginalExternalTransactionId() 提供原始购买交易的外部交易 ID,而不是在 SubscriptionUpdateParams 对象下指定其他参数。

在此调用中,还必须提供 DeveloperBillingOptionParams。采用这种方式不会显示用户选择界面,因为系统会保留原始购买交易的相关用户选择以用于升级和降级。您必须为此交易生成新的外部交易令牌,如此处所述。

当用户使用开发者的网站或付款应用完成升级或降级后,您需要使用通过之前针对新订阅购买交易的调用所获得的外部交易令牌来报告新交易

通过 Google Play 结算系统购买的订阅

同样,如果用户选择通过 Google Play 结算系统购买其当前订阅,系统应向该用户显示标准 Google Play 结算流程。不得在对 launchBillingFlow 的调用中设置 DeveloperBillingOptionParams

订阅取消和恢复

用户应该能够随时取消订阅。用户取消订阅后,使用权可能直到付费期结束才会终止。例如,如果用户在月中取消了月度订阅,可以在剩下的大约 2 周内继续使用该服务,直到其使用权限被撤消为止。在此期间,订阅在技术层面上仍处于有效状态,因此用户可以使用该服务。

在这一活跃期内,用户决定撤消取消订阅操作的情况并不少见。在本指南中,此情况称为“恢复”。以下部分介绍了如何在外部付款 API 集成中处理恢复场景。

通过开发者的网站购买的订阅

如果您有一项已取消的订阅的外部交易 ID,则无需调用 launchBillingFlow() 即可恢复该订阅,因此它不应被用于此类激活。如果用户在已取消的订阅的有效期内恢复订阅,则不会发生任何交易;如果当前周期到期后发生下次续订,您只需继续报告续订即可。这包括以下情形:用户在恢复期间会收到赠送金额或获享特殊续订价格(例如,一项旨在鼓励用户继续订阅的促销活动)。

通过 Google Play 结算系统购买的订阅

通常,用户可以在 Google Play 结算系统中恢复订阅。 对于最初通过 Google Play 结算系统购买的订阅,用户可以在订阅处于有效状态时通过 Google Play 的重新订阅功能选择撤消之前的取消操作。在这种情况下,您会在后端收到 SUBSCRIPTION_RESTARTED 实时开发者通知,并且系统不会发放新的购买令牌,而会使用原始令牌来继续订阅。如需了解如何管理 Google Play 结算系统中的恢复,请参阅订阅管理指南中的恢复

您还可以通过调用 launchBillingFlow(),从应用中触发 Google Play 结算系统中的恢复订阅流程。如需了解实现方法,请参阅订阅到期之前 - 应用内。如果用户完成了原始购买交易的用户选择流程(已取消,但仍处于有效状态),系统会自动检测用户的选择,并显示用于恢复这些购买交易的界面。系统会提示用户通过 Google Play 确认重新购买相应订阅,但用户无需再次经历用户选择流程。在这种情况下,系统会为用户发放新的购买令牌。您的后端会收到 SUBSCRIPTION_PURCHASED 实时开发者通知,并且新购买交易状态的 linkedPurchaseToken 值会设为升级或降级情形下的状态,采用被取消的订阅之前所用的购买令牌。

重新订阅

如果订阅完全过期,无论是由于被取消还是未恢复且付款遭拒(账号保留期已过),如果用户想要重获使用权,必须重新订阅。

也可通过该应用来实现重新订阅,处理方法与标准订阅方式类似。用户应该能够选择要使用的结算系统。在这种情况下,系统可能会调用 launchBillingFlow(),如启动外部支付流程中所述。

响应处理

发生错误时,方法 isBillingProgramAvailableAsync()createBillingProgramReportingDetailsAsync()launchBillingFlow() 可能会提供除 BillingResponseCode.OK 之外的 BillingResponseCode。请考虑按如下方式处理这些响应代码:

测试外部支付链接

许可测试人员应用于测试外部付款集成。 您不会收到许可测试账号发起的交易的账单。如需详细了解如何配置许可测试人员,请参阅使用应用许可来测试应用内购结算功能

后续步骤

完成应用内集成后,您就可以集成后端了。