MOB-37Required
Restore and acknowledge every store purchase
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.
How to do it
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 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
Plain text example
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
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)) }
}
How to 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.
Sources
Related rules
- MOB-5 Verify every store purchase on your server in Mobile apps
For agents: this playbook is free to use under CC 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.