【问题标题】:Can Google Play Server be queried to find out if an item was purchased by user?是否可以查询 Google Play 服务器以了解用户是否购买了商品?
【发布时间】:2018-01-12 15:58:21
【问题描述】:

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

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

我的 Android 应用(又名:客户端)与收集用户付款信息的 Google Play 应用通信,然后与 Google Play 服务器通信。 Google Play 服务器依次将商品分配给用户并响应 Google Play 应用程序,然后通知我的客户购买成功。之后,客户端交付商品,然后向 Google Play 应用报告该商品已被消费,这反过来又导致 Google Play 服务器将商品标记为已消费。

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

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

相反,我希望我的服务器询问 Google Play 服务器:此用户是否真正拥有此项目? Google Play 服务器报告的答案是可信的。但是有 API 可以做到这一点吗?如果是这样,该文档在哪里?如果没有这样的API,那么多人游戏如何保证购买的安全??

【问题讨论】:

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


    【解决方案1】:

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

    查询购买的物品

    检索有关用户从以下网站进行的购买的信息 您的应用,请在应用内结算服务上调用 getPurchases 方法。 传递 In-app Billing API 版本,你调用的包名 应用程序,以及方法中的购买类型(“inapp”或“subs”)。这里 是一个例子:

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

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

    为提高性能,应用内结算服务最多只能返回 getPurchase 优先时用户拥有的 700 个产品 叫。如果用户拥有大量产品,Google Play 包括一个映射到键的字符串标记 响应 Bundle 中的 INAPP_CONTINUATION_TOKEN 表示更多 可以检索产品。然后,您的应用程序可以进行后续 getPurchases 调用并传入此令牌作为参数。谷歌播放 继续在响应包中返回一个延续令牌,直到 用户拥有的所有产品都会发送到您的应用。

    有关 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
    }
    

    【讨论】:

    • 这似乎必须从设备上的应用程序调用 - 而不是我的服务器。 "The Google Play service returns only the purchases made by the user account that is currently logged in to the device."我需要知道我的服务器如何从 Google Play(不信任应用程序)中找到已购买但尚未消费的物品。
    • 我没有像您那样在应用计费中对 Google Play 进行过多试验,所以我只能引用官方文档。不确定您正在做的事情是否受支持。
    【解决方案2】:

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

    你应该做以下事情

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-15
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多