本指南介绍了如何与相关 API 集成,以便在符合条件的应用和地区中支持外部优惠。如需详细了解外部优惠计划(包括资格要求和地理范围),请参阅计划要求。
Play 结算库设置
如需使用外部优惠 API,请向您的 Android 应用添加 Play 结算库依赖项(版本 8.2 或更高版本)。如果您需要从较早版本迁移,请先按照迁移指南中的说明操作,然后再尝试实现外部优惠。
连接到 Google Play
集成流程的最初步骤与结算服务集成指南中所述的一些步骤相同,但您必须在初始化 BillingClient 时调用 enableBillingProgram 来指明您要使用外部优惠:
以下示例演示了如何通过这些调整来初始化 BillingClient:
Kotlin
val billingClient = BillingClient.newBuilder(context)
.enableBillingProgram(BillingProgram.EXTERNAL_OFFER)
.build()
Java
private BillingClient billingClient = BillingClient.newBuilder(context)
.enableBillingProgram(BillingProgram.EXTERNAL_OFFER)
.build();
初始化 BillingClient 后,您需要按照集成指南中的说明与 Google Play 建立连接。
查看适用范围
如需确认当前用户是否可享受外部优惠,请调用 isBillingProgramAvailableAsync。
如果有外部优惠,此 API 会返回 BillingResponseCode.OK。
如需详细了解您的应用应如何响应其他响应代码,请参阅响应处理部分。
Kotlin
billingClient.isBillingProgramAvailableAsync(
BillingProgram.EXTERNAL_OFFER,
object : BillingProgramAvailabilityListener {
override fun onBillingProgramAvailabilityResponse(
billingResult: BillingResult,
billingProgramAvailabilityDetails: BillingProgramAvailabilityDetails) {
if (billingResult.responseCode != BillingResponseCode.OK) {
// Handle failures such as retrying due to network errors,
// handling external offers unavailable, etc.
return
}
// External offers are available. Continue with steps in the
// guide.
}
})
Java
billingClient.isBillingProgramAvailableAsync(
BillingProgram.EXTERNAL_OFFER,
new BillingProgramAvailabilityListener() {
@Override
public void onBillingProgramAvailabilityResponse(
BillingResult billingResult,
BillingProgramAvailabilityDetails billingProgramAvailabilityDetails) {
if (billingResult.getResponseCode() != BillingResponseCode.OK) {
// Handle failures such as retrying due to network errors,
// handling external offers being unavailable, etc.
return;
}
// External offers are available. Continue with steps in the
// guide.
}
});
准备外部交易令牌
如需向 Google Play 报告外部交易,您必须拥有通过 Play 结算库生成的外部交易令牌。您可以通过调用 createBillingProgramReportingDetailsAsync API 来获取此令牌。在将用户引导到应用外部之前,必须立即为每个外部优惠生成新令牌。不得跨交易缓存令牌。
Kotlin
val params =
BillingProgramReportingDetailsParams.newBuilder()
.setBillingProgram(BillingProgram.EXTERNAL_OFFER)
.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 transaction token in your backend. You may pass it
// to the external website when calling the launchExternalLink API.
}
})
Java
BillingProgramReportingDetailsParams params =
BillingProgramReportingDetailsParams.newBuilder()
.setBillingProgram(BillingProgram.EXTERNAL_OFFER)
.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 transaction token in your backend. You may pass it
// to the external website when calling the launchExternalLink API.
}
});
或者,您可以使用 Kotlin 扩展查询挂起函数 createBillingProgramReportingDetailsAsync,这样您就无需定义监听器:
val createBillingProgramReportingDetailsResult =
withContext(context) {
billingClient
.createBillingProgramReportingDetails(params)
}
// Process the result
启动外部优惠流程
如需启动外部优惠流程,符合条件的应用必须从应用的主线程调用 launchExternalLink() API。此 API 接受 LaunchExternalLinkParams 对象作为输入。如需创建 LaunchExternalLinkParams 对象,请使用 LaunchExternalLinkParams.Builder 类。此类包含以下参数:
- linkUri - 提供数字内容或应用下载的外部网站的链接。对于应用下载,此链接必须在 Play 管理中心内注册并获得批准。
- linkType - 向用户提供的内容类型。
- launchMode - 指定链接的启动方式。对于应用下载,您必须将此属性设置为
LAUNCH_IN_EXTERNAL_BROWSER_OR_APP。 - billingProgram - 将此项设置为
BillingProgram.EXTERNAL_OFFER。
当您调用 launchExternalLink() 时,系统可能会根据用户的设置向用户显示其他信息对话框。Play 会根据 launchMode 参数在外部浏览器中启动链接 URI,或者将流程返回到您的应用以启动该 URI。在大多数情况下,您可以使用 LAUNCH_IN_EXTERNAL_BROWSER_OR_APP 模式,让 Play 为您启动 URI。如果您想实现更自定义的行为,例如在 WebView 中启动 URI 或在特定浏览器中打开 URI,可以使用 CALLER_WILL_LAUNCH_LINK 模式。为保护用户隐私,请确保 URI 中未传递任何个人身份信息 (PII)。
Kotlin
// An activity reference from which the external offers flow will be launched.
val activity = ...;
val params =
LaunchExternalLinkParams.newBuilder()
.setBillingProgram(BillingProgram.EXTERNAL_OFFER)
// You can pass along the external transaction token from
// BillingProgramReportingDetails as a URL parameter in the URI
.setLinkUri(yourLinkUri)
.setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_APP_DOWNLOAD)
.setLaunchMode(
LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
.build()
val listener : LaunchExternalLinkResponseListener =
LaunchExternalLinkResponseListener {
override fun onLaunchExternalLinkResponse(billingResult: BillingResult) {
if (billingResult.responseCode == BillingResponseCode.OK) {
// Proceed with the rest of the external offer flow. If the user
// purchases an item, be sure to report the transaction to Google Play.
} else {
// Handle failures such as retrying due to network errors.
}
}
}
billingClient.launchExternalLink(activity, params, listener)
Java
// An activity reference from which the external offers flow will be launched.
Activity activity = ...;
LaunchExternalLinkParams params = LaunchExternalLinkParams.newBuilder()
.setBillingProgram(BillingProgram.EXTERNAL_OFFER)
// You can pass along the external transaction token from
// BillingProgramReportingDetails as a URL parameter in the URI
.setLinkUri(yourLinkUri)
.setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_APP_DOWNLOAD)
.setLaunchMode(
LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
.build();
LaunchExternalLinkResponseListener listener =
new LaunchExternalLinkResponseListener() {
@Override
public void onLaunchExternalLinkResponse(BillingResult billingResult) {
if (billingResult.responseCode == BillingResponseCode.OK) {
// Proceed with the rest of the external offer flow. If the user
// purchases an item, be sure to report the transaction to Google
// Play.
} else {
// Handle failures such as retrying due to network errors.
}
}
}
billingClient.launchExternalLink(activity, params, listener);
如果您将 LaunchMode 设置为 CALLER_WILL_LAUNCH_LINK,则仅当 onLaunchExternalLinkResponse 提供 BillingResponseCode.OK 时,才应将用户引导至应用外部。
向 Google Play 报告交易
您必须从后端调用 Google Play Developer API,向 Google Play 报告所有外部交易。报告交易时,您必须提供从 createBillingProgramReportingDetailsAsync API 获取的 externalTransactionToken。如果用户进行多次购买,您可以使用同一 externalTransactionToken 来报告每次购买。如需了解如何报告交易,请参阅后端集成指南。
响应处理
如果发生错误,方法 isBillingProgramAvailableAsync()、createBillingProgramReportingDetailsAsync() 和 launchExternalLink() 可能会返回除 BillingResponseCode.OK 之外的响应。建议按如下方式处理这些响应代码:
ERROR:这是内部错误。请勿继续进行交易或打开外部网站。通过调用launchExternalLink()进行重试,以便在下次尝试将用户引导至应用外部时,向用户显示信息对话框。FEATURE_NOT_SUPPORTED:当前设备上的 Play 商店不支持外部优惠 API。请勿继续进行交易或打开外部网站。USER_CANCELED:不继续打开外部网站。再次调用launchExternalLink()以在下次尝试将用户引导至应用外部时向用户显示信息对话框。BILLING_UNAVAILABLE:交易无法使用外部优惠,因此不应按照此计划继续进行。这是因为用户不在符合此计划条件的国家/地区,或者您的账号未成功注册此计划。如果是后一种情况,请在 Play 管理中心内检查您的注册状态。DEVELOPER_ERROR:请求中存在错误。使用调试消息找出并更正错误,然后再继续交易。NETWORK_ERROR, SERVICE_DISCONNECTED, SERVICE_UNAVAILABLE:这些是暂时性错误,应通过适当的重试政策进行处理。如果发生SERVICE_DISCONNECTED错误,请重新与 Google Play 建立连接,然后再重试。
测试外部优惠
许可测试人员应用于测试外部优惠集成。您不会收到许可测试人员账号发起的交易的账单。如需详细了解如何配置许可测试人员,请参阅使用应用许可来测试应用内购结算功能。
后续步骤
完成应用内集成后,您就可以集成后端了。