跳到主要内容
App Store Refund Management

什么是 Apple CONSUMPTION_REQUEST?它是如何运作的?

一文读懂 CONSUMPTION_REQUEST。了解它如何与 App Store Server Notifications 配合运作,以及如何帮助 Apple 评估退款请求。

5 min read
什么是 Apple CONSUMPTION_REQUEST?它是如何运作的?

如果你近几年在任何地方读到过 CONSUMPTION_REQUEST,大概率见过一份包含十二个字段的清单:账户使用时长、累计消费金额、游戏时长、平台等等。

那份清单属于旧版本的端点。Apple 当前的端点只接受五个字段,其中三个为必填,且覆盖的产品类型比原版更多。不少仍在线上运行的集成依然是按旧结构构建的。

所以,这篇文章会带你梳理这个通知到底是什么、Apple 如今希望你返回什么,以及如何构建一条经得起考验的响应路径。

要点速览

• CONSUMPTION_REQUEST 是一条在退款审核期间请求信息的通知。它不是退款,也不是裁决。

• 退款决定由 Apple 做出。你的响应只是其中一项输入。

• 当前端点接受五个字段,三个必填,覆盖所有产品类型。

• 客户同意是强制要求。未确认同意的请求会被 Apple 拒绝。

• Apple 要求在收到通知后 12 小时内响应。

• 该端点存在两个版本。请检查你的集成调用的是哪一个。

什么是 Apple CONSUMPTION_REQUEST?

Apple CONSUMPTION_REQUEST 是一种 App Store Server Notification,用于告知你的服务器:某位客户已申请退款,并邀请你发送与该笔购买相关的消费信息。它会发送到你配置的通知 URL,携带相关的交易信息,并给你一个有限的响应时间窗口。

它不是退款通知。通知到达时,什么都还没有定论——Apple 正处于评估请求的过程中,在做出结论之前收集上下文。对开发者而言,它的实际含义很明确:一项任务刚刚落到了你的后端,有截止时间,并且需要只有你的系统才掌握的数据。

Apple 为什么会发送 CONSUMPTION_REQUEST?

因为 Apple 只能看到交易的一半。

Apple 知道买了什么、何时购买、由哪个账户购买,以及该账户的历史记录。但它看不到你的应用内部:金币是否已到账、解锁是否成功,或者客户在要求退款之前使用了多少。

这里的“消费”(consumption)指的是客户对所购内容的使用程度。一份每天使用、持续三周的订阅,和一份从未打开过的订阅,在 Apple 眼中并无区别。但在你眼中截然不同。

有必要说清楚其中的边界。Apple 不会仅凭一个消费数字来批准或拒绝退款。这些信息只是输入到一个综合多项因素的决策之中,高消费百分比并不是一个“拒绝按钮”。

Apple CONSUMPTION_REQUEST 是如何运作的?

整个流程如下:

客户发起退款请求

Apple 开始退款审核

CONSUMPTION_REQUEST 到达你的通知端点

你验证通知并识别对应的交易

你检查客户同意状态并收集使用数据

在满足要求的情况下,你发送消费信息

Apple 权衡这些信息

Apple 做出退款决定

你跟踪最终的交易状态

有一点需要说明。Apple 当前的文档将这一通知与所有产品类型的退款请求关联在一起,范围比旧文档描述的更广。但 Apple 并未承诺每种情况都一定会发送通知,所以你应该构建一个在请求到达时进行响应的处理程序,而不是依赖“通知一定会来”的逻辑。

Apple 要求开发者提供哪些信息?

Apple 当前的 Send Consumption Information 端点接受五个字段。三个必填,两个可选。

字段

是否必填

含义

customerConsented

必须为 true,否则 Apple 会拒绝该请求。

deliveryStatus

你的应用是否交付了可正常使用的购买内容;如果没有,原因是什么。

sampleContentProvided

客户在购买前能否试用内容。

consumptionPercentage

已消费的比例,以毫单位(milliunits)表示(50% 即 50000)。

refundPreference

全额退款、拒绝退款或按比例退款——这是你的偏好,而非决定。

有两条校验规则常让人栽跟头。如果交付状态不是“已交付”,消费百分比必须为零,否则请求会失败。另外,毫单位不等于百分比:消费一半是 50000。

退款偏好是最新加入的部分,也最容易被误读。你可以告诉 Apple 你倾向于全额退款、拒绝退款或按比例退款,Apple 会将其与其他所有因素一起权衡。最终结果可能不同。如果按比例退款获批,被撤销的部分会体现在交易 payload 中,因此你的权益(entitlement)逻辑需要能处理部分撤销。

值得核查的版本差异

Apple 为这个端点提供了两个版本的文档,命名方式很容易让人误解。 Send Consumption Information V1 是较早的版本,采用的是大多数第三方文章仍在描述的十二字段请求体。Apple 在该页面上的说明明确指出,标准应用内购买应改用当前端点,而 V1 仅适用于通过 Advanced Commerce API 完成的购买。

当前端点

V1 端点

请求字段

5 个(3 个必填)

12 个

产品类型

全部四种类型

消耗型和自动续期订阅

适用于

标准应用内购买

通过 Advanced Commerce API 完成的购买

如果你的集成早于这次变更,请从这里开始检查。

什么是消费信息?

消费信息是你发送给 Apple 的数据,用于描述客户购买之后这笔购买发生了什么:是否已交付、客户在购买前能否试用,以及他们使用了多少。

它之所以重要,是因为这是整幅图景中 Apple 唯一看不到的部分。对订阅类应用来说,它描述客户购买后是否使用了服务;对消耗型商品来说,是余额花掉了多少;对非消耗型商品来说,是解锁是否成功。

关键词是“准确”。这是你在获得客户同意后、从自己的记录中提取的数据。它不是你在构建的一套说辞,为了得到某个理想结果而对数据加以修饰,会带来实实在在的风险,却换不来任何可靠的收益。

开发者应如何响应 CONSUMPTION_REQUEST?

共九个步骤,而且大部分工作都在任何请求到达之前就要完成。

1. 接收通知

请求会发送到你为 App Store Server Notifications V2 设置的 URL。Apple 的 App Store Server Notifications 文档介绍了配置方式和 payload 结构。如果端点配置有误,请求根本不会到达你这里,而且不会有任何提示。

2. 验证通知

Payload 是经过签名的。在处理其中任何内容之前,先依据 Apple 的证书链进行验证,并确认 bundle ID。

3. 识别相关交易

从解码后的 payload 中提取交易标识符,并与你的购买记录进行匹配。没有存储记录,就无法查找,也就没有描述消费情况的依据。

4. 检查客户同意是否允许响应

Apple 要求你在分享客户数据之前获得有效的客户同意,而获取同意是你的责任。通知中不包含同意标记,所以你必须从自己的记录中获知。Apple 还明确指出,App Tracking Transparency 提示并不是用于此目的的机制——这是一项单独的同意,需要在你的应用内收集。如果没有获得同意,Apple 的指导是不要响应。我们关于 appAccountToken 与 Apple 退款防御的文章介绍了让这种查找成为可能的身份识别环节。

5. 收集相关的消费信息

从你自己的系统中读取交付状态和使用情况。如果你跟踪消耗型商品的余额,这个数字本来就存在。如果某次解锁失败了,你的日志会知道。

6. 准备符合规范的响应

组装必填字段,在有真实数据的情况下加入可选字段,并先核对校验规则。

7. 在 Apple 的时间窗口内提交

使用通知中的原始交易标识符,向消费信息端点发送 PUT 请求。

8. 记录响应

保存你发送的内容、发送时间以及返回结果。如果没有记录结果,一次校验失败的提交看起来和成功的提交一模一样。

9. 跟踪最终的退款结果

Apple 会以单独的通知发送裁决结果。请将其记录到对应的交易和客户名下。

开发者有多长时间可以响应?

Apple 当前的文档要求在收到通知后 12 小时内响应。

十二小时听起来很宽裕,直到你考虑通知到达的时间。请求会在深夜、周末、节假日到来,而计时不会暂停。周五晚上 11 点到达的请求,到周一之前就已经过期了。

Apple 并未表示错过窗口就自动意味着退款获批,这样说是不对的。它的实际含义更简单:你没有提供 Apple 愿意考虑的信息,决定就在没有这些信息的情况下做出了。

开发者响应之后会发生什么?

Apple 会将这些信息纳入审核并做出决定。你会以通知的形式看到结果:已批准、已拒绝,或者之后 Apple 撤回先前批准的退款时的“已撤销”。

接下来就是你的工作了。退款获批时撤销权益,退款撤销时恢复权益,并处理只有部分交易金额被退回的按比例退款情形。

订阅状态也需要留意,因为被退款的周期通常会终止订阅,而不是让它继续运行;退款也应当计入正确周期的营收记录。

这种分工值得明确说明:你提供信息,Apple 做出决定,然后你让自己的系统与结果保持同步。三项各自独立的职责,只有中间那一项属于 Apple。

为什么手动处理 CONSUMPTION_REQUEST 很困难?

这个工作流中的每一项约束都在与人工操作作对。

通知全天候到达。窗口是 12 小时。每个请求都需要签名校验、交易查找、用户匹配、同意检查、使用量计算、一次带认证的 API 调用,以及一条结果日志。这些都不难,但全都有时限、重复性高,而且做对了也看不到任何成果。

规模会让情况更糟:多个应用、交易数据在一个系统而使用数据在另一个系统、响应日志变得零散、权益状态与交易状态悄然脱节却无人察觉。这并不意味着手动处理一定会让你损失金钱,但风险是真实存在的,而且会在无声中累积。

Apple CONSUMPTION_REQUEST 可以自动化吗?

可以,而且这个工作流的形态本身就支持自动化,因为几乎每一步都是确定性的。

自动化可以监控并验证通知、专门识别消费请求、将交易解析到对应账户、根据你的记录组装响应、跟踪时间窗口、提交、记录结果、记录裁决,并推送权益更新。

它做不到的是影响 Apple 的决定。没有任何工具能改变这一点,任何暗示可以做到的产品都是在错误描述这个流程。自动化改变的是,你这一侧的工作能否稳定地、在窗口期内完成。

RefundSensor 如何帮助开发者处理 Apple 退款工作流

App Store 退款管理正是这项工作所属的类别。RefundSensor 覆盖的是开发者这一侧:监控 Apple 退款相关工作流、处理受支持的 CONSUMPTION_REQUEST 响应路径,并将退款事件和结果集中在一处,而不是分散在各个 dashboard 和表格里。

在实际使用中,响应会在窗口期内发出,无需有人盯着通知;随着数量增长,退款记录也能保持准确。它不能阻止退款,也无法保证 Apple 做出任何特定的决定。它减少的是人工监控和遗漏的步骤。

这些规则的文档出处

上述所有内容都有三份 Apple 官方资料作为依据。请直接阅读它们,并定期回看——这一领域近期有过变动,二手资料往往滞后。

Send Consumption Information——当前端点。同意要求、12 小时窗口、五字段请求体,以及它覆盖的产品类型。标准应用内购买请基于此版本构建。

Send Consumption Information V1——较早的端点,采用十二字段请求体。可用于判断你的集成处于哪个版本,也适用于使用 Advanced Commerce API 的团队。

App Store Server Notifications——通知如何到达你的后端、签名 payload 的格式,以及包括 CONSUMPTION_REQUEST 和退款结果在内的各种通知类型。


如果这些仍在靠人工处理

12 小时的窗口和凌晨 3 点到达的通知,与一个依赖有人查看 dashboard 的流程实在不匹配。

如果你的团队正处于这种状态, RefundSensor 可以处理这些工作流中开发者这一侧的工作:监控通知、在窗口期内准备并提交响应,并将结果一路跟踪到你的权益记录。

常见问题

这是一种 App Store Server Notification,用于告知你的服务器某位客户已申请退款,并且 Apple 邀请你发送与该笔购买相关的消费信息。它不是退款通知,也不是裁决。Apple 会单独做出决定,你的响应只是多项因素中的一项输入。

因为 Apple 看不到你的应用内部。它知道交易和账户历史,但不知道内容是否已交付、是否正常工作,以及客户使用了多少。这些上下文存在于你的系统中,Apple 会在完成审核之前向你索取。

客户申请退款,Apple 开始审核,通知随即到达你配置的端点。你验证通知、识别交易、确认客户同意、收集使用数据,并在时间窗口内发送消费信息。Apple 权衡这些信息后做出决定,并以单独的通知发送结果。

当前端点接受五个字段。三个必填:客户同意、交付状态,以及是否提供了试用内容。两个可选:购买内容的消费比例,以及你倾向的退款结果。早期的 V1 端点要求十二个字段,这就是为什么旧文章描述的清单要长得多。

Apple 当前的文档将该通知与所有产品类型的退款请求关联在一起,范围比旧文档描述的更广。但 Apple 并未承诺每种情况都一定会发送,所以你应该构建一个在请求到达时进行响应的处理程序,而不是依赖“通知一定会来”的逻辑。

Apple 的文档要求在收到通知后 12 小时内响应。请求随时可能到达,包括周末,因此这是人工流程中最容易错过的一步。请以 Apple 页面上的当前要求为准,不要依赖旧的集成。

你可以为决定提供信息,但无法控制它。准确的消费数据为 Apple 提供了它原本缺少的上下文,当前端点也允许你表明退款偏好。Apple 会将两者与其他因素一起权衡,最终可能做出不同的决定。开发者没有任何机制可以批准或拒绝退款。

可以。验证通知、识别交易、检查同意状态、从记录中组装数据、遵守时间窗口、提交以及记录结果,都是确定性的步骤。仍需人工完成的是在应用中设计同意流程,以及确定你的退款偏好策略。

#Apple CONSUMPTION_REQUEST#App Store Server API#App Store Server Notifications#In-App Purchases#Apple Refunds#StoreKit
Refund SensorRefund Sensor TeamRefund defense for App Store and Google Play developers