区分初始购买和免费“重新购买”在 StoreKit/应用内购买
根据 StoreKit 指南:
如果用户尝试购买非消耗产品或他们已经购买的可更新订阅,您的应用程序会收到该商品的常规交易,而不是恢复交易。但是,用户不会再次为该产品付费。您的应用程序应该以与原始交易相同的方式对待这些交易。
这在我正在开发的应用程序中提出了一个巨大的问题。我们已从出版商处获得大量内容的许可,通过应用内购买进行销售。他们要求每次我们出售一段内容(即用户向我们付款)时,我们的服务器都会调用他们服务器上的 API 来报告交易。这是出于会计目的,并最终用于根据我们与他们的协议确定我们在月底向他们支付的金额。
我读过一些关于 SO 和其他地方的建议,关于频繁调用 RestoreCompletedTransactions 并在设备上保持对用户已经购买的内容的本地理解,以便他们不能再次购买。对我来说,这似乎应该能够在服务器端实现。然而,正如 StoreKit 指南所承诺的那样,我们从 Apple 服务器返回的购买和重新购买的收据完全相同。
如果在这种情况下(“您收到付款”与“您没有收到付款”),来自 StoreKit 的付款回调不能被信任为有效的记账机制,那么还有哪些其他实时交易流量洞察可用?如果我们告诉与我们合作的发行商我们必须在月底后等待 45 天才能从 iTunes Connect 中获取实际付费金额,我认为他们不会高兴。
From the StoreKit guide:
If the user attempts to purchase a nonconsumable product or a renewable subscription they have already purchased, your application receives a regular transaction for that item, not a restore transaction. However, the user is not charged again for that product. Your application should treat these transactions identically to those of the original transaction.
This presents a huge problem in an app I am working on. We have licensed a large body of content from a publisher for sale through in-app purchase. They require that every time we sell a piece of this content (i.e. user pays us), our server calls an API on their servers to report the transaction. This is for accounting purposes and ultimately used to determine how much we pay them at the end of the month, per our agreement with them.
I have read several suggestions on SO and elsewhere about calling restoreCompletedTransactions rather frequently and maintaining a local understanding, on the device, of what the user has already purchased so they cannot be allowed to purchase it again. This to me seems like something that should be able to be implemented on the server side. However, the receipts that we are getting back from the Apple servers are exactly the same for a buy and a re-buy, as promised by the StoreKit guide.
If payment callbacks from StoreKit cannot be trusted as a valid accounting mechanism in this kind of situation ("you got paid" vs. "you didn't get paid"), what other real-time insights into transaction traffic are available? I don't think the publisher we are working with is going to be happy if we tell them we have to wait 45 days after the end of the month to get the REAL paid dollar amount out of iTunes Connect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我最近研究了同样的问题。就我而言,我希望使用移动应用跟踪来实施准确的收入跟踪,以跟踪不同客户获取活动产生的收入。
幸运的是,有一种方法可以做到这一点。应该注意的是,
SKPaymentTransactionStatePurchased
与SKPaymentTransactionStateRestored
仅取决于启动操作,例如您是否启动了恢复或(重新)购买,因此这不起作用。相反,有效的是检查
SKPaymentTransaction.originalTransaction
,对于恢复和重新购买,该值将为!= nil
。不幸的是,后者是未定义的行为(docs)。不过,我认为空检查足够公平。另一种选择是使用
SKPaymentTransactionStatePurchased
验证交易的交易收据,并检查返回的经过验证的收据中的original_transaction_id
属性是否与transaction_id
匹配。I have recently looked into the same problem. In my case, I wanted to implement accurate revenue tracking using Mobile App Tracking to track revenue generated from different customer acquisition campaigns.
Fortunately enough, there is a way to do it. It should be noted that
SKPaymentTransactionStatePurchased
vs.SKPaymentTransactionStateRestored
solely depends on the initating action, e.g. whether you initiated a restore or a (re-)purchase, so that doesn't work.What does work instead is checking for
SKPaymentTransaction.originalTransaction
which will be!= nil
for restores and re-purchases. The latter is unfortunately undefined behavior (docs). I'd consider a null check fair enough though.Another option is to validate the transaction-receipt of transactions with
SKPaymentTransactionStatePurchased
and check that theoriginal_transaction_id
property in the returned, validated receipt matches thetransaction_id
.坏消息是:在当前的 iOS 版本 (4.3.x) 中,无法区分非消耗产品的购买和重新购买。
为了缓解这种情况,我建议两件事:
首先,
成功购买后,将所购买产品的
产品标识符
存储在NSUserDefaults
中设备。然后,您可以向用户隐藏已购买的产品,从而处理重新购买的情况。当用户同步其设备时,
NSUserDefaults
由 iTunes 备份。因此,当用户获得新设备时,您存储的购买信息不会丢失。其次 将
收据数据与设备 ID 一起存储在您的服务器上。分析收据的产品标识符和设备 ID。
如果您收到另一张具有相同产品标识符和设备 ID 组合的收据,则假设您重新购买。至少这可以让您覆盖大部分重新购买的情况。
假设一个普通的 iPhone 用户每 1-2 年更换一次设备,你至少会覆盖大部分重新购买的情况,也许苹果将来会解决这个问题。
The bad news is: In the current iOS version (4.3.x) there's no way to distinguish between a buy and a re-buy of non-consumable products.
To ease the situation I would recommend two things:
First
After a successful purchase, store the
product identifier
of the purchased product in theNSUserDefaults
on the device. You can then hide the already purchased products from the user and thus handle a re-buy situation.The
NSUserDefaults
are backed up by iTunes when the user synchronizes his device. So your stored purchase information is not lost when the user gets a new device.Second
Store the receipt data together with the device ID on your server. Analyze the receipt's product identifier and the device ID.
If you receive another receipt with the same product identifier and device ID combination, then assume a re-buy. At least this would allow you to cover most of the re-buy cases.
Assuming that an ordinary iPhone user switches his device every 1-2 years, you will at least cover most of the re-buy cases and maybe apple will fix this in the future.
我有一个解决方案,
将产品配置为消耗品。
这将解决问题 - (他们要求我们每次出售该内容的一部分(即用户向我们付款))。
接下来您需要在产品购买选项中实现逻辑。在某种程度上,一旦用户购买了产品,购买选项就需要删除,否则用户可能会碰巧去购买同一设备中的同一产品,并再次损失现金。
您可以使用 NSUserdefaults 来实现此目的。
谢谢,
I have one solution,
Configure the product as consumable.
this will solve the problem - (They require that every time we sell a piece of this content (i.e. user pays us)).
Next you need to implement a logic in product buy option. It is in a way that once the user purchase a product the buy option need to remove otherwise the user may happendly go purchase and lost is cash once again for same product in same device.
you can use NSUserdefaults for this purpose.
thanks,