是否可以查询Google Play服务器,以确定某个项目是否是由用户购买的?

时间:2017-08-04 16:16:59

标签: android google-play google-play-services google-play-games google-play-developer-api

我正在学习如何处理来自Android应用的应用内购买。我正在阅读this document

基本上,本文档描述的流程如下:

我的Android应用程序(AKA:客户端)与Google Play应用程序进行通信,该应用程序收集用户的付款信息,然后与Google Play服务器进行通信。 Google Play服务器又将该项目分配给用户并响应Google Play应用程序,然后告知我的客户购买成功。之后,客户提供商品,然后向Google Play应用报告该商品已被消费,从而引导Google Play服务器将商品标记为已消费。

这引发了一个安全问题:我的客户通过告诉我的服务器该商品已被购买来交付商品。我的服务器是提供物品的服务器。我的客户端应用程序是一个多人游戏。因此,我的服务器是 来提供此项目的服务器。仅客户端应用程序无法做到。

但是上述流程要求我的服务器信任客户端。如果客户端被黑客攻击或被恶意程序替换,它可能会告诉我的服务器多次传递任何项目。我的服务器现在可以验证这些购买是否有效。这是一个安全风险。

相反,我希望我的服务器询问Google Play服务器:此用户是否真的拥有此项目? Google Play服务器报告的答案可能会受到信任。但是有API可以这样做吗?如果是这样,该文件在哪里?如果没有这样的API,那么多玩家游戏如何确保其购买的安全性?

2 个答案:

答案 0 :(得分:1)

这个Querying for purchased items主题可能有所帮助:

查询已购买的商品

  

检索有关用户购买的信息   您的应用,请在应用内结算服务中调用getPurchases方法。   传递应用内结算API版本,即您的通话的套餐名称   app,以及购买类型(“inapp”或" subs")到方法中。这里   是一个例子:

Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
  

Google Play服务仅返回用户进行的购买   当前登录到设备的帐户。如果请求是   成功后,返回的Bundle的响应代码为0.响应   Bundle还包含产品ID列表,订单列表   每次购买的详细信息以及每次购买的签名。

     

要提高效果,应用内结算服务最多只返回   当getPurchase第一时,用户拥有的700种产品   调用。如果用户拥有大量产品,Google Play   包括映射到键的String标记   响应Bundle中的INAPP_CONTINUATION_TOKEN表示更多   产品可以检索。然后您的应用程序可以随后进行   getPurchases调用并将此标记作为参数传递。 Google Play   继续在响应Bundle中返回一个延续令牌,直到   用户拥有的所有产品都会发送到您的应用。

     

有关getPurchases返回的数据的更多信息,   请参阅应用内结算参考。以下示例显示了您的操作方法   从响应中检索此数据:

int response = ownedItems.getInt("RESPONSE_CODE");
if (response == 0) {
   ArrayList<String> ownedSkus =
      ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
   ArrayList<String>  purchaseDataList =
      ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
   ArrayList<String>  signatureList =
      ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
   String continuationToken =
      ownedItems.getString("INAPP_CONTINUATION_TOKEN");

   for (int i = 0; i < purchaseDataList.size(); ++i) {
      String purchaseData = purchaseDataList.get(i);
      String signature = signatureList.get(i);
      String sku = ownedSkus.get(i);

      // do something with this purchase information
      // e.g. display the updated list of products owned by user
   }

   // if continuationToken != null, call getPurchases again
   // and pass in the token to retrieve more items
}

答案 1 :(得分:0)

理想情况下,您不应该相信在客户端上进行的购买,因为我们已经看到第三方应用可以在越狱的Android手机上使用,模仿与Google Play商店的互动。

您应该执行以下操作

  1. 列表项
  2. 使用服务器上生成的购买令牌浏览应用程序上的购买流程。
  3. 在客户端收到购买信息
  4. 将购买信息发送到服务器 - 确保购买代币,产品,订单信息有效
  5. 让服务器与Google通话以验证购买 - 请参阅https://developer.android.com/google/play/billing/api.html
  6. 验证后,将响应返回给客户
  7. 让客户将回复返回给Google - 然后将购买标记为已消费。