feat(google): upgrade to Google Play Billing Library 8.1.0#50
Conversation
- Upgrade Billing Library from 8.0.0 to 8.1.0 - Increase minSdk from 21 to 23 (Android 6.0) - Upgrade Kotlin from 2.0.21 to 2.2.0 New features: - isSuspendedAndroid: Detect suspended subscriptions due to payment failures - PreorderDetailsAndroid: Support for pre-order products with presale end time and release time GQL schema updates: - Add PreorderDetailsAndroid type with preorderPresaleEndTimeMillis and preorderReleaseTimeMillis - Add isSuspendedAndroid field to PurchaseAndroid Documentation: - Update types page with new Android fields - Add release notes for openiap-google v1.3.11 / openiap-gql v1.3.1 - Add Google Play Billing 8.1.0 section to recent updates - Include links to official release notes
WalkthroughAdds Android preorder and suspended-subscription fields across models, conversion logic, GraphQL schema, docs, and build configs to support Google Play Billing Library 8.1.0. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (4)**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
packages/docs/**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
packages/docs/**/*📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (GEMINI.md)
Files:
🧠 Learnings (5)📓 Common learnings📚 Learning: 2025-12-06T20:15:59.223ZApplied to files:
📚 Learning: 2025-12-06T20:15:59.223ZApplied to files:
📚 Learning: 2025-12-06T20:15:59.223ZApplied to files:
📚 Learning: 2025-12-06T20:15:59.223ZApplied to files:
🧬 Code graph analysis (1)packages/docs/src/pages/docs/updates/notes.tsx (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (8)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
packages/google/openiap/build.gradle.kts (1)
20-24: Billing 8.1.0 + minSdk 23 wiring looks correct; POM description is slightly vagueThe Gradle updates for
minSdk = 23andbilling-ktx:8.1.0(play compile/runtime + tests) are consistent and should be fine. The POM description still says “Google Play Billing v8”, which is technically correct but not version-specific; if you want ultra-clear release metadata, consider updating it to “v8.1.0” or “v8.x” so it doesn’t drift from the dependency in future bumps.Also applies to: 89-91, 115-116
packages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.kt (2)
635-641: Acceptable use of deprecatedsetSubscriptionReplacementMode, but plan a future migrationThe added comment +
@Suppress("DEPRECATION")aroundsetSubscriptionReplacementMode(replacementMode)make it clear you’re intentionally relying on the legacy API for single‑product upgrades under Billing 8.1.0. That’s fine for now, but it would be good to track a follow‑up to migrate toSubscriptionProductReplacementParamsso you’re aligned with the current API surface and ready for any future removals.
436-437: Hard‑coded “Billing 8.1.0” strings may drift from the actual dependencyBoth the alternative‑billing error message and the initialization log embed
"Billing 8.1.0"as a literal. This is helpful today but easy to forget when bumping the Gradle dependency again; if they get out of sync, the logs will be misleading when debugging billing issues. Consider either making the text version‑agnostic (e.g. “Billing 8.x+”) or pulling the version from a single constant/BuildConfig so it stays in sync automatically.Also applies to: 1081-1092
packages/gql/src/type-android.graphql (1)
17-32: Schema additions for preorderDetailsAndroid and isSuspendedAndroid look correct and backward‑compatible
PreorderDetailsAndroidand its use onProductAndroidOneTimePurchaseOfferDetail, plus theisSuspendedAndroidflag onPurchaseAndroid, are all additive, nullable at the entry point, and match the generated Kotlin/Swift types (String millis + Boolean). This is a safe extension of the API for Billing 8.1.0 features. Just ensure you’ve re-runbun run generateand the platform bindings (Kotlin/Swift/TS/Dart) are regenerated from this schema so everything stays in lockstep. Based on learnings, this should also be wired via thegqlversion inopeniap-versions.json.Also applies to: 38-42, 118-125
packages/google/openiap/src/play/java/dev/hyo/openiap/utils/BillingConverters.kt (1)
96-102: MissingpreorderDetailsAndroidin subscription product conversion.The
toSubscriptionProduct()method at lines 96-102 creates aProductAndroidOneTimePurchaseOfferDetailbut doesn't include thepreorderDetailsAndroidfield, unlike thetoInAppProduct()method. While pre-orders are typically for one-time purchases, this inconsistency could cause issues if the field is ever needed for subscriptions.For consistency with
toInAppProduct(), consider extracting pre-order details here as well:oneTimePurchaseOfferDetailsAndroid = oneTimePurchaseOfferDetails?.let { + val preorderDetails = it.preorderDetails?.let { preorder -> + PreorderDetailsAndroid( + preorderPresaleEndTimeMillis = preorder.preorderPresaleEndTimeMillis.toString(), + preorderReleaseTimeMillis = preorder.preorderReleaseTimeMillis.toString() + ) + } ProductAndroidOneTimePurchaseOfferDetail( formattedPrice = it.formattedPrice, priceAmountMicros = it.priceAmountMicros.toString(), - priceCurrencyCode = it.priceCurrencyCode + priceCurrencyCode = it.priceCurrencyCode, + preorderDetailsAndroid = preorderDetails ) },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
packages/gql/src/generated/Types.ktis excluded by!**/generated/**packages/gql/src/generated/Types.swiftis excluded by!**/generated/**packages/gql/src/generated/types.dartis excluded by!**/generated/**packages/gql/src/generated/types.tsis excluded by!**/generated/**
📒 Files selected for processing (9)
packages/apple/Sources/Models/Types.swift(3 hunks)packages/docs/src/pages/docs/types.tsx(2 hunks)packages/docs/src/pages/docs/updates/notes.tsx(3 hunks)packages/google/build.gradle.kts(1 hunks)packages/google/openiap/build.gradle.kts(3 hunks)packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt(7 hunks)packages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.kt(3 hunks)packages/google/openiap/src/play/java/dev/hyo/openiap/utils/BillingConverters.kt(5 hunks)packages/gql/src/type-android.graphql(2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
packages/gql/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
Run
bun run generateto regenerate types for all platforms (TypeScript, Swift, Kotlin, Dart) from the GraphQL schema
Files:
packages/gql/src/type-android.graphql
packages/google/**/*.kt
📄 CodeRabbit inference engine (CLAUDE.md)
DO NOT add
Androidsuffix to function names in the Android-only package, even for Android-specific APIs (e.g., useacknowledgePurchase()notacknowledgePurchaseAndroid())
Files:
packages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.ktpackages/google/openiap/src/play/java/dev/hyo/openiap/utils/BillingConverters.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
packages/apple/**/*.swift
📄 CodeRabbit inference engine (CLAUDE.md)
packages/apple/**/*.swift: iOS-specific functions MUST haveIOSsuffix (e.g.,presentCodeRedemptionSheetIOS(),showManageSubscriptionsIOS())
Use Pascal case for acronyms at the beginning or middle of names (e.g.,IapManager,IapPurchase), but ALL CAPS only when appearing as a suffix (e.g.,ProductIAP,OpenIAP)
Files:
packages/apple/Sources/Models/Types.swift
packages/apple/Sources/Models/Types.swift
📄 CodeRabbit inference engine (CLAUDE.md)
DO NOT edit
Types.swiftinSources/Models/as it is auto-generated from the OpenIAP GraphQL schema; regenerate using./scripts/generate-types.sh
Files:
packages/apple/Sources/Models/Types.swift
packages/apple/Sources/Models/**/*.swift
📄 CodeRabbit inference engine (CLAUDE.md)
OpenIAP official types in
Sources/Models/must match types defined at openiap.dev/docs/types
Files:
packages/apple/Sources/Models/Types.swift
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: iOS-specific functions must end withIOSsuffix (e.g.,clearTransactionIOS,getAppTransactionIOS)
Android-specific functions must end withAndroidsuffix (e.g.,acknowledgePurchaseAndroid,consumePurchaseAndroid)
Use action prefixes for function naming:getfor retrieval,requestfor async operations,clearfor removal,is/hasfor boolean checks,show/presentfor UI display,begin/finish/endfor process controlPrefer interface for defining object shapes in TypeScript
Files:
packages/docs/src/pages/docs/types.tsxpackages/docs/src/pages/docs/updates/notes.tsx
packages/docs/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/docs/**/*.{ts,tsx}: Use kebab-case for search modal IDs (e.g.,id: 'request-products')
Modal state should be defined once at the app root level using Preact Signals (signal from '@preact/signals-react'), not instantiated multiple times
ALL components must fit within parent boundaries and never overflow outside parent containers; useoverflow-hidden,break-words, andwhitespace-nowrapas needed
Delete unused components, functions, and imports immediately; do not keep commented-out code or unused variables
ANY function that returns a Promise must be wrapped withvoidoperator when used where a void return is expected (e.g., event handlers)
Files:
packages/docs/src/pages/docs/types.tsxpackages/docs/src/pages/docs/updates/notes.tsx
packages/docs/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
packages/docs/**/*: Before committing, runnpx prettier --write,npm run lint,bun run tscornpm run typecheck, andnpm run buildto verify formatting, linting, types, and build success
Use conventional commit format with lowercase type prefix and lowercase description (e.g.,feat: add user authentication)
Files:
packages/docs/src/pages/docs/types.tsxpackages/docs/src/pages/docs/updates/notes.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (GEMINI.md)
**/*.{ts,tsx,js,jsx}: Use camelCase for variable and function names
Use PascalCase for class and component names
Always use async/await for handling promises instead of .then() chains
Add JSDoc comments for public functions and exported APIs
Use const by default, let if reassignment is needed, avoid var
Files:
packages/docs/src/pages/docs/types.tsxpackages/docs/src/pages/docs/updates/notes.tsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap-versions.json : To update OpenIAP GraphQL types in the Android library, edit the `gql` field in `openiap-versions.json`, then run `./scripts/generate-types.sh` and compile to verify
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap-versions.json : To update OpenIAP GraphQL types in the Android library, edit the `gql` field in `openiap-versions.json`, then run `./scripts/generate-types.sh` and compile to verify
Applied to files:
packages/gql/src/type-android.graphqlpackages/google/openiap/build.gradle.ktspackages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.ktpackages/docs/src/pages/docs/updates/notes.tsxpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap/src/main/Types.kt : DO NOT edit `openiap/src/main/Types.kt` as it is auto-generated from the GraphQL schema; regenerate it using `./scripts/generate-types.sh`
Applied to files:
packages/gql/src/type-android.graphqlpackages/google/openiap/build.gradle.ktspackages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.ktpackages/google/openiap/src/play/java/dev/hyo/openiap/utils/BillingConverters.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/apple/openiap-versions.json : To update OpenIAP GraphQL types in the iOS/macOS library, edit the `gql` field in `openiap-versions.json`, run `./scripts/generate-types.sh`, and run `swift test` to verify compatibility
Applied to files:
packages/gql/src/type-android.graphqlpackages/docs/src/pages/docs/updates/notes.tsx
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/apple/Sources/Models/Types.swift : DO NOT edit `Types.swift` in `Sources/Models/` as it is auto-generated from the OpenIAP GraphQL schema; regenerate using `./scripts/generate-types.sh`
Applied to files:
packages/gql/src/type-android.graphqlpackages/apple/Sources/Models/Types.swift
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap/src/main/java/dev/hyo/openiap/utils/**/*.kt : Place reusable Kotlin helper functions in `openiap/src/main/java/dev/hyo/openiap/utils/`
Applied to files:
packages/google/openiap/build.gradle.ktspackages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.ktpackages/google/openiap/src/play/java/dev/hyo/openiap/utils/BillingConverters.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/**/*.kt : DO NOT add `Android` suffix to function names in the Android-only package, even for Android-specific APIs (e.g., use `acknowledgePurchase()` not `acknowledgePurchaseAndroid()`)
Applied to files:
packages/google/openiap/src/play/java/dev/hyo/openiap/OpenIapModule.ktpackages/google/openiap/src/play/java/dev/hyo/openiap/utils/BillingConverters.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/apple/Sources/Models/**/*.swift : OpenIAP official types in `Sources/Models/` must match types defined at [openiap.dev/docs/types](https://www.openiap.dev/docs/types)
Applied to files:
packages/apple/Sources/Models/Types.swift
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to **/*.{ts,tsx} : Android-specific functions must end with `Android` suffix (e.g., `acknowledgePurchaseAndroid`, `consumePurchaseAndroid`)
Applied to files:
packages/docs/src/pages/docs/types.tsx
🧬 Code graph analysis (3)
packages/apple/Sources/Models/Types.swift (2)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (1)
preorderPresaleEndTimeMillis(853-880)packages/gql/src/generated/Types.kt (1)
preorderPresaleEndTimeMillis(920-947)
packages/docs/src/pages/docs/types.tsx (2)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (2)
code(1334-1356)code(1886-1905)packages/gql/src/generated/Types.kt (2)
code(1401-1423)code(1953-1972)
packages/docs/src/pages/docs/updates/notes.tsx (2)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (2)
code(1334-1356)code(1886-1905)packages/gql/src/generated/Types.kt (2)
code(1401-1423)code(1953-1972)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test Android
🔇 Additional comments (9)
packages/apple/Sources/Models/Types.swift (1)
379-388: Generated Swift types for Billing 8.1.0 fields are consistent with schema
PreorderDetailsAndroid, the optionalpreorderDetailsAndroidonProductAndroidOneTimePurchaseOfferDetail, andisSuspendedAndroidonPurchaseAndroidall line up with the Kotlin and GraphQL definitions (names + String millis semantics and suspension behavior). Assuming this file was regenerated from the updated GraphQL schema (and not hand‑edited), the additions look correct and schema‑aligned. As per coding guidelines, keep updating this file only via./scripts/generate-types.sh.Also applies to: 420-426, 505-511
packages/docs/src/pages/docs/types.tsx (1)
373-384: Android docs for preorderDetailsAndroid and isSuspendedAndroid are clear and accurateThe updated Android docs correctly describe
oneTimePurchaseOfferDetailsAndroidnow includingpriceCurrencyCodeandpreorderDetailsAndroidwith the two millis fields, and theisSuspendedAndroiddescription clearly warns not to grant entitlements and points to Billing 8.1.0 release notes. This keeps the public docs in sync with the new schema/runtime fields and should help avoid misuse on the client side.Also applies to: 1181-1199
packages/docs/src/pages/docs/updates/notes.tsx (2)
508-523: LGTM - Version compatibility table accurately reflects the upgrade.The table correctly shows v8.x as the current recommended version with the minSdk 23 and Kotlin 2.2.0 requirements, while maintaining v7.x and v6.x as supported versions with their respective deprecation dates.
544-577: LGTM - Recent Updates section provides comprehensive feature overview.The section accurately documents the key features from Billing Library 8.1.0 including suspended subscriptions detection, pre-order support, SDK requirements, and the deprecated
setSubscriptionReplacementMode()API.packages/google/openiap/src/play/java/dev/hyo/openiap/utils/BillingConverters.kt (2)
30-36: LGTM - Clean extraction of pre-order details.The null-safe chain correctly extracts
preorderDetailsfrom the one-time purchase offer and maps it to thePreorderDetailsAndroiddata class. The conversion ofLongtimestamps toStringis consistent with the GraphQL schema definition.
113-124: Reflection approach for backward compatibility is sound and aligns with Billing Library 8.1.0 design.The use of reflection to call
isSuspended()is appropriate since the method was introduced in Billing Library 8.1.0. TherunCatchingwithgetOrNull()safely handles older versions where this method doesn't exist.Two considerations for future maintenance:
- Reflection incurs minor performance overhead on every purchase conversion
- Silent
nullreturn if Google changes the method signature in future versionsConsider adding a compile-time check or annotation to revisit this implementation when the minimum Billing Library version is bumped past 8.1.0.
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (3)
849-880: LGTM - Auto-generatedPreorderDetailsAndroidtype is correctly structured.The data class follows the established patterns in this file with proper
fromJson/toJsonserialization,__typenameinclusion, and KDoc documentation explaining the Billing Library 8.1.0+ requirement.Based on learnings, this file is auto-generated from the GraphQL schema via
./scripts/generate-types.sh.
987-1016: LGTM -preorderDetailsAndroidfield correctly added to one-time purchase offer details.The optional field with proper null-safe deserialization and serialization is consistent with the pattern used for other nested types in this file.
1255-1262: LGTM - Well-documentedisSuspendedAndroidfield with clear usage guidance.The KDoc comment effectively communicates:
- What suspended means (payment method failure)
- What action developers should take (direct users to subscription center)
- Critical warning not to grant entitlements for suspended subscriptions
- Billing Library version requirement (8.1.0+)
| id("org.jetbrains.kotlin.android") version "2.2.0" apply false | ||
| id("org.jetbrains.kotlin.plugin.compose") version "2.2.0" apply false |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Jetpack Compose compiler extension versions support Kotlin 2.2.0 compatibility matrix
💡 Result:
Short answer: for Kotlin 2.2.0 you must use the Compose compiler that matches the Kotlin version — i.e. the Compose Compiler Gradle plugin version 2.2.0 (or the corresponding kotlin-compose-compiler plugin artifact 2.2.0 if not using the Gradle plugin). [1][2][3]
References:
- Compose ⇄ Kotlin compatibility map (Kotlin 2.0+ → use Compose Compiler Gradle plugin). [1]
- Compose Compiler Gradle plugin docs (plugin version = Kotlin version; example use with 2.0.0). [2]
- Kotlin migration / Compose compiler docs (compiler moved into Kotlin repo; use matching 2.x compiler or kotlin-compose-compiler-plugin artifacts). [3]
🏁 Script executed:
cat -n packages/google/build.gradle.ktsRepository: hyodotdev/openiap
Length of output: 2164
Ensure Compose compiler version is set to 2.2.0 to match Kotlin 2.2.0
The Kotlin plugins are correctly aligned at 2.2.0. However, the Compose compiler version must also be 2.2.0—since Kotlin 2.0+, the Compose compiler is bundled in the Kotlin repository and versions must match. Verify that your COMPOSE_COMPILER_VERSION gradle property is set to 2.2.0 (lines 41-42 reference this property).
🤖 Prompt for AI Agents
In packages/google/build.gradle.kts around lines 4-5, the Kotlin plugin versions
are set to 2.2.0 but the Compose compiler Gradle property referenced later must
match; update the COMPOSE_COMPILER_VERSION Gradle property to "2.2.0" (or add it
if missing) so the Compose compiler version aligns with Kotlin 2.2.0, and ensure
any usages or references (e.g., lines 41-42) read that property.
- Format notes.tsx with prettier - Update COMPOSE_COMPILER_VERSION to 2.2.0 to match Kotlin version
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/docs/src/pages/docs/updates/notes.tsx(7 hunks)packages/google/gradle.properties(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: iOS-specific functions must end withIOSsuffix (e.g.,clearTransactionIOS,getAppTransactionIOS)
Android-specific functions must end withAndroidsuffix (e.g.,acknowledgePurchaseAndroid,consumePurchaseAndroid)
Use action prefixes for function naming:getfor retrieval,requestfor async operations,clearfor removal,is/hasfor boolean checks,show/presentfor UI display,begin/finish/endfor process controlPrefer interface for defining object shapes in TypeScript
Files:
packages/docs/src/pages/docs/updates/notes.tsx
packages/docs/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/docs/**/*.{ts,tsx}: Use kebab-case for search modal IDs (e.g.,id: 'request-products')
Modal state should be defined once at the app root level using Preact Signals (signal from '@preact/signals-react'), not instantiated multiple times
ALL components must fit within parent boundaries and never overflow outside parent containers; useoverflow-hidden,break-words, andwhitespace-nowrapas needed
Delete unused components, functions, and imports immediately; do not keep commented-out code or unused variables
ANY function that returns a Promise must be wrapped withvoidoperator when used where a void return is expected (e.g., event handlers)
Files:
packages/docs/src/pages/docs/updates/notes.tsx
packages/docs/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
packages/docs/**/*: Before committing, runnpx prettier --write,npm run lint,bun run tscornpm run typecheck, andnpm run buildto verify formatting, linting, types, and build success
Use conventional commit format with lowercase type prefix and lowercase description (e.g.,feat: add user authentication)
Files:
packages/docs/src/pages/docs/updates/notes.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (GEMINI.md)
**/*.{ts,tsx,js,jsx}: Use camelCase for variable and function names
Use PascalCase for class and component names
Always use async/await for handling promises instead of .then() chains
Add JSDoc comments for public functions and exported APIs
Use const by default, let if reassignment is needed, avoid var
Files:
packages/docs/src/pages/docs/updates/notes.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap-versions.json : To update OpenIAP GraphQL types in the Android library, edit the `gql` field in `openiap-versions.json`, then run `./scripts/generate-types.sh` and compile to verify
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/**/*.kt : DO NOT add `Android` suffix to function names in the Android-only package, even for Android-specific APIs (e.g., use `acknowledgePurchase()` not `acknowledgePurchaseAndroid()`)
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap-versions.json : To update OpenIAP GraphQL types in the Android library, edit the `gql` field in `openiap-versions.json`, then run `./scripts/generate-types.sh` and compile to verify
Applied to files:
packages/docs/src/pages/docs/updates/notes.tsx
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/apple/openiap-versions.json : To update OpenIAP GraphQL types in the iOS/macOS library, edit the `gql` field in `openiap-versions.json`, run `./scripts/generate-types.sh`, and run `swift test` to verify compatibility
Applied to files:
packages/docs/src/pages/docs/updates/notes.tsx
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to **/*.{ts,tsx} : Android-specific functions must end with `Android` suffix (e.g., `acknowledgePurchaseAndroid`, `consumePurchaseAndroid`)
Applied to files:
packages/docs/src/pages/docs/updates/notes.tsx
🧬 Code graph analysis (1)
packages/docs/src/pages/docs/updates/notes.tsx (2)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (2)
code(1334-1356)code(1886-1905)packages/gql/src/generated/Types.kt (2)
code(1401-1423)code(1953-1972)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test Android
🔇 Additional comments (4)
packages/google/gradle.properties (1)
34-37: Correct version alignment for Kotlin 2.2.0 upgrade.The update of
COMPOSE_COMPILER_VERSIONto2.2.0correctly matches the Kotlin upgrade (2.0.21 → 2.2.0). The added comments accurately document that the Compose compiler has been bundled with Kotlin since version 2.0+, and the guidance that compiler and Kotlin versions should be aligned is sound.packages/docs/src/pages/docs/updates/notes.tsx (3)
517-529: LGTM! Version compatibility table accurately updated.The table correctly reflects the current state:
- v8.x as the latest version with minSdk 23 and Kotlin 2.2.0 requirements
- v7.x and v6.x as supported with deprecation timeline
- Clear progression and compatibility information
This aligns with the library upgrade documented in the PR.
555-588: Comprehensive update summary for v8.1.The Recent Updates section provides a clear, chronological overview of Google Play Billing Library v8.1 features. The information is consistent with the detailed announcement block above and adds useful context about deprecated APIs.
Note: The external link verification in the previous comment also covers the links in this section.
534-534: Accurate terminology correction.Changing "External Purchase support" to "Alternative Billing support" for v6.x is more precise, as Google Play Billing Library v6.x specifically introduced Alternative Billing, while External Purchase is iOS terminology.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/docs/src/pages/docs/updates/notes.tsx(7 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: iOS-specific functions must end withIOSsuffix (e.g.,clearTransactionIOS,getAppTransactionIOS)
Android-specific functions must end withAndroidsuffix (e.g.,acknowledgePurchaseAndroid,consumePurchaseAndroid)
Use action prefixes for function naming:getfor retrieval,requestfor async operations,clearfor removal,is/hasfor boolean checks,show/presentfor UI display,begin/finish/endfor process controlPrefer interface for defining object shapes in TypeScript
Files:
packages/docs/src/pages/docs/updates/notes.tsx
packages/docs/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/docs/**/*.{ts,tsx}: Use kebab-case for search modal IDs (e.g.,id: 'request-products')
Modal state should be defined once at the app root level using Preact Signals (signal from '@preact/signals-react'), not instantiated multiple times
ALL components must fit within parent boundaries and never overflow outside parent containers; useoverflow-hidden,break-words, andwhitespace-nowrapas needed
Delete unused components, functions, and imports immediately; do not keep commented-out code or unused variables
ANY function that returns a Promise must be wrapped withvoidoperator when used where a void return is expected (e.g., event handlers)
Files:
packages/docs/src/pages/docs/updates/notes.tsx
packages/docs/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
packages/docs/**/*: Before committing, runnpx prettier --write,npm run lint,bun run tscornpm run typecheck, andnpm run buildto verify formatting, linting, types, and build success
Use conventional commit format with lowercase type prefix and lowercase description (e.g.,feat: add user authentication)
Files:
packages/docs/src/pages/docs/updates/notes.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (GEMINI.md)
**/*.{ts,tsx,js,jsx}: Use camelCase for variable and function names
Use PascalCase for class and component names
Always use async/await for handling promises instead of .then() chains
Add JSDoc comments for public functions and exported APIs
Use const by default, let if reassignment is needed, avoid var
Files:
packages/docs/src/pages/docs/updates/notes.tsx
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap-versions.json : To update OpenIAP GraphQL types in the Android library, edit the `gql` field in `openiap-versions.json`, then run `./scripts/generate-types.sh` and compile to verify
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to **/*.{ts,tsx} : Android-specific functions must end with `Android` suffix (e.g., `acknowledgePurchaseAndroid`, `consumePurchaseAndroid`)
Applied to files:
packages/docs/src/pages/docs/updates/notes.tsx
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/docs/**/*.{md,mdx} : Use kebab-case for URL anchors (e.g., `#fetch-products`, `#get-app-transaction-ios`)
Applied to files:
packages/docs/src/pages/docs/updates/notes.tsx
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap-versions.json : To update OpenIAP GraphQL types in the Android library, edit the `gql` field in `openiap-versions.json`, then run `./scripts/generate-types.sh` and compile to verify
Applied to files:
packages/docs/src/pages/docs/updates/notes.tsx
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/apple/openiap-versions.json : To update OpenIAP GraphQL types in the iOS/macOS library, edit the `gql` field in `openiap-versions.json`, run `./scripts/generate-types.sh`, and run `swift test` to verify compatibility
Applied to files:
packages/docs/src/pages/docs/updates/notes.tsx
🧬 Code graph analysis (1)
packages/docs/src/pages/docs/updates/notes.tsx (2)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (2)
code(1334-1356)code(1886-1905)packages/gql/src/generated/Types.kt (2)
code(1401-1423)code(1953-1972)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test Android
🔇 Additional comments (2)
packages/docs/src/pages/docs/updates/notes.tsx (2)
22-107: No issues found. The internal documentation anchors (#purchase-platformand#product-platform) are correctly defined inpackages/docs/src/pages/docs/types.tsxat lines 863 and 293 respectively. The Kotlin code example is accurate: all API field names (isSuspendedAndroid,preorderDetailsAndroid,preorderReleaseTimeMillis,preorderPresaleEndTimeMillis) match the actual type definitions in the codebase, and the optional chaining and type conversions are valid.
1-705: Run pre-commit checks before committing.Ensure these checks pass per the coding guidelines for
packages/docs/**/*:
npx prettier --write(code formatting)npm run lint(linting)bun run tscornpm run typecheck(type checking)npm run build(build verification)
New features:
GQL schema updates:
Documentation:
Summary by CodeRabbit
New Features
Chores
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.