iOS 的 IAP 收据验证

2024-05-27

我正在开发一个客户端/服务器应用程序,它使用 Apple 的 IAP 和 StoreKit 框架来购买订阅。

我们希望客户(iPhone 或 iPad)能够使用 StoreKit 框架通过其 iTunes 帐户向 Apple 进行初始订阅购买,然后将收据传递到我们的服务器,服务器将对其进行验证,然后更新用户帐户状态。我们还希望服务器负责管理订阅的状态(检查自动续订、取消等。)这全部使用 iOS 7 风格的 appleReceipts,而不是当前已弃用的 iOS 6 风格的交易收据。

Apple 的文档表示,要 POST 到以下 URL,以验证沙箱中的收据以及收据和密码

https://sandbox.itunes.apple.com/verifyReceipt https://sandbox.itunes.apple.com/verifyReceipt

到目前为止..一切都按预期进行。

让我感到困惑的是回复。 Apple 的文档称响应最多应有 4 个字段。如果您正在验证 iOS 7 风格的应用程序收据,那么您应该只看到前 2 个。如果是 iOS 6 风格的订阅交易收据,那么您应该看到所有 4 个。

1) 状态(0 表示有效,否则为一些错误代码)

2) 收据(已发送收据的 JSON 表示形式)

3)latest_receipt(仅针对自动续订订阅的 iOS 6 样式交易收据返回。最近续订的 Base-64 编码交易收据。)

4)latest_receipt_info(与上面JSON格式相同)

问题一:尽管我正在验证 iOS 7 风格的应用程序收据,但我还是看到了全部 4 个。文档说这不应该发生。

https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW1 https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW1

问题2:我们希望服务器通过使用客户端在首次购买后传递的原始应用程序收据轮询此 API 来维护用户订阅状态。这latest_receipt_info字段似乎确实包含一个不断更新的交易列表,而receipt字段是原始的副本,没有更新的交易信息。

我的问题:看来服务器获取有关更新事务的信息的唯一方法是查看latest_receipt_info or latest_receipt字段,但根据文档,这些字段不应出现在响应中。

这是苹果文档中的错误吗?或者获取最新交易集的唯一方法是让客户端在收到通知时发送更新的 AppReceiptsSKPayementTransactionObserver?

编辑 - 根据下面的评论添加所采取的步骤和一些代码。

1) 使用 SKPaymentQueue 购买 autoRenewSubscription 产品:

 SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
    payment.applicationUsername = [self hashedValueForAccountName:[UserAccount sharedInstance].subscriberKey];
    [[SKPaymentQueue defaultQueue] addPayment:payment];

2) 付款完成后,我会通过 SKPaymentTransactionObserver 收到回电,并通过以下 URL 发送文件:

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];

到我的远程服务器。

3)我使用以下Python代码来验证收据

import itunesiap
import base64

file = "/path/to/receipt/sandboxReceipt"
f = open(file)
encoded = base64.b64encode(f.read())

with itunesiap.env.current().clone(use_sandbox=True):  # additional change for current environment.
    response = itunesiap.verify(encoded,"mysecretkey")

响应包含一本字典。 字典有以下字段

"latest_receipt" = base64 encoded receipt here
"latest_receipt_info" = a JSON representation of the latest receipt
"receipt" = a JSON representation fo the receipt I sent for verification

文档说前 2 个字段是

“仅针对自动更新的 iOS 6 样式交易收据返回 订阅。”

  1. 为什么它们会出现在这里,因为我正在验证 iOS 7 样式 应用程序收据?
  2. 如果这些字段不应该出现,我该如何 获取最新交易信息?

苹果文档中的措辞含糊不清。仅返回 iOS 6 风格的交易收据用于自动续订订阅

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS 的 IAP 收据验证 的相关文章

随机推荐

  • 关于编写惯用的 Golang 的建议

    我正在掌握 Golang 的做事方式 首先是一些示例代码 package main import log os func logIt s string f os OpenFile errors log os O RDWR os O CREA
  • 为什么 git 无法识别我的本地存储库?

    我刚刚回到一个我已经使用 Git 大约 6 个月的项目 看到了这个 cd d DEVELOP BlenderAe My repo root git status fatal not a git repository or any of th
  • 当浏览器在后台运行时收到通知时,使用 Firebase 播放声音

    我想知道如何使用 Firebase Cloud Messaging FCM 播放声音 当Chrome Firefox等网络浏览器在后台运行时收到通知消息时 notification while running in the backgrou
  • 如何对 SQL Server 中的数据库进行单元测试?

    有哪些方法呢 您可以使用哪些框架 好吧 我想你的意思是对访问数据库的代码进行单元测试 在这种情况下 有NDbUnit http www ndbunit org 它似乎是 NET 的 DbUnit 克隆 我从来没有使用过它 但是我使用过DbU
  • 如何在 Three.js 中重新调整三角形面的方向

    用更好的例子进行编辑 我使用 Three js 来显示 MRI 胃图像的外壳 外壳是从 vtk 格式的外部文件加载的 这是一个演示 http www menne biomed de uni 3d alphahull html http ww
  • 为什么在这里使用BeginInvoke?

    我正在研究其他人的代码 并且对与多线程有关的任何事情没有太多经验 我遇到了这行代码 BeginInvoke MethodInvoker delegate btnCalibrate PerformClick 我想知道为什么要这样做 因为这样就
  • 未捕获的类型错误:无法设置未定义的属性“[任何 AMD]”

    示例scrollmagic模块 但它也发生在其他模块上 我怀疑这是为了 Babel 但不确定 我们如何重现这个错误 git克隆https github com zurb foundation zurb template https gith
  • 在 gnuplot 中创建仅带有箭头的向量

    如何创建一个没有线条而只有箭头的矢量 有一个名为 nohead 的选项 它删除了箭头的头部 但我想做相反的事情 删除矢量的线并只保留头部 最优选地还能够基于单个数字重新缩放该箭头的大小 找到了一些有用的建议TeX交换 https tex s
  • 如何在没有 API 请求的情况下使用 Nuxt.js 生成 100% 静态网站?

    我正在测试周围Nuxt js https nuxtjs org 生成静态网站 使用API 获取数据时是否可以生成100 静态站点 从而摆脱API和请求 根据我到目前为止的测试 所有文件都已正确生成并托管在Github 页面 https pa
  • 重写方法时,我的自定义代码应该位于 super(base) 之前还是之后

    重写方法时 我的自定义代码应该在对父类的超级 基 调用之前还是之后 这里有 3 个选择 如果你想执行代码之前的基本行为 然后之前调用它 如果你想执行代码后的基本行为 然后调用它 如果你想完全覆盖基本行为 根本不调用它 重要的是还检查您的 A
  • Sidekiq 停止一项正在运行的作业

    所以我需要停止running以编程方式 而非预定的 在 Sidekiq 3 1 2 中进行作业 我确实阅读了 API 文档 但没有真正找到有关取消正在运行的作业的任何内容 sidekiq 可以做到这一点吗 当这不可能直接实现时 我的想法是通
  • Python Pandas 按列对多索引进行排序,但保留树结构

    使用 pandas 0 20 3 我尝试按列 D 对数据帧的 n 个多级进行排序 其中的值 降序 以便维护组的层次结构 输入示例 D A B C Gran1 Par1 Child1 3 Child2 7 Child3 2 Par2 Chil
  • 自动部署资源

    我足够了解我们需要通过单个用户操作来部署我们的应用程序 但是 我don t know 在 NET 商店中可以使用哪些好工具 您如何管理每个环境的配置更改 有人可以给我指出一些用于持续集成的好资源吗 我希望看到一些理论以及逐步的实践指南 Ed
  • Node.js + Express.js |尝试设置 HTTPS 服务器

    我正在尝试使用 Node js 和 Express js 设置 HTTPS 服务器 我目前正在尝试 const filesystem require fs const express require express const server
  • Xamarin MasterDetailPage 看起来很难看

    I m trying to create a MasterDetailPage and I am not quite sure if I am doing that right but the drawer master just look
  • Oracle 事务在 C++ 和 Java 之间的传播

    我们有一个现有的 C 应用程序 我们将逐步将其替换为新的基于 Java 的系统 在我们用 Java 完全重新实现所有内容之前 我们期望 C 和 Java 必须相互通信 RMI SOAP 消息传递等 我们尚未决定 现在我的经理认为我们需要 J
  • Pandas 在读取 SAS 文件时数据类型正确失败

    我有一个SAS数据集 http www principlesofeconometrics com sas cars sas7bdat当我运行它时 我在 SAS 上得到以下输出 我还有以下 Python 代码 它获取 sas7bdat 文件并
  • 底部带有缩略图的轮播

    在 Codenameone 应用程序中 我尝试开发一个底部带有缩略图列表的轮播 我使用 Tabs 控件在表单中心以轮播样式显示文件 具有不同类型 如图像 视频 文本 按钮等 并使用另一个 Tabs 控件在底部显示缩略图图像 第一个轮播文件的
  • 如何在 Pro*C 查询中指定变量表达式列表?

    我尝试优化的 Pro C 查询出现问题 解释一下 我们的应用程序在一个巨大的数据库中搜索行 这些行存在于多种语言中 旧代码为数组中的每种语言选择一行 现在 由于这些查询是我们应用程序中最耗时的部分 因此我只想进行一个直接写入数组的查询 语言
  • iOS 的 IAP 收据验证

    我正在开发一个客户端 服务器应用程序 它使用 Apple 的 IAP 和 StoreKit 框架来购买订阅 我们希望客户 iPhone 或 iPad 能够使用 StoreKit 框架通过其 iTunes 帐户向 Apple 进行初始订阅购买