-
Google Play 创建商品(一次性商品和订阅商品)
首先进入 Google Play Console 后台:https://play.google.com/console/u/0/developers/,找到对应的项目,点击进入项目。找到左侧的Produces-->In-App produces(一次性商品), Produces-->Subscriptions(订阅商品) 中文:商品-->应用内商品和订阅
点击Create product 可以去创建商品,注意Product ID 在一个项目中是唯一的,不能重复,价格直接输入美元即可,各国货币会自动换算,最后创建完商品一定要记得使用哦
-
使用Google Play 结算库购买
文档地址:https://developer.android.com/google/play/billing/integrate?hl=zh-cn
2.1 添加 Google Play 结算库依赖:
将 Google Play 结算库依赖项添加到应用的 build.gradle 文件中,如下所示:
dependencies {
def billing_version = "5.1.0"
implementation "com.android.billingclient:billing:$billing_version"
}
2.2 初始化 BillingClient
添加对 Google Play 结算库的依赖关系后,您需要初始化 BillingClient 实例。BillingClient 是 Google Play 结算库与应用的其余部分之间进行通信的主接口。BillingClient 为许多常见的结算操作提供了方便的方法,既有同步方法,又有异步方法。我们强烈建议您一次打开一个活跃的 BillingClient 连接,以避免对某一个事件进行多次 PurchasesUpdatedListener 回调。
如需创建 BillingClient,请使用 newBuilder()。您可以将任何上下文传递给 newBuilder(),BillingClient 则使用前者来获取应用上下文。这意味着您不必担心内存泄漏。为了接收有关购买交易的更新,您还必须调用 setListener(),并传递对 PurchasesUpdatedListener 的引用。此监听器可接收应用中所有购买交易的更新。
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
// To be implemented in a later section.
}
};
private BillingClient billingClient = BillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases()
.build();
2.3 连接到 Google Play
注意:国内的Google账号这一步会失败,测试时将 Google账号切换到国外大区,创建 BillingClient 后,需要与 Google Play 建立连接。
如需连接到 Google Play,请调用 startConnection()。连接过程是异步进行的,因此必须实现 BillingClientStateListener,以便在客户端的设置完成后且它准备好发出进一步的请求时接收回调。
此外,还必须实现重试逻辑,以处理与 Google Play 失去连接的问题。如需实现重试逻辑,请替换 onBillingServiceDisconnected() 回调方法,并确保 BillingClient 先调用 startConnection() 方法以重新连接到 Google Play,然后再发出进一步的请求。
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
}
}
@Override
public void onBillingServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
}
});
2.4 展示商品
这一步一般商品从服务端获取,价格从Google Play 获取,这样就可以展示本地化的货币价格,在将商品展示给用户之前,查询商品详情是非常重要的一步,因为查询会返回本地化的商品信息。对于订阅,请确保您的商品展示符合所有 Play 政策。如需查询应用内商品详情,请调用 queryProductDetailsAsync()。为了处理该异步操作的结果,还必须指定实现 ProductDetailsResponseListener 接口的监听器。然后,可以替换 onProductDetailsResponse()
QueryProductDetailsParams queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
.setProductList(
ImmutableList.of(
Product.newBuilder()
.setProductId("product_id_example")
.setProductType(ProductType.SUBS)
.build()))
.build();
billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
new ProductDetailsResponseListener() {
public void onProductDetailsResponse(BillingResult billingResult,
List<ProductDetails> productDetailsList) {
// check billingResult
// process returned productDetailsList
}
}
)
2.5 启动购买流程
从应用发起购买请求,请从应用的主线程调用 launchBillingFlow() 方法。此方法接受对 BillingFlowParams 对象的引用,该对象包含通过调用 queryProductDetailsAsync() 获取的相关 ProductDetails 对象,launchBillingFlow() 方法会返回 BillingClient.BillingResponseCode 中列出的几个响应代码之一。请务必检查此结果,以确保在启动购买流程时没有错误。BillingResponseCode 为 OK 表示成功启动。成功调用 launchBillingFlow() 后,系统会显示 Google Play 购买界面
// An activity reference from which the billing flow will be launched.
Activity activity = ...;
ImmutableList productDetailsParamsList =
ImmutableList.of(
ProductDetailsParams.newBuilder()
// retrieve a value for "productDetails" by calling queryProductDetailsAsync()
.setProductDetails(productDetails)
// to get an offer token, call ProductDetails.getSubscriptionOfferDetails()
// for a list of offers that are available to the user
.setOfferToken(selectedOfferToken)
.build()
);
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.build();
// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
Google Play 会调用 onPurchasesUpdated(),以将购买操作的结果传送给实现 PurchasesUpdatedListener 接口的监听器。您可以在初始化客户端时使用 setListener() 方法指定监听器。必须实现 onPurchasesUpdated() 来处理可能的响应:
@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
if (billingResult.getResponseCode() == BillingResponseCode.OK
&& purchases != null) {
for (Purchase purchase : purchases) {
handlePurchase(purchase);
}
} else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
// Handle an error caused by a user cancelling the purchase flow.
} else {
// Handle any other error codes.
}
}
如果成功购买商品,系统会显示 Google Play 购买成功界面:
如果成功购买商品,系统还会生成购买令牌,它是一个唯一标识符,表示用户及其所购应用内商品的商品 ID。应用可以在本地存储购买令牌,不过建议您将令牌传递到安全的后端服务器,随后可以在该服务器上验证购买交易及防范欺诈行为。下一部分对此过程进行了详细说明。
用户还会收到包含交易收据的电子邮件,其中包含订单 ID 或交易的唯一 ID。用户每次购买一次性商品时,都会收到包含唯一订单 ID 的电子邮件。此外,用户最初购买订阅时以及后续定期自动续订时,也会收到这样的电子邮件。可以在 Google Play 管理中心内使用订单 ID 来管理退款。
2.6 处理交易: 消费订单
用户完成购买交易后,您的应用需要处理该购买交易。在大多数情况下,您的应用会通过 PurchasesUpdatedListener 收到购买交易的通知。但在某些情况下,应用通过调用 BillingClient.queryPurchasesAsync() 得知购买交易,如提取购买交易中所述。
应用应按以下方式处理购买交易:
-
验证购买交易。
-
向用户提供内容,并确认内容已传送给用户。还可以选择性地将商品标记为已消费,以便用户可以再次购买商品。
如需验证购买交易,请先检查购买交易的状态是否为 PURCHASED。如果购买交易的状态为 PENDING,则您应按照处理待处理的交易中的说明处理购买交易。对于通过 onPurchasesUpdated() 或 queryPurchasesAsync() 接收的购买交易,您应在应用授予权利之前进一步验证购买交易,以确保其合法性。如需了解如何正确验证购买交易,请参阅在授予权利前验证购买交易。
一旦您验证了购买交易,应用就可以向用户授予权利了。授予权利后,应用必须确认购买交易。此确认会告知 Google Play 已授予购买权。
void handlePurchase(Purchase purchase) {
// Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener.
Purchase purchase = ...;
// Verify the purchase.
// Ensure entitlement was not already granted for this purchaseToken.
// Grant entitlement to the user.
ConsumeParams consumeParams =
ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
ConsumeResponseListener listener = new ConsumeResponseListener() {
@Override
public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
// Handle the success of the consume operation.
}
}
};
billingClient.consumeAsync(consumeParams, listener);
}
注意:由于消耗请求偶尔会失败,因此您必须检查安全的后端服务器,确保所有购买令牌都未被使用过,这样应用就不会针对同一购买交易多次授予权利。或者,您的应用也可以等到您收到 Google Play 发来的成功消耗响应后再授予权利。如果您选择在 Google Play 发来成功消耗响应之前不让用户消耗所购商品,那么您必须非常小心,在消耗请求发出后时刻跟踪相应商品。
如需确认非消耗型商品的购买交易,请使用 Google Play 结算库中的 BillingClient.acknowledgePurchase() 或 Google Play Developer API 中的 Product.Purchases.Acknowledge。在确认购买交易之前,应用应使用 Google Play 结算库中的 isAcknowledged() 方法或 Google Play Developer API 中的 acknowledgementState 字段检查该购买交易是否已经过确认。
以下示例展示了如何使用 Google Play 结算库来确认购买交易:
BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...
void handlePurchase(Purchase purchase) {
if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
if (!purchase.isAcknowledged()) {
AcknowledgePurchaseParams acknowledgePurchaseParams =
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
}
}
}
订阅的处理方式与非消耗型商品类似。可以使用 Google Play 结算库中的 BillingClient.acknowledgePurchase() 或 Google Play Developer API 中的 Purchases.Subscriptions.Acknowledge 确认订阅。所有初始订阅购买交易都需要确认。订阅续订不需要确认。如需详细了解订阅何时需要确认,请参阅销售订阅内容主题。
2.7 提取购买交易,补单逻辑
使用 PurchasesUpdatedListener 监听购买交易更新不足以确保您的应用会处理所有购买交易。有时您的应用可能不知道用户进行的部分购买交易。在下面这几种情况下,您的应用可能会跟踪不到或不知道购买交易:
-
在购买过程中出现网络问题:用户成功购买了商品并收到了 Google 的确认消息,但他们的设备在通过 PurchasesUpdatedListener 收到购买交易的通知之前失去了网络连接。
-
多台设备:用户在一台设备上购买了一件商品,然后在切换设备时期望看到该商品。
-
处理在您的应用外进行的购买交易:某些购买交易(如促销活动兑换)可能会在您的应用外进行。
为了处理这些情况,请确保您的应用在 onResume() 方法中调用 BillingClient.queryPurchasesAsync(),以确保所有购买交易都得到成功处理,如处理购买交易中所述。
以下示例展示了如何提取用户的订阅购买交易。 请注意,queryPurchasesAsync() 仅返回有效订阅和非消耗型一次性购买交易。
billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder()
.setProductType(ProductType.SUBS)
.build(),
new PurchasesResponseListener() {
public void onQueryPurchasesResponse(BillingResult billingResult, List purchases) {
// check billingResult
// process returned purchase list, e.g. display the plans user owns
}
}
);
queryPurchaseHistoryAsync() 会返回用户针对每个商品发起的最近一笔购买记录,即使该购买交易已过期、已取消或已消耗,也仍会提取相关记录。
billingClient.queryPurchaseHistoryAsync(
QueryPurchaseHistoryParams.newBuilder()
.setProductType(ProductType.SUBS)
.build(),
new PurchaseHistoryResponseListener() {
public void onPurchaseHistoryResponse(
BillingResult billingResult, List purchasesHistoryList) {
// check billingResult
// process returned purchase history list, e.g. display purchase history
}
}
);
整个支付流程图:
3.用户购买后,查看用户购买订单
去 Google Play Console 后台 Order management(订单管理) 查看订单:https://play.google.com/console/u/0/developers/