在沙箱测试期间,iOS中的收据验证返回错误信息

时间:2019-05-06 13:08:18

标签: ios swift

我正在为我的应用程序实施收据验证,因为它已经付款并且以后可以免费购买应用程序。

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

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

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

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

3 个答案:

答案 0 :(得分:1)

根据documentation,您在沙盒环境中获得的结果是一致的:

  

原始应用版本

     

最初购买的应用版本。

     

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

     

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

     

参考:Receipt Fields: Original Application Version

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

基于此,大多数人使用以下解决方案:

  • 他们将CFBundleVersionBuild(而不是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构建

无论哪种情况,我都会得到正确的课程收据,并请注意,只要我们的else条件能够正常工作,那么只要QA通过,这两个TestFlight构建都是可发布的:采取{{1 }}。


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

答案 1 :(得分:1)

好吧,我终于解决了这个问题。如其他人先前在其他堆栈溢出线程中所述,original_application_version完全没有用。在沙盒中,它始终返回1.0。在生产环境中,它不返回版本号,而是返回应用程序的 build 号,因此命名也很糟糕。

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

答案 2 :(得分:0)

可能是SandBox问题。

如何捕获生产答复并验证是否还存在错误的AppVersion。 (假设您已经存储了1.1+版本),如果是的话,这将是一个BugReport,但我怀疑该字段不正确。

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