快速答案:当客户就应用内购买或订阅向 Apple 申请退款时,App Store 会向你的服务器发送一条 CONSUMPTION_REQUEST 通知,并给你大约 12 小时的时间,通过 Send Consumption Information 端点提交消费数据以作回应。Apple 会在决策时权衡这些数据。如果你未能及时回应,Apple 将在没有你输入信息的情况下做出决定,而没有正当理由的退款申请通常会被默认批准。将这一回应流程自动化,意味着每一次请求都能在窗口期内得到回应,每次都不例外。
简而言之
Apple 掌控着支付通道。当有人在你的应用中购买订阅或应用内商品时,Apple 会收款、抽取分成,并负责处理退款。多年来,开发者在退款决策中完全没有发言权。
这一情况已经改变。现在 Apple 允许你发送消费信息——即客户如何使用其所购商品的结构化证据——并将其纳入退款决策的考量因素。你无法自行批准或拒绝退款,最终决定权仍在 Apple 手中。但保持沉默会让 Apple 没有任何可参考的信息,而一份格式规范的回应则能为其提供上下文。
问题的关键在于时机和一致性。退款窗口期很短,Apple 退款响应时间有限,且开启时间难以预测,一旦请求量达到一定规模,靠人工处理根本不现实。这正是自动化要解决的问题。
Apple 退款流程的实际运作方式
以下是完整的流程顺序:
客户提交退款申请。客户访问 reportaproblem.apple.com,选择相应的购买项目,选择理由并提交申请。
Apple 通知你的服务器。对于符合条件的购买项目,App Store 会通过 App Store Server Notifications V2 发送一条 CONSUMPTION_REQUEST 通知。该负载中包含用于识别该笔购买的已签名交易数据。
你以消费数据作出回应。你需要调用 Send Consumption Information,提供原始交易 ID,以及一个描述交付情况、使用情况、同意状态和你的退款偏好的结构化 ConsumptionRequest 主体。
Apple 做出决定。其退款决策系统会结合你提供的数据、客户的历史记录以及其他因素进行权衡,然后做出裁定。
你会收到结果通知。REFUND 通知表示退款已获批准;REFUND_DECLINED 通知(针对通过 StoreKit API 发起的请求)则表示退款未获批准。
CONSUMPTION_REQUEST 包含哪些内容,以及你需要回传哪些内容
该通知本身携带已签名的交易信息以及客户陈述的理由(consumptionRequestReason)。真正的工作在于你的回应。Apple 定义了一个结构化的 ConsumptionRequest,包含以下字段:
以下是根据你的图片重新整理的表格:
字段 | 这向 Apple 传达了什么信息 |
customerConsented | 客户是否同意分享此数据。此项必须为 true,否则 Apple 会拒绝该提交。 |
consumptionStatus | 所购内容是未消费、部分消费还是已完全消费。 |
deliveryStatus | 应用内价值或服务是否已实际交付。 |
accountTenure | 客户在你这里拥有账户的时长。 |
playTime | 客户在应用中花费的时长。 |
lifetimeDollarsPurchased | 客户在你所有应用中的累计消费总额。 |
lifetimeDollarsRefunded | 此前已退还给该客户的总金额。 |
sampleContentProvided | 客户在购买前是否可以试用内容。 |
userStatus | 客户账户的当前状态(active、suspended 等)。 |
refundPreference | 你向 Apple 提出的建议:undeclared(未声明)、prefer grant(倾向批准)或 prefer decline(倾向拒绝)。 |
你向 Apple 提出的建议:undeclared(未声明)、prefer grant(倾向批准)或 prefer decline(倾向拒绝)。
每个字段都是一种信号。如果留空,Apple 就永远无法获得这部分上下文信息。我们在《What Is a CONSUMPTION_REQUEST Notification? A Field-by-Field Breakdown》一文中逐一拆解了每个字段及其可接受的取值。
12 小时窗口期
在生产环境中,你大约有 12 小时的时间来回应一条 CONSUMPTION_REQUEST。这个 consumption_request 截止时间至关重要,因为一旦错过,你就丧失了提供信息的机会,Apple 只会依据其已掌握的信息做出决定。
问题不在于 Apple 退款响应窗口期的长短,而在于它何时开启。退款请求不会等到工作时间才出现。退款窗口期可能在深夜、周末或节假日开启,而如果没有人 24 小时待命,人工审核队列根本无法覆盖这些情况。这正是开发者错失本可争取到的退款的最常见原因:不是回应得不好,而是根本没有回应。我们在《The 12-Hour Window: Why Most Developers Lose Refunds by Default》一文中对此有更深入的探讨。
同意授权要求,切勿跳过这一步
这是几乎所有人都会踩坑的地方,而且这不仅仅是一个技术问题,更是一个法律问题。
Apple 的 CONSUMPTION_REQUEST 并不会告诉你客户是否同意分享其数据。这是有意为之的设计:Apple 期望由你的应用(而非服务器)在发送任何消费数据之前收集并确认用户同意。你必须在 API 调用中将 customerConsented 设置为 true,而作为开发者,你需要对是否已获得有效同意负全部责任,因为你才是分享这些从用户处收集来的数据的一方。
如果处理不当,你面临的不仅仅是提交被拒的风险,还可能引发 GDPR 或 DPDP 合规问题。在实现任何自动化之前,务必在应用的条款和购买流程中妥善处理用户同意事宜。我们在《Customer Consent & the Consumption API: What Apple Actually Requires》一文中详细说明了具体的位置和方法。
实现这一自动化流程实际需要什么
从表面上看,将回应流程自动化似乎只是个周末就能搞定的小项目:捕获通知、填写字段、调用端点。但在生产环境中,这其实是一套需要长期维护的基础设施,而真正理解其中的复杂程度,往往决定了团队最终是选择“我们自己做”还是“我们放弃这个念头”。
一个可靠的内部响应系统必须能够接收并验证 Apple 发出的已签名通知,在请求到达的瞬间为每位客户拉取准确、实时的使用数据和账单数据,将这些数据映射到 Apple 精确的 ConsumptionRequest 取值格式,并在大约 12 小时的 Apple 退款响应窗口期内完成提交——无论何时,全程无需人工值守。除此之外,它还需要具备保证不超期的重试机制、故障处理、可供审计的日志记录、监控机制(以便你知道系统是否出现故障),以及每当 Apple 修改其负载或字段时进行的持续维护。这些都不是你产品的一部分。所有这一切,都是你需要无限期自行维护的基础设施,而这套工作流程与你应用本身要做的事情毫无关系。(我们在《Setting Up App Store Server Notifications V2》一文中对通知层做了更深入的探讨。)
这正是大多数团队最终得出的结论:具体机制并非无法弄懂,但构建并持续维护一个合规、能保证不超期的响应系统,是一项永久性的成本支出,对应用本身却没有任何附加价值。这正是托管服务所要解决的那类毫无差异化价值的“管道工程”。
这正是 RefundSensor 所做的事情。只需一个 webhook URL 即可接入你的 App Store Connect 配置,无需 SDK、无需修改代码、无需重新提交应用,随后系统会在 Apple 的退款窗口期内自动回应每一条 CONSUMPTION_REQUEST,从你的数据中映射相应字段,处理重试和监控,并随 Apple 的变更保持同步更新,同时将每一次结果都记录在同一个 dashboard 中。对于正在寻找 Apple 退款自动化软件的团队来说,这省去了自行构建和维护整套退款响应基础设施的必要。
回应退款请求真的能减少退款数量吗?
是的,尽管结果因情况而异,且最终决定权始终在 Apple 手中。提交准确的消费数据能为 Apple 的系统提供更多上下文信息,而持续做出回应的开发者,通常比对请求置之不理的开发者获批的退款要更少。当你的证据确实能够支持时,选择“prefer decline”(倾向拒绝)建议,也是 Apple 会纳入考量的又一项信息。
因此,在 Apple 退款响应时间内作出回应,有助于确保 Apple 在 consumption_request 截止时间之前收到你的信息。这并不能保证结果,但能避免因错过回应而导致你的信息未被纳入考量。
自动化能做到什么,又做不到什么
你需要对自动化的能力边界有清醒的认识:
它无法保证任何特定的退款申请一定会被拒绝。每一次的最终决定权都在 Apple 手中。
它无法为那些从未触发 CONSUMPTION_REQUEST 的退款申请提出异议——并非每一笔退款都会触发该通知。
它能确保每一条符合条件的请求都在 Apple 退款响应窗口期内得到回应,数据始终保持一致和准确,让你不会仅仅因为没人看到通知而白白失去一笔退款。
它可以将“如何在 12 小时内回应 Apple 退款请求”这一流程自动化,降低错过 consumption_request 截止时间的风险。
最后这一点才是关键所在。你并不是在凌驾于 Apple 之上,而是在确保自己每次都有机会发声。
为什么人工处理无法填补这一缺口
尝试用人工方式处理这件事的团队,通常会陷入以下三种境地之一:
“早上再看”策略——这会错过所有深夜和周末提交的请求,而这些往往占据了相当大的一部分。
轮班值守——名义上有人 24 小时负责这项 12 小时窗口期的任务,但这份工作令人苦不堪言,而且依然难免出现人为失误。
“我们放弃了”策略——这是沉默的大多数,他们因为实在跟不上节奏而干脆不再回应。
这些情况的共同点是:截止时间以机器的速度运转,而回应却依赖人的速度。你无法凭借自律战胜一台在你熟睡时仍在运转的时钟。任何人工处理方式,本质上都只是在选择错过哪些请求而已。
这是一个时机问题,而非产品问题
需要重新认识的关键一点是:失去这些退款并不能说明你的应用有任何问题。
你完全可以拥有一款出色的产品、满意的用户群体,以及很低的真实退款率,却依然会因为这个窗口期而不断流失收入——因为这些损失与退款申请是否合理无关,而在于当时是否有人在那里作出回应。说来奇怪,这其实是个好消息。产品问题很难解决,而时机问题却有一个清晰明确的解决方案:确保无论何时,都始终有系统能够立即作出回应。
真正的解决方案是什么
唯一能够填补机器速度窗口期的,只有机器速度的回应。自动化系统会在 CONSUMPTION_REQUEST 到达的瞬间——携带准确的消费数据和你的退款偏好——在 Apple 的窗口期内作出回应,无论是周日凌晨 3 点,还是周二下午 3 点,都同样可靠。
这正是 RefundSensor 所做的事情。它会监听每一条退款请求,在窗口期内自动作出回应,并追踪结果,让你不再因为没人看到通知而白白失去退款。设置过程大约只需 30 分钟,无需修改任何代码,而且它同样覆盖了 Google Play 的拒付审核窗口期——这个窗口期同样存在“随时开启、迅速关闭”的问题。(欲了解全貌,请参阅 How to Automate Apple Refund Requests和 Google Play Refunds & Chargebacks。)
[产品数据占位符——待 Refund Index 上线后,在此处插入真实的 RefundSensor 统计数据,例如非工作时间到达的请求占比,或已挽回的金额。请勿凭空编造数字。]
你并不是在钻 Apple 的空子,你只是在确保自己始终能获得发声的机会——而这正是大多数开发者在不知不觉中放弃的机会。
官方资料来源 {#official-sources}
Apple 的时间安排和流程可能会发生变化,因此请以其官方文档为最终依据:
无论你的客户何时提出请求,窗口期都会随之开启。无论如何,你都要在场。RefundSensor 会在 12 小时窗口期内自动回应每一条 Apple 退款请求——凌晨 3 点、周末、节假日皆不例外——并追踪每一个结果。设置大约只需 30 分钟,无需修改代码。 免费开始 →
发布后需添加的内部链接:Apple 退款自动化核心文章 · CONSUMPTION_REQUEST 字段详解 · Google Play 退款核心文章。
常见问题
在生产环境中大约有 12 小时,从客户提交请求时开始计算。一旦错过,Apple 将在没有你输入信息的情况下做出决定。
Apple 会依据其已掌握的信息继续处理,即仅有客户的请求信息,而没有来自你的任何信息。未得到回应的请求,即便是没有正当理由的请求,也常常会被默认批准。
不可以。这个窗口期是由 Apple 设定的。唯一可靠、能确保每次都及时赶上的方法,就是在请求到达的瞬间自动作出回应。
这通常不是因为理由不充分,而是因为时机问题。请求往往在非工作时间到达,而人工处理流程无法及时回应每一条请求,因此本可争取到的退款就这样被默认放弃了。
不能。最终决定权始终在 Apple 手中。自动化能确保你每次都作出回应,但并不能凌驾于 Apple 的决定之上。






