1. 概览
通过 Google Play 提供的 Play 结算库集成 Codelab,优化您的收入来源并放心地发布应用。此 Codelab 将引导您完成设置、测试和实现可靠的购买交易处理流程,助您实现变现目标并提供更顺畅的用户体验。
我们将帮助您为应用和游戏设置实时开发者通知 (RTDN) 和 Play 结算服务实验室,以便处理订阅和一次性商品。您将了解如何降低订阅者流失率;防范欺诈和滥用行为;测试极端情况;模拟、重现和解决潜在问题;在不影响用户的情况下对优惠和价格变动进行实验。
到最后,您将能够实施赢回用户策略、快速解决集成问题、提高投资回报率、提供卓越体验,并自信地发布应用和更新。
前提条件
- 熟悉基本的 Play 结算库集成
- 熟悉 Android 应用开发 (Java)
学习内容
- 如何通过提升购买转化次数和客户留存率的相关技巧,妥善管理购买生命周期,从而助力优化增长
- 如何使用 Google Cloud Pub/Sub 设置实时开发者通知 (RTDN),以便利用这些通知来实施赢回广告系列和其他生命周期管理策略
- 如何在后端服务器上设置接收器,以便通过准确的跟踪和使用权安全地处理通知,从而降低意外退款或欺诈和滥用风险
- 如何使用 Play Billing Lab 测试集成并模拟错误,从而改善用户体验并降低开发成本
所需条件
- 对应用的 Play 开发者账号的访问权限(在 Google Play 管理中心中)
- 有权访问已启用 Google Play Developer API 的 Google Cloud Platform 项目
- 用于处理 Android 应用的账号和使用权的后端服务器
- 在 Play 管理中心内为您的应用注册的许可测试人员
- 在测试设备上安装了 Play Billing Lab
2. 适用于订阅和一次性购买的变现策略
通过应用销售数字商品时,成功的变现策略必须考虑一次性购买和订阅的整个用户体验。顺畅的体验可以提高购买意愿并降低流失率。
一次性购买或订阅的常见购买流程将涉及多个阶段:
- 用户浏览要购买的商品。
- 启动购买流程,以便用户完成购买和付款。
- 通知服务器完成了购买交易
- 在您的服务器上验证购买交易。
- 向用户提供内容。
- 确认内容已传送给用户。对于消耗型商品,请在适当的时间将购买的商品标记为消耗,以便用户可以再次购买该商品。
借助应用内集成,您可以启动购买流程并管理此类用户体验,但请务必确保您的后端能及时了解用户购买交易的最新权限。这对于跟踪购买交易以及管理用户体验的其他方面(例如跨平台权限)而言非常重要。
实时开发者通知 (RTDN) 是识别购买生命周期中这些不同阶段的绝佳方式,既可用作实时效果跟踪工具,也可用作实现订阅者赢回策略的工具。
例如:假设您的用户刚刚购买了新商品或刚刚错过了付款,因此订阅进入了宽限期。借助合适的 RTDN,您可以近乎实时地识别用户状态的变化,并采取相应措施,例如让用户与刚刚购买的商品产生更深层次的互动,或者向用户发送提醒电子邮件,让他们更新付款详细信息以继续订阅。
RTDN 还非常适合添加额外的服务器端控件,以便在用户的客户端出现问题时帮助您管理购买交易。假设用户成功购买了商品并收到了 Google 的确认消息,但用户设备在通过购买监听器收到购买交易的通知之前失去了网络连接。借助 RTDN,您会通过服务器收到独立通知,从而能够独立于客户端问题来识别购买交易并向用户授予使用权,确保购买流程可靠无误。
您可以点击此处详细了解目前支持的所有类型的 RTDN。每种类型的 RTDN 都表示不同的购买状态。请务必实现相应的处理机制,以确保根据您的用例需要进行适当的处理。此 Codelab 将引导您通过一个示例了解如何在安全的后端服务器中处理 RTDN 消息,包括在用户在您的应用中成功完成购买交易时接收消息、验证购买交易并向正确的用户授予使用权。接下来,我们将向您展示如何为应用配置 RTDN。
3. 配置实时开发者通知 (RTDN)
实时开发者通知 (RTDN) 利用 Google Cloud Pub/Sub,让您能够立即对购买交易状态变化做出响应。Cloud Pub/Sub 是一项完全托管的实时消息传递服务,您可以使用该服务在独立应用之间发送和接收消息。Google Play 使用 Cloud Pub/Sub 发布有关您所订阅主题的推送通知。
如需启用 RTDN,您必须先使用自己的 Google Cloud Platform (GCP) 项目设置 Cloud Pub/Sub,然后再为您的应用启用通知。如果您不熟悉 GCP 和 Cloud Pub/Sub,请参阅快速入门指南。
创建主题
如需开始接收通知,您必须创建一个主题,Google Play 会将通知发布到该主题。如需创建主题,请按照创建主题中的说明操作。
创建 Pub/Sub 订阅
如需接收发布到某个主题的消息,您必须针对该主题创建 Pub/Sub 订阅。如需创建 Pub/Sub 订阅,请执行以下操作:
- 阅读 Cloud Pub/Sub 订阅者指南,熟悉如何将订阅配置为“推送订阅”或“提取订阅”。在此 Codelab 中,我们将使用拉取订阅,该订阅要求您的安全后端服务器向 Cloud Pub/Sub 服务器发起请求以检索消息。
- 按照添加订阅中的说明来创建订阅。
针对您的主题授予发布权限
Cloud Pub/Sub 要求您向 Google Play 授予向您的主题发布通知的权限。
- 打开 Google Cloud 控制台。
- 选择您的项目,然后在搜索栏中搜索“Pub/Sub”,并前往 Pub/Sub 配置页面。
- 找到您的主题,然后打开权限设置。
- 点击添加主账号以添加服务账号
google-play-developer-notifications@system.gserviceaccount.com
,然后为其授予 Pub/Sub 发布商角色。 - 点击保存以完成主题的设置。
为应用启用 RTDN
了解如何设置实时开发者通知 (RTDN),以显著增强 Play 结算服务集成。您可以通过个性化消息提高购买交易的可靠性,还可以防范欺诈和滥用行为,从而提高整体投资回报率。
RTDN 可直接从 Google Play 针对关键事件(例如订阅续订、新购买交易和付款问题)提供服务器到服务器的即时更新。它们可帮助您的后端系统自动与用户使用权的真实状态同步,从而超越客户端限制,让您能够立即做出适当的响应。
如何为您的应用启用实时开发者通知:
- 打开 Google Play 管理中心。
- 选择您的应用。
- 依次前往通过 Play 创收 > 创收设置。
- 滚动到实时开发者通知部分。
- 选中启用实时通知。
- 在主题名称字段中,输入您之前配置的完整 Cloud Pub/Sub 主题名称。主题名称应采用 projects/{project_id}/topics/{topic_name} 格式,其中 project_id 是项目的唯一标识符,topic_name 是之前创建的主题的名称。
- 点击发送测试消息以发送测试消息。执行测试发布有助于确保一切均已正确设置和配置。如果测试发布成功,则系统会显示一条消息,表明测试发布已成功。如果您已附加该主题的订阅,则应收到测试消息。对于“拉取订阅”,请在 Cloud 控制台中找到该订阅,点击查看消息,然后继续拉取消息。您应确认提取的任何消息,以避免 Cloud Pub/Sub 重复传送。对于推送订阅,检查测试消息是否已传送至您的推送端点。成功的响应代码将充当消息确认的作用。如果发布失败,则系统会显示错误。请确保主题名称正确,并且
google-play-developer-notifications@system.gserviceaccount.com
服务账号拥有对该主题的 Pub/Sub 发布商访问权限。 - 选择您希望接收的通知类型。
- 接收与订阅和所有废弃的购买交易相关的通知 - 接收与订阅和废弃的购买交易相关的实时开发者通知。您不会收到一次性商品购买交易的通知。
- 接收与订阅和一次性商品相关的所有通知 - 接收与所有订阅和作废的购买交易事件相关的通知。您还会收到一次性商品购买事件,例如
ONE_TIME_PRODUCT_PURCHASED
和ONE_TIME_PRODUCT_CANCELED
。如需详细了解这些购买事件,请参阅一次性购买生命周期。
- 点击保存更改。
现在,您已为应用完成实时开发者通知设置,可以使用相关工具来解决常见问题,例如通过发送挽回消息来防止用户流失,或防范欺诈和滥用行为。在下一部分中,我们将在安全后端服务器中构建一个订阅器,以使用发送到您的 Cloud Pub/Sub 主题的消息。
4. 接收通知
为了在您的应用中提供最佳用户体验,请务必让后端服务器及时更新购买交易状态。例如,当用户在应用中成功完成付款交易后,应尽快将内容提交到其账号。
这需要及时检测和处理购买交易完成情况。Play 结算库提供了多种在应用中检测购买交易的方法。检测到已完成的购买交易后,您的应用必须通知后端服务器以验证购买交易、向正确的用户授予内容,然后通知 Google 已处理购买交易。不过,由于各种原因,您的应用可能未及时检测到购买交易。例如,用户可以成功购买商品并收到 Google 的确认消息,但在用户设备和您的应用通过 Play 结算库接口收到通知之前,用户设备的网络连接中断了。RTDN 提供了额外的服务器端控件,即使用户的客户端出现问题,也能帮助您管理购买交易。RTDN 可确保在购买交易状态发生变化时向您的服务器发送独立通知,让您能够通过第二条路径几乎立即识别购买交易状态变化,而不会受到潜在客户端问题的影响,从而确保购买流程更加可靠。
在本部分中,您将使用 Cloud Pub/Sub 客户端库构建一个订阅器,以使用发送到您的 Cloud Pub/Sub 主题的消息。这些库有多种语言版本。在以下部分中,我们将添加订阅者以验证购买交易、向正确的用户授予使用权,并在服务器上确认/使用购买交易。在本 Codelab 中,我们使用的是 Java。
发布到 Cloud Pub/Sub 主题的每条消息都包含一个以 base64 编码的数据字段。
{
"message": {
"attributes": {
"key": "value"
},
"data": "eyAidmVyc2lvbiI6IHN0cmluZywgInBhY2thZ2VOYW1lIjogc3RyaW5nLCAiZXZlbnRUaW1lTWlsbGlzIjogbG9uZywgIm9uZVRpbWVQcm9kdWN0Tm90aWZpY2F0aW9uIjogT25lVGltZVByb2R1Y3ROb3RpZmljYXRpb24sICJzdWJzY3JpcHRpb25Ob3RpZmljYXRpb24iOiBTdWJzY3JpcHRpb25Ob3RpZmljYXRpb24sICJ0ZXN0Tm90aWZpY2F0aW9uIjogVGVzdE5vdGlmaWNhdGlvbiB9",
"messageId": "136969346945"
},
"subscription": "projects/myproject/subscriptions/mysubscription"
}
对以 base64 编码的数据字段进行解码后,DeveloperNotification
包含以下字段:
{
"version": string,
"packageName": string,
"eventTimeMillis": long,
"oneTimeProductNotification": OneTimeProductNotification,
"subscriptionNotification": SubscriptionNotification,
"voidedPurchaseNotification": VoidedPurchaseNotification,
"testNotification": TestNotification
}
如需了解详情,请参阅实时开发者通知参考指南。
以下是用于安全后端服务器处理 Pub/Sub 消息的 NotificationReceiver 示例代码。如需向 Security Command Center 进行身份验证,请设置应用默认凭据,具体请参阅为本地开发环境设置身份验证。
import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
import java.util.Base64;
import org.json.JSONObject;
/** Real-time developer notifications receiver. */
public class NotificationReceiver {
private NotificationReceiver() {}
/*
* Receive notification messages from the subscription.
*
* @param projectId The project ID of your Google Cloud Project.
* @param subscriptionId The subscription ID of the subscriber to the pub/sub topic.
*/
public static void receiveNotificationMessages(String projectId, String subscriptionId) {
ProjectSubscriptionName subscriptionName =
ProjectSubscriptionName.of(projectId, subscriptionId);
try {
Subscriber subscriber =
Subscriber.newBuilder(subscriptionName, new NotificationMessageReceiver()).build();
// Start the subscriber.
subscriber.startAsync().awaitRunning();
subscriber.awaitTerminated();
} catch (IllegalStateException e) {
System.out.println("Subscriber stopped: " + e);
}
}
static class NotificationMessageReceiver implements MessageReceiver {
@Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
// Decode the data into a String from the message data field.
String jsonString = new String(Base64.getDecoder().decode(message.getData().toStringUtf8()));
// Parse the String into a JSON object.
JSONObject messageJson = new JSONObject(jsonString);
// Fetch the value for certain fields.
String version = messageJson.getString("version");
String packageName = messageJson.getString("packageName");
System.out.println("version: " + version);
System.out.println("packageName: " + packageName);
// Validate the purchase and grant the entitlement as needed.
// More details in the following sections.
// ......
// Acknowledge the message to avoid repeated delivery.
consumer.ack();
}
}
}
现在,您有一个通知接收器,用于在安全后端服务器中使用发送到您的 Cloud Pub/Sub 主题的消息。在以下部分中,我们将介绍在后端服务器中处理 RTDN 消息的最佳实践。
5. 在应用的购买流程中附加用户标识符
当您的服务器收到有关购买交易状态更新的 RTDN 消息时,需要知道是哪位用户进行了购买交易,以便进行处理,例如将内容提交给正确的用户。为此,您可以在应用中启动购买流程时,使用 obfuscatedAccountId 附加您为进行购买交易的用户拥有的任何用户标识符。示例标识符可以是系统中用户登录信息的经过混淆处理的版本。设置此参数有助于 Google 检测欺诈行为。此外,它还有助于您确保将购买交易归因于正确的用户,如向用户授予使用权中所述。
以下示例代码展示了如何通过设置 obfuscatedAccountId 在应用中启动购买流程时附加用户标识符。
// An activity reference from which the billing flow will be launched.
Activity activity = ...;
// A user identifier, e.g. an obfuscated user id in your system.
String obfuscatedAccountId = ...;
ImmutableList<ProductDetailsParams> productDetailsParamsList =
ImmutableList.of(
ProductDetailsParams.newBuilder()
// retrieve a value for "productDetails" by calling queryProductDetailsAsync()
.setProductDetails(productDetails)
// set the offer token to specify the offer to purchase when applicable, e.g., subscription products
// .setOfferToken(offerToken)
.build()
);
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.setObfuscatedAccountId(obfuscatedAccountId)
.build();
// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
如您将在下一部分中看到,在购买流程中设置的用户标识符将包含在购买交易中,可用于向正确的用户授予权限。
6. 在授予权利前验证购买交易
在本部分中,我们将介绍在安全的后端服务器中授予权利前验证购买交易的最佳实践。
用户购买一次性商品后,安全后端服务器中的 Pub/Sub 订阅方将收到 Pub/Sub 消息。您应在后端服务器中执行以下操作:
- 解析 Pub/Sub 消息中的
purchaseToken
。您应维护一份所有购买交易的所有purchaseToken
值记录。 - 验证当前购买交易的
purchaseToken
值是否与以前的任何purchaseToken
值都不匹配。purchaseToken
具有全局唯一性,因此您可以放心地使用此值作为数据库中的主键。 - 使用 Google Play Developer API 中的 purchases.products:get 端点向 Google 验证购买交易是否合法。
- 如果购买交易合法且过去没有使用过,那么您就可以放心地授予对应用内商品或订阅的权利。
- 只有在购买交易状态为
PURCHASED
时,您才能授予权利,并确保正确处理PENDING
购买交易。如需了解详情,请参阅处理待处理的交易。
以下代码示例会为 Google Play Developer API 创建一个 API 客户端。我们稍后会使用它来进行 API 调用。
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisherScopes;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
/** Helper class to initialize the publisher APIs client library. */
public class AndroidPublisherHelper {
/* Your application name */
private static final String APPLICATION_NAME = "YourApplicationName";
/* Load credentials from a JSON key file. Replace with the actual path to your downloaded service
* account key file.
*/
private static final String RESOURCES_CLIENT_SECRETS_JSON =
"/path/to/your/service_account_key.json";
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
/* The API client */
private static final AndroidPublisher ANDROID_PUBLISHER = init();
/**
* Performs all necessary setup steps for running requests against the API.
*
* @return the {@link AndroidPublisher} service
*/
private static AndroidPublisher init(){
try {
// Authorization.
Credential credential =
GoogleCredential.fromStream(
AndroidPublisherHelper.class.getResourceAsStream(RESOURCES_CLIENT_SECRETS_JSON))
.createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
// Set up and return API client.
return new AndroidPublisher.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(ApplicationConfig.APPLICATION_NAME)
.build();
} catch (GeneralSecurityException | IOException ex) {
throw new RuntimeException("fail to initialize the publisher APIs client library", ex);
}
}
}
然后,我们添加了用于进行 API 调用的逻辑,并修改了之前构建的接收器,以验证购买交易并向正确的用户授予使用权。
在 AndroidPublisherHelper
中,添加以下方法以从 Google Play Developer API 中的 Purchases.products:get 端点提取 ProductPurchase。
/* Fetch the ProductPurchase for the one-time product purchase from
* Purchases.products.get endpoint in the Google Play Developer API
*/
public static ProductPurchase executeProductPurchasesGet(
String packageName, String sku, String purchaseToken) {
try {
ProductPurchase productPurchase =
ANDROID_PUBLISHER.purchases().products().get(packageName, sku, purchaseToken).execute();
return productPurchase;
} catch (IOException ex) {
log.error("Exception was thrown while getting a product purchase", ex);
// It is recommended to apply some retry mechanism, such as exponential backoff, to fetch the purchase in case of transient failures.
return null;
}
}
在 NotificationMessageReceiver
中,根据通知中包含的数据验证购买交易,并向系统中的正确用户授予使用权。您应持续跟踪服务器中的 purchaseToken
,以免重复处理。
@Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
// Decode the data into a String from the message data field.
String jsonString = new String(Base64.getDecoder().decode(message.getData().toStringUtf8()));
// Parse the String into a JSON object.
JSONObject messageJson = new JSONObject(jsonString);
// Fetch the value for certain fields.
String version = messageJson.getString("version");
String packageName = messageJson.getString("packageName");
// Process notification data based on your business requirements.
// Process oneTimeProductNotification in the message.
JSONObject oneTimeProductNotificationJson =
messageJson.getJSONObject("oneTimeProductNotification");
if (oneTimeProductNotificationJson != null) {
String purchaseToken = oneTimeProductNotificationJson.getString("purchaseToken");
String sku = oneTimeProductNotificationJson.getString("sku");
int notificationType = oneTimeProductNotificationJson.getInt("notificationType");
if (notificationType == 1) {
// ONE_TIME_PRODUCT_PURCHASED - A one-time product was successfully purchased by a user.
// Verify that the purchaseToken value does not match any previous purchaseToken values in
// your backend system to avoid duplicate processing.
......
// Fetch the ProductPurchase from Purchases.products.get endpoint
ProductPurchase productPurchase =
AndroidPublisherHelper.executeProductPurchasesGet(packageName, sku, purchaseToken);
if (productPurchase != null && productPurchase.getPurchaseState() == 0) {
// The purchase is valid and in PURCHASED state.
// The account Id set in the App when launching the billing flow.
String obfuscatedExternalAccountId = productPurchase.getObfuscatedExternalAccountId();
// Grant the entitlement to the correct account for obfuscatedExternalAccountId in your
// system.
......
}
}
// Process subscriptionNotification in the message.
JSONObject subscriptionNotificationJson = messageJson.getJSONObject("subscriptionNotification");
if (subscriptionNotificationJson != null) {
......
}
// Process other notification data in the message as needed.
......
}
// Acknowledge the message to avoid repeated delivery.
consumer.ack();
}
7. 通知 Google 购买交易已处理
授予权利后,您应通过安全后端服务器调用 Play Developer API 中的 purchases.products:consume 或 purchases.products:acknowledge 端点来消耗消耗型商品或确认非消耗型商品,以通知 Google 购买交易已处理完毕。
在 AndroidPublisherHelper
中,添加以下方法以调用 Google Play Developer API 中的 purchases.products:consume 或 purchases.products:acknowledge。
/* Consume the one-time product purchase by calling
* Purchases.products.consume endpoint in the Google Play Developer API
*/
public static void executeProductPurchasesConsume(
String packageName, String sku, String purchaseToken) {
try {
ANDROID_PUBLISHER
.purchases().products().consume(packageName, sku, purchaseToken).execute();
} catch (IOException ex) {
log.error("Exception was thrown while consuming a product purchase", ex);
// It is recommended to apply some retry mechanism, such as exponential backoff, to ensure the purchase is correctly consumed in case of transient failures.
}
}
/* Acknowledge the one-time product purchase by calling
* Purchases.products.acknowledge endpoint in the Google Play Developer API
*/
public static void executeProductPurchasesAcknowledge(
String packageName, String sku, String purchaseToken) {
try {
ANDROID_PUBLISHER
.purchases().products().acknowledge(packageName, sku, purchaseToken, new ProductPurchasesAcknowledgeRequest()).execute();
} catch (IOException ex) {
log.error("Exception was thrown while acknowledging a product purchase", ex);
// It is recommended to apply some retry mechanism, such as exponential backoff, to ensure the purchase is correctly acknowledged in case of transient failures.
}
}
在 NotificationMessageReceiver
中,在后端服务器中授予使用权后,消耗消耗型商品购买交易或确认非消耗型商品购买交易。
@Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
......
String obfuscatedExternalAccountId = productPurchase.getObfuscatedExternalAccountId();
// Grant the entitlement to the correct account for obfuscatedExternalAccountId in your
// system.
......
// If the product is a consumable product, consume the purchase.
AndroidPublisherHelper.executeProductPurchasesConsume(packageName, sku, purchaseToken);
// Or if the product is a non-consumable product, acknowledge the purchase.
// AndroidPublisherHelper.executeProductPurchasesAcknowledge(packageName, sku, purchaseToken);
......
}
必须进行确认,这样才能向 Google Play 告知用户已获得购买交易的权利。您应在授予使用权后立即确认购买交易。
太棒了!您已成功集成实时开发者通知,从而实现了可靠的购买交易处理,如此 Codelab 中所示。现在,为了确保一切正常运行,我们来探索一下 Play Billing Lab。这是一个简单易用的工具,旨在帮助您测试 Play 结算服务集成。
8. 使用 Play Billing Lab 进行测试
为了能够放心地发布应用,您应在整个开发过程中不断测试集成情况。Play Billing Lab 是一款免费的 Android 应用,可帮助开发者测试其与 Google Play 结算系统的集成,让开发者能够轻松便捷地测试 Play 结算功能,更快地进行集成,并更加信心十足地发布应用。
Play 结算实验室提供各种测试功能,可帮助您测试不同的场景,包括:
- 在 Play 结算服务实验室中更改 Play 国家/地区,并将设置应用于您的测试。这样一来,无论测试人员实际在哪里进行测试,都可以在不同国家/地区测试自定义用户体验
- 使用同一账号反复测试试用或初次体验优惠
- 测试订阅价格变动,而不会影响其他活跃订阅者
- 模拟 Play 结算库响应代码,以便在各种错误场景下进行测试
- 加快订阅续订速度以加快测试速度
- 使用真实的付款方式进行测试,以绕过某些购买流程风险信号
我们会不断向 Play Billing Lab 应用添加新的测试功能。您可以从 Play 商店下载并安装 Play Billing Lab,也可以参阅测试集成,详细了解如何使用 Play Billing Lab 进行测试。
使用 Play Billing Lab 测试 BillingResponseCode
在将应用与 Play 结算库集成时,测试所有 BillingResponseCode 流程是一项常见的挑战,因为您无法对 Play 商店与 Play 后端之间的通信进行太多控制。借助 Play 结算实验室应用中的响应模拟器功能,您可以为 Play 结算库配置错误代码响应,以测试各种复杂的错误场景。
例如,您在应用中实现了在应用检测到成功购买交易后消耗购买交易的逻辑。您想测试以下场景:您的应用因网络故障而未能消耗购买交易,而后端服务器中的 RTDN 接收器会接收消息并正确处理购买交易。您可以利用响应模拟器来模拟测试场景。以下内容将引导您完成使用 Play Billing Lab 响应模拟器进行测试的步骤。
使用响应模拟器进行测试
使用响应模拟器进行测试时,您的应用将与 Play Billing Lab 通信,以获取您在 Play Billing Lab 响应模拟器中配置的响应代码。
为 Play 结算库启用结算替换项测试
如需实现 Response Simulator 与应用之间的通信,您必须先在应用内为 Play 结算库启用结算替换项测试。为此,请将以下元数据标记添加到应用的 AndroidManifest.xml
文件中。
<manifest ... >
<application ... >
...
<meta-data
android:name="com.google.android.play.largest_release_audience.NONPRODUCTION"
android:value="" />
<meta-data
android:name="com.google.android.play.billingclient.enableBillingOverridesTesting"
android:value="true" />
</application>
</manifest>
使用更新后的 AndroidManifest.xml
文件构建应用。现在,您的应用已准备好使用 Play Billing Lab 响应模拟器。
在测试后将应用部署到生产环境时,您应使用不包含这些元数据标记的单独 AndroidManifest.xml
文件,或者确保已从 AndroidManifest.xml
文件中移除这些标记。
模拟 Play 结算库错误
如需使用模拟的 Play 结算库错误进行测试,请先在 Play Billing Lab 应用中配置响应代码,然后在您的应用中执行测试。
配置响应代码
- 使用应用的许可测试人员账号登录 Play Billing Lab 应用。下图显示了 Play Billing Lab 信息中心,其中包含响应模拟器卡片。
- 点击“响应模拟器”卡片上的管理,前往“响应模拟器”界面。
- 出现提示时,允许 Play 结算服务实验室发送通知,以了解应用的连接状态。
- 启用“模拟 Play 结算库响应”开关(如果尚未启用)。
- 为您要测试的 Play 结算库 API 选择响应代码。如需模拟消耗购买交易的错误,请为
consumeAsync
API 选择一个错误代码。系统会自动保存您的选择。现在,响应模拟器已准备好向您的应用发送所选的响应代码。
测试应用
现在,您可以测试应用,以验证在配置的错误场景中是否一切正常。打开您的应用并触发 Play 结算库 API 方法。如果您的应用调用 consumeAsync
来消耗购买交易,则会收到您刚刚配置的错误代码。您可以根据错误代码验证应用是否正常运行,以及后端服务器是否正确处理购买交易。
测试完成后,只需关闭“模拟 Play 结算库响应”开关即可停止模拟响应。
详细了解如何使用 Play 结算实验室进行测试,或访问帮助中心,详细了解如何使用许可测试人员测试应用内购结算功能。
9. 恭喜!
您已完成此 Codelab,现在可以从战略层面优化应用变现,从而改善用户体验,进而提高用户满意度、购买转化次数和订阅者流失率。
通过利用实时开发者通知和 Play 结算实验室配套应用,您可以主动处理一次性购买交易和订阅的购买生命周期事件。
借助这些工具,您可以有效实施富有吸引力的再吸引策略、快速解决集成问题,并最终提升用户体验和收入来源,从而放心地发布应用或游戏。
通过完成此 Codelab,您现在已掌握了管理整个购买历程的技能,并可以使用 Play 结算实验室对您的实现进行严格测试,从而确保顺畅的用户体验,并最大限度地发挥您在 Google Play 上的创收潜力。