【问题标题】:Receipt validation before showing IAP-page显示 IAP 页面前的收据验证
【发布时间】:2018-08-13 10:59:46
【问题描述】:

我对我们的应用内购买流程有疑问,因为它被 Apple 拒绝了。

因为我们不知道用户是否有有效的订阅,所以我们必须先获取收据,这会导致 iTunes Store 密码提示(这是我们在非生产环境中正确理解的正常行为)。然后进行验证,并根据结果显示自动续订订阅页面或传递请求的操作。

我们的流程是:

  1. 获取收据
  2. 验证收据
  3. 如果
    • 有效:通过请求的操作;
    • 无效:显示用户可以在其中进行购买的自动续订订阅页面。

现在,Apple 在拒绝中表示他们看不到自动续订订阅页面。相反,他们从 iTunes Store 获得了密码提示。

正如我们正确理解的那样,密码提示是非生产环境中的正常行为,但苹果似乎并不期望这种行为。我们获取收据的方式没有任何改变。

我们使用SwiftyStoreKit 来轻松处理。这是我们的代码:

SwiftyStoreKit.fetchReceipt(forceRefresh: false) { result in
    switch result {
    case .success(let receiptData):
        let encryptedReceipt = receiptData.base64EncodedString(options: [])
        Log.info("Fetch receipt success")
        //further code to send the receipt to our server
    case .error(let error):
        observer.send(error: error.localizedDescription)
    }
}

我们的流程是否不正确,或者我们如何在不获取收据的情况下验证用户是否拥有有效订阅?我们在这里有点困惑。有人可以在这里给我们任何建议吗?

【问题讨论】:

    标签: ios in-app-purchase receipt-validation


    【解决方案1】:

    您当前的流程并没有提供很好的用户体验;他们启动您的应用程序并看到一个 iTunes 帐户密码提示,而没有任何关于它出现原因的上下文。

    我建议您采用类似于以下的流程:

    1. 当您在此设备上验证订阅时,将布尔值添加到 UserDefaults
    2. 当您的应用程序启动时,检查此值。
    3. 如果值为 true,则刷新收据并验证订阅
    4. 如果该值为 false/不存在,则显示您的商店界面。确保您的商店界面包含“恢复”按钮。
    5. 现在,如果用户知道他们有订阅,他们可以点击恢复,您可以验证他们的订阅;如果此时系统提示他们输入 iTunes 帐户密码,那么他们就会明白原因。
    6. 如果用户没有订阅,那么他们可以购买一个。即使他们确实有一个并开始购买,StoreKit 也会处理并告诉他们他们已经有一个有效的订阅
    7. 无论订阅是购买还是恢复,您都会获得订阅的交易。然后,您可以更新 UserDefaults 并按照第 3 步继续操作。

    或者,在尝试刷新之前检查本地收据是否存在。如果收据不存在,则可能会提示用户输入 iTunes 密码:

    if let receiptDataURL = appStoreReceiptURL,
       let _ = try? Data(contentsOf: receiptDataURL)  {
           SwiftyStoreKit.fetchReceipt(forceRefresh: false) { result in
    
           switch result {
               case .success(let receiptData):
    
                   let encryptedReceipt = receiptData.base64EncodedString(options: [])
    
                   Log.info("Fetch receipt success")
    
        //further code to send the receipt to our server
    
               case .error(let error):
                   observer.send(error: error.localizedDescription)
           }
       }
    }  else {
        // Display purchase/restore interface
    }
    

    【讨论】:

    • 据我所知,出于安全原因,iTunes 帐户密码提示是在非生产环境中获取收据时的本机行为。因为我们已经在应用商店中有一个应用程序,它可以像我的代码一样获取收据,并且不要求输入密码,这是我们的理解。还是我们不正确?
    • 如果用户最近没有对商店进行身份验证,iTunes帐户密码提示也可能出现在生产环境中。一般来说,如果您在appStoreReceiptURL 找不到收据,那么您应该显示购买/恢复界面而不是刷新它。我不喜欢 SwifyStoreKit 的方法,即在找不到收据时刷新收据。实际上,我从来没有找到我喜欢的 StoreKit 包装器;他们似乎都隐藏了重要的行为
    • 非常感谢。这是一些非常有用的信息。也许我们也应该考虑离开 SwiftStoryKit
    • 这取决于你。就我个人而言,我更喜欢直接编写 StoreKit 代码;它没有那么复杂。它只是基于委托而不是基于闭包。
    • @Paulw11 : 订阅过期如何处理?
    猜你喜欢
    • 1970-01-01
    • 2016-06-24
    • 2018-06-16
    • 1970-01-01
    • 2015-11-24
    • 2015-01-08
    • 2012-05-04
    • 1970-01-01
    • 2017-11-11
    相关资源
    最近更新 更多