feat(google): expose amazon userId and marketplace on purchases - #275
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Warning Review limit reached
Next review available in: 41 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthrough
ChangesAmazon purchase metadata
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant AmazonUserData
participant OpenIapModule
participant AmazonReceipt
participant PurchaseAndroid
AmazonUserData->>OpenIapModule: Return user ID and marketplace
OpenIapModule->>OpenIapModule: Cache accepted identity data
AmazonReceipt->>OpenIapModule: Convert receipt
OpenIapModule->>PurchaseAndroid: Build purchase with Amazon metadata
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
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 `@packages/google/openiap/src/amazon/java/dev/hyo/openiap/OpenIapModule.kt`:
- Around line 1010-1015: The successful callback in the user-data handling flow
must pass lifecycle validation through completeOrCache before updating cached
identity state, so stale callbacks after endConnection or newer requests are
rejected. Clear the cached Amazon identity in endConnection, and replace
separate cachedAmazonUserId/cachedAmazonMarketplace updates with one immutable
snapshot consumed consistently by toPurchase.
🪄 Autofix (Beta)
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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b47d8db9-ffb9-4602-bdf1-0770ce000f31
⛔ Files ignored due to path filters (6)
packages/gql/src/generated/Types.csis excluded by!**/generated/**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.gdis excluded by!**/generated/**packages/gql/src/generated/types.tsis excluded by!**/generated/**
📒 Files selected for processing (10)
libraries/expo-iap/src/types.tslibraries/flutter_inapp_purchase/lib/types.dartlibraries/godot-iap/addons/godot-iap/types.gdlibraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.ktlibraries/maui-iap/src/OpenIap.Maui/Types.cslibraries/react-native-iap/src/types.tspackages/apple/Sources/Models/Types.swiftpackages/google/openiap/src/amazon/java/dev/hyo/openiap/OpenIapModule.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.ktpackages/gql/src/type-android.graphql
|
Thanks for the well-researched PR — the direction is exactly right, and the schema/codegen work was clean. The remaining gap was our SDK parity requirement: new schema fields must be wired through every SDK surface (that's what the failing Rather than round-tripping, I've pushed a commit on top of yours (e72c63b) that completes the wiring:
One behavioral change: purchases now prefer the Field names stay as you proposed ( Will merge once CI is green. |
Amazon getUserData() returns a userId + marketplace that server-side Amazon RVS verification requires (userId + receiptId), but the amazon flavor dropped them when mapping a purchase — apps doing their own receipt verification had no way to obtain the userId. (OpenIAP already documents this id on RequestVerifyPurchaseWithIapkitAmazonProps.userId, but only for the built-in IAPKit path.) Add nullable userIdAmazon and userMarketplaceAmazon to PurchaseAndroid (populated only on the amazon flavor; null on Google Play and Horizon). The amazon OpenIapModule caches the values from onUserDataResponse and sets them in buildAmazonPurchase. Additive and non-breaking; all platform bindings regenerated via `bun run generate`.
Complete the userIdAmazon/userMarketplaceAmazon schema addition so the fields flow through every SDK surface instead of stopping at the Amazon module: - google/amazon: prefer the userData carried on each Purchase(Updates)Response over the getUserData() cache; the cache is refreshed by every successful response and only used as fallback - google/play, google/horizon, kmp-iap: enumerate the new fields explicitly (always null off-Amazon) to satisfy the parity audit - react-native-iap: expose the fields on the NitroPurchase transport, map them in HybridRnIap.kt and type-bridge.ts, pass nil on iOS - react-native-iap, expo-iap: populate the fields in the Vega mapReceipt path from the response/cached user data - maui-iap: cover the fields in the canonical PurchaseAndroid payload round-trip fixture - docs: document both fields on the Purchase type page - knowledge: codify the store-suffix naming rule the fields introduce - google/testAmazon: add AmazonUserDataMappingTest Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/google/openiap/src/testAmazon/java/dev/hyo/openiap/AmazonUserDataMappingTest.kt (1)
9-41: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winAdd coverage for Amazon cache fallback and precedence.
These tests verify direct builder assignment and null defaults. They do not exercise the selection logic that prefers per-purchase RVS data and falls back to cached data. Add tests for both branches to prevent stale Amazon identity after an account change.
The PR objective defines this precedence as part of the contract.
🤖 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 `@packages/google/openiap/src/testAmazon/java/dev/hyo/openiap/AmazonUserDataMappingTest.kt` around lines 9 - 41, Add tests around the Amazon purchase user-data selection logic to cover both precedence branches: assert that per-purchase RVS identity overrides cached Amazon identity, and that cached identity is used when per-purchase data is unavailable. Anchor the tests to the existing Amazon mapping/test helpers and verify account changes do not retain stale cached identity.
🤖 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 `@libraries/maui-iap/tests/OpenIap.Maui.Tests/RecordJsonTests.cs`:
- Around line 158-160: Update the PurchaseAndroidJson fixture to keep
userIdAmazon and userMarketplaceAmazon null when store is google, and add a
dedicated Amazon fixture with those metadata values plus a round-trip test if
Amazon coverage is required.
In `@libraries/react-native-iap/src/utils/type-bridge.ts`:
- Around line 543-544: Update the non-iOS purchase mapper around userIdAmazon
and userMarketplaceAmazon to return null for both fields unless
nitroPurchase.store equals STORE_AMAZON; preserve the existing nullable-string
conversion for Amazon purchases.
---
Nitpick comments:
In
`@packages/google/openiap/src/testAmazon/java/dev/hyo/openiap/AmazonUserDataMappingTest.kt`:
- Around line 9-41: Add tests around the Amazon purchase user-data selection
logic to cover both precedence branches: assert that per-purchase RVS identity
overrides cached Amazon identity, and that cached identity is used when
per-purchase data is unavailable. Anchor the tests to the existing Amazon
mapping/test helpers and verify account changes do not retain stale cached
identity.
🪄 Autofix (Beta)
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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4f4969fb-7ead-4511-b3d8-f4501c03d3e3
📒 Files selected for processing (15)
knowledge/_claude-context/context.mdknowledge/internal/01-naming-conventions.mdlibraries/expo-iap/src/vega-adapter.tslibraries/kmp-iap/library/src/androidMain/kotlin/io/github/hyochan/kmpiap/Helper.ktlibraries/maui-iap/tests/OpenIap.Maui.Tests/RecordJsonTests.cslibraries/react-native-iap/android/src/main/java/com/margelo/nitro/iap/HybridRnIap.ktlibraries/react-native-iap/ios/RnIapHelper.swiftlibraries/react-native-iap/src/specs/RnIap.nitro.tslibraries/react-native-iap/src/utils/type-bridge.tslibraries/react-native-iap/src/vega-adapter.tspackages/docs/src/pages/docs/types/purchase.tsxpackages/google/openiap/src/amazon/java/dev/hyo/openiap/OpenIapModule.ktpackages/google/openiap/src/horizon/java/dev/hyo/openiap/utils/BillingConverters.ktpackages/google/openiap/src/play/java/dev/hyo/openiap/utils/BillingConverters.ktpackages/google/openiap/src/testAmazon/java/dev/hyo/openiap/AmazonUserDataMappingTest.kt
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/google/openiap/src/amazon/java/dev/hyo/openiap/OpenIapModule.kt
Address CodeRabbit review on PR hyodotdev#275: a late onUserDataResponse callback could overwrite the active Amazon identity after endConnection or a newer request, and the two separate @volatile fields allowed a torn userId/marketplace pair. - completeOrCache now reports lifecycle acceptance; onUserDataResponse caches user data only for accepted callbacks - purchase and purchase-updates flows refresh the cache only while their issuing generation is still current - cache is a single immutable UserData snapshot, cleared in endConnection alongside the generation bump, so purchase mapping always reads one consistent identity Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
e72c63b to
9cd7afa
Compare
- react-native-iap type bridge nulls userIdAmazon/userMarketplaceAmazon unless the purchase store is amazon, so Amazon identity metadata can never leak onto Google Play or Horizon purchases; the parity audit allowlist now permits the store guard on those two fields (matching the existing transactionId precedent) while still requiring the matching nitro field to be read first - maui-iap gains a realistic Amazon-store round-trip test covering the user data fields; the canonical full-coverage fixture stays synthetic because WhenWritingNull drops null members from round trips Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Problem
On the Amazon flavor,
PurchaseResponse.getUserData()provides auserIdandmarketplace, but they are dropped when mapping toPurchaseAndroid. Apps that verify receipts server-side via Amazon RVS needuserId+receiptId, so there is currently no supported way to obtain the AmazonuserIdfrom a purchase. OpenIAP already documents this exact id onRequestVerifyPurchaseWithIapkitAmazonProps.userId, but only for the built-in IAPKit verification path.Prior art: react-native-iap exposes these fields
For comparison,
react-native-iapattaches the Amazon user data to every purchase it emits, so server-side RVS verification works out of the box. From its AmazonReceipt.toMap(userData):openiap receives the same
PurchaseResponse.userDatabut does not forwarduserId/marketplace, so migrating from react-native-iap to openiap loses the ability to verify Amazon receipts on a backend. This PR restores parity.Change
type-android.graphql): add nullableuserIdAmazonanduserMarketplaceAmazontoPurchaseAndroid, documented as Amazon-flavor-only (null on Google Play / Horizon).OpenIapModule.kt): cacheuserId/marketplacefromonUserDataResponse(already fetched at init) and populate the new fields inbuildAmazonPurchase/toPurchase.bun run generate(Kotlin, Swift, TS, Dart, C#, GDScript, kmp, expo-iap, react-native-iap).Notes
null.userIdAmazon/userMarketplaceAmazon) for easy migration; happy to adjust to match OpenIAP conventions.Summary by CodeRabbit
New Features
Documentation