Apple's CONSUMPTION_REQUEST, explained: the 12 hours that decide your refund
When a customer asks Apple for a refund, Apple asks you first. Here's exactly what the CONSUMPTION_REQUEST notification contains, what Apple expects back, how to answer one end to end, and why most developers silently forfeit.
Poin utama
- When a customer requests an App Store refund, Apple sends your server a CONSUMPTION_REQUEST notification and waits up to 12 hours for evidence before deciding.
- You respond by calling the Send Consumption Information endpoint with a small payload: consent, delivery status, sample content, consumption percentage, and your refund preference.
- Silence is an answer: if you send nothing, Apple decides from the customer's claim and account history alone.
- Consent is a hard gate. Apple's documentation says that without the customer's consent to share consumption data, you should not respond at all.
- For auto-renewable subscriptions Apple calculates the consumption percentage itself from elapsed time; sending your own value returns an error.
- The window is too short for a manual process. The developers who benefit are the ones whose response is generated and submitted automatically.
Here is what this whole mechanism is about: Apple decides every App Store refund itself, but it does not want to decide blind. So it built a formal channel for your side of the story. When a customer requests a refund, Apple pauses, sends your server a question, and gives you a fixed window to answer with facts about the purchase. Answer well and unreasonable requests get declined. Ignore it and Apple rules on the customer's word alone.
Every App Store refund starts the same way: a customer opens reportaproblem.apple.com, picks a purchase, and taps a reason. What most developers don't know is what happens next — Apple turns to you and asks for evidence before it decides.
The notification nobody answers
If your app has App Store Server Notifications V2 configured, Apple sends a CONSUMPTION_REQUEST notification the moment the refund is requested. The payload names the transaction, the product, and — since 2024 — the customer's stated reason: UNINTENDED_PURCHASE, FULFILLMENT_ISSUE, UNSATISFIED_WITH_PURCHASE, LEGAL, or OTHER.
From that moment you have 12 hours to call the Send Consumption Information endpoint with your side of the story. The current payload is deliberately small: five fields, numbers and flags only.
| Field | What it tells Apple | Example |
|---|---|---|
| customerConsented | The customer agreed that usage data may be shared | true |
| deliveryStatus | Whether the purchase was delivered and works | DELIVERED |
| sampleContentProvided | A free sample or trial existed before purchase | true |
| consumptionPercentage | How much of the purchase was used, 100% = 100000 | 67500 |
| refundPreference | Your preference: decline, grant, or no preference | DECLINE |
What Apple does with your answer
Apple explicitly uses consumption information as an input to its refund decision. Send nothing and the decision is made entirely from the customer's claim and account history. Send evidence — '87 scans in six days' reads very differently from silence — and contested refunds are frequently declined.
How to answer one yourself, end to end
If you want to build the response path in-house, this is the full sequence. None of it is secret; all of it has to work at 3 a.m.
1. Get the notification flowing
In App Store Connect, open your app's App Information page and set a Production Server URL under App Store Server Notifications, on Version 2. V1 does not carry consumption requests. Apple will now POST every notification, refunds included, to that URL as a signed JWS payload.
2. Create the right key
Responses are authenticated with an In-App Purchase key from Users and Access, under Integrations. This is its own key type: the App Store Connect API key next to it will not work. You download the .p8 once, then mint a short-lived ES256 JWT for every call.
3. Verify, match, decide
When the CONSUMPTION_REQUEST arrives, verify the JWS signature chain against Apple's root certificates before trusting a byte of it. Then match the transaction to your user, ideally through the appAccountToken UUID you attached at purchase, and pull their real usage. Decide your preference: grant the goodwill cases, contest the consumed ones.
4. Send it back in time
PUT your five fields to the Send Consumption Information endpoint for that transaction id, within the 12-hour window. Two traps catch almost everyone: the percentage is in milliunits, so 100% is 100000, not one million; and consent is a gate, because Apple's own documentation says that without customer consent you should not respond at all. Add the consent language to your terms of service before you ship any of this.
Why developers forfeit
Twelve hours is a brutal window for a human process. The notification can land at 3 a.m. on a Saturday. It requires a server that verifies Apple's JWS signature chain, matches the transaction to a user, computes a consumption percentage in milliunits, and calls a JWT-authenticated API — per request, every time, forever.
The practical checklist looks like this:
- Configure App Store Server Notifications V2 so the request reaches you at all.
- Verify the signed payload against Apple's certificate chain before trusting it.
- Match the transaction to your own user, usually through the appAccountToken you attached at purchase.
- Compute a consumption percentage from real usage, not guesswork.
- Call Send Consumption Information with an In-App Purchase key before the window closes.
That's the entire reason RefundHalt exists: the response is generated and submitted in seconds, from real usage data when you connect it, with your policy applied — grant the goodwill cases, contest the rest. The 12-hour window stops being a threat and becomes your home-field advantage.
Pertanyaan yang sering diajukan
- What happens if I never respond to a CONSUMPTION_REQUEST?
- Apple still decides the refund, but only from the customer's claim and account history. You lose the only opportunity to show that the purchase was delivered and heavily used. In practice unanswered requests are approved far more often.
- Do I need the customer's consent to send consumption data?
- Yes. Apple requires that customerConsented is true, and that you actually obtained that consent, typically through your terms of service or privacy policy. Apple's documentation says that without consent you should not respond to the notification at all.
- Can I send a consumption percentage for subscriptions?
- Only for non-renewing subscriptions. For auto-renewable subscriptions Apple calculates consumption from elapsed time in the current billing period and the API rejects a supplied percentage. Your evidence still drives the refund preference.
- Which key do I use to call the API?
- An In-App Purchase key, created in App Store Connect under Users and Access, Integrations. It is a different key type from the App Store Connect API key, and the .p8 file can only be downloaded once, at creation.
- How fast do I really need to answer?
- Apple's production window is 12 hours from the notification. In the sandbox environment it is only 5 minutes, which is a hint about the direction Apple expects: an automated response, not a human one.
Sumber dan bacaan lanjutan
RefundHalt
Autopilot refund untuk App Store dan Google Play
Baca selanjutnya
The refunds you cannot contest: what Apple and Google decide without asking you
Only two refund flows ever ask for your evidence: Apple's consumption request and Google Play's chargeback review. Everything else, the 48-hour Play refund, support refunds, voided purchases, unacknowledged trials, is decided without you. Here is the full map, what you can prevent, and what you can only record.
Google Play is making chargebacks your problem starting August 3, here's what changes
Google quietly rewrote who pays when a Play purchase gets disputed with the bank. For orders placed after August 3, 2026, a lost chargeback comes out of your pocket, and you get 24 hours to fight back. What changed, what it costs, and how to be ready.