【问题标题】:Receipt validation in iOS returns incorrect info during sandbox testingiOS 中的收据验证在沙盒测试期间返回不正确的信息
【发布时间】:2019-05-06 13:08:17
【问题描述】:

我正在为我的应用实施收据验证,因为它是付费的,以后在应用内购买时将免费。

我已经设置了我的服务器和所有东西,并且我已经发送了收据数据。但是,当我得到响应时,无论如何,响应 JSON 总是说original_application_version1.0。我验证收据背后的想法是,如果您的原始应用程序版本早于 1.x,那么您可以自动解锁高级版本。

但是,即使对于以前从未安装过该应用的全新 Beta 测试人员,JSON 中的 original_application_version 也会返回 1.0 的值。

我服务器上的 URL 是 https://sandbox.itunes.apple.com/verifyReceipt。当我将其更改为生产 URL 时,我得到了 21007 的响应(这意味着我应该更改为测试环境)。

有人经历过吗?我非常怀疑它会神奇地开始在生产中返回正确的值,但出于测试目的它完全被破坏了。它在 TestFlight 构建和直接从 Xcode 构建时返回的信息不正确。

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    您在沙盒环境中获得的内容与documentation 一致:

    原始应用程序版本

    最初购买的应用版本。

    这对应于 CFBundleVersion 的值(在 iOS 中)或 Info.plist 文件中的 CFBundleShortVersionString(在 macOS 中)当 最初是购买的。

    在沙盒环境中,该字段的值始终为“1.0”。

    参考:Receipt Fields: Original Application Version

    在沙盒环境中,该字段的值始终为1.0,而在生产环境中,它将是用户首次安装此应用时的CFBundleVersion

    基于此,大部分人采用以下方案:

    • 他们将 CFBundleVersion 又名 Build(不是 Version)更改为新样式
    • 检查此值以区分旧的付费应用和新的免费应用(使用 iAP)

    WWDC2013 Session 308: Using Receipts to Protect Your Digital Sales 谈到了这个确切的场景,所以无论如何你正在做的事情都是 Apple 推荐的。

    摘录:

    因此,对于今天在商店购买付费应用并且想要 通过应用内购买过渡到免费应用, 以前这对你来说是一个相当大的挑战,因为如果你 只需切换为具有应用内购买功能的免费应用,您的 客户将不得不再次购买所有这些应用内购买, 但他们已经为此付出了代价,他们不会喜欢的。

    所以现在在收据本身我们有日期,当用户第一次 购买了您的应用,以及当时的版本。

    因此,您可以使用它来做出真正明智、明智的决定 关于授予该用户使用哪些功能和内容,所以如果您的 应用程序查看收据并检查它并看到该用户购买了我的 在我通过应用内购买转换为免费之前的应用, 授予他们支付的费用,但如果他们购买了您的应用程序 在您通过应用内购买过渡到免费后, 你知道然后不要太解锁功能和内容,直到他们使 购买,然后您使用收据本身验证该交易。

    参考:Using Receipts to Protect Your Digital Sales


    总结:

    但您似乎已经采用了这种方法。
    唯一的问题是,在沙盒环境中,它始终是 1.0,因为每次安装都被视为全新安装,没有结转信息。
    所以在它投入生产之前你不能真正测试它,这很可怕。

    可行的解决方案:

    那么如何测试以下场景?

    1. 用户在付费时安装的应用程序
    2. 用户在应用免费后安装

    嗯...我会使用 environmentoriginal_application_version... 和 2 个 TestFlight 构建:

    案例 1:用户在应用免费后安装应用,但之前已付费

    • 如果environment 显示Sandbox,那么我会将original_application_version 模拟为旧的应用内部版本号并检查流程
    • 否则environment 显示Production,我会从收据中取出original_application_version
    • 为 TestFlight 构建提供说明案例的发行说明

    案例 2:用户在应用免费后安装但未付费

    • 如果environment 显示Sandbox,那么我会将original_application_version 模拟为新的应用内部版本号并检查流程
    • 否则environment 显示Production,我会从收据中取出original_application_version
    • 为 TestFlight 构建提供说明案例的发行说明

    在任何一种情况下,我都会得到正确的收据,并且请注意,如果 QA 通过它,两个 TestFlight 构建都是可发布的,只要保证我们的 else 条件有效:从收据。


    PS:解决方案是我现在能想到的最好的解决方案

    【讨论】:

    • 感谢您的宝贵时间。我终于找到了解决方案,并在这里发布了我所做的作为答案。
    • @joey 我不确定是否只有original_purchase_date 是个好主意。检查similar answer。但是,根据这个blog,这家伙同时使用了original_application_versionoriginal_purchase_date
    【解决方案2】:

    好的,我终于解决了这个问题。正如其他人之前在其他堆栈溢出线程中所说的那样,original_application_version 完全没用。在沙盒中,它总是返回1.0。在生产中,它不返回版本号,而是返回您的应用程序的 build 号 - 所以命名也很糟糕。

    最后,我的解决方案(可能是一个非常糟糕的解决方案,但最直接的解决方案并且确实有效)是使用original_purchase_date_ms。所以从我的服务器上,我加载了我的应用程序正式免费上线的日期(以毫秒为单位的 Unix 时间戳)。所以我只是将这个数字与original_purchase_date_ms 进行比较,如果原始购买日期早于之前,则验证他们已经购买了该应用程序。

    【讨论】:

      【解决方案3】:

      可能是沙盒问题。

      如何捕获生产回复并验证是否也存在错误的 AppVersion。 (假设您已经有 1.1+)如果是这样,这将是一个错误报告,但我怀疑该字段不正确。

      但是,如果那里的字段也不正确,如何验证我上次测试时正确的购买日期。

      【讨论】:

      • 目前此版本的应用程序尚未投入生产,因此我无法收到这些。经过一番挖掘,我看到 original_purchase_date 的值在沙盒模式下始终为 1.0:developer.apple.com/library/archive/releasenotes/General/…。我也尝试了 original_purchase_date,但返回的值为 2013 年 8 月 1 日。我的应用最初于 2019 年 3 月开始销售,所以显然这也是不正确的。
      猜你喜欢
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      • 2012-10-28
      • 2015-08-14
      相关资源
      最近更新 更多