A purchase clears, the customer gets their product, and three days later it's gone. Google Play reverses the charge and pulls the entitlement back, without the customer asking for it and without anyone on your support team touching a button. The purchase failed silently because your server never told Google it was handled.
That's the whole rule: acknowledge a Google Play purchase within three days or Google auto-refunds it and revokes it. Every time, no exceptions. Of all the ways a sale can reverse on either store, this is one of the very few sitting entirely inside your own integration, which also makes it one of the quietest ways to bleed revenue.
It isn't a fraud check and it isn't a policy call. It's a callback that never fired. The repair is small, the money you lose by skipping it is not, so it's worth knowing exactly what the rule says, why purchases slip past it, and what each vanished sale drags down with it.
What Google's documentation actually requires
Play Billing requires your app to notify Google once it has granted entitlement and told the user the purchase went through. Google's documentation puts a hard number on it: this notification "must be done within three days so that the purchase isn't automatically refunded and entitlement revoked." The one-time product docs repeat the same line without hedging. Skip the acknowledgement and "the user automatically receives a refund, and Google Play revokes the purchase." The initial purchase of a subscription follows the identical rule.
Acknowledgement isn't paperwork. It's the only signal Google has that delivery actually happened. No signal means Google assumes nothing was delivered, so it reverses the whole exchange for the buyer without consulting you. The buyer sees an unexpected refund. You see a sale that vanished from your books.
Key takeaways
Leave a sale unconfirmed for 72 hours and the reversal happens on its own: buyer repaid, entitlement withdrawn, nobody consulted. No shopper triggered that. Your backend did, by saying nothing, and your backend is equally able to prevent it.
Reaching the PURCHASED state is what sets the countdown running, which makes the checkout moment irrelevant to your deadline. Anything resting in PENDING has no timer attached and deserves no confirmation call yet.
Either of two calls discharges the obligation. Run purchases.products.consume against a consumable, or reach for purchases.products.acknowledge and purchases.subscriptions.acknowledge on anything that isn't one. Google treats each as proof the goods arrived.
Subscriptions ask this of you exactly once, at signup. Every billing cycle afterward is settled by Google itself, flagged as confirmed without your code lifting a finger.
Selling a prepaid plan that runs under seven days? Your allowance collapses to fifty percent of however long the plan lasts. Briefer product, briefer fuse.
Only the ticket price journeys back to the shopper. Compute time, model API spend, storage bills, creator payouts: that money left your account during fulfilment and none of it returns. Real damage exceeds whatever the refund line reports.
Nothing on iOS operates this way. StoreKit re-presents an unfinished transaction at every launch and waits patiently, never once reversing the charge. This particular exposure lives on Google Play and nowhere else.
Checkout isn't when the deadline begins
Tapping "buy" doesn't start the timer. The purchase state has to transition to PURCHASED first, and some purchases sit in PENDING before that. Cash payment methods do this, so do slow bank transfers and parent-approval requests. Google states it directly: "The three-day acknowledgement window begins only when the purchase state transitions from PENDING to PURCHASED."
That means two things for how you build the flow. Grant entitlement only once the state reads PURCHASED, never on PENDING, or you'll hand out product for money that might not actually arrive. And don't acknowledge a PENDING purchase either, because there's nothing to acknowledge yet. Call enablePendingPurchases() when you set up the BillingClient, wait for the state transition, and only start counting once it lands on PURCHASED.
Read PENDING as "not sold yet." Nothing is owed: no entitlement, no acknowledgement, nothing booked as revenue. The second it flips to PURCHASED, the entitlement and the three-day countdown both become your problem.
Picking the right API call for what you sold
Two API paths clear the deadline, and which one applies depends on what you sold. Both satisfy the requirement equally. What separates them is what else they do to the product afterwards.
Consumables get consumed. That's purchases.products.consume on a secure backend, or consumeAsync() from the Play Billing Library on the client. Consuming does double duty, since it satisfies the acknowledgement requirement and makes the item purchasable again. That's what you want for coins, credits, or any one-shot generation a customer might buy repeatedly.
Non-consumables and subscriptions get acknowledged instead, through purchases.products.acknowledge, purchases.subscriptions.acknowledge, or acknowledgePurchase() on the client. This clears the deadline but doesn't reopen the item for purchase.
Here is how each product type maps to a call and a deadline:
For a consumable, call purchases.products.consume or consumeAsync(). That also makes the item purchasable again, and your deadline is three days from PURCHASED.
For a non-consumable, call purchases.products.acknowledge or acknowledgePurchase(). Entitlement is confirmed with no repurchase, and your deadline is three days from PURCHASED.
For the initial purchase of a subscription, call purchases.subscriptions.acknowledge or acknowledgePurchase(). That confirms the new subscription, and your deadline is three days from PURCHASED.
For a subscription renewal, you need no call at all. Google marks it acknowledged on its own, so there is no deadline.
For a prepaid plan shorter than a week, use the same acknowledgement calls, but your deadline shrinks to half the plan duration.
The obligation stops at the first payment
Subscription renewals don't need acknowledgement at all. Google says so directly: "you don't need to acknowledge subscription renewals," and it marks each one as acknowledged on its own. It's the very first purchase of a subscription that arrives in a pending acknowledgement state and sits on your plate until you clear it. Check the acknowledgement state server-side, or use isAcknowledged() on the client, before acting. That way you never send a duplicate acknowledgement call.
A tighter clock for short-term prepaid plans
Prepaid plans a week or longer follow the standard three-day rule. Shorter ones don't. Google's documentation says plans "with a duration shorter than one week must be acknowledged within half of the plan duration." A three-day prepaid plan gives you a day and a half, not the full window. If short prepaid top-ups are part of your catalog, the acknowledgement path has to be quick and server-driven, never dependent on the customer reopening the app.
Where the acknowledgement call usually gets lost
Nobody deliberately skips this step. It goes missing because the acknowledgement logic gets attached to the wrong trigger. The common anti-pattern is a client that only acknowledges when the purchase flow comes back to the foreground. That covers a customer who finishes buying and keeps using the app right after. It doesn't cover anyone else.
Developers run into this constantly. Threads in Google's own developer community follow the same script every time, some version of a user being automatically refunded three days after buying, or a plea to understand why payments keep reversing themselves on day three. The diagnosis rarely changes: the acknowledgement call was wired to a user action that never happened, so it simply never fired.
Free trials and the customer who never opens the app again
The ugliest version of this is a free trial, or a purchase made in the last moments before someone closes your app for the last time. When acknowledgement waits on the next app open and no next app open ever arrives, the purchase simply ages out. Google refunds and revokes it on day three. For a trial that was on track to convert, you lose the first billing you never got to charge, and a customer entitlement quietly evaporates alongside it. Neither shows up in your support queue. Both show up as a voided purchase, assuming you go looking.
Acknowledgement that depends on the next app open is a sale you forfeit every time a customer stays away for three days. Trials and one-tap purchases are exactly the moments when customers stay away.
The real bill behind an unacknowledged refund
The refund line understates what you actually lost. Google reverses the sale, you hand back the price, and that's the number everyone sees. It isn't the whole bill.
Take a consumable that kicks off real work the moment someone buys it. A batch of image generations, a run of calls to a model provider's API, a video export, a payout owed to a creator. You paid for that compute, those API calls, that storage, and those payouts at the time of use. The refund returns the sale price to the customer. It does not return the provider invoice to you. Real cost went out the door and nothing came back for it.
For subscriptions and trials, the loss is the first billing you never collect plus a customer relationship that ended before it began. And the stakes are about to rise. Starting August 3, 2026, Google Play shifts chargeback purchase price and bank fees onto developers for orders placed after that date, which makes any avoidable leak worth sealing now rather than later. An unacknowledged refund isn't a chargeback, but it teaches the same lesson. Money you already spent is not automatically money you keep.
Building the acknowledgement step so it can't be missed
The dependable pattern takes your app off the critical path entirely. Run it on your backend, driven by notifications, not by whether someone reopens a screen.
Subscribe to real-time developer notifications. A one-time product purchase event, or a subscription purchase event, reaches your server the instant Google registers the sale, whether or not the app is running.
Validate the purchase token through the Play Developer API and confirm the state reads PURCHASED rather than PENDING.
Record the entitlement in your own system, tied to that customer's account.
Consume or acknowledge without delay. Consumables get consumed, non-consumables and initial subscriptions get acknowledged. Read the acknowledgement state first so the call never goes out twice.
Keep a client-side backfill. Calling queryPurchasesAsync() in onResume() picks up anything that settled while the app was shut. Treat it as insurance, not the main route.
The whole point is that acknowledgement fires off an event Google hands you, rather than a user action you have no way to guarantee. Someone who buys once and never returns is still fully covered, because your server already did the work the moment the purchase landed.
A backstop for whatever still gets by
However well-built the pipeline, it still deserves a safety net underneath. Google's Voided Purchases API enumerates orders that ended in a refund, a revocation, or a chargeback, and it singles out the particular scenario where the cause was a purchase that "was never acknowledged by the developer, and therefore may not exist in the developer's records." Query it on a rhythm and you can strip access from anyone whose order Google has quietly undone behind you. Mind the boundary, though: only the trailing 30 days are retrievable, which makes this a scheduled job rather than something you get around to each quarter.
iOS was never built to do this to you
Cross over to the App Store and none of this applies. Apple built a closing step of its own, finishing a transaction, except the penalty for skipping it runs in the opposite direction. An unfinished transaction stays parked in Apple's queue. It resurfaces at every app launch, and again whenever the observer attaches, handing you repeated chances to deliver what the customer paid for. Apple issues no reversal over it. Nothing resembling a 72-hour refund trigger exists on that platform.
Which is exactly why a single mental model can't stretch across both stores. Android hands you a countdown and a sale that evaporates if you lose it. iOS hands you a persistent reminder and unlimited time to answer it. Bring iOS habits into an Android codebase and sooner or later you're staring at a heap of reversed orders nobody on the team can account for.
Sealing that gap is precisely the job Refund Sensor does. Confirmation fires straight off the store notification, within moments of it landing, while a standing reconciliation pass against the Voided Purchases API withdraws access wherever Google has already undone an order behind your back. A countdown you could lose becomes a box that was ticked before you thought to check.
Where these rules are documented
Frequently asked questions
Your server never sent the acknowledgement call in time. Once a purchase sits unacknowledged past the three-day mark from reaching PURCHASED, Google reverses the sale and pulls the entitlement automatically. It isn't something the customer did, and it isn't a Google-imposed penalty. It's a missing acknowledgement call, and acknowledging server-side from the store notification removes the problem completely.
They both stop the three-day clock, but they leave the product in different states. Consuming, via purchases.products.consume or consumeAsync(), is for consumables. It clears the deadline and puts the item back up for sale. Acknowledging, via purchases.products.acknowledge, purchases.subscriptions.acknowledge, or acknowledgePurchase(), is for non-consumables and subscriptions. It confirms entitlement without freeing the product for repurchase.
No, just the first purchase. Google doesn't require renewals to be acknowledged and marks them as acknowledged automatically. It's only the initial subscription purchase, which arrives in a pending acknowledgement state, that stays your responsibility until you clear it.
No, wait for PURCHASED. A PENDING purchase, like a cash payment or a parent-approval request, hasn't started the three-day clock at all. Grant entitlement and send the acknowledgement only once the state has actually moved from PENDING to PURCHASED.
No, and that's worth knowing before you assume Android and iOS behave the same way. An unfinished StoreKit transaction just gets redelivered on every app launch until you finish it. Apple never auto-refunds it. The three-day auto-refund is unique to Google Play, so the two platforms need different handling.
The refund itself can't be reversed. What you can do is reconcile. The Voided Purchases API surfaces refunded and revoked purchases from the past 30 days and flags the ones voided specifically because they were never acknowledged, so you can revoke the entitlement you granted. Going forward, acknowledging from the store notification is what keeps the next one from slipping.






