iOS - IAP 问题,对应用商店收据感到困惑

Posted

技术标签:

【中文标题】iOS - IAP 问题,对应用商店收据感到困惑【英文标题】:iOS - IAP problems, confused about app store receipt 【发布时间】:2015-03-03 18:38:18 【问题描述】:

我做了一个游戏。我没想到它会变得非常流行,所以我不在乎编写复杂的密码学代码来验证收据。我的游戏的 IAP(删除广告)在沙盒模式下运行良好。该应用程序已在过去 16 小时内实时发布,但存在问题。该应用的行为就像每个人都购买了“删除广告”IAP。

这是我非常基本的收据验证码:

override init()
    super.init()

    // storekit delegation
    SKPaymentQueue.defaultQueue().addTransactionObserver(self)

    if SKPaymentQueue.canMakePayments() 

        let request = SKProductsRequest(productIdentifiers: NSSet(object: self.productID))
        request.delegate = self
        request.start()
    

    self.checkReceipt()



func checkReceipt()
    if let url = NSBundle.mainBundle().appStoreReceiptURL 
        if let receipt = NSData(contentsOfURL: url) 
            self.adsRemoved = true
        
    

问题:

    在我的沙盒环境中。除非我购买了 IAP,否则receipt 变量不会被解包。 self.adsRemoved 未设置为 true。似乎在应用商店本身,这些变量总是被解包。那是怎么回事?我该怎么办。

    我现在知道 IAP 在应用提交后一两天激活是标准的。这可能与此有关吗?我知道如果我按下恢复按钮,什么也不会发生。在我的沙盒环境中,它要求提供凭据.. 显示成功消息等。

【问题讨论】:

嗯。生产中是否有空收据?即,一个没有任何购买?看来您没有实现标准的事务观察者委托方法。是这样吗?如果没有购买交易成功,为什么还要检查收据? 我不知道什么是空收据。我知道在沙盒环境中,如果沙盒用户没有购买我的 IAP,则不会返回任何收据。在实时应用商店中,总是会返回收据。我会在每次应用启动时检查此收据。我正在为新购买或恢复购买实现交易观察者委托方法。 >= ios7 中的收据是购买记录信息的容器。那些可以(可能;我不记得我是否真的看到过这种情况)是有效的非零容器,但包含不购买的信息。区分这一点的唯一方法是解码收据。 【参考方案1】:
    在我的沙盒环境中.. 收据变量不会得到 除非我购买了 IAP,否则打开包装。 self.adsRemoved 不是 设置为真。好像在应用商店本身,这些 变量总是被解包。那是怎么回事?我该怎么办。

您的checkReceipt() 方法检查-appStoreReceiptURL 提供的URL 是否存在收据。

这是有问题的,因为从 App Store 下载的每个应用都会包含收据,无论该应用是免费的还是付费的。

这记录在Apple's Receipt Validation Programming Guide:

从 App Store 安装应用程序时,它包含一个 加密签名的申请收据,确保 只有 Apple 可以创建有效收据。收据存放在 应用程序包。调用 NSBundle 的 appStoreReceiptURL 方法 类来定位收据。

那么为什么它在沙盒模式下对你有用?这是因为通过 Xcode 安装的沙盒应用程序不包含收据,直到发生以下任一情况:

    通过SKReceiptRefreshRequest (link) 请求收据 进行应用内购买时,或 当通过-restoreCompletedTransactions恢复以前的事务时

因此,简而言之,您的 checkReceipt 方法肯定会将 adsRemoved 设置为 true,因为您正在检查 收据是否存在,由于上述原因,这对您来说根本没有任何意义。

您需要做的是验证收据是否 (1) 合法,以及 (2) 是否表明进行了正确的应用内购买。

    我现在知道 IAP 在应用提交后一两天激活是标准的。这可能与此有关吗?我知道如果我打 我的恢复按钮没有任何反应。在我的沙盒环境中,它询问 对于凭据.. 显示成功消息等。

在应用批准后 IAP 需要一两天才能激活,这不是真的 - 出现问题是因为您正在检查收据是否存在,而不是验证收据。

遗憾的是,收据验证很复杂,但如果您想实现您想要实现的目标(即检查是否已进行 IAP),这是必要的。您需要参考此objc.io article on receipt validation 以获取有关如何实际验证收据的更多信息。至少,所涉及的步骤是:

    找到收据,这就是您已经在做的事情。 验证收据合法且未被篡改。 解析收据以确定 IAP 已生成,因为即使没有购买 IAP 也存在收据

【讨论】:

【参考方案2】:

您必须验证发送 Apple 提供的 url 的收据数据的收据。稍后,根据您将收到的响应,您必须设置值 self.adsRemoved = true/false。

【讨论】:

我对验证它不感兴趣。我只想检查此 IAP 的收据是否存在。同样,对编写复杂的密码学代码不感兴趣。我只是想检查某人是否有此 IAP 的收据,无论是伪造的还是其他的。 我不明白为什么在沙盒环境中直到购买才能找到收据..但在实时环境中总是找到收据。 @Deepak--您绝对没有使用 Apple 提供的 URL 来验证收据。在 >= iOS7 上,您可以在设备本地进行收据验证。 @ChrisPrince -- 哦,太好了。我有一个疑问。如果有多个productId怎么办?每个产品的详细信息都会有每张收据,还是永远只有一张收据包含所有购买的产品详细信息。 使用 >= iOS7 风格的收据,这取决于产品类型。例如,对于非消耗性产品,如果用户购买了不止一种非消耗性产品,收据将永久保存所有这些购买的记录。这有帮助吗?

以上是关于iOS - IAP 问题,对应用商店收据感到困惑的主要内容,如果未能解决你的问题,请参考以下文章

刷新 iOS IAP 收据以恢复购买始终会返回收据,即使未进行任何购买也是如此

如何清除测试设备上非消耗品的 iOS IAP 收据?

IOS7验证iap收据,in_app文件是啥意思?

对应用程序精简感到完全困惑

IAP 正在使用 TestFlight 构建。它也可以使用 Live 应用程序吗?

刷新iOS应用收据:如何确定用户是不是需要登录应用商店?