22

我正在使用 Unity 开发一个应用程序(适用于 Android 和 iOS)。我正在使用 SOOMLA 插件来允许用户通过 In App Purchase 购买 Gems(虚拟货币)。

用户和宝石以及所有其他游戏逻辑都通过我在 Azure 上的服务器。

我希望以某种方式将以下过程作为单个事务进行:

  1. 用户通过 IAP 购买宝石
  2. 应用程序通知服务器
  3. 服务器验证购买并更新数据

但是,如果互联网连接在第 1 步和第 2 步之间中断 - 用户支付了他没有收到的宝石(不好!)

所以我目前的做法是这样的:

  1. 用户发起购买
  2. 应用通知服务器
  3. 服务器相应地盲目更新数据
  4. 用户通过 IAP 购买宝石
  5. 如果购买被取消,通知服务器撤消

这样,用户可以保证得到他购买的宝石,但我不能保证得到报酬(不是很好......)

注意: 我不想在商店本身管理用户 Gems。我希望一切都在我自己的服务器上。所以 SOOMLA 的平衡对我来说毫无意义。我不在乎。

我在想也许该应用程序可以将购买数据存储在持久存储中,直到它设法通知服务器,然后将其删除。但我也认为这可能是一个糟糕的解决方案。因此这个问题。


我认为最好的解决方案可以正确处理这种情况:

  1. 用户通过 IAP 购买宝石
  2. IAP 成功
  3. 互联网崩溃了
  4. 我自己的服务器没有收到通知
  5. 用户从他的设备上卸载应用程序
  6. 然后用户可以在其他设备上安装该应用程序:

    • 要么他被指控,要么他通过某种魔法得到了宝石
    • 或者他被自动退款,因为没有收到宝石

到目前为止,这似乎无论如何都是不可能的,这让我对 IAP 的技术感到失望。希望能证明我错的答案。


似乎我所需要的只是能够从我的服务器获取用户的购买历史记录,并通过对 Google Play 或 Apple Store 的安全请求。但这不是框架的一部分。


那么其他人在做什么呢?最好的方法是什么?

4

5 回答 5

6

一般来说,您似乎遇到了两将问题

第一个被证明无法解决的计算机通信问题。

由于您的通信协议中的任何地方都可能丢失消息(甚至是确认或确认的确认或...),您不能 100% 确定通信双方(用户设备和您的服务器)已同意相同状态。只能说状态信息交换成功的概率是一定的。

如果有足够的数量达到低谷,我会来回发送几个 ACK​​ 并存储购买。引用自维基百科:

此外,第一个将军可以在每条消息上发送一个标记,说明它是消息 1、2、3 ... of n。这种方法将允许第二位将军知道信道的可靠性,并发送适当数量的消息,以确保接收到至少一条消息的概率很高

为了让客户满意,我会采取有利于他们的赔率 - 1% 的未交付货物会给您带来很多麻烦,但您这边 1% 的损失是可以接受的。

于 2016-02-17T13:47:08.950 回答
5

考虑到您的宝石是一种虚拟货币,那么自然应用内产品类型应该是可消耗的,即它们不是可恢复的购买。

要使用 Google Play 购买消费购买,您将调用consumePurchase。在 iOSfinishTransaction上,您将调用SKPaymentQueue. 在这两个市场中,消耗品购买将保持活跃状态​​,直到它们被消费。如果用户在购买被消费之前从他们的设备上删除了应用程序,他们将能够重新安装并恢复他们之前未消费的购买。

在初始购买和消费之间是您想要放置服务器端验证的地方。购买后,将收据或令牌发送到您的服务器,执行验证并做出相应的响应。在消费购买之前,应用程序应该等待来自服务器的有效响应。

(请注意,已消费的购买不会出现在in_appiTunes 收据上的收藏中。它们仅在购买尚未消费时出现)。

如果服务器超时或网络连接丢失,则购买将保持活动状态,并且应用程序应继续尝试定期发送详细信息,直到收到预期的响应。

Google Play 和 iOS 的购买都存储在本地,因此您只需运行一个流程,在重新建立网络连接后查找未消费的购买。

您可以像银行处理支票存款一样对待 Gems 的供应;新余额将立即更新,但在支票(或在您的情况下为验证)被清除之前,可花费的金额将不匹配。

一些伪代码使过程清晰:

Purchase product or Restore purchases
While consumable purchases > 0
  Send purchase receipt to API
  If response is ok
    If purchase is valid
      Consume product
      Allocate gems
      Break
    Else
      Remove retroactive gem allocation
      Discipline the naughty user
      Break
  Else
    Retroactively allocate un-spendable gems
    Pause process until network is re-established
      Re-send receipt to API
于 2016-02-20T18:07:07.373 回答
0

一些忠告:

  1. 用户通过 IAP 购买宝石

  2. IAP 成功

  3. 互联网崩溃了

  4. 我自己的服务器没有收到通知

  5. 用户从他的设备上卸载应用程序

  6. 然后用户可以在其他设备上安装该应用程序:

    要么他被收费并通过某种魔法获得了宝石,要么他自动退还,因为没有收到宝石。


  1. 在步骤 3,收据信息被存储在用户的设备上。如果用户卸载并重新安装您的应用程序,收据信息将丢失。但是你可以恢复它;苹果在这里谈论那个。您可以将恢复的收据重新发送到您的服务器。在您的服务器上,您为用户验证加宝石,以便他可以收到他应该是的。

  2. 他被自动退款,因为没有收到宝石

    这对于 IAP 来说似乎是不可能的,因为 Apple 不允许用户取消他们的购买。(使用 Google IAB,允许退款,更多信息请点击此处

于 2016-02-18T11:04:32.780 回答
0

我对 android 了解不多,但在阅读了您的帖子后,我真的很感兴趣,并且更感兴趣地搜索像部落冲突这样的游戏在应用程序购买逻辑中的工作原理并防止自由假购买黑客

在做了一些研究之后,我想就您的问题分享我的想法,您可以通过以下方法实现它

使您的应用内购买验证完全在线。例如,您可以考虑部落的游戏冲突。

这个怎么运作:

1)游戏加载,与服务器同步。需要网络连接,因为网络连接会中断从服务器重新加载游戏。

2)用户有10颗宝石,服务器也有10颗宝石。

3)用户购买的宝石,服务器对购买的消耗品单独验证购买,宝石记入用户账户。

4)如果万一网络出现故障,那么服务器也可以验证购买,然后在用户帐户中更新它,无论它是否在任何设备上。

5)这也将帮助您绕过许多虚假的应用程序购买黑客,如自由预防)和幸运修补程序

谷歌为服务器端提供 api 来验证或获取购买细节,当从应用程序端和服务器端购买匹配时,只有您将宝石或消耗品记入用户帐户。

有关应用内购买及其黑客预防措施的更多信息,您可以访问以下链接:

1)应用内购买第 1 部分和第 2部分的服务器端验证

2)您将如何在应用购买计费服务器端进行验证

3)通过 PHP 验证购买

4)在网络服务器上的应用购买场景中安全

希望这可能会引导你走向你想要去的方向,我也很想听听你的想法。

于 2016-02-19T12:03:25.300 回答
0

您可以尝试恢复使用特定帐户进行的应用内购买。

该功能仅适用于这种情况,即付款后用户未收到承诺的物品或更换设备时。

恢复购买后,您将再次从 iTunes 服务器收到购买的产品,然后您可以相应地通知您的服务器。

于 2016-02-22T09:39:40.010 回答