Blog · October 26, 2026

Who actually decides when your user gets a refund?

Sooner or later a support email arrives that says “I want my money back.” What you can do about it depends entirely on which store took the payment. On the App Store, the answer is almost nothing directly: Apple decides, and you get one structured chance to weigh in. On Google Play, the first 48 hours belong to Google and every day after that belongs to you. Those are two different jobs, and most apps are set up for neither.

On the App Store, Apple is the only one with the button

App Store Connect has no refund button. Every In-App Purchase and paid download is refunded, or not, by Apple. The customer asks through Apple’s own channels: the Report a Problem site, Apple support, or a refund sheet you can open inside your app with StoreKit’s beginRefundRequest. That sheet doesn’t give you any say. It just saves the customer from hunting for the right Apple page.

So the honest reply to an App Store refund email is a link and a sentence: we can’t issue App Store refunds ourselves, here’s where to request one. Don’t promise an outcome you don’t control. A customer told “sure, you’ll get it back” who then gets declined is angrier than one who was pointed to the right door.

Your one lever: the consumption request

If you’ve set up App Store Server Notifications (version 2), Apple tells your server when a refund request comes in with a CONSUMPTION_REQUEST notification. Apple sends it for every product type: consumables, non-consumables, non-renewing subscriptions and auto-renewing subscriptions. You then have 12 hours to answer by calling the Send Consumption Information endpoint. Apple’s documentation says plainly that it “uses a variety of factors” to decide, and that your data informs the decision. It’s evidence, not a veto.

The current request body is short. It has five fields:

The catch is the first field. You may only send this data if the customer consented to you sharing it with Apple, and that consent has to exist before the request arrives. Apple is specific: consent should be opt-in, the customer must be able to withdraw it, and you may not use the App Tracking Transparency prompt for it. If you adopt the endpoint, your privacy label has to disclose the data too. Without consent, the documented answer is to stay silent.

That makes this a decision to take once, at design time, not in the moment. If your app sells consumables, such as credits, AI generations or in-game currency, the consumption data is the strongest case you can make against a “bought 500 credits, spent 490, asked for a refund” pattern, and a consent line at the point of purchase is worth the copywriting. If you sell a subscription people mostly cancel honestly, it may not be worth the extra privacy surface at all. Both are defensible. Drifting into neither is the expensive option, because every 12-hour window then passes with nothing from you.

After Apple decides

The decision arrives as another notification: REFUND when Apple grants it, REFUND_DECLINED when it doesn’t, and occasionally REFUND_REVERSED when Apple undoes a refund it already granted. The one that matters for your code is REFUND. The money is already gone from your proceeds, so the entitlement should go too: remove the Pro flag, claw back unspent credits, end the subscription access. Apps that skip this end up giving the product away to anyone who knows to ask Apple. And if you handle REFUND, handle REFUND_REVERSED as well, or a customer whose payment was restored stays locked out.

On Google Play, the clock hands it to you

Google’s consumer policy is built around time. Within 48 hours of a purchase, a customer can ask Google directly, and Google may refund depending on the details. Paid apps also get a short return window right after the first purchase; Google's developer help page puts it at up to two hours, and returning the app uninstalls it. After 48 hours, Google’s help page tells the customer to contact the developer, who “can process refunds according to their policies and applicable laws.”

In other words, past day two, the refund policy on Google Play is whatever you decide it is. You issue refunds from the Order management page in Play Console, on the web or in the Play Console app, and a few mechanics are worth knowing before the first request lands:

Refunds that happen outside your console, through Google’s 48-hour flow, a chargeback or a cancelled payment, still need to reach your entitlement logic. Play sends a voidedPurchaseNotification through Real-time Developer Notifications, with the order ID, the product type and whether the refund was full or a partial quantity refund. The Voided Purchases API lets you pull the same events for a time range, which is useful as a nightly sweep in case a notification went missing. Treat a voided purchase exactly like Apple’s REFUND: take the entitlement back.

Write the policy down before you need it

Because Google makes you the decider, the worst time to invent a refund policy is while reading an angry email. A short written rule keeps you consistent and keeps you from being generous to the loudest customer and stingy to the polite one. A workable one fits in three lines, and yours probably can too:

Then put the store-specific routing in your support macros, because the customer doesn’t know or care which store they paid through. App Store purchase: here’s Apple’s refund page. Play purchase under 48 hours: you can request it from Google directly, or we’ll handle it. Play purchase older than that: we’ll look at it, and here’s our rule.

The short version: on Apple, decide once whether to collect consent for consumption data, then answer every CONSUMPTION_REQUEST within 12 hours or not at all. On Google, you own every refund after 48 hours, so write the rule down. On both, a refund notification must remove the entitlement, and a reversal must restore it.

Fewer refunds start on the product page

The cheapest refund is the one nobody asks for, and a lot of “this isn’t what I thought it was” requests trace back to a listing that promised a different app. Keep your screenshots showing what the paid tier actually does, and say where the paywall sits. ShotCanvas makes it quick to keep that set honest as the app changes.

Make an honest screenshot set → How to count trial conversions honestly