Google Play Billing Library 7 Deadline Passed: Migrate to PBL 9 Before November 1
If an Android app still ships Google Play Billing Library 7, the normal deadline has already passed. Google Play's current deprecation schedule says new apps and app updates using Billing Library 7 stopped meeting the normal submission requirement after August 31, 2026. Developers who qualify can request an extension through Play Console until November 1, 2026.
The better target is not Billing Library 8 just because it is the next number. Google's current integration and migration documentation uses Play Billing Library 9.1.0, and the official migration guide supports moving directly from PBL 7 or 8 to PBL 9.
The practical job is therefore:
Find every app still on PBL 7
↓
Move directly to PBL 9.1.0
↓
Replace removed/deprecated APIs
↓
Re-test product queries and purchase state
↓
Verify purchases on the backend
↓
Release before the extension window becomes the emergency planThis guide focuses on the migration risks that can break real purchases even when the project compiles.
What is the Google Play Billing Library 7 deadline?
Google's Billing Library deprecation FAQ currently lists:
| Billing Library version | Normal new-app/update deadline | Extension deadline |
|---|---|---|
| PBL 7 | August 31, 2026 | November 1, 2026 |
| PBL 8 | August 31, 2027 | November 1, 2027 |
| PBL 9 | August 31, 2028 | November 1, 2028 |
Google uses a two-year deprecation cycle for Play Billing Library versions.
The August 31 cutoff does not mean every already-installed app using PBL 7 immediately stops selling products. Google's FAQ says existing/unmaintained APKs can continue to work. The immediate problem is submission eligibility for maintained apps: new apps and updates need a supported Billing Library version.
If Play Console shows a Billing Library warning, Google's FAQ says the extension form is available from the warning details on the Policy status page for eligible apps.
Treat that extension as schedule relief, not a reason to freeze the codebase until late October.
Should you migrate from PBL 7 to PBL 8 or PBL 9?
For a migration starting in September 2026, PBL 9 is the more durable default unless a dependency blocks it.
Google's current PBL 9 migration guide explicitly supports upgrades from versions 7 or 8 to version 9. The guide currently uses:
dependencies {
def billing_version = "9.1.0"
implementation "com.android.billingclient:billing:$billing_version"
}For Kotlin projects using the KTX package:
dependencies {
val billing_version = "9.1.0"
implementation("com.android.billingclient:billing-ktx:$billing_version")
}PBL 8 is still supported, but its normal submission deadline arrives a year earlier than PBL 9's. If the app is already being changed, moving only to 8 can create another avoidable billing migration sooner.
Choose PBL 8 temporarily only when a real dependency, SDK wrapper or release risk prevents a tested PBL 9 migration. Document that decision and the next deadline.
What breaks when moving directly from PBL 7 to PBL 9?
The migration is not only a Gradle version change.
Google's PBL 9 guide says version 9 removes several APIs that had already been deprecated. A direct PBL 7 → 9 upgrade can therefore expose technical debt that PBL 7 still tolerated.
The most important replacements include:
| Old pattern removed in PBL 9 | Current direction |
|---|---|
| __INLINE_CODE_0__ | __INLINE_CODE_0__ |
| __INLINE_CODE_0__ | __INLINE_CODE_0__ |
| __INLINE_CODE_0__ | __INLINE_CODE_0__ |
| __INLINE_CODE_0__ | __INLINE_CODE_0__ |
| __INLINE_CODE_0__ / __INLINE_CODE_1__ | __INLINE_CODE_0__ |
| no-argument __INLINE_CODE_0__ | parameterised __INLINE_CODE_0__ |
| old __INLINE_CODE_0__ overload | parameterised __INLINE_CODE_0__ |
| __INLINE_CODE_0__ | active/pending query + backend history + Voided Purchases API where appropriate |
The clean migration sequence is to search the codebase for the old types before changing the dependency.
For example:
SkuDetails
SkuDetailsParams
SkuDetailsResponseListener
querySkuDetailsAsync
queryPurchaseHistoryAsync
BillingClient.SkuType
enablePendingPurchases()That gives you a migration inventory rather than a compile-error scavenger hunt.
The PBL 7 → 9 __INLINE_CODE_0__ change matters
Google's PBL 9 migration guide calls out an additional step specifically for apps migrating from PBL 7: the __INLINE_CODE_0__ response handling changed.
PBL 8 introduced a richer result that can report unfetched products and their product-level status rather than silently returning only the products that were fetched successfully. That also changed the listener signature.
This is useful operationally because a missing product can mean different things:
product configured incorrectly
user not eligible for an offer
product unavailable in region
catalog mismatch
request failureDo not preserve an old assumption such as:
returned product list is shorter
→ product does not existUpdate the response handling so the app can distinguish successful product details from unfetched product results and log useful diagnostics without exposing internal error noise to customers.
Initialise __INLINE_CODE_0__ with current pending-purchase handling
PBL 9 no longer supports the old no-argument __INLINE_CODE_0__ method.
Google's current Billing integration guide shows a builder using a __INLINE_CODE_0__ object and recommends automatic service reconnection:
val billingClient = BillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases(
PendingPurchasesParams.newBuilder()
.enableOneTimeProducts()
.build()
)
.enableAutoServiceReconnection()
.build()__INLINE_CODE_0__ was introduced in PBL 8 and lets the library try to reconnect automatically when an API call occurs while the Play Billing service is disconnected.
That does not mean connection failures disappear. It reduces the amount of manual reconnection plumbing and can reduce __INLINE_CODE_0__ responses.
Keep your result handling and telemetry. A payment dependency should never fail into a blank spinner.
PBL 9 adds more specific purchase-flow error context
The PBL 9 migration guide recommends handling new sub-response codes returned with __INLINE_CODE_0__ for some __INLINE_CODE_1__ failures.
Current examples include:
- __INLINE_CODE_0__
- __INLINE_CODE_0__
- __INLINE_CODE_0__
That allows a better product experience than treating every failed purchase as the same generic error.
The migration also changes one class of blocked-Play-Store failures. Google says cases where the Play Store is blocked by the system, for example some OEM kids-mode environments, now use __INLINE_CODE_0__ rather than a generic __INLINE_CODE_1__ response. Google notes that this behaviour requires AndroidX Core 1.9 or later.
Audit any code that switches on exact Billing response codes.
A brittle handler such as:
when (billingResult.responseCode) {
BillingClient.BillingResponseCode.OK -> completePurchase()
else -> showGenericFailure()
}may still compile, but the migration is an opportunity to make failures observable and user-actionable.
Do not grant entitlement from the client purchase callback alone
A Billing Library migration should not preserve a weak payment architecture merely because it existed before the deadline.
Google's current billing security guidance recommends sending the __INLINE_CODE_0__ to a secure backend, verifying the purchase with the Google Play Developer API, and granting entitlement only after verification.
A stronger flow is:
Android purchase flow
↓
purchaseToken
↓
Your backend
↓
Google Play Developer API verification
↓
Purchase state == PURCHASED?
↓ yes
Check token not already processed
↓
Grant entitlement
↓
Acknowledge / consume as appropriateGoogle says purchase tokens are globally unique and can be used as a primary key in your purchase records.
Do not use __INLINE_CODE_0__ as the only duplicate key. Google's security guidance notes that not every purchase generates an order ID, including some promotional purchases.
Pending is not purchased
Google's billing documentation repeatedly emphasises one rule:
Do not grant the purchased benefit while the purchase is still __INLINE_CODE_0__.
Pending transactions can complete later, including when a user finishes an offline payment method or a parent approves a purchase on another device.
Your application therefore needs to handle a state transition that may happen outside the original checkout session:
PENDING
↓ later
PURCHASED
↓
verify
↓
grant entitlement
↓
acknowledge/consumeGoogle recommends calling __INLINE_CODE_0__ after a successful Billing connection so the app can discover purchases it may have missed while disconnected or on another device.
This is one of the most important regression tests after a Billing Library upgrade.
Acknowledgement failures can turn successful payments into refunds
Google's current one-time purchase lifecycle guidance says an unacknowledged purchase is automatically refunded after three days.
That creates a nasty class of migration bug:
Payment succeeds
→ user receives access
→ acknowledgement code broke during migration
→ three days later Google refunds purchaseTest acknowledgement and consumption as first-class billing workflows.
For apps with a secure backend, Google recommends server-side purchase processing and acknowledgement because it is more resilient to client connectivity problems and harder to tamper with.
Real-time developer notifications are signals, not complete purchase state
Apps with subscriptions or backend-managed purchases should review Real-time Developer Notifications (RTDN) during the migration as well.
Google's current RTDN reference says an RTDN tells your backend that purchase state changed, but does not contain the complete purchase state. After receiving it, the backend should call the Google Play Developer API to retrieve current authoritative status.
Use:
RTDN
→ identify purchase token / affected product
→ call Play Developer API
→ update internal entitlement staterather than:
RTDN type
→ blindly flip subscription booleanThat pattern matters for renewals, holds, grace periods, cancellations, revocations, pauses and the newer subscription-state transitions Google adds over time.
What should Flutter apps do?
Flutter developers often do not depend on __INLINE_CODE_0__ directly. A plugin or another SDK can pull it transitively.
The migration workflow should start by checking the resolved Android dependency tree, not only Dart code.
For example:
cd android
./gradlew app:dependenciesSearch for:
com.android.billingclient:billingThen identify who owns that dependency:
your Android code?
Flutter in-app-purchase plugin?
third-party monetisation SDK?
subscription platform SDK?If a plugin controls the Billing Library version, update to a plugin release whose Android billing dependency meets Google's current requirement and retest your purchase flows.
Do not force a Gradle dependency override blindly if the plugin's Java/Kotlin implementation still calls APIs removed in PBL 9. A version override can make the dependency graph look modern while the integration is runtime-fragile.
How do you confirm which Billing Library version Play sees?
Google's deprecation FAQ recommends checking the application's build configuration and notes that Play Console can raise a deprecated Billing Library warning.
If Play Console still warns after you upgraded, Google says to verify that the merged __INLINE_CODE_0__ contains the __INLINE_CODE_1__ metadata and that manifest merging has not removed it.
Use both views:
local dependency resolution
+
merged release manifest
+
Play Console warning statusDo not assume a source-level __INLINE_CODE_0__ edit proves the final release artifact contains the intended library version.
A production migration plan from PBL 7 to PBL 9
Step 1: inventory the billing stack
Record:
- current Billing Library version
- direct vs transitive dependency
- one-time products
- subscriptions
- prepaid plans if used
- pending-purchase support
- backend verification
- acknowledgement/consumption path
- RTDN setup
- third-party subscription SDKs
- alternative/external billing features if used
Step 2: request the extension only if schedule risk is real
If Play Console offers the November 1 extension and you genuinely need it, request it early enough that your release plan is not blocked by administrative timing.
But keep the engineering target earlier than November.
Step 3: migrate code to PBL 9.1.0
Replace removed APIs and update the PBL 7-specific product-details response handling.
Enable automatic service reconnection where appropriate.
Step 4: compile all billing-enabled variants
Many teams test only the default flavour.
Compile:
- production/release
- regional flavours
- white-label variants
- app bundles with billing-enabled modules
- any legacy variant still receiving updates
Step 5: test the purchase state machine
Test at minimum:
successful one-time purchase
successful subscription
user cancellation
payment decline
pending purchase
pending → purchased transition
restore/query existing purchase
acknowledgement
consumption
subscription renewal/change
account hold / grace state if relevantStep 6: test backend reconciliation
Verify that purchase tokens are unique in your database and repeated notifications cannot grant entitlement twice.
Confirm RTDN handlers retrieve current state from Google rather than treating the notification payload as the complete record.
Step 7: release through a controlled track
Use internal/closed testing first, then a staged production rollout where the product allows it.
Watch:
- purchase attempts
- purchase success rate
- __INLINE_CODE_0__ distribution
- acknowledgement failures
- backend verification errors
- duplicate-token rejects
- RTDN processing errors
- customer-support reports
A billing migration deserves more monitoring than “the app did not crash”.
A migration test matrix
| Test | Why it matters |
|---|---|
| Product details load | Catches API/listener/catalog regressions |
| Unfetched product handling | Catches eligibility/catalog problems hidden by old assumptions |
| Successful purchase | Basic end-to-end flow |
| User cancels purchase UI | Ensures cancellation is not shown as payment failure |
| Payment declined | Validates new error/sub-response handling |
| Pending purchase | Prevents premature entitlement |
| Pending completes later | Validates reconciliation outside original session |
| Backend verifies token | Prevents client-side trust |
| Duplicate token replay | Prevents double entitlement |
| Acknowledgement | Prevents three-day auto-refund |
| Consumption | Allows consumables to be purchased again correctly |
| Existing purchases queried | Covers device switch/reconnect scenarios |
| RTDN + API refresh | Keeps subscription backend authoritative |
Five mistakes to avoid
1. Upgrading only to PBL 8 by reflex
PBL 8 is supported, but PBL 9 gives a longer current deprecation runway. Pick 8 only for a real compatibility reason.
2. Changing the Gradle version and stopping when the project compiles
Removed APIs, result-shape changes and purchase-state behaviour need functional testing.
3. Granting entitlement on __INLINE_CODE_0__
Wait for __INLINE_CODE_0__ and verify the transaction.
4. Relying only on the client for verification and acknowledgement
Google recommends a secure backend where available.
5. Waiting until the November extension deadline to start
The extension is the parachute, not the flight plan.
A September 2026 checklist
- □Find every maintained app still using PBL 7.
- □Identify direct and transitive Billing Library dependencies.
- □Check Play Console Policy status for billing warnings.
- □Request the November 1 extension only if genuinely needed.
- □Target PBL 9.1.0 unless a documented dependency blocks it.
- □Replace removed __INLINE_CODE_0__/old query APIs.
- □Update PBL 7 __INLINE_CODE_0__ response handling.
- □Use current parameterised pending-purchase configuration.
- □Consider __INLINE_CODE_0__.
- □Handle current billing response/sub-response codes.
- □Verify purchases on a secure backend where available.
- □Grant entitlement only for __INLINE_CODE_0__ state.
- □Test acknowledgement and consumption.
- □Reconcile subscriptions from RTDN through the Developer API.
- □Test the resolved release artifact, not only source dependencies.
- □Run internal/closed testing before production rollout.
FAQs
Can I still update an app using Google Play Billing Library 7 after August 31, 2026?
Under Google's normal schedule, PBL 7 passed its new-app and update deadline on August 31, 2026. Google lists an extension deadline of November 1, 2026 for eligible apps, with the extension request surfaced through the Play Console policy warning.
Does an existing PBL 7 app stop working immediately?
No. Google's deprecation FAQ says existing apps can continue working; the deadline concerns use of supported Billing Library versions for new apps and updates. Maintained apps should migrate rather than depend indefinitely on an old release.
Should I migrate PBL 7 to version 8 or version 9?
For a migration starting now, PBL 9.1.0 is the stronger default because Google's current migration guide supports a direct 7 → 9 path and PBL 9 has a later deprecation deadline. Use PBL 8 only when a real dependency or release constraint requires it.
What is the biggest code change from PBL 7 to PBL 9?
There is no single change. PBL 9 removes old __INLINE_CODE_0__-era APIs, requires current pending-purchase configuration, and a direct PBL 7 migration must update __INLINE_CODE_1__ result handling. Billing result handling should also account for newer sub-response and error classifications.
Do I need a backend for Google Play Billing?
Google strongly recommends backend verification and acknowledgement where your architecture permits it. Send the purchase token to your server, verify it with the Google Play Developer API, grant entitlement only after validation, and make purchase processing idempotent.
How long do I have to acknowledge a Google Play purchase?
Google's current purchase lifecycle documentation says purchases that are not acknowledged within three days are automatically refunded and revoked. Test acknowledgement as part of the migration, not as an afterthought.
Conclusion
The PBL 7 deadline is no longer a future warning. The normal submission cutoff passed on August 31, 2026.
For maintained Android apps, the clean response is:
PBL 7
→ PBL 9.1.0
→ replace removed APIs
→ test product discovery and purchase states
→ verify on backend
→ acknowledge reliably
→ reconcile subscription changes
→ release before November 1 becomes a crisisThe most dangerous migration is one that only satisfies Play Console while leaving the purchase lifecycle brittle.
Use the deadline to improve the whole billing boundary: current client APIs, server verification, idempotent entitlement, acknowledgement, pending purchases, RTDN reconciliation and observable failure handling.
If your Android or Flutter app needs a billing upgrade alongside subscription, backend or Play Store release work, Softotic's mobile app development service can handle the application migration, while custom software development can support purchase verification, entitlement and billing-backend architecture.
Sources and references
- Android Developers: Google Play Billing Library version deprecation
- Android Developers: Migrate to Google Play Billing Library 9 from versions 7 or 8
- Android Developers: Google Play Billing Library release notes
- Android Developers: Integrate the Google Play Billing Library into your app
- Android Developers: Fight fraud and abuse in Play Billing
- Android Developers: Real-time developer notifications reference