If your Android app takes payments, it needs to be on Google Play Billing Library 8.0.0 or later, and the window to do it quietly has closed. Google's documentation puts the deadline at 31 August 2026. The warning email landing in developer inboxes puts it at 1 November 2026. Both are real, and the gap between them is an extension you have to ask for.
One of those emails landed in our inbox this week, which is what prompted this. It's worth being precise about what it means, because the practical answer isn't "bump a version number in Gradle". Version 8 is where Google removed a set of APIs that most billing implementations were built on, and one of those removals breaks paid purchases in a way that compiles cleanly and passes your tests.
The published deprecation schedule runs on a two-year cycle. Version 5 came off support in 2024 and version 6 in 2025. Version 7 stopped being accepted for new apps and updates on 31 August 2026, with an extension available until 1 November 2026. Version 8 follows on 31 August 2027, and version 9 on 31 August 2028.
So the 31 August 2026 date has already passed. The 1 November date in the console warning is the extension backstop, requested through the Policy status page in Play Console by opening the warning and completing the form. If you haven't asked for one, treat the deadline as live now rather than as something sitting eight weeks out.
One thing this does not mean: your app is not going to stop working. Apps already installed keep working, purchases keep processing, and an unmaintained APK sitting in production stays there. What stops is your ability to publish anything. No security patch, no crash fix, no price change, no target API level bump. The revenue keeps arriving and the app freezes.
That matters more than it first sounds, because it collides with the other Android deadlines. Target API level enforcement and developer verification both have their own dates, and all three want you to be able to ship an update. Being locked out of publishing in the same quarter you need to ship a compliance change is how a small task becomes an incident.

Google's recommendation is version 9, and for once I'd take the recommendation at face value rather than treating it as an upsell.
Version 8, released on 30 June 2025, is where all the pain is. It removed a batch of APIs that had been deprecated for years. Version 9.0.0, released on 19 May 2026, removed nothing at all. Its changes are a nullable return value on DeveloperProvidedBillingDetails.getLinkUri(), an error code that moved from ERROR to BILLING_UNAVAILABLE when the Play Store is blocked (which needs AndroidX Core 1.9 or later), and in-app messaging for subscription price increases. Version 9.1.0 followed on 18 June 2026 with the billing choice APIs.
Landing on 8 buys you eleven months. Landing on 9 buys you two years and costs you an afternoon more. If you're doing the work anyway, do it once.
Everything below was removed in version 8. If your billing code predates mid-2025, expect to hit most of them.
enablePendingPurchases() with no arguments is replaced by enablePendingPurchases(PendingPurchasesParams). This compiles after a lazy fix and then silently breaks cash payments. More on it below.
queryPurchaseHistoryAsync() has no client-side replacement at all. Restore-purchases and trial eligibility flows go wrong. Also covered below.
querySkuDetailsAsync(), SkuDetails, SkuDetailsParams and BillingClient.SkuType become queryProductDetailsAsync(), ProductDetails, QueryProductDetailsParams and BillingClient.ProductType. You get a compile error, then a callback signature change to deal with.
queryPurchasesAsync(String, listener) becomes queryPurchasesAsync(QueryPurchasesParams, listener). Straight compile error.
enableAlternativeBilling(), AlternativeBillingListener and AlternativeChoiceDetails become enableUserChoiceBilling(), UserChoiceBillingListener and UserChoiceDetails. Renamed types, compile error.
setOldSkuPurchaseToken(), setReplaceProrationMode() and setReplaceSkusProrationMode() become setOldPurchaseToken() and setSubscriptionReplacementMode(). Compile error on subscription upgrades and downgrades.
Most of that list is honest work: the compiler tells you, you fix it, you move on. Two of them deserve more attention.
enablePendingPurchases() used to take no arguments. In version 8 it takes a PendingPurchasesParams object, and the obvious fix is to build an empty one and get the build green.
Do that and you've turned off support for pending one-time purchases. You have to explicitly enable one-time products on the params builder to get the old behaviour back.
Pending purchases are how Google Play handles payment methods that don't settle instantly: convenience store cash payments in Japan, bank transfers in Germany, boleto in Brazil, OXXO in Mexico, and equivalents in Indonesia. In those markets a meaningful slice of paying users never touch a card. If you drop pending purchase support, those transactions initiate and then never complete, and the user gets nothing.
Nothing about that shows up in a unit test. It doesn't show up in your own device testing either, unless you happen to be testing from Osaka with a convenience store payment. It shows up six weeks later as a regional revenue dip that nobody can attribute. This is the single change I'd have someone check first, before any of the compile errors.
queryPurchaseHistoryAsync() is gone, and there is no drop-in replacement. This is an architectural change dressed up as an API removal.
The reasoning is sound: the client was never a trustworthy source of truth about what a user has bought, and plenty of apps were treating it as one. What you get on the device now is queryPurchasesAsync(), which returns only active purchases tied to the signed-in Google account. Expired subscriptions and consumed one-time products are simply not there any more.
Restore purchases breaks first. If your restore flow walked purchase history to rebuild entitlements, it now sees a smaller set. For active subscriptions that's fine. For anything historical, you need your own record of what was granted, which means a backend that recorded the purchase at the point it happened.
Free trial eligibility goes next. Working out whether a user has already burned their trial was commonly done by checking history on the device. That's no longer possible. Eligibility now comes from the subscription offer details returned by queryProductDetailsAsync(), or from a server-side call to the Play Developer API.
Refunds and cancellations move server-side too. For voided purchases you want the Voided Purchases API and Real-time Developer Notifications rather than a client query.
If your app has no backend at all, this is where the migration stops being a version bump. In our experience that's the single biggest cause of a "quick" billing upgrade turning into a two-week piece of work: the code change is small, and the thing it depends on doesn't exist yet.
There's a related change that catches people in the other direction. In version 8, queryProductDetailsAsync() returns a QueryProductDetailsResult rather than a flat list, and it now tells you about products it couldn't fetch, with a per-product status code explaining why. That's a genuine improvement, and it also means the callback signature changed, so every implementation of ProductDetailsResponseListener needs updating. Watch for one-time products where the offer list comes back empty: with multiple purchase options now supported, an empty list can mean "this user isn't eligible for any offer" rather than "this product doesn't exist".

If you build with a cross-platform framework, you don't call BillingClient directly, but you still ship it, and Play still reads the version out of your bundle. The version you need is whatever your plugin bundles.
Flutter: in_app_purchase 3.3.0, which pulls in_app_purchase_android 0.5.x and bundles Billing Library 8.0.0. Compliant, but not on 9 yet. queryPurchaseHistory and its wrapper were removed from the Dart API too.
React Native: migrate off react-native-iap. The repository was archived on 4 August 2026 and is read-only. expo-iap is the maintained successor and works in bare React Native, not only Expo.
Unity: Unity IAP 5.0.0 or later, released 7 August 2025 with Billing Library 8.0.0. Anything on Unity IAP 4.x will be rejected.
Capacitor and Cordova: cordova-plugin-purchase 13.13.1 or later. Version 13.15 added native Capacitor bridges with no Cordova dependency, via capacitor-plugin-cdv-purchase, and 13.13.1 fixed a regression where non-consumable ownership stopped firing on Billing Library 8.3.0.
RevenueCat: Android 9.0.0 (9.1.1 recommended), Flutter 9.0.0, React Native 9.0.0, Kotlin Multiplatform 2.0.0+15.0.0. Mostly a dependency bump. Needs Kotlin 1.8.0 or later.
Qonversion: Android SDK 9. Billing Library 8 support landed on the native Android SDK first, so check your wrapper's version rather than assuming the Flutter, React Native or Unity package has caught up.
Two of those need more than a line.
React Native is the difficult one. react-native-iap was the default choice for years, and it was archived on 4 August 2026, three weeks before the deadline. If that's what you're on, you're replacing your in-app purchase layer rather than bumping a version, and the clock is already running. expo-iap is the route most teams are taking, and its Android implementation sits on Billing Library 9.1.0. Budget properly for it. It touches your purchase flow, your restore flow and your receipt validation, and it needs testing on real devices.
Managed SDKs are the easy one, with a caveat. If you're on RevenueCat or Qonversion, the removed APIs are their problem rather than yours, which is a fair chunk of what you're paying them for. You still have to ship an update containing the newer SDK. A subscription platform that handles Billing Library 8 perfectly does nothing for you while it sits in a version of your app you haven't published.

This is the part that generates the most support threads, and it's almost never a Play Console bug.
Google doesn't read your source. It reads the com.google.android.play.billingclient.version metadata entry in your app's merged manifest, which the billing library contributes automatically. Three things commonly go wrong.
The most common by far is an old artefact still live somewhere. The check runs across every track you publish to, not just production. A forgotten open testing build from 2024, or a closed testing track you set up once for a client demo, is enough to keep the warning lit, and you have to update or remove the old artefact in every one of them.
The second is manifest merging quietly dropping the metadata. In multi-module projects, or where someone has added merger rules to resolve a conflict, that entry can disappear from the merged output. Check the merged manifest in your build outputs rather than trusting the source file.
The third is something else dragging in an old copy of the library. Ad SDKs, analytics wrappers and older subscription libraries sometimes bundle their own. If you've updated your direct dependency and the reported version hasn't moved, print your dependency tree and look for a second, older com.android.billingclient on the graph.
Google also now ships a migration skill for its Android CLI, added with the play-billing-library-version-upgrade skill, which handles a good portion of the mechanical rewrites. I'd use it for the compile errors and still review the pending purchases change by hand, because that's the one where a passing build tells you nothing.
The cheap checks come first, because two of them can tell you that you're already compliant and can stop reading.
1. Find out which version you are actually shipping. Open the merged manifest in your build outputs and read the value of com.google.android.play.billingclient.version. That is the number Google reads. If it is 8.0.0 or higher, you are compliant and the rest of this list is optional.
2. Check whether you need the billing library at all. If your app does not sell anything, print your dependency tree and find out what is pulling com.android.billingclient in. Ad and analytics SDKs sometimes bundle it. Removing the dependency clears the warning outright.
3. Request the extension if you are anywhere near the line. Play Console, Policy status, open the billing library warning and complete the extension form. It buys you until 1 November 2026. Requesting it and not needing it costs nothing. Needing it in late October and not having it is a frozen release.
4. Audit every track, not just production. Internal, closed and open testing tracks all count. Old artefacts in a forgotten testing track keep the warning lit after you have fixed production.
5. Upgrade to version 9, not version 8. All the breaking changes are in version 8. Landing on 9 buys you until 31 August 2028 instead of 31 August 2027. On a cross-platform stack, this means bumping your plugin or SDK rather than the library directly.
6. Check pending purchases by hand. Confirm that one-time products are explicitly enabled on your PendingPurchasesParams. Leaving them off compiles cleanly, passes tests, and silently breaks cash and bank transfer payments in Japan, Germany, Brazil, Mexico and Indonesia.
7. Rebuild anything that relied on purchase history. Restore purchases and free trial eligibility can no longer be answered on the device. Move them to your own entitlement records, the Play Developer API, and Real-time Developer Notifications.
8. Test on a real device with licence testers. Purchase, restore, subscription upgrade, subscription downgrade, and at least one delayed payment method. Billing behaviour cannot be verified in an emulator on a debug build.
9. Put the 2027 date in the calendar before you close the ticket. Version 8 comes off support on 31 August 2027 and version 9 on 31 August 2028.
For a native Android app with a backend that already records entitlements and a straightforward subscription setup: one to three days including testing.
For an app on a managed SDK like RevenueCat: half a day, mostly release process.
For a React Native app on the archived react-native-iap: one to two weeks. You're changing library, not version.
For an app with no server-side record of purchases, where restore-purchases was built on client-side history: two to four weeks, because you're building the backend piece that the old API let you avoid. This is the case where I'd ask for an extension in Play Console today rather than at the end of October.
Testing is the part people underestimate. You need licence testers configured, a closed testing track, and a real device. Billing behaviour cannot be verified in an emulator with a debug build, and the pending purchase path in particular needs a test account configured for a delayed payment method.
We do this migration for other people's apps, and for most of the cases above it's days rather than weeks of your team's time gone.
The starting point is a code review: we look at what version you're actually shipping, what's pulling it in, whether your restore flow depends on the API that's gone, and whether pending purchases are configured correctly. That review is the same one-off onboarding step we run for any app we take on, £500 to £1,000 depending on complexity, and it tells you which of the four timelines above you're in before you commit to anything.
From there it's either a short piece of work to get you onto version 9 and shipped, or, if the restore-purchases problem means you need the server side building, a scoped project with a number attached.
We can usually start a handover within a week or two. You'll need to give us access to the codebase and the Play Console account, which is worth checking you can still do either way.
Get in Touch and tell us which framework you're on. If you're already past the point where you can publish, say so, because the extension request is the first thing to sort and it takes minutes.
Google runs a two-year deprecation cycle on this library, announced at Google I/O 2019, and it has never slipped. Version 8 comes off support on 31 August 2027. Version 9 goes on 31 August 2028.
Teams that find these deadlines cheap have them in a calendar and do the work in a quiet week. Teams that find them expensive tend to find the email in an inbox nobody monitors, six weeks after their only Android developer moved on. The migration itself is rarely what costs the money. What costs money is the fortnight spent working out who holds the Play Console account and whether anyone can still sign a release.
Store compliance deadlines are core scope on an App Care retainer, which is the version of this where you never get the email in the first place. We track the platform dates, schedule the upgrade into a quiet week, and you hear about it in your Slack channel rather than from Google. Retainers start at £675 a month, and every client gets a named contact rather than a ticket queue.
Most of our clients arrive the other way round, though: after a developer left, or an offshore team stopped replying, or an email like this one turned up and nobody knew who owned the app. That's a normal way to start. Get in Touch and we'll tell you what you're actually dealing with.
If you're reconsidering the billing setup itself rather than just the library version, our post on app store fees in 2026 and web-to-app billing covers the commercial side of the same decision.
Your existing app keeps working and keeps taking payments, but you can't publish updates. Google rejects new releases from apps on a deprecated billing library version, which means no security fixes, no crash fixes, and no ability to meet other Play deadlines that also require shipping an update.
Both dates are real. 31 August 2026 is the published deadline for new apps and updates to move off Billing Library 7. 1 November 2026 is the extension backstop, and you only get it if you request the extension through the Policy status page in Play Console. The console warning quotes the later date, so read it as the floor rather than the deadline.
Version 9. All the breaking changes are in version 8, and version 9.0.0 removed no APIs at all. Going to 8 keeps you compliant until 31 August 2027. Going to 9 keeps you compliant until 31 August 2028 for very little extra work.
If the Play Billing Library is present in your app at all, including through a third-party SDK you don't use for payments, Play will read the version and flag it. Either update it or remove the dependency.
Yes. RevenueCat handles the removed APIs for you, but you still have to ship an app update containing the newer SDK. Android 9.0.0 or later adds Billing Library 8 support, with 9.1.1 recommended, and you'll need Kotlin 1.8.0 or later.
Almost always because an old artefact is still live in a track you'd forgotten about, the com.google.android.play.billingclient.version metadata was dropped during manifest merging, or a third-party SDK is pulling in an older copy of the library. Update every track, check the merged manifest, and print your dependency tree.
Yes, and it's a common reason people get in touch. We start with a code review (£500 to £1,000 as a one-off, depending on complexity) that establishes which version you're shipping, what's pulling it in, and whether your restore-purchases flow depends on the API that was removed. That tells you whether this is a couple of days or a couple of weeks before you commit to the work. We can usually start a handover within a week or two, and we work in Flutter, React Native, Swift and Kotlin. Get in Touch with the framework you're on.
Put the platform deadlines in a calendar that somebody actually owns, or put the app on a maintenance retainer where that's somebody's job. Store compliance deadlines are core scope on our App Care retainers, which start at £675 a month: we track the dates, schedule the upgrade before it's urgent, and you find out in Slack rather than through a warning email. Version 8 comes off support on 31 August 2027, so the next one is already dated.
Start by confirming who holds the Play Console account and whether anyone can still sign a release build with the original upload key. Both of those take longer to resolve than the code change, and neither can be rushed at the end of October.