Feat/play billing 8 - #124
Conversation
Billing 8 removes three APIs the SDK relied on: - enablePendingPurchases() no-arg overload. Replaced with the PendingPurchasesParams form using enableOneTimeProducts(), which reproduces the old semantics. Also adopt enableAutoServiceReconnection(), since onBillingServiceDisconnected() has no retry logic and a dropped connection would otherwise strand queued requests. - queryProductDetailsAsync now yields a QueryProductDetailsResult instead of a nullable List<ProductDetails>. loadProductDetails() logs unfetchedProductList, which was previously dropped silently, and purchase() guards on an empty productDetailsList rather than calling first(). - queryPurchaseHistoryAsync is gone. Restore and receipt validation now use queryPurchasesAsync with includeSuspendedSubscriptions(true), mapping Purchase.products into PurchaseTransaction. The two identical pass-through wrappers are collapsed and the remaining helpers renamed off "history". This narrows restorePurchases: only purchases Google Play still associates with the account are returned. Cancelled-but-unexpired, paused, in-trial and suspended subscriptions still come through, but fully expired ones no longer do, even with includeInActivePurchases set to true. Documented on CBPurchase.restorePurchases and in the README. billing-ktx 8.3.0 depends on kotlin-stdlib 2.2.10, whose metadata the 1.8.20 compiler cannot read, so Kotlin moves to 2.1.21. That requires AGP 7.4.2 on Gradle 7.6.4 built with JDK 17, and String.toUpperCase(Locale) is a hard error under Kotlin 2.x. Billing 8 also raises the floor to minSdk 23 and compileSdk 34. The public API surface is unchanged: a javap diff of the 2.0.0-beta-6 AAR against released 2.0.0-beta-5 shows only compiler-generated access$ bridges and lambda classes that Kotlin 2.x no longer emits, plus the getEntries() accessors it adds to enums. Co-authored-by: Cursor <cursoragent@cursor.com>
queryPurchases always reported errors through restorePurchaseCallBack, but queryAllPurchases is only reached from receipt validation, which sets purchaseCallBack or oneTimePurchaseCallback instead. A failed Play query during validation therefore either threw UninitializedPropertyAccessException from the lateinit restore callback, or notified a stale restore callback while the validation caller never completed. Pass the error handler down from the caller so restore keeps using its own callback and validation completes through its. Co-authored-by: Cursor <cursoragent@cursor.com>
WalkthroughThe SDK upgrades to Google Play Billing 8.3.0 and Android API 34. It updates build tooling and version metadata. Purchase restoration and receipt validation now use current purchase queries instead of removed purchase-history APIs. ChangesBilling Library 8 migration
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant BillingClientManager
participant GooglePlayBilling8
participant PurchaseTransaction
BillingClientManager->>GooglePlayBilling8: queryPurchases with QueryPurchasesParams
GooglePlayBilling8-->>BillingClientManager: current subscription and in-app purchases
BillingClientManager->>PurchaseTransaction: convert Purchase records
PurchaseTransaction-->>BillingClientManager: restored transactions for validation
🚥 Pre-merge checks | ❌ 1❌ Failed checks (1 warning)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
Comment |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@build.gradle`:
- Line 10: Upgrade the Android Gradle Plugin declaration in build.gradle to
8.1.1 or later, then update gradle/wrapper/gradle-wrapper.properties to the
Gradle version required by that AGP release. Review app/build.gradle and
chargebee/build.gradle for compatibility with the upgraded AGP and adjust only
affected configuration.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: 6eee962d-802a-460b-bc40-3fd4e5f14963
📒 Files selected for processing (10)
README.mdapp/build.gradlebuild.gradlechargebee/build.gradlechargebee/src/main/java/com/chargebee/android/Chargebee.ktchargebee/src/main/java/com/chargebee/android/billingservice/BillingClientManager.ktchargebee/src/main/java/com/chargebee/android/billingservice/CBPurchase.ktchargebee/src/main/java/com/chargebee/android/billingservice/ProductType.ktchargebee/src/test/java/com/chargebee/android/billingservice/BillingClientManagerTest.ktgradle/wrapper/gradle-wrapper.properties
| } | ||
| dependencies { | ||
| classpath 'com.android.tools.build:gradle:4.2.2' | ||
| classpath 'com.android.tools.build:gradle:7.4.2' |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
import re
from pathlib import Path
root = Path("build.gradle").read_text()
wrapper = Path("gradle/wrapper/gradle-wrapper.properties").read_text()
agp = re.search(r"com\.android\.tools\.build:gradle:(\d+\.\d+\.\d+)", root).group(1)
gradle = re.search(r"gradle-(\d+\.\d+(?:\.\d+)?)-", wrapper).group(1)
def version(value):
return tuple(map(int, (value.split(".") + ["0", "0"])[:3]))
if version(agp) < version("8.1.1"):
raise SystemExit(f"AGP {agp} does not support Android API 34; use AGP 8.1.1 or later.")
if version(gradle) < version("8.0"):
raise SystemExit(f"Gradle {gradle} is below the minimum for AGP 8.1.x.")
print(f"Supported baseline configured: AGP {agp}, Gradle {gradle}")
PYRepository: chargebee/chargebee-android
Length of output: 232
🌐 Web query:
site:developer.android.com/build/releases/about-agp Android Gradle plugin 7.4.2 API 34 compileSdk support minimum AGP 8.1.1
💡 Result:
To compile with Android API level 34 (Android 14), the minimum required version of the Android Gradle Plugin (AGP) is 8.1.1 [1]. While AGP 7.4.2 is an earlier version, using it with a compileSdk of 34 is not supported and may lead to unexpected build issues or failures, as official documentation explicitly specifies 8.1.1 as the minimum version for API level 34 [1]. Therefore, upgrading your project to at least AGP 8.1.1 is required to properly support compilation against SDK 34 [1].
Citations:
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
import re
from pathlib import Path
files = {
"build.gradle": Path("build.gradle").read_text(),
"gradle-wrapper.properties": Path("gradle/wrapper/gradle-wrapper.properties").read_text(),
"app/build.gradle": Path("app/build.gradle").read_text(),
"chargebee/build.gradle": Path("chargebee/build.gradle").read_text(),
}
agp = re.search(r"com\.android\.tools\.build:gradle:([0-9.]+)", files["build.gradle"]).group(1)
gradle = re.search(r"/gradle-([0-9.]+)-", files["gradle-wrapper.properties"]).group(1)
compile_sdks = dict(re.findall(r"compileSdkVersion\s+(\d+)", files["app/build.gradle"] + "\n" + files["chargebee/build.gradle"]))
target_sdks = dict(re.findall(r"targetSdkVersion\s+(\d+)", files["app/build.gradle"] + "\n" + files["chargebee/build.gradle"]))
print(f"AGP={agp}")
print(f"Gradle={gradle}")
print(f"compileSdkVersion values={sorted(set(compile_sdks.values()))}")
print(f"targetSdkVersion values={sorted(set(target_sdks.values()))}")
PYRepository: chargebee/chargebee-android
Length of output: 249
Use an Android API 34-supported AGP version.
AGP 7.4.2 does not support compilation against Android API 34. Upgrade to AGP 8.1.1 or later, then upgrade Gradle 7.6.4 to the version required by the selected AGP release.
📍 Affects 4 files
build.gradle#L10-L10(this comment)gradle/wrapper/gradle-wrapper.properties#L3-L3app/build.gradle#L6-L14chargebee/build.gradle#L5-L11
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@build.gradle` at line 10, Upgrade the Android Gradle Plugin declaration in
build.gradle to 8.1.1 or later, then update
gradle/wrapper/gradle-wrapper.properties to the Gradle version required by that
AGP release. Review app/build.gradle and chargebee/build.gradle for
compatibility with the upgraded AGP and adjust only affected configuration.
CHANGELOG
REPLACE_ME_WITH_CHANGELOG
SUMMARY
REPLACE_ME_WITH_SUMMARY_OF_THE_CHANGES
FUNCTIONAL AUTOMATION CHANGES PR
AUTOMATION TEST REPORT URL
REPLACE_ME_WITH_TEST_REPORT_URL
AREAS OF IMPACT
REPLACE_ME_WITH_AREAS_OF_IMPACT_OR_NA
TYPE OF CHANGE
DOCUMENTATION
REPLACE_ME_WITH_DOCUMENTATION_LINK_OR_NA
Upgraded Google Play Billing to 8.3.0 and updated Android build tools, SDK levels, and Kotlin. Migrated removed Billing APIs, improved purchase restoration and failure callbacks, and documented restoration limits. Updated the SDK version to
2.0.0-beta-6.