Skip to content

fix(maui): add net10 targets and trim android aars#184

Merged
hyochan merged 5 commits into
mainfrom
codex/fix-maui-net10-packaging
Jun 15, 2026
Merged

fix(maui): add net10 targets and trim android aars#184
hyochan merged 5 commits into
mainfrom
codex/fix-maui-net10-packaging

Conversation

@hyochan

@hyochan hyochan commented Jun 15, 2026

Copy link
Copy Markdown
Member

Summary

  • add OpenIapClient as the preferred MAUI facade and keep Iap as a hidden legacy shim for compatibility
  • add net10 shared, Android, iOS, and macCatalyst TFMs across MAUI projects and workflows
  • stop fat-bundling Google/AndroidX/Kotlin transitive Android AARs; expose them as NuGet dependencies while packaging only OpenIAP-owned AARs
  • update MAUI docs, examples, generated LLM context, and parity audits for the new facade and packaging shape

Gitdog review

Verification

  • bash scripts/sync-versions.sh
  • bun run compile:ai in scripts/agent
  • bun audit:parity
  • bun audit:docs
  • bun run typecheck in packages/docs
  • bun run build in packages/docs
  • ./gradlew :openiap:assemblePlayRelease in packages/google
  • ../../../packages/google/gradlew :openiap:assembleRelease in libraries/maui-iap/android
  • dotnet build libraries/maui-iap/src/OpenIap.Maui/OpenIap.Maui.csproj -p:TargetFrameworks=net9.0 --nologo
  • dotnet build libraries/maui-iap/src/OpenIap.Maui/OpenIap.Maui.csproj -p:TargetFrameworks=net10.0 --nologo
  • dotnet build libraries/maui-iap/src/OpenIap.Maui.Bindings.Android/OpenIap.Maui.Bindings.Android.csproj -p:TargetFrameworks=net9.0-android --nologo
  • dotnet build libraries/maui-iap/src/OpenIap.Maui.Bindings.Android/OpenIap.Maui.Bindings.Android.csproj -p:TargetFrameworks=net10.0-android --nologo
  • dotnet build libraries/maui-iap/src/OpenIap.Maui/OpenIap.Maui.csproj -p:TargetFrameworks=net9.0-android --nologo
  • dotnet build libraries/maui-iap/src/OpenIap.Maui/OpenIap.Maui.csproj -p:TargetFrameworks=net10.0-android --nologo
  • bash packages/apple/scripts/build-xcframework.sh
  • dotnet pack libraries/maui-iap/src/OpenIap.Maui/OpenIap.Maui.csproj -c Release -o /tmp/openiap-maui-pack-178180 --nologo
  • inspected /tmp/openiap-maui-pack-178180/OpenIap.Maui.1.1.1.nupkg: only openiap-release.aar and openiap-play-release.aar are packaged; Google/AndroidX/Kotlin artifacts are nuspec dependencies
  • dotnet build /tmp/openiap-conflict-test/openiap-conflict-test.csproj --nologo
  • dotnet build /tmp/openiap-net10-android-plain/openiap-net10-android-plain.csproj --nologo
  • dotnet build libraries/maui-iap/example/OpenIap.Maui.Example/OpenIap.Maui.Example.csproj -p:TargetFrameworks=net9.0-android --nologo
  • git diff --check

Closes #178
Closes #179
Closes #180

Summary by CodeRabbit

  • New Features

    • Added .NET 10 support across MAUI platform targets (Android, iOS, macOS/macCatalyst) alongside existing .NET 9 targets.
  • Documentation

    • Updated MAUI usage, examples, and API references to use OpenIapClient (with Iap retained as a backward-compatible alias).
    • Updated setup/prerequisites and net10-target guidance; refreshed published reference version snippets.
  • Build / CI

    • CI and release validation now build and verify both net9 and net10 targets for shared and platform bindings.

Add net10 MAUI target frameworks, move Android Google dependencies to NuGet PackageReferences, and introduce OpenIapClient as the preferred facade while keeping Iap as a legacy shim.

Closes #178

Closes #179

Closes #180
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 911d42c7-bf8c-47e0-af8b-2f639c05e0a9

📥 Commits

Reviewing files that changed from the base of the PR and between ebd901a and fe5705b.

📒 Files selected for processing (14)
  • libraries/maui-iap/example/OpenIap.Maui.Example/OpenIap.Maui.Example.csproj
  • packages/docs/src/pages/docs/apis/get-active-subscriptions.tsx
  • packages/docs/src/pages/docs/apis/get-available-purchases.tsx
  • packages/docs/src/pages/docs/apis/get-storefront.tsx
  • packages/docs/src/pages/docs/apis/has-active-subscriptions.tsx
  • packages/docs/src/pages/docs/apis/ios/get-storefront-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/get-transaction-jws-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/is-eligible-for-external-purchase-custom-link-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/is-eligible-for-intro-offer-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/is-transaction-verified-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/latest-transaction-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/subscription-status-ios.tsx
  • packages/docs/src/pages/docs/types/billing-programs.tsx
  • scripts/audit-non-godot-parity.mjs
✅ Files skipped from review due to trivial changes (4)
  • packages/docs/src/pages/docs/apis/ios/subscription-status-ios.tsx
  • packages/docs/src/pages/docs/apis/get-active-subscriptions.tsx
  • packages/docs/src/pages/docs/apis/get-available-purchases.tsx
  • packages/docs/src/pages/docs/apis/ios/get-transaction-jws-ios.tsx
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/docs/src/pages/docs/apis/has-active-subscriptions.tsx
  • packages/docs/src/pages/docs/apis/ios/is-transaction-verified-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/is-eligible-for-external-purchase-custom-link-ios.tsx
  • packages/docs/src/pages/docs/apis/get-storefront.tsx
  • packages/docs/src/pages/docs/apis/ios/is-eligible-for-intro-offer-ios.tsx
  • packages/docs/src/pages/docs/types/billing-programs.tsx
  • packages/docs/src/pages/docs/apis/ios/get-storefront-ios.tsx
  • scripts/audit-non-godot-parity.mjs

📝 Walkthrough

Walkthrough

Renames the primary C# MAUI IAP entry point from Iap to OpenIapClient, retaining Iap as an EditorBrowsable(Never) forwarding shim. Adds net10.0 target frameworks across all .csproj files, CI, and release workflows. Replaces embedded Maven AndroidMavenLibrary bindings with NuGet PackageReference dependencies. Migrates all example app pages, documentation code snippets, and tooling/knowledge files to reference OpenIapClient.*.

Changes

OpenIap.Maui v1.1.1 Release

Layer / File(s) Summary
OpenIapClient facade + Iap backward-compat shim
libraries/maui-iap/src/OpenIap.Maui/OpenIap.cs
Renames the public static class from Iap to OpenIapClient; reintroduces Iap as a hidden forwarding alias decorated with EditorBrowsable(EditorBrowsableState.Never) that delegates all members (Instance, OverrideInstance, KitApi, ConnectWebhookStream, WebhookEventTypes, ParseWebhookEventData) to OpenIapClient.
.NET 10 multi-targeting and Android dependency refactor
libraries/maui-iap/src/Directory.Build.props, libraries/maui-iap/src/OpenIap.Maui.Bindings.Android/...csproj, libraries/maui-iap/src/OpenIap.Maui.Bindings.iOS/...csproj, libraries/maui-iap/src/OpenIap.Maui/OpenIap.Maui.csproj, libraries/maui-iap/example/OpenIap.Maui.Example/OpenIap.Maui.Example.csproj
Expands all TargetFrameworks to include net10.0/net10.0-android/net10.0-ios/net10.0-maccatalyst alongside existing net9.0 variants; replaces AndroidMavenLibrary entries with NuGet PackageReference items for Xamarin.Android.Google.BillingClient and GoogleGson; switches AAR packaging to two explicit OpenIap-owned AARs gated by Exists(...) checks; bumps several AndroidX, Kotlin, and coroutines NuGet version properties; splits example MAUI package references into conditional groups for net9.0 and net10.0 targets.
CI and release workflow net10 expansion
.github/workflows/ci-maui-iap.yml, .github/workflows/release-maui.yml
Switches all three .NET SDK setup steps from 9.0.x to 10.0.x; adds dotnet build invocations for net10.0-android, net10.0-ios, and net10.0-maccatalyst; updates job display names to reference net9.0/net10.0 dual support; updates comments to document net10.0 target framework inclusion.
Example app migration to OpenIapClient.Instance
libraries/maui-iap/example/OpenIap.Maui.Example/Pages/*, libraries/maui-iap/example/OpenIap.Maui.Example/Utils/IapLifecycle.cs
Replaces every Iap.Instance / Iap.ConnectWebhookStream call site across all example pages (AllProducts, AlternativeBilling, AvailablePurchases, HomePage, OfferCode, PurchaseFlow, SubscriptionFlow, WebhookStream) and IapLifecycle with the OpenIapClient.* equivalents.
Audit and version-sync tooling
scripts/audit-non-godot-parity.mjs, scripts/sync-versions.sh
Expands the MAUI Android parity audit to validate six new NuGet/AndroidX version properties, enforce net10 TFM presence in workflows and setup docs, and strengthen BillingClient NuGet/Maven version alignment rules; trims sync-versions.sh to only emit the retained billing, Gson, AndroidX activity/fragment/lifecycle/saved-state, and Kotlin props.
Documentation, knowledge base, and LLM context
libraries/maui-iap/README.md, libraries/maui-iap/CLAUDE.md, libraries/maui-iap/CONVENTION.md, knowledge/*, packages/docs/src/pages/docs/**, packages/docs/public/llms*.txt, llms*.txt, packages/docs/scripts/replace-csharp-tabs.mjs, scripts/agent/compile-context.ts
Updates all C# code snippets in ~70 documentation pages from Iap.* to OpenIapClient.*; adds .NET 10 prerequisites and TFM examples throughout README and setup docs; adds R10 docs-version-metadata consistency rule to the Claude context; bumps cross-platform version references (iOS/Android 2.2.1, Godot 2.3.1, kmp-iap 2.3.1, OpenIap.Maui 1.1.1).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • hyodotdev/openiap#107: Both PRs involve docs consistency enforcement, with shared interest in audit tooling and the knowledge/internal/ guidance files.

Poem

🐇 Hop, hop — the old Iap hops aside,
OpenIapClient takes the stride!
Ten-dot-zero joins nine on the shelf,
No more fat AARs — NuGet does it itself.
The docs all gleam with the right name shown,
This bunny ships clean code, right down to the bone! 🚀

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-maui-net10-packaging

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces .NET 10 support for the MAUI SDK, transitions transitive Google/Android dependencies from fat-bundled AARs to standard NuGet package references to allow deduplication, and renames the static facade from Iap to OpenIapClient to prevent namespace collisions. A backward-compatible Iap shim is provided for legacy consumers, and documentation, examples, and audit scripts are updated accordingly. Feedback suggests adding the [Obsolete] attribute to the legacy Iap class to trigger compiler warnings and encourage migration to OpenIapClient.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

/// use <see cref="OpenIapClient"/> to avoid namespace/type name collisions in
/// projects whose namespaces start with <c>OpenIap.Maui.Iap</c>.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To explicitly discourage the use of the legacy Iap facade in new code, consider adding the [Obsolete] attribute in addition to [EditorBrowsable]. This will trigger compiler warnings for any active references, helping developers migrate to OpenIapClient.

[Obsolete("Use OpenIapClient instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not applying this one in the compatibility shim. Adding [Obsolete] would produce compiler warnings for existing consumers, and warning-as-error projects could treat that as a source break. EditorBrowsable(Never) keeps new-code guidance toward OpenIapClient without making the legacy Iap shim risky for existing apps.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
packages/docs/src/pages/docs/apis/ios/validate-receipt-ios.tsx (1)

136-143: ⚠️ Potential issue | 🟡 Minor

Cast this sample to QueryResolver.

ValidateReceiptIOSAsync is declared on QueryResolver, not MutationResolver, so this cast points at the wrong interface and the C# example won't compile. Switch the receiver cast to QueryResolver.

🔧 Proposed fix
-await ((MutationResolver)OpenIapClient.Instance).ValidateReceiptIOSAsync(
+await ((QueryResolver)OpenIapClient.Instance).ValidateReceiptIOSAsync(
🤖 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/docs/src/pages/docs/apis/ios/validate-receipt-ios.tsx` around lines
136 - 143, The code example casts OpenIapClient.Instance to MutationResolver,
but ValidateReceiptIOSAsync is actually declared on QueryResolver, causing a
compilation error. Change the cast from MutationResolver to QueryResolver in the
line where ValidateReceiptIOSAsync is being called to reference the correct
interface.
packages/docs/src/pages/docs/apis/ios/get-external-purchase-custom-link-token-ios.tsx (1)

138-145: ⚠️ Potential issue | 🟡 Minor

Fix the C# call syntax in the example.

tokenType = ... is not valid C# named-argument syntax; use tokenType: instead. The statement is also missing a trailing semicolon.

🛠 Proposed fix
-var token = await ((QueryResolver)OpenIapClient.Instance).GetExternalPurchaseCustomLinkTokenIOSAsync(
-    tokenType = ExternalPurchaseCustomLinkTokenTypeIOS.ACQUISITION
-)
+var token = await ((QueryResolver)OpenIapClient.Instance).GetExternalPurchaseCustomLinkTokenIOSAsync(
+    tokenType: ExternalPurchaseCustomLinkTokenTypeIOS.ACQUISITION
+);
🤖 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/docs/src/pages/docs/apis/ios/get-external-purchase-custom-link-token-ios.tsx`
around lines 138 - 145, The C# code example in the CodeBlock component contains
invalid named-argument syntax and is missing a semicolon. In the
GetExternalPurchaseCustomLinkTokenIOSAsync method call within the csharp
CodeBlock, change the named argument from `tokenType =
ExternalPurchaseCustomLinkTokenTypeIOS.ACQUISITION` to `tokenType:
ExternalPurchaseCustomLinkTokenTypeIOS.ACQUISITION` (use a colon instead of an
equals sign for C# named arguments) and add a semicolon at the end of the
statement after the closing parenthesis.
packages/docs/src/pages/docs/apis/ios/get-pending-transactions-ios.tsx (1)

52-54: ⚠️ Potential issue | 🟡 Minor

Update C# signature to match the library contract.

The C# documentation shows Task<List<PurchaseIOS>>, but QueryResolver.GetPendingTransactionsIOSAsync() actually returns Task<IReadOnlyList<PurchaseIOS>> as defined in Types.cs and implemented across all platform resolvers. Update the signature to reflect the actual immutable contract.

🔧 Proposed fix
-Task<List<PurchaseIOS>> GetPendingTransactionsIOSAsync()
+Task<IReadOnlyList<PurchaseIOS>> GetPendingTransactionsIOSAsync()
🤖 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/docs/src/pages/docs/apis/ios/get-pending-transactions-ios.tsx`
around lines 52 - 54, The C# method signature in the CodeBlock for
GetPendingTransactionsIOSAsync() is showing Task<List<PurchaseIOS>> but the
actual implementation returns Task<IReadOnlyList<PurchaseIOS>>. Update the
csharp CodeBlock content to use IReadOnlyList instead of List to match the
actual library contract defined in Types.cs and implemented across all platform
resolvers.
🤖 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 @.github/workflows/ci-maui-iap.yml:
- Around line 55-58: Replace all instances of the `actions/setup-dotnet@v5`
action with a pinned commit SHA instead of the mutable version tag. For each
occurrence of `actions/setup-dotnet@v5` in the workflow file, replace the `@v5`
reference with the full commit SHA (e.g., `@a9f0a2d3...`) to ensure immutable
supply-chain inputs and prevent the action from being retagged unexpectedly.

In @.github/workflows/release-maui.yml:
- Around line 43-46: The release workflow references the actions/setup-dotnet
action using a version tag (v5) instead of a pinned commit SHA. Replace all
instances of actions/setup-dotnet@v5 with the full commit SHA of that action
version to prevent supply-chain drift and ensure release automation uses
immutable action references. This applies to every occurrence of the
setup-dotnet action in the workflow file.

In
`@packages/docs/src/pages/docs/apis/ios/can-present-external-purchase-notice-ios.tsx`:
- Line 99: The C# code snippets in the documentation are missing trailing
semicolons, which makes them invalid C# syntax. Add a semicolon to the end of
each var assignment statement at the following locations: in
packages/docs/src/pages/docs/apis/ios/can-present-external-purchase-notice-ios.tsx
at line 99, append `;` to the `var can = await
((QueryResolver)OpenIapClient.Instance).CanPresentExternalPurchaseNoticeIOSAsync()`
statement; in packages/docs/src/pages/docs/apis/ios/current-entitlement-ios.tsx
at line 114, append `;` to the `var entitlement = ...` statement; and in
packages/docs/src/pages/docs/apis/ios/get-all-transactions-ios.tsx at line 108,
append `;` to the `var txs = ...` statement.

In `@packages/docs/src/pages/docs/apis/ios/get-app-transaction-ios.tsx`:
- Around line 99-100: Add missing statement-terminating semicolons to the C#
code examples in four iOS API documentation files. In
packages/docs/src/pages/docs/apis/ios/get-app-transaction-ios.tsx lines 99-100,
add a semicolon after GetAppTransactionIOSAsync() before the closing CodeBlock
tag. In packages/docs/src/pages/docs/apis/ios/get-pending-transactions-ios.tsx
lines 102-103, add a semicolon after GetPendingTransactionsIOSAsync(). In
packages/docs/src/pages/docs/apis/ios/get-promoted-product-ios.tsx lines
100-101, add a semicolon after GetPromotedProductIOSAsync(). In
packages/docs/src/pages/docs/apis/ios/get-receipt-data-ios.tsx lines 97-98, add
a semicolon after GetReceiptDataIOSAsync(). Each change follows the same
pattern: locate the respective method call and append a semicolon before the
closing CodeBlock tag to match proper C# syntax.

In
`@packages/docs/src/pages/docs/events/android/developer-provided-billing-listener-android.tsx`:
- Around line 63-66: The external transaction token should not be logged to
stdout in documentation examples as it is sensitive data meant to be forwarded
to your backend and reported to Google Play only. Remove all Console.WriteLine
calls that print the ExternalTransactionToken in the Subscribe callback across
all affected sites. In
packages/docs/src/pages/docs/events/android/developer-provided-billing-listener-android.tsx
at lines 63-66, remove the Console.WriteLine(details.ExternalTransactionToken)
call from the DeveloperProvidedBillingAndroid.Subscribe callback. Apply the same
fix at lines 175-182 in the same file. Also remove the Console.WriteLine call
that prints the external transaction token from the user choice billing listener
callback in
packages/docs/src/pages/docs/events/android/user-choice-billing-listener-android.tsx
at lines 177-185.

In `@scripts/audit-non-godot-parity.mjs`:
- Around line 2804-2811: The `startsWith` call on
`mauiBillingClientNuGetVersion` in the condition can throw and crash the script
if the variable is null or undefined, since earlier validation checks only call
`fail(...)` without returning. Add a guard condition to verify that
`mauiBillingClientNuGetVersion` is defined before calling `startsWith` on it,
ensuring missing or invalid values are handled as validation failures rather
than runtime errors.

---

Outside diff comments:
In
`@packages/docs/src/pages/docs/apis/ios/get-external-purchase-custom-link-token-ios.tsx`:
- Around line 138-145: The C# code example in the CodeBlock component contains
invalid named-argument syntax and is missing a semicolon. In the
GetExternalPurchaseCustomLinkTokenIOSAsync method call within the csharp
CodeBlock, change the named argument from `tokenType =
ExternalPurchaseCustomLinkTokenTypeIOS.ACQUISITION` to `tokenType:
ExternalPurchaseCustomLinkTokenTypeIOS.ACQUISITION` (use a colon instead of an
equals sign for C# named arguments) and add a semicolon at the end of the
statement after the closing parenthesis.

In `@packages/docs/src/pages/docs/apis/ios/get-pending-transactions-ios.tsx`:
- Around line 52-54: The C# method signature in the CodeBlock for
GetPendingTransactionsIOSAsync() is showing Task<List<PurchaseIOS>> but the
actual implementation returns Task<IReadOnlyList<PurchaseIOS>>. Update the
csharp CodeBlock content to use IReadOnlyList instead of List to match the
actual library contract defined in Types.cs and implemented across all platform
resolvers.

In `@packages/docs/src/pages/docs/apis/ios/validate-receipt-ios.tsx`:
- Around line 136-143: The code example casts OpenIapClient.Instance to
MutationResolver, but ValidateReceiptIOSAsync is actually declared on
QueryResolver, causing a compilation error. Change the cast from
MutationResolver to QueryResolver in the line where ValidateReceiptIOSAsync is
being called to reference the correct interface.
🪄 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

Run ID: 8723bdfa-1767-4cb2-a86f-10c951d02426

📥 Commits

Reviewing files that changed from the base of the PR and between 18da3e6 and 925cfef.

📒 Files selected for processing (98)
  • .github/workflows/ci-maui-iap.yml
  • .github/workflows/release-maui.yml
  • knowledge/_claude-context/context.md
  • knowledge/internal/04-platform-packages.md
  • libraries/maui-iap/CLAUDE.md
  • libraries/maui-iap/CONVENTION.md
  • libraries/maui-iap/README.md
  • libraries/maui-iap/example/OpenIap.Maui.Example/Pages/AllProductsPage.xaml.cs
  • libraries/maui-iap/example/OpenIap.Maui.Example/Pages/AlternativeBillingPage.xaml.cs
  • libraries/maui-iap/example/OpenIap.Maui.Example/Pages/AvailablePurchasesPage.xaml.cs
  • libraries/maui-iap/example/OpenIap.Maui.Example/Pages/HomePage.xaml.cs
  • libraries/maui-iap/example/OpenIap.Maui.Example/Pages/OfferCodePage.xaml.cs
  • libraries/maui-iap/example/OpenIap.Maui.Example/Pages/PurchaseFlowPage.xaml.cs
  • libraries/maui-iap/example/OpenIap.Maui.Example/Pages/SubscriptionFlowPage.xaml.cs
  • libraries/maui-iap/example/OpenIap.Maui.Example/Pages/WebhookStreamPage.xaml.cs
  • libraries/maui-iap/example/OpenIap.Maui.Example/Utils/IapLifecycle.cs
  • libraries/maui-iap/src/Directory.Build.props
  • libraries/maui-iap/src/OpenIap.Maui.Bindings.Android/OpenIap.Maui.Bindings.Android.csproj
  • libraries/maui-iap/src/OpenIap.Maui.Bindings.iOS/OpenIap.Maui.Bindings.iOS.csproj
  • libraries/maui-iap/src/OpenIap.Maui/OpenIap.Maui.csproj
  • libraries/maui-iap/src/OpenIap.Maui/OpenIap.cs
  • llms-full.txt
  • llms.txt
  • packages/docs/public/llms-full.txt
  • packages/docs/public/llms.txt
  • packages/docs/scripts/replace-csharp-tabs.mjs
  • packages/docs/src/pages/docs/apis/android/acknowledge-purchase-android.tsx
  • packages/docs/src/pages/docs/apis/android/check-alternative-billing-availability-android.tsx
  • packages/docs/src/pages/docs/apis/android/consume-purchase-android.tsx
  • packages/docs/src/pages/docs/apis/android/create-alternative-billing-token-android.tsx
  • packages/docs/src/pages/docs/apis/android/create-billing-program-reporting-details-android.tsx
  • packages/docs/src/pages/docs/apis/android/enable-billing-program-android.tsx
  • packages/docs/src/pages/docs/apis/android/is-billing-program-available-android.tsx
  • packages/docs/src/pages/docs/apis/android/launch-external-link-android.tsx
  • packages/docs/src/pages/docs/apis/android/show-alternative-billing-dialog-android.tsx
  • packages/docs/src/pages/docs/apis/deep-link-to-subscriptions.tsx
  • packages/docs/src/pages/docs/apis/end-connection.tsx
  • packages/docs/src/pages/docs/apis/fetch-products.tsx
  • packages/docs/src/pages/docs/apis/finish-transaction.tsx
  • packages/docs/src/pages/docs/apis/get-active-subscriptions.tsx
  • packages/docs/src/pages/docs/apis/get-available-purchases.tsx
  • packages/docs/src/pages/docs/apis/get-storefront.tsx
  • packages/docs/src/pages/docs/apis/has-active-subscriptions.tsx
  • packages/docs/src/pages/docs/apis/init-connection.tsx
  • packages/docs/src/pages/docs/apis/ios/begin-refund-request-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/can-present-external-purchase-notice-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/clear-transaction-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/current-entitlement-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/get-all-transactions-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/get-app-transaction-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/get-external-purchase-custom-link-token-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/get-pending-transactions-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/get-promoted-product-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/get-receipt-data-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/get-storefront-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/get-transaction-jws-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/is-eligible-for-external-purchase-custom-link-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/is-eligible-for-intro-offer-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/is-transaction-verified-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/latest-transaction-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/present-code-redemption-sheet-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/present-external-purchase-link-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/present-external-purchase-notice-sheet-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/request-purchase-on-promoted-product-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/show-external-purchase-custom-link-notice-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/show-manage-subscriptions-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/subscription-status-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/sync-ios.tsx
  • packages/docs/src/pages/docs/apis/ios/validate-receipt-ios.tsx
  • packages/docs/src/pages/docs/apis/request-purchase.tsx
  • packages/docs/src/pages/docs/apis/restore-purchases.tsx
  • packages/docs/src/pages/docs/events/android/developer-provided-billing-listener-android.tsx
  • packages/docs/src/pages/docs/events/android/user-choice-billing-listener-android.tsx
  • packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx
  • packages/docs/src/pages/docs/events/purchase-error-listener.tsx
  • packages/docs/src/pages/docs/events/purchase-updated-listener.tsx
  • packages/docs/src/pages/docs/events/subscription-billing-issue-listener.tsx
  • packages/docs/src/pages/docs/features/discount.tsx
  • packages/docs/src/pages/docs/features/refund.tsx
  • packages/docs/src/pages/docs/features/subscription-billing-issue.tsx
  • packages/docs/src/pages/docs/features/subscription/index.tsx
  • packages/docs/src/pages/docs/features/subscription/upgrade-downgrade.tsx
  • packages/docs/src/pages/docs/features/validation.tsx
  • packages/docs/src/pages/docs/getting-started.tsx
  • packages/docs/src/pages/docs/kit-backend.tsx
  • packages/docs/src/pages/docs/setup/maui.tsx
  • packages/docs/src/pages/docs/types/alternative-billing-types.tsx
  • packages/docs/src/pages/docs/types/billing-programs.tsx
  • packages/docs/src/pages/docs/types/external-purchase-link.tsx
  • packages/docs/src/pages/docs/types/ios/app-transaction-ios.tsx
  • packages/docs/src/pages/docs/types/product-request.tsx
  • packages/docs/src/pages/docs/types/purchase-updated-listener-options.tsx
  • packages/docs/src/pages/docs/types/request-purchase-props.tsx
  • packages/docs/src/pages/docs/types/verify-purchase-with-provider-result.tsx
  • packages/docs/src/pages/introduction.tsx
  • scripts/agent/compile-context.ts
  • scripts/audit-non-godot-parity.mjs
  • scripts/sync-versions.sh

Comment thread .github/workflows/ci-maui-iap.yml
Comment thread .github/workflows/release-maui.yml
Comment thread packages/docs/src/pages/docs/apis/ios/get-app-transaction-ios.tsx Outdated
Comment thread scripts/audit-non-godot-parity.mjs
Fix MAUI C# documentation snippets, avoid logging external transaction tokens in examples, and guard the parity audit against missing BillingClient NuGet metadata.
@hyochan

hyochan commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

Addressed the actionable CodeRabbit feedback in 9fd446d2:

  • fixed invalid/missing C# semicolons and named-argument syntax in iOS docs snippets
  • corrected GetAllTransactionsIOSAsync / GetPendingTransactionsIOSAsync C# return docs to IReadOnlyList<PurchaseIOS>
  • changed the ValidateReceiptIOSAsync sample to cast OpenIapClient.Instance to QueryResolver
  • removed C# sample logging of external transaction tokens
  • added a null guard before startsWith(...) in the parity audit

I intentionally left the actions/setup-dotnet@v5 SHA-pinning suggestion out because this repo consistently uses versioned GitHub Action tags across workflows, and changing that policy in this MAUI fix PR would be broader than the review finding. I also did not add [Obsolete] to the legacy Iap shim because it would surface new compiler warnings for existing consumers, including projects that treat warnings as errors; EditorBrowsable(Never) keeps migration guidance without turning the compatibility shim into a build risk.

Pin actions/setup-dotnet to the current v5 commit SHA in MAUI CI and release workflows.
@hyochan

hyochan commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@hyochan

hyochan commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the .NET MAUI SDK (maui-iap) by renaming the static facade Iap to OpenIapClient to prevent namespace collisions, while retaining Iap as a backward-compatible alias. It also introduces support for .NET 10 target frameworks and refactors Android dependencies to use NuGet PackageReferences instead of fat-bundled Maven AARs, allowing consumer apps to deduplicate dependencies. Feedback on the changes suggests a security improvement in billing-programs.tsx to avoid logging the sensitive ExternalTransactionToken to the console, aligning with best practices implemented in other documentation files.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/docs/src/pages/docs/types/billing-programs.tsx
Extend the MAUI sample app to build net10 Android, iOS, and Mac Catalyst targets alongside net9.

Add a parity audit guard for the sample target matrix and clean up generated docs snippets flagged during review.
@hyochan

hyochan commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@hyochan

hyochan commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Update the MAUI billing-programs C# example to avoid printing ExternalTransactionToken values in logs.
@hyochan

hyochan commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@hyochan

hyochan commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for .NET 10 target frameworks across the MAUI SDK (maui-iap), transitions transitive Google and AndroidX dependencies from fat-bundled AARs to standard NuGet PackageReference dependencies to allow deduplication, and renames the static facade from Iap to OpenIapClient (with a legacy Iap compatibility shim) to prevent namespace collisions. Additionally, the documentation, examples, version sync scripts, and parity audits are updated to reflect these changes. The review feedback correctly points out a security improvement opportunity to avoid logging the raw ExternalTransactionToken in the billing programs documentation example to prevent sensitive data exposure.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/docs/src/pages/docs/types/billing-programs.tsx

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for .NET 10 in the maui-iap library, updating target frameworks, workflows, and example apps. It refactors the Android package dependency structure by moving transitive Google, AndroidX, and Kotlin libraries from fat-bundled AARs to standard NuGet PackageReference dependencies to allow consumer apps to deduplicate them. Additionally, it renames the static facade Iap to OpenIapClient to prevent namespace collisions, while retaining Iap as a backward-compatible legacy shim. Documentation and examples are updated accordingly. Feedback suggests marking the legacy Iap class with the [Obsolete] attribute to guide developers toward the new OpenIapClient class.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +162 to +163
[EditorBrowsable(EditorBrowsableState.Never)]
public static class Iap

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since the Iap class is kept as a legacy backward-compatible alias/facade, it should be marked with the [Obsolete] attribute. This will provide compiler warnings and IDE visual cues (like strikethroughs) to guide developers toward using the new OpenIapClient class instead.

[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Use OpenIapClient instead.")]
public static class Iap

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not applying this duplicate for the same compatibility reason as the earlier thread. This class is a source-compatible shim for existing consumers; adding [Obsolete] would introduce compiler warnings in current apps, and warning-as-error projects could experience this as a source break. EditorBrowsable(Never) gives new-code guidance without making the compatibility alias risky.

@hyochan hyochan merged commit 47643fc into main Jun 15, 2026
11 checks passed
@hyochan hyochan deleted the codex/fix-maui-net10-packaging branch June 15, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 android Related to android 🐛 bug Something isn't working 👷‍♀️ build Build issue 🎯 feature New feature maui maui library 📦 update packages

Projects

None yet

1 participant