Highlight
Apple 在 WWDC23 为 App Store Server API 新增了 Get Transaction Info 端点、为 Notifications V2 新增了 subscription status 字段和 onlyFailures 筛选器,同时正式废弃了 verifyReceipt 和 Notifications V1,推动开发者迁移到更现代的 JWS 签名数据体系。
核心内容
用 transactionId 直接查询单笔交易
以前,服务器上验证一笔交易需要调用 Get Transaction History,然后在多页结果中翻找匹配的记录。如果用户的交易历史很长,这个过程既慢又繁琐。更麻烦的是,已完成的消耗型交易不会出现在 Get Transaction History 的响应中,这让验证消耗型交易变得不可能。
(03:12)Apple 推出了新的 Get Transaction Info 端点。你只需要提供一个 transactionId,就能直接获取该笔交易的签名信息。所有类型的交易 ID 都支持,包括已完成的消耗型交易。
调用方式很简单:
GET https://api.storekit.itunes.apple.com/inApps/v1/transactions/{transactionId}
响应中包含 signedTransactionInfo 字段,解码后即可查看该笔交易的完整信息。
(06:32)另一个便利更新是:原先需要 originalTransactionId 作为路径参数的核心端点(如 Get Transaction History、Get All Subscription Statuses),现在支持使用任意 transactionId。你不再需要先用 Get Transaction Info 去转换 ID,直接就能调用。
订阅状态一目了然
(07:42)追踪订阅状态是订阅制应用的核心需求。Notifications V2 会在订阅状态变化时发送事件,但有些通知的类型并不能直接告诉你当前状态。
比如收到 REFUND 通知时,你无法直接判断订阅是否被撤销。如果用户在同一 originalTransactionId 下有更新的续期交易,订阅状态可能仍然是 Active。仅凭通知数据无法做出正确判断。
(10:22)Apple 在 Notifications V2 的数据对象中新增了一个 status 字段。这是一个整数,直接表示订阅的五种核心状态之一。每个自动续期订阅相关的通知都会包含这个字段,服务器不再需要额外调用 API 来确认状态。
只获取失败的通知
(11:36)当服务器出现故障时,App Store 可能无法成功发送通知。Get Notification History 端点允许你请求过去六个月内的 V2 通知,用于恢复遗漏的通知。
但问题是:即使服务器正常运行,偶尔也可能因为瞬时网络问题错过个别通知。这种情况下,你没有一个明确的时间窗口去查询,只能翻阅大量已经收到的通知来寻找遗漏。
(12:30)Apple 为 Get Notification History 新增了一个 onlyFailures 请求字段。启用后,响应中只包含那些未能成功送达你服务器的通知,包括正在重试过程中的通知。
请求示例:
{
"onlyFailures": true
}
响应中的每个通知条目包含 sendAttempts 数组,记录了每次发送尝试的结果。如果后续重试成功,该通知将不再出现在 onlyFailures 的查询结果中。
verifyReceipt 正式废弃
(14:44)Apple 宣布 verifyReceipt 端点和 App Store Server Notifications V1 正式废弃。这两个 API 不会再接收新功能更新。
迁移到 App Store Server API 需要三个步骤:
- 生成 JWT 以代表你的应用身份
- 为每个用户保存一个 transactionId
- 使用 transactionId 调用核心端点
迁移到 Notifications V2 更简单:
- 让服务器准备好解析 V2 格式(使用与 Server API 相同的 JWS 交易格式)
- 在 App Store Connect 中将通知偏好从 V1 切换到 V2
- 先在沙盒环境测试 V2 通知
(19:35)Apple 还发布了 App Store Server Library 开源库,支持 Swift、Java、Node.js 和 Python,帮助开发者更轻松地调用 API、验证签名数据,以及从收据中提取 transactionId 来简化迁移。
详细内容
Get Transaction Info 端点详解
(05:47)新的 Get Transaction Info 端点解决了服务器端验证单笔交易的痛点。
请求格式:
GET /inApps/v1/transactions/{transactionId}
Authorization: Bearer {JWT}
响应格式:
{
"signedTransactionInfo": "eyJhbGciOiJFUzI1Ni..."
}
关键点:
signedTransactionInfo是 JWS 格式的签名交易数据- 解码后可获得完整的交易信息,包括 productId、purchaseDate、type 等
- 支持所有交易类型:消耗型、非消耗型、自动续期订阅、非续期订阅
- 支持已完成和未完成的交易
Notifications V2 的 status 字段
(10:30)status 字段是一个整数,对应五种订阅状态:
| 值 | 状态 | 含义 |
|---|---|---|
| 1 | Active | 订阅活跃中 |
| 2 | Expired | 订阅已过期 |
| 3 | Billing Retry | 账单重试中 |
| 4 | Billing Grace Period | 账单宽限期内 |
| 5 | Revoked | 订阅已撤销 |
这个字段出现在所有自动续期订阅相关的通知中。收到 REFUND 通知时,直接检查 status 就能知道是否需要禁用内容访问。
onlyFailures 的使用场景
(13:08)onlyFailures 字段解决了两种场景:
- 已知服务器故障:服务器宕机后恢复,查询故障期间遗漏的通知
- 未知网络问题:日常运行中偶尔漏掉个别通知,快速定位遗漏项
{
"startDate": 1686000000000,
"endDate": 1686086400000,
"onlyFailures": true
}
响应中的 notificationHistory 数组只包含失败的通知。每个条目包含:
signedPayload:原始通知的签名内容sendAttempts:发送尝试记录,最多 6 条(1 次初始发送 + 5 次重试)
迁移路径
(17:16)从 verifyReceipt 迁移:
旧流程:
设备 → 收据 → 你的服务器 → verifyReceipt → Apple → 解码后的收据 → 你的服务器
新流程:
设备 → transactionId → 你的服务器 → App Store Server API → 签名交易数据
你不再需要存储 base64 编码的收据,只需要保存一个 transactionId。
核心启发
-
构建实时订阅状态看板
- 做什么:在服务器上维护一个实时订阅状态仪表板,支持客服团队查看用户订阅状态
- 为什么值得做:Notifications V2 的
status字段让状态同步变得直接可靠,不再需要复杂的推断逻辑 - 怎么开始:设置 Notifications V2 接收端点,解析每个通知中的
status字段,更新数据库中的用户订阅状态
-
实现智能通知恢复机制
- 做什么:在服务器健康检查流程中集成
onlyFailures查询,自动恢复遗漏的通知 - 为什么值得做:网络问题不可避免,
onlyFailures让恢复遗漏通知从”翻遍历史”变成”精准定位” - 怎么开始:在服务器启动或定时任务中调用 Get Notification History 并传入
onlyFailures: true,处理返回的遗漏通知
- 做什么:在服务器健康检查流程中集成
-
简化服务器端交易验证
- 做什么:用 Get Transaction Info 替代 Get Transaction History 进行单笔交易验证
- 为什么值得做:代码更简洁、响应更快、支持消耗型交易验证
- 怎么开始:将现有验证逻辑从”查询历史+搜索匹配”改为直接调用 Get Transaction Info,传入 transactionId
-
规划 verifyReceipt 迁移
- 做什么:制定从 verifyReceipt 到 App Store Server API 的迁移计划
- 为什么值得做:verifyReceipt 已废弃,新功能只会在 JWS 签名数据体系中发布
- 怎么开始:使用 App Store Server Library 开源库,从收据中提取 transactionId,逐步替换 verifyReceipt 调用
关联 Session
- Explore testing in-app purchases — 了解如何使用 StoreKit Testing、Sandbox 和 TestFlight 测试内购
- Meet the App Store Server Library — Apple 官方开源库,简化 Server API 调用和数据验证
- What’s new in StoreKit 2 — StoreKit 2 客户端新特性,与 Server API 配合使用
- Subscription Offers Best Practices — 订阅优惠的设计和实现最佳实践
评论
GitHub Issues · utterances