gpt4 book ai didi

android - 在 Google Play 的 Billing API v3 中解决消耗品的 API-purchase-logic-flaws(与使用 API v3 消耗品的每个人相关)

转载 作者:行者123 更新时间:2023-12-02 15:19:43 24 4
gpt4 key购买 nike

使用 Billing API 的第 3 版,Google has removed the distinction between consumable and non-consumable products .两者都被组合成一种称为“托管”的新类型,其行为有点像混合:您的应用程序需要主动调用一个方法来“使用”项目。如果对于一组 skus 从来没有这样做,那么这些元素基本上表现为它们是非消耗品。

documentation将预期的购买流程描述如下:

  • 使用 getBuyIntent 启动购买流程称呼。
  • 得到回复 Bundle来自 Google Play,指示购买是否成功完成。
  • 如果购买成功,请通过 consumePurchase 消费购买称呼。
  • 从 Google Play 获取响应代码,指示消费是否成功完成。
  • 如果消费成功,请在您的应用程序中配置产品。

  • 我发现这种方法有两个问题。一个是相当明显的,在文档中比 API 更像是一个“错误”,但另一个是相当微妙的,我仍然没有想出如何最好地处理它。为了完整起见,让我们从显而易见的开始:

    问题一:单机丢失购买:

    文档说应用程序应该调用 getPurchases每次启动时都会“检查用户是否拥有任何未完成的可消耗应用内产品”。如果是这样,应用程序应该使用这些并提供关联的项目。这涵盖了购买流程在购买完成后但在元素被消耗之前(即在第 2 步左右)中断的情况。

    但是,如果购买流程在第 4 步和第 5 步之间中断怎么办? IE。该应用程序已成功消费购买,但在它有机会向用户提供产品之前就被终止了(电话打进来,周围没有足够的内存,电池没电,崩溃等等)。在这种情况下,购买将不再包含在 getPurchases 中。并且基本上用户永远不会收到他支付的费用(在此处插入愤怒的支持电子邮件和一星评论)......

    幸运的是,通过引入“日志”( like in a file system )将购买流程更改为更像这样的内容(步骤 1 和 2 与上述相同),这个问题很容易解决:
  • 如果购买成功,在日记中写上“一旦购买 成功消费,硬币从300增加到400”。
  • 确认日记帐分录后,通过制作 consumePurchase 消费购买。称呼。
  • 从 Google Play 获取响应代码,指示消费是否成功完成。
  • 如果消费成功,请在您的应用程序中配置产品。
  • 确认供应后,将日记帐分录更改为“purchase completed”。

  • 然后,每次应用程序启动时,它不应该只是检查 getPurchases ,也是杂志。如果那里有一个条目未由 getPurchases 报告的未完成购买,继续第 6 步。如果稍后 getPurchase应该再次返回该订单 ID 作为拥有的(例如,如果消费毕竟失败了),如果日志将此订单 ID 列为完整,则只需忽略该交易。

    这应该可以解决问题 1,但是如果您发现这种方法有任何缺陷,请告诉我。

    问题二:涉及多个设备时的问题:

    假设用户拥有两台设备(例如手机和平板电脑),并在两台设备上使用相同的帐户。

    他(或她 - 从现在开始暗示)可以尝试在他的 上购买更多的硬币。电话 并且该应用程序可能会在购买完成后但在消费之前被杀死。现在,如果他在他的 上打开应用程序平板电脑接下来, getPurchases将报告该产品为自有产品。

    平板电脑上的应用程序必须假设购买是在那里发起的,并且在创建日记帐分录之前就已终止,因此它将创建日记帐分录、消费产品并提供硬币。

    如果手机应用程序在它有机会进行日记条目之前就死了,则永远不会在手机上配置硬币(在此处插入愤怒的支持电子邮件和一星评论)。如果手机应用程序在日记条目创建后死亡,硬币将 还有在手机上进行配置,基本上是让用户在平板电脑上免费购买(在此处插入收入损失)。

    解决此问题的一种方法是将一些唯一的安装或设备 ID 作为有效负载添加到购买中,以检查购买是否适用于该设备。然后,平板电脑可以简单地忽略购买,只有手机会记入硬币并消费该元素。

    但是:由于此时 sku 仍为用户所有,因此 Play 商店不会允许用户购买另一个副本,因此基本上,直到用户在手机上再次启动该应用以完成待处理的交易,他才能在平板电脑上购买更多虚拟硬币(在此处插入愤怒的支持电子邮件、一星评论和收入损失)。

    有没有一种优雅的方法来处理这种情况?我能想到的唯一解决方案是:
  • 向用户显示一条消息,请先在其他设备上启动应用程序(糟糕!)
  • 或者为同一个消耗品添加多个 skus(应该可以工作,但仍然很糟糕!)

  • 有没有更好的办法?或者我可能只是从根本上误解了一些东西,这里真的没有问题? (我意识到这个问题出现的可能性很小,但是有了足够大的用户群,“不太可能”最终会变成“一直”。)

    最佳答案

    这是解决所有这些问题的最简单方法,这是我迄今为止提出的。这不是最优雅的方法,但至少它应该有效:

  • 生成全局唯一 购买编号 并将其存储在本地设备上。
  • 使用 getBuyIntent 启动购买流程与 购买编号 作为开发人员有效负载。
  • 得到回复 Bundle来自 Google Play,指示购买是否成功完成。
  • 如果购买成功,请配置产品并记住 购买编号 完成(这必须以原子方式完成)。
  • 如果配置成功,则通过 consumePurchase 消费购买。调用(我以“即发即忘”的方式执行此操作)。

  • 每次启动应用程序时,请执行以下操作:
  • 发送 getPurchases请求查询用户拥有的应用内商品。
  • 如果发现任何消耗品,请检查 购买编号 在开发人员有效负载中存储在设备上。如果没有,请忽略该产品。
  • 对于带有“本地”字样的产品 购买编号 , 检查 购买编号 包含在已完成列表中。如果不是,则继续上述第 4 步,否则继续上述第 5 步。

  • 以下是在单个设备上出现问题的方式以及随后会发生的情况:
  • 如果购买从未开始或未完成,则不会向用户收费,应用将返回到购买前状态,用户可以重试。未使用的 购买编号 仍然在“本地”列表中,但这应该只是一个相当小的“内存泄漏”,可以用一些过期逻辑来修复。
  • 如果购买完成,但应用程序在第 4 步之前终止,当它重新启动时,它会找到待处理的购买(该产品仍报告为已拥有)并可以继续第 4 步。
  • 如果应用程序在第 4 步之后但在产品被消费之前终止,应用程序会在重新启动时找到待处理的购买,但知道将其忽略为 购买编号 在已完成列表中。该应用程序只是继续第 5 步。

  • 在多设备情况下 ,任何其他设备将简单地忽略任何非本地挂起的购买(消耗品报告为拥有)作为 购买编号 不在该设备的本地列表中。

    一个问题是待处理的购买将阻止其他设备开始并行购买同一产品。因此,如果用户在他的手机上的第 2 步和第 5 步之间(即购买完成之后,消费完成之前)有一个未完成的交易,他将无法在他的平板电脑上再购买相同的产品,直到应用程序完成第 5 步,即在手机上消费产品。

    通过将每个消耗品 SKU 的多个副本(也许是 5 个?)添加到 Google Play 并将第一个列表中的第 2 步更改为:
  • 发起购买流程用于集合中的下一个可用 SKU getBuyIntent购买编号 作为开发人员有效负载。

  • 关于可破解性的说明(按照黑客难度增加的顺序):
  • 通过 Freedom APK 完成虚假购买或类似:这些应用程序基本上是冒充 Google Play 商店来完成购买。要检测它们,需要verify the signature包含在购买收据中并拒绝未通过检查的购买,大多数应用程序不会这样做(right)。大多数情况下问题已解决(见第 4 点)。
  • 通过 Game Killer 增加消耗品的应用内帐户余额或类似:这些应用程序会尝试找出您的应用程序在内存(或本地存储)中存储当前硬币或其他消耗品数量的位置,以直接修改数量。为了使这更难(即对于普通用户来说不可能),需要想出一种方法来存储帐户余额,而不是将其存储为“纯文本”整数,而是以某种加密方式或与一些校验和一起存储。大多数情况下问题已解决(见第 4 点)。
  • 在正确的时间杀死应用程序并弄乱其本地存储:如果有人在他们的 上购买了消耗品电话 并设法在产品供应后但在使用之前终止应用程序(可能很难强制),然后他们可以修改其 上的本地存储。平板电脑添加 购买编号 到本地列表,在每台设备上授予一次产品。或者,他们可能会破坏已完成的列表 购买 ID 在手机上并重新启动应用程序以获得两次奖励。如果他们在配置之后但在使用产品之前再次设法杀死应用程序(现在只需将手机设置为飞行模式并删除 Google Play 商店缓存就很容易),他们可以通过这种方式继续窃取越来越多的产品。同样,混淆或校验存储会使这变得更加困难。
  • 为应用程序反编译和开发补丁:当然,这种方法允许黑客几乎可以对您的应用程序做任何他们想做的事情(包括破坏为缓解第 1 点和第 2 点而采取的任何对策),并且很难完全阻止。但是,通过对关键的采购管理代码使用代码混淆 ( ProGuard ) 和过于复杂的逻辑(可能会导致错误代码,因此这不一定是最好的主意),黑客可能会更加困难。此外,代码的编写方式可以在不影响其功能的情况下修改其逻辑,以允许定期部署破坏任何可用补丁的替代版本。

  • 总的来说,购买的签名验证和一些相对简单但不明显的校验和或相关数据(在内存和本地存储中)的签名应该足以迫使黑客反编译(或以其他方式逆向工程)应用程序为了窃取产品。除非应用程序变得非常流行,否则这应该是一个足够的威慑力。代码中的灵活逻辑加上破坏任何已开发补丁的频繁更新可以使应用程序成为黑客的移动目标。

    请记住,我可能会忘记其他一些技巧。如果您知道其中之一,请发表评论。

    结论:

    总的来说,这不是最干净的解决方案,因为需要为每个消耗品维护多个并行 SKU,但到目前为止,我还没有想出一个更好的解决方案来真正解决这些问题。

    所以,请分享您可能有的任何其他想法。 +1 保证任何好的指针。 :)

    关于android - 在 Google Play 的 Billing API v3 中解决消耗品的 API-purchase-logic-flaws(与使用 API v3 消耗品的每个人相关),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30921789/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com