与来自 Apple 的 verifyReceipt 端点的响应文档不一致
Inconsistencies with documentation in response from Apple's verifyReceipt endpoint
我正在我们的服务器上为 Apple 的自动续订订阅设置收据验证,发现与官方 documentation 存在一些不一致。使用沙盒 verifyReceipt 端点验证沙盒收据时,响应如下所示:
{
"auto_renew_status": 1,
"status": 0,
"auto_renew_product_id": "app.xxx",
"receipt": {
"original_purchase_date_pst": "2020-03-18 01:11:45 America/Los_Angeles",
"quantity": "1",
"unique_vendor_identifier": "6D2xxx194",
"bvrs": "2",
"expires_date_formatted": "2020-03-20 12:27:07 Etc/GMT",
"is_in_intro_offer_period": "false",
"purchase_date_ms": "1584703627636",
"expires_date_formatted_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"is_trial_period": "false",
"item_id": "15xxx27",
"unique_identifier": "cd5xxx424",
"original_transaction_id": "100xxx735",
"subscription_group_identifier": "20xxx02",
"transaction_id": "100xxx439",
"web_order_line_item_id": "100xxx419",
"version_external_identifier": "0",
"purchase_date": "2020-03-20 11:27:07 Etc/GMT",
"product_id": "app.xxx",
"expires_date": "1584707227636",
"original_purchase_date": "2020-03-18 08:11:45 Etc/GMT",
"purchase_date_pst": "2020-03-20 04:27:07 America/Los_Angeles",
"bid": "app.xxx",
"original_purchase_date_ms": "1584519105000"
},
"latest_receipt_info": {
"original_purchase_date_pst": "2020-03-18 01:11:45 America/Los_Angeles",
"quantity": "1",
"unique_vendor_identifier": "6D2xxx194",
"bvrs": "2",
"expires_date_formatted": "2020-03-20 12:27:07 Etc/GMT",
"is_in_intro_offer_period": "false",
"purchase_date_ms": "1584703627000",
"expires_date_formatted_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"is_trial_period": "false",
"item_id": "15xxx27",
"unique_identifier": "cd5xxx424",
"original_transaction_id": "100xxx735",
"subscription_group_identifier": "20xxx02",
"transaction_id": "100xxx439",
"bid": "app.xxx",
"web_order_line_item_id": "100xxx419",
"purchase_date": "2020-03-20 11:27:07 Etc/GMT",
"product_id": "app.xxx",
"expires_date": "1584707227000",
"original_purchase_date": "2020-03-18 08:11:45 Etc/GMT",
"purchase_date_pst": "2020-03-20 04:27:07 America/Los_Angeles",
"original_purchase_date_ms": "1584519105000"
},
"latest_receipt": "xxx"
}
我特别想指出该回复的以下字段:
{
...
"latest_receipt_info": {
...
"expires_date": "1584707227000",
"expires_date_formatted": "2020-03-20 12:27:07 Etc/GMT",
"expires_date_formatted_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"subscription_group_identifier": "20xxx02",
"bid": "app.xxx",
...
},
"receipt": {
...
"expires_date": "1584707227636",
"expires_date_formatted": "2020-03-20 12:27:07 Etc/GMT",
"expires_date_formatted_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"subscription_group_identifier": "20xxx02",
"bid": "app.xxx",
...
},
...
}
与官方不一致的地方documentation有:
latest_receipt_info
是 documented 数组,但是,它是单个 json 对象。
- 在
latest_receipt_info
中,expires_date
并不像 documentation 所说的那样在 "date-time format similar to the ISO 8601" 中,但看起来它是从纪元开始的毫秒数(应该是expires_date_ms
)。但是,我们可以找到日期时间格式的键expires_date_formatted
。
- 与 (2) 中相同的字段也可以在收据中找到,但是,documentation 仅声明一个键
expiration_date
(类似于 expires_date
latest_receipt_info
日期时间格式)和 expiration_date_ms
(自纪元以来的毫秒数)。
- 记录的
bundle_id
密钥 (here and here) 不存在,但存在一个密钥 bid
,它包含包 ID。
- 密钥
subscription_group_identifer
不包含在 AppStoreConnect 中作为订阅组标识符输入的确切字符串,如记录的那样 (here and here),但包含一些整数值。
所以根据文档,对我来说响应应该是这样的:
{
...
"latest_receipt_info": [
{
...
"expires_date": "2020-03-20 12:27:07 Etc/GMT",
"expires_date_ms": "1584707227000",
"expires_date_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"subscription_group_identifier": "MY_SUBSCRIPTION_GROUP_ID",
"bundle_id": "app.xxx",
...
}
],
"receipt": {
...
"expiration_date": "2020-03-20 12:27:07 Etc/GMT",
"expiration_date_ms": "1584707227636",
"expiration_date_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"subscription_group_identifier": "MY_SUBSCRIPTION_GROUP_ID",
"bundle_id": "app.xxx",
...
},
...
}
- 我不确定如何处理这种情况,这是 API 中的错误还是文档完全错误?
- 生产端点是否会出现同样的不一致(有人可以分享示例响应)吗?
- server-to-server notifications中的通知怎么样,是否也有不一致的地方?
提前致谢!
你从哪里得到那个收据例子?这是来自 verifyReceipt endint 的正确收据示例:https://gist.github.com/ren6/3da2d14ea629ab9add489c0e6df1917c
我还可以推荐您阅读我们博客中的文章:https://blog.apphud.com/receipt-validation/
关于 Apple 服务器到服务器的通知,它们现在是统一的,即数据以与 verifyReceipt
端点相同的结构返回。
对于面临同样问题的每个人:我们向后端发送了错误的收据数据,因为我们通过已弃用的 transactionReceipt and not via appStoreReceiptURL 请求收据。
我正在我们的服务器上为 Apple 的自动续订订阅设置收据验证,发现与官方 documentation 存在一些不一致。使用沙盒 verifyReceipt 端点验证沙盒收据时,响应如下所示:
{
"auto_renew_status": 1,
"status": 0,
"auto_renew_product_id": "app.xxx",
"receipt": {
"original_purchase_date_pst": "2020-03-18 01:11:45 America/Los_Angeles",
"quantity": "1",
"unique_vendor_identifier": "6D2xxx194",
"bvrs": "2",
"expires_date_formatted": "2020-03-20 12:27:07 Etc/GMT",
"is_in_intro_offer_period": "false",
"purchase_date_ms": "1584703627636",
"expires_date_formatted_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"is_trial_period": "false",
"item_id": "15xxx27",
"unique_identifier": "cd5xxx424",
"original_transaction_id": "100xxx735",
"subscription_group_identifier": "20xxx02",
"transaction_id": "100xxx439",
"web_order_line_item_id": "100xxx419",
"version_external_identifier": "0",
"purchase_date": "2020-03-20 11:27:07 Etc/GMT",
"product_id": "app.xxx",
"expires_date": "1584707227636",
"original_purchase_date": "2020-03-18 08:11:45 Etc/GMT",
"purchase_date_pst": "2020-03-20 04:27:07 America/Los_Angeles",
"bid": "app.xxx",
"original_purchase_date_ms": "1584519105000"
},
"latest_receipt_info": {
"original_purchase_date_pst": "2020-03-18 01:11:45 America/Los_Angeles",
"quantity": "1",
"unique_vendor_identifier": "6D2xxx194",
"bvrs": "2",
"expires_date_formatted": "2020-03-20 12:27:07 Etc/GMT",
"is_in_intro_offer_period": "false",
"purchase_date_ms": "1584703627000",
"expires_date_formatted_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"is_trial_period": "false",
"item_id": "15xxx27",
"unique_identifier": "cd5xxx424",
"original_transaction_id": "100xxx735",
"subscription_group_identifier": "20xxx02",
"transaction_id": "100xxx439",
"bid": "app.xxx",
"web_order_line_item_id": "100xxx419",
"purchase_date": "2020-03-20 11:27:07 Etc/GMT",
"product_id": "app.xxx",
"expires_date": "1584707227000",
"original_purchase_date": "2020-03-18 08:11:45 Etc/GMT",
"purchase_date_pst": "2020-03-20 04:27:07 America/Los_Angeles",
"original_purchase_date_ms": "1584519105000"
},
"latest_receipt": "xxx"
}
我特别想指出该回复的以下字段:
{
...
"latest_receipt_info": {
...
"expires_date": "1584707227000",
"expires_date_formatted": "2020-03-20 12:27:07 Etc/GMT",
"expires_date_formatted_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"subscription_group_identifier": "20xxx02",
"bid": "app.xxx",
...
},
"receipt": {
...
"expires_date": "1584707227636",
"expires_date_formatted": "2020-03-20 12:27:07 Etc/GMT",
"expires_date_formatted_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"subscription_group_identifier": "20xxx02",
"bid": "app.xxx",
...
},
...
}
与官方不一致的地方documentation有:
latest_receipt_info
是 documented 数组,但是,它是单个 json 对象。- 在
latest_receipt_info
中,expires_date
并不像 documentation 所说的那样在 "date-time format similar to the ISO 8601" 中,但看起来它是从纪元开始的毫秒数(应该是expires_date_ms
)。但是,我们可以找到日期时间格式的键expires_date_formatted
。 - 与 (2) 中相同的字段也可以在收据中找到,但是,documentation 仅声明一个键
expiration_date
(类似于expires_date
latest_receipt_info
日期时间格式)和expiration_date_ms
(自纪元以来的毫秒数)。 - 记录的
bundle_id
密钥 (here and here) 不存在,但存在一个密钥bid
,它包含包 ID。 - 密钥
subscription_group_identifer
不包含在 AppStoreConnect 中作为订阅组标识符输入的确切字符串,如记录的那样 (here and here),但包含一些整数值。
所以根据文档,对我来说响应应该是这样的:
{
...
"latest_receipt_info": [
{
...
"expires_date": "2020-03-20 12:27:07 Etc/GMT",
"expires_date_ms": "1584707227000",
"expires_date_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"subscription_group_identifier": "MY_SUBSCRIPTION_GROUP_ID",
"bundle_id": "app.xxx",
...
}
],
"receipt": {
...
"expiration_date": "2020-03-20 12:27:07 Etc/GMT",
"expiration_date_ms": "1584707227636",
"expiration_date_pst": "2020-03-20 05:27:07 America/Los_Angeles",
"subscription_group_identifier": "MY_SUBSCRIPTION_GROUP_ID",
"bundle_id": "app.xxx",
...
},
...
}
- 我不确定如何处理这种情况,这是 API 中的错误还是文档完全错误?
- 生产端点是否会出现同样的不一致(有人可以分享示例响应)吗?
- server-to-server notifications中的通知怎么样,是否也有不一致的地方?
提前致谢!
你从哪里得到那个收据例子?这是来自 verifyReceipt endint 的正确收据示例:https://gist.github.com/ren6/3da2d14ea629ab9add489c0e6df1917c
我还可以推荐您阅读我们博客中的文章:https://blog.apphud.com/receipt-validation/
关于 Apple 服务器到服务器的通知,它们现在是统一的,即数据以与 verifyReceipt
端点相同的结构返回。
对于面临同样问题的每个人:我们向后端发送了错误的收据数据,因为我们通过已弃用的 transactionReceipt and not via appStoreReceiptURL 请求收据。