Apple's DeviceCheck remembers the phone behind a refund abuser, even after they sign up with a new account
Account bans and purchase identifiers stop working the moment a refund abuser makes a new account. Apple's DeviceCheck and Google Play's device recall keep a few bits per device on the store's servers. Here's what they store, when to set them, and what they save you.

Key takeaways
- Apple's DeviceCheck lets your server set and query two binary bits per device, stored on Apple's servers, and Apple names flagging a device you've found to be fraudulent as one of its intended uses.
- Google Play's device recall, a beta feature of the Play Integrity API, stores three custom bits per device on Google's servers, and they survive an app reinstall and a device reset.
- Device recall values are shared by every app in the same Google Play developer account and are kept for 3 years after the last read or write.
- A Play Integrity token can be used to write device recall bits for up to 14 days after it's verified, which covers Google Play's 48-hour self-service refund window.
- Neither Apple's refund notifications nor Google's voided purchases carry a device identifier, so a device can only be flagged by a server that linked purchases to its own accounts first.
- Device flags can't stop a refund. They decide what your own app gives a device next, such as free credits, a trial you fund, or a promotional offer your server signs.
- Only two refund flows let a developer submit evidence before the store decides: Apple's CONSUMPTION_REQUEST, answered within 12 hours, and Google Play's chargeback review through orders.reviewrefund, answered within 24 hours.
Banning the account doesn't stop a refund abuser who signs up again on the same phone. Apple's DeviceCheck and Google Play's device recall exist for exactly that gap. Each one lets your server attach a few bits of your own meaning to a physical device, stored on the store's servers, so the flag is still there when the person behind it comes back with a fresh email address. Neither tool hands you a device ID, and neither can stop a refund. What they do is tell you, at sign-up or at the paywall, that this device has burned you before.
Here's what each store actually stores, the timing trap that decides whether you can set the flag at all, and what a repeat abuser costs before you catch them.
Why a new account beats every account-level defense
Most refund defenses are keyed to an account. Apple's appAccountToken ties a transaction to a user in your database. Google Play's obfuscated account ID does the same on Android. Both are the right thing to set on every purchase, and both describe a person's account, not the hardware they hold. Delete the account, sign up with a new email, and your history for that person starts from zero.
The stores don't fill the gap for you. An App Store refund notification tells you which transaction was refunded. A Google Play voided purchase tells you the purchase token, the order ID and a voidedReason. None of them carries a device identifier. A dating app developer described the result in an Apple Developer Forums thread: scam profiles kept buying a premium membership that was later refunded, and banning their devices with the developer's own method didn't help.
Does a new account reset the store's own trial?
Not on the same Apple Account. Apple's documentation says introductory offers, free trials included, go to customers who haven't already received one for that product or any product in the same subscription group. So a new login inside your app doesn't buy a second Apple trial. A new Apple Account does, and so does anything you hand out yourself: sign-up credits, a server-funded trial, a referral bonus. Those are the gifts a device flag protects.
What Apple's DeviceCheck actually stores
DeviceCheck has two parts. In the app, the DCDevice class generates an ephemeral token that identifies the device. On your server, you send that token to Apple with a JSON web token signed by a key from your developer account, and Apple lets you query or update two bits for that device. The query response returns bit0, bit1 and last_update_time, given as a year and month. Apple's own example uses are a device that has already taken a promotional offer and a device you've determined to be fraudulent.
Apple keeps the bits, but the meaning is yours. Its documentation says you're responsible for tracking what the bits mean and for deciding when to reset them, and gives a sold device as the example. Two bits give you four states, so a simple scheme is one bit for refunded after heavy use and one for already received free credits.
- The token is single-use. Apple says it stays valid long enough to retry a request, but you should generate a new one for each call.
- Development builds talk to api.development.devicecheck.apple.com. Production must use api.devicecheck.apple.com, or your flags land in the wrong place.
- Apple describes DeviceCheck as one input to an overall risk assessment, not a verdict. Treat a set bit as a reason to look closer.
What Google's device recall adds on Android
Google's version lives inside the Play Integrity API and is still in beta, behind an interest form. Once you're approved and turn it on in Play Console, every integrity verdict carries three custom bits for the device. You write them with a server call to the deviceRecall:write endpoint, using an integrity token you've already verified. Google says the data survives an app reinstall and a device reset, because it lives on Google's servers.
Google's documentation is unusually direct about the use case. It names devices with evidence of severe abuse, devices that already redeemed a high-value item such as a free trial, and devices used again and again to create new accounts for abusive purposes. It's just as direct about the limit: device recall may only be used to protect app security and fight abuse, fraud and unauthorized access, never to fingerprint or track individual users, and never to store sensitive traits like age, gender or location.
| Question | Apple DeviceCheck | Google Play device recall |
|---|---|---|
| Status | Generally available | Beta, approval through an interest form |
| Bits per device | 2 | 3 |
| Where they live | Apple's servers | Google's servers |
| Survives reinstall and reset | Stored server-side, Apple leaves resets to you | Yes, both, per Google |
| Shared across your apps | Tied to your developer account | Yes, every app in the developer account |
| Timestamp | Year and month of last update | Write date per bit |
| Retention | Until you reset them | 3 years after the last read or write |
| Token to write | Fresh, single-use DCDevice token | A verified integrity token, usable for 14 days |
| Extra requirements | App ID registered to your account | Recent Play Store and Play services, a Play-licensed user, no emulators |
The timing problem: refunds arrive after the token is gone
Both tools need something from the device itself before you can flag it. Apple needs a fresh DCDevice token. Google needs an integrity token from that device that's no more than 14 days old. The refund, meanwhile, arrives at your server through a store notification that knows nothing about the device. So the question isn't whether to flag a device. It's whether you'll still have a way to reach it when the refund lands.
Google's 48-hour refunds fit inside the 14-day window
Google Play's self-service refunds are only available within 48 hours of purchase, which is well inside the 14 days an integrity token stays usable for writes. Run an integrity check at the moment of purchase, keep the verified token next to the order ID, and when a voided purchase arrives for that order, you can write the bit straight away. Chargebacks are the harder case, since a bank dispute can arrive long after day 14.
Apple's refunds need the device to come back
An Apple refund can land weeks after the purchase, and a stored DeviceCheck token isn't meant to be reused. The practical answer is to mark the account first and the device second. When the refund notification arrives, flag the account in your database. The next time that account opens the app, ask for a DeviceCheck token and set the bit. Abusers who keep the content after a refund usually do come back, because using it was the point.
- At purchase, record the transaction against your own account through appAccountToken or the obfuscated account ID.
- On a refund or void, flag that account on your server.
- On the flagged account's next session, collect a device token and set your bit.
- At every sign-up, query the bits before you grant anything that costs you money.
What a repeat refund abuser costs you
The refunded price is the visible part. The rest is everything the purchase already set in motion. If your app spends money to deliver what it sells, every cycle of buy, consume and refund leaves that money spent: GPU time for generated images, paid calls to a model or data API, storage for exports the customer keeps, and payouts to creators that were calculated on the sale. A new account reopens the loop, and your ledger records it as a brand new customer.
Free giveaways leak the same way with no refund at all. A device that farms sign-up credits on ten accounts consumes ten times the compute you budgeted for one trial. On Google Play, chargebacks on orders after August 3, 2026 also cost you the purchase price less Google's service fee, plus the bank's fees, so a person who disputes from a fresh account each time costs you the full dispute again.
| Cost line | Without a device flag | With a device flag |
|---|---|---|
| Sign-up credits or a trial you fund | Granted again on every new account | Withheld or reduced on a flagged device |
| Compute and paid API calls | Spent again on each cycle | Spent once, then gated |
| Creator or affiliate payouts | Paid on sales that come back as refunds | Held for review on flagged devices |
| Google Play chargebacks after August 3, 2026 | Price less service fee, plus bank fees, each time | Same per dispute, but fewer repeat disputes |
| Store refund decisions | Decided by the store | Still decided by the store |

What to do with a flagged device
A flag answers one question: should this device get something for free again? Keep your response proportionate, because a set bit is evidence, not proof. Phones get resold, families share iPads, and Google explicitly tells you to consider ignoring or resetting old data for that reason.
- Skip the sign-up credits, the server-funded trial or the referral bonus on a flagged device, and offer the paid plan instead.
- Don't sign a promotional offer for a flagged device. On the App Store, your server generates the signature that unlocks a promotional offer, so the choice is yours.
- Require payment to clear before delivering expensive consumables on a flagged device.
- Use the timestamp. A flag set last month weighs more than one set two years ago.
- Give people a way to reach support. A wrongly flagged buyer of a used phone should get an answer, and you can reset the bits.
Can you just ban the device?
You can refuse your own free extras, and that's where device flags pay off. A hard lockout is riskier. The person holding the phone today may not be the person who abused it, and Google's own terms limit device recall to abuse prevention, not tracking people. Gate what costs you money and leave the paid path open.
What about the Keychain or a device identifier?
Developers often ask whether a Keychain marker or a hardware ID would do the same job. A marker your app stores on the phone is gone after a device reset, and Apple doesn't give apps a stable hardware identifier for this. DeviceCheck and device recall are the store-sanctioned answers, precisely because the bits sit on Apple's and Google's servers instead of the phone.
Where the store still decides
Device flags change what your app gives away next. They don't touch the refund in front of you. Only two refund flows let you submit evidence before the store decides. Apple sends a CONSUMPTION_REQUEST and asks for consumption data within 12 hours. Google Play opens a chargeback review that you answer within 24 hours through orders.reviewrefund. Everything else, from Google Play's 48-hour refunds to support refunds and auto-refunds of unacknowledged purchases, is decided without you. Chargebacks are final once the bank rules.
RefundHalt answers every CONSUMPTION_REQUEST and Google Play chargeback review inside its window with your real usage data, and ties each refund back to the account that made it, so your server knows which device to flag the next time it checks in.
Frequently asked questions
- What is Apple's DeviceCheck used for?
- DeviceCheck lets your server store and read two bits per device on Apple's servers. Apple's own examples are marking a device that has already taken a promotional offer and flagging a device you've determined to be fraudulent. You decide what the bits mean and when to reset them.
- Does DeviceCheck work after a user deletes the app or makes a new account?
- Yes. The bits belong to the device and are stored on Apple's servers, not inside your app or a user account, so a new sign-up on the same device reads the same bits after the app is reinstalled. Apple leaves resetting them to you, for example when a device is sold.
- Is there a DeviceCheck equivalent on Android?
- Yes, device recall in the Play Integrity API. It stores three custom bits per device on Google's servers, survives reinstalls and device resets, is shared across all apps in your developer account, and keeps data for 3 years after the last access. It's in beta and requires approval.
- Can a device flag stop a customer from getting a refund?
- No. Apple and Google decide refunds themselves. A device flag only controls what your own app offers next, such as free credits or a promotional offer. Your evidence counts only in Apple's CONSUMPTION_REQUEST, answered within 12 hours, and Google Play's chargeback review, answered within 24 hours.
- Is it allowed to block a device for refund abuse?
- Google allows device recall only for app security and abuse, fraud and unauthorized access prevention, and forbids using it to fingerprint or track users. Because devices get resold and shared, the safer use is withholding free extras on a flagged device rather than locking it out of paid features.
Sources and further reading
- Apple Developer: DeviceCheck
- Apple Developer: Accessing and modifying per-device data
- Apple Developer: DCDevice
- Apple Developer: Implementing introductory offers in your app
- Android Developers: Detect repeat abuse using device recall (beta)
- Apple Developer Forums: Refund abuse
- Google Play Help: Apps, games, and in-app purchases refund policies
- Play Console Help: Updates to refund protection and chargeback cost responsibility
RefundHalt
The refund autopilot for the App Store and Google Play
Keep reading
Google Play alternative billing fees started in the US on October 1, and the refunds on those sales are still yours to run
Since October 1, 2026, Google Play charges a service fee on US purchases made through alternative billing or external content links. Google still runs none of the refunds. Here's what the fee tables say, how refunds get reported back, and what each refund costs you.
Excessive refund requests can cost you more than the refunds, because both app stores treat them as a quality signal
Apple's Guideline 5.6.4 names excessive refund requests as a sign an app isn't meeting quality standards, and Google's Distribution Agreement lets it remove new developers' apps on refund rates. Here's what each store says, what removal costs, and how to stay clear.