---
title: "Restore and acknowledge every store · Agent Wranglers"
url: https://agentwranglers.se/playbook/mobile-apps/store-review-and-listing/restore-and-acknowledge-purchases
id: MOB-37
level: Required
applies: payments
risk: money
updated: 2026-10-22
tokens: 1021
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Restore and acknowledge every store purchase

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Store review and listing](https://agentwranglers.se/playbook/mobile-apps/store-review-and-listing.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: MOB-37
- Level: Required
- Chapter: [Store review and listing](https://agentwranglers.se/playbook/mobile-apps/store-review-and-listing.md)
- Rule: Give every app that sells subscriptions or permanent unlocks a Restore Purchases button. Acknowledge each Google Play purchase within three days of it becoming paid.
- Check: On a fresh install, signed in to the store sandbox with an active test subscription, Restore Purchases gives access within 30 seconds. A server query lists no Google Play purchase older than 48 hours whose `acknowledgementState` is still pending.
- Risk: Money lost or taken twice
- Applies when: The project takes payments.
- How: Apple asks for a restore option for any purchase that can be restored, under guideline 3.1.1. People change phones, reinstall the app or sign in on a tablet. Restore reads the store's current transactions, and your server checks them as [verify every store purchase on your server](https://agentwranglers.se/playbook/mobile-apps/store-review-and-listing/verify-store-purchases.md) says. On StoreKit 2 that is `AppStore.sync()`, and on Google Play it is `queryPurchasesAsync()`. Google Play refunds and revokes a purchase that is not acknowledged within three days. The window starts when a pending payment turns into purchased. Acknowledge from the server once access is granted, and never while the purchase is still pending. Call `queryPurchasesAsync()` at start and on resume too. It catches purchases made outside the app, or lost when the network dropped.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### Plain text example

```swift
func restorePurchases() async throws {
    try await AppStore.sync()
    for await result in Transaction.currentEntitlements {
        if case .verified(let transaction) = result {
            try await api.post("/store/apple/transactions", ["id": String(transaction.id)])
        }
    }
}
```

### Kotlin example

```kotlin
suspend fun restorePurchases() {
    val params = QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS).build()
    billingClient.queryPurchasesAsync(params).purchasesList
        .filter { it.purchaseState == Purchase.PurchaseState.PURCHASED }
        .forEach { api.post("/store/google/purchases", mapOf("token" to it.purchaseToken)) }
}
```

## Sources

- [App Review Guidelines 3.1.1 In-App Purchase](https://developer.apple.com/app-store/review/guidelines/#in-app-purchase)
- [Google Play Billing, process purchases](https://developer.android.com/google/play/billing/integrate)

## Related rules

- MOB-5 [Verify every store purchase on your server](https://agentwranglers.se/playbook/mobile-apps/store-review-and-listing/verify-store-purchases.md) in Mobile apps

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/mobile-apps/store-review-and-listing/restore-and-acknowledge-purchases">Agent Wranglers mobile apps playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Verify every store purchase on your server](https://agentwranglers.se/playbook/mobile-apps/store-review-and-listing/verify-store-purchases.md)
- Next: [Map every store subscription state to access](https://agentwranglers.se/playbook/mobile-apps/store-review-and-listing/store-subscription-states.md)
- [Store review and listing](https://agentwranglers.se/playbook/mobile-apps/store-review-and-listing.md)
