InAppPurchase 验证和游戏逻辑的独立服务器
InAppPurchase verification & separate server for game logic
我正在使用 Unity 开发应用程序(针对 Android 和 iOS)。我正在使用 SOOMLA 插件来允许用户通过应用内购买来购买宝石(虚拟货币)。
用户和宝石以及所有其他游戏逻辑都通过我在 Azure 上的服务器。
我希望以下过程以某种方式作为单个事务发生:
- 用户使用 IAP 购买宝石
- 应用程序通知服务器
- 服务器验证购买并更新数据
但是如果互联网连接在第 1 步和第 2 步之间中断 - 用户支付了他没有收到的宝石(不好!)
所以我目前的做法是这样的:
- 用户发起购买
- 应用程序通知服务器
- 服务器相应地盲目更新数据
- 用户使用 IAP 购买宝石
- 如果取消购买,通知服务器撤销
这样一来,用户可以保证得到他购买的宝石,但我不能保证得到报酬(不太好...)
注意: 我不想在商店本身管理用户宝石。我希望一切都在我自己的服务器上。所以SOOMLA的余额对我来说毫无意义。我才不管呢
我在想也许应用程序可以将购买数据存储在持久存储中,直到它设法通知服务器,然后将其删除。但我也在想,这可能是一个糟糕的解决方案。因此这个问题。
我认为最好的解决方案可以正确处理这种情况:
- 用户使用 IAP 购买宝石
- 应用内购成功
- 互联网出现故障
- 我自己的服务器没有收到通知
- 用户从他的设备卸载应用程序
用户随后可以在其他设备上安装该应用程序:
- 要么他被充能了,要么他通过某种魔法获得了宝石
- 或者他被自动退款,因为没有收到宝石
到目前为止,这似乎是不可能的,这让我对 IAP 的技术感到失望。希望得到能证明我错了的答案。
似乎我所需要的只是能够从我的服务器获取用户的购买历史记录,并向 Google Play 或 Apple Store 发出安全请求。但这不是框架的一部分。
那么其他人在做什么呢?什么是最好的方法?
总的来说,您似乎患有 Two Generals' Problem
the first computer communication problem to be proved to be unsolvable.
由于您的通信协议中的任何地方都可能丢失一条消息(即使是确认或确认的确认或...)您不能 100% 确定通信双方(用户设备和您的服务器)同意相同的状态。只能说是某种概率状态信息交换成功了。
如果有足够的数量,我会来回发送几个 ACK 并存储购买。引自维基百科:
Also, the first general can send a marking on each message saying it is message 1, 2, 3 ... of n. This method will allow the second general to know how reliable the channel is and send an appropriate number of messages back to ensure a high probability of at least one message being received
为了让客户满意,我愿意赌他们的胜算——1% 的未交付货物会给您带来很多麻烦,但 1% 的损失对您而言是可以接受的。
一些建议:
用户使用 IAP 购买宝石
应用内购成功
互联网出现故障
我自己的服务器没有收到通知
用户从他的设备上卸载了应用程序
用户随后可以在其他设备上安装该应用程序:
要么他被收费并通过某种魔法获得了宝石,要么他被自动退款,因为没有收到宝石。
我对 android 了解不多,但在阅读了您的 post 之后,我真的很想更深入地搜索 clash of clans 这样的游戏在应用程序中的表现购买逻辑工作并防止自由虚假购买黑客。
经过一些研究,我想分享一下我对你的问题的看法,你可以通过以下方法实现它:
让您的应用内购买验证完全在线。例如,你可以考虑部落冲突
工作原理:
1)游戏加载,与服务器同步。需要网络连接,因为网络连接会中断游戏从服务器重新加载。
2)用户有10颗宝石,服务器也有10颗宝石。
3)用户购买宝石,购买的消耗品服务器单独验证购买,宝石记入用户账户。
4) 如果在网络出现故障的情况下,服务器也可以验证购买并稍后根据用户的帐户更新它,无论它是否在任何设备上。
5)这也将帮助您绕过许多虚假的应用内购买黑客攻击,例如 freedom (prevention) and lucky patcher。
Google 为服务器端提供 api 以验证或获取购买详细信息,当从应用程序端购买和服务器端匹配时,您只能将宝石或消耗品记入用户帐户。
有关应用内购买及其黑客攻击预防的更多信息,您可以访问这些链接:
1)Server side verification of in app purchase part 1 and part 2.
2)How would you verify in app purchase billing server side.
3)Verify purchase via PHP.
4)Secure in app purchase scenario on web server.
希望这可能会引导你走向你想去的方向,我也很想听听你的想法。
考虑到您的宝石是一种虚拟货币,那么自然的in-app产品类型应该是消耗品,即它们是不可恢复的购买。
要使用 Google Play 购买消费购买,您将在 SKPaymentQueue
上致电 consumePurchase
. On iOS you will call finishTransaction
。在这两个市场中,消耗品购买将保持活跃状态,直到它们被消耗掉。如果用户在消费之前从他们的设备上删除了该应用程序,他们将能够re-install,并恢复他们之前未消费的购买。
In-between 最初的购买和消费是您要进行 server-side 验证的地方。购买后,将收据或令牌发送到您的服务器,执行验证并做出相应响应。应用程序应等待服务器的有效响应,然后再消费购买的商品。
(请注意,已消费的购买不会出现在 iTunes 收据的 in_app
collection 中。它们仅在购买尚未消费时才会出现)。
如果服务器 timing-out 或网络连接丢失,购买将保持活动状态,应用程序应继续尝试定期发送详细信息,直到收到预期的响应。
Google Play 和 iOS 的购买都存储在本地,因此您只需要 运行 在网络连接 re-established 后查找未消费的购买的过程.
您可以像银行处理支票存款一样处理宝石的供应;新余额将立即更新,但在支票(或在您的情况下为验证)被清除之前,可花费的金额将不匹配。
一些伪代码使过程清晰:
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
您可以尝试恢复使用特定帐户进行的应用内购买。
此功能仅针对已付款但用户未收到承诺的物品或更换设备时的情况。
恢复购买后,您将从 iTunes 服务器再次收到购买的产品,然后您可以相应地通知您的服务器。
我正在使用 Unity 开发应用程序(针对 Android 和 iOS)。我正在使用 SOOMLA 插件来允许用户通过应用内购买来购买宝石(虚拟货币)。
用户和宝石以及所有其他游戏逻辑都通过我在 Azure 上的服务器。
我希望以下过程以某种方式作为单个事务发生:
- 用户使用 IAP 购买宝石
- 应用程序通知服务器
- 服务器验证购买并更新数据
但是如果互联网连接在第 1 步和第 2 步之间中断 - 用户支付了他没有收到的宝石(不好!)
所以我目前的做法是这样的:
- 用户发起购买
- 应用程序通知服务器
- 服务器相应地盲目更新数据
- 用户使用 IAP 购买宝石
- 如果取消购买,通知服务器撤销
这样一来,用户可以保证得到他购买的宝石,但我不能保证得到报酬(不太好...)
注意: 我不想在商店本身管理用户宝石。我希望一切都在我自己的服务器上。所以SOOMLA的余额对我来说毫无意义。我才不管呢
我在想也许应用程序可以将购买数据存储在持久存储中,直到它设法通知服务器,然后将其删除。但我也在想,这可能是一个糟糕的解决方案。因此这个问题。
我认为最好的解决方案可以正确处理这种情况:
- 用户使用 IAP 购买宝石
- 应用内购成功
- 互联网出现故障
- 我自己的服务器没有收到通知
- 用户从他的设备卸载应用程序
用户随后可以在其他设备上安装该应用程序:
- 要么他被充能了,要么他通过某种魔法获得了宝石
- 或者他被自动退款,因为没有收到宝石
到目前为止,这似乎是不可能的,这让我对 IAP 的技术感到失望。希望得到能证明我错了的答案。
似乎我所需要的只是能够从我的服务器获取用户的购买历史记录,并向 Google Play 或 Apple Store 发出安全请求。但这不是框架的一部分。
那么其他人在做什么呢?什么是最好的方法?
总的来说,您似乎患有 Two Generals' Problem
the first computer communication problem to be proved to be unsolvable.
由于您的通信协议中的任何地方都可能丢失一条消息(即使是确认或确认的确认或...)您不能 100% 确定通信双方(用户设备和您的服务器)同意相同的状态。只能说是某种概率状态信息交换成功了。
如果有足够的数量,我会来回发送几个 ACK 并存储购买。引自维基百科:
Also, the first general can send a marking on each message saying it is message 1, 2, 3 ... of n. This method will allow the second general to know how reliable the channel is and send an appropriate number of messages back to ensure a high probability of at least one message being received
为了让客户满意,我愿意赌他们的胜算——1% 的未交付货物会给您带来很多麻烦,但 1% 的损失对您而言是可以接受的。
一些建议:
用户使用 IAP 购买宝石
应用内购成功
互联网出现故障
我自己的服务器没有收到通知
用户从他的设备上卸载了应用程序
用户随后可以在其他设备上安装该应用程序:
要么他被收费并通过某种魔法获得了宝石,要么他被自动退款,因为没有收到宝石。
我对 android 了解不多,但在阅读了您的 post 之后,我真的很想更深入地搜索 clash of clans 这样的游戏在应用程序中的表现购买逻辑工作并防止自由虚假购买黑客。
经过一些研究,我想分享一下我对你的问题的看法,你可以通过以下方法实现它:
让您的应用内购买验证完全在线。例如,你可以考虑部落冲突
工作原理:
1)游戏加载,与服务器同步。需要网络连接,因为网络连接会中断游戏从服务器重新加载。
2)用户有10颗宝石,服务器也有10颗宝石。
3)用户购买宝石,购买的消耗品服务器单独验证购买,宝石记入用户账户。
4) 如果在网络出现故障的情况下,服务器也可以验证购买并稍后根据用户的帐户更新它,无论它是否在任何设备上。
5)这也将帮助您绕过许多虚假的应用内购买黑客攻击,例如 freedom (prevention) and lucky patcher。
Google 为服务器端提供 api 以验证或获取购买详细信息,当从应用程序端购买和服务器端匹配时,您只能将宝石或消耗品记入用户帐户。
有关应用内购买及其黑客攻击预防的更多信息,您可以访问这些链接:
1)Server side verification of in app purchase part 1 and part 2.
2)How would you verify in app purchase billing server side.
3)Verify purchase via PHP.
4)Secure in app purchase scenario on web server.
希望这可能会引导你走向你想去的方向,我也很想听听你的想法。
考虑到您的宝石是一种虚拟货币,那么自然的in-app产品类型应该是消耗品,即它们是不可恢复的购买。
要使用 Google Play 购买消费购买,您将在 SKPaymentQueue
上致电 consumePurchase
. On iOS you will call finishTransaction
。在这两个市场中,消耗品购买将保持活跃状态,直到它们被消耗掉。如果用户在消费之前从他们的设备上删除了该应用程序,他们将能够re-install,并恢复他们之前未消费的购买。
In-between 最初的购买和消费是您要进行 server-side 验证的地方。购买后,将收据或令牌发送到您的服务器,执行验证并做出相应响应。应用程序应等待服务器的有效响应,然后再消费购买的商品。
(请注意,已消费的购买不会出现在 iTunes 收据的 in_app
collection 中。它们仅在购买尚未消费时才会出现)。
如果服务器 timing-out 或网络连接丢失,购买将保持活动状态,应用程序应继续尝试定期发送详细信息,直到收到预期的响应。
Google Play 和 iOS 的购买都存储在本地,因此您只需要 运行 在网络连接 re-established 后查找未消费的购买的过程.
您可以像银行处理支票存款一样处理宝石的供应;新余额将立即更新,但在支票(或在您的情况下为验证)被清除之前,可花费的金额将不匹配。
一些伪代码使过程清晰:
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
您可以尝试恢复使用特定帐户进行的应用内购买。
此功能仅针对已付款但用户未收到承诺的物品或更换设备时的情况。
恢复购买后,您将从 iTunes 服务器再次收到购买的产品,然后您可以相应地通知您的服务器。