OpenIap.Maui 3.0.1

dotnet add package OpenIap.Maui --version 3.0.1
                    
NuGet\Install-Package OpenIap.Maui -Version 3.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OpenIap.Maui" Version="3.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OpenIap.Maui" Version="3.0.1" />
                    
Directory.Packages.props
<PackageReference Include="OpenIap.Maui" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OpenIap.Maui --version 3.0.1
                    
#r "nuget: OpenIap.Maui, 3.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OpenIap.Maui@3.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OpenIap.Maui&version=3.0.1
                    
Install as a Cake Addin
#tool nuget:?package=OpenIap.Maui&version=3.0.1
                    
Install as a Cake Tool

maui-iap

OpenIAP for .NET MAUI - unified in-app purchases on iOS, Android, and macCatalyst from a single C# API.

Status matrix

Layer iOS Android macCatalyst
Generated types (Types.cs) yes yes yes
OpenIapClient.Instance facade and listener streams yes yes yes
StoreKit 2 / Play Billing native bindings yes yes yes
Example MAUI app yes yes yes
NuGet package shape single public package single public package single public package

Install

OpenIap.Maui 2.x requires the supported .NET 10 SDK and MAUI workload:

dotnet workload install maui
dotnet add package OpenIap.Maui

For manual .csproj edits, copy the current PackageReference from the OpenIap.Maui NuGet package page.

OpenIap.Maui is the only NuGet package apps reference. The Android and iOS binding outputs are flattened into the main NuGet package, while Play Services, Gson, AndroidX, and Kotlin Android libraries remain normal NuGet dependencies so apps can deduplicate them with their own package graph. The store SDK itself (Google Play Billing, the Horizon billing library, or the Amazon Appstore SDK) is linked when the app builds; see Android store.

Stable NuGet releases rebuild the embedded Apple XCFramework with the current App Store-accepted toolchain (Xcode 26.6 / SDK 26.5) and verify every packaged Mach-O slice before publishing. Xcode 27 remains a source-compatibility CI lane until Apple accepts it for App Store submissions, so its guarded StoreKit 27 paths are not included in stable release artifacts yet.

Usage

using OpenIap;
using OpenIap.Maui;

var iap = OpenIapClient.Instance;
var query = (QueryResolver)iap;
var mutate = (MutationResolver)iap;

IDisposable purchaseSub = iap.PurchaseUpdated.Subscribe(async purchase =>
{
    bool verified = await VerifyOnServerAsync(purchase);
    if (!verified) return;

    await mutate.FinishTransactionAsync(
        purchase: new PurchaseInput(purchase),
        isConsumable: true);
});

IDisposable errorSub = iap.PurchaseError.Subscribe(error =>
{
    Console.WriteLine($"{error.Code}: {error.Message}");
});

await mutate.InitConnectionAsync();

var result = await query.FetchProductsAsync(new ProductRequest
{
    Skus = new[] { "premium", "coins_100" },
    Type = ProductQueryType.InApp,
});

await mutate.RequestPurchaseAsync(new RequestPurchaseProps
{
    Type = ProductQueryType.InApp,
    RequestPurchase = new RequestPurchasePropsByPlatforms
    {
        Apple = new RequestPurchaseIosProps { Sku = "coins_100", Quantity = 1 },
        Google = new RequestPurchaseAndroidProps { Skus = new[] { "coins_100" } },
    },
});

Always validate purchases on your server before granting entitlement, then call FinishTransactionAsync. On Android, unfinished purchases are refunded automatically after 3 days.

OpenIap.Maui 2.x exposes OpenIapClient; the deprecated Iap compatibility facade was removed. Replace Iap calls before upgrading from 1.x.

IAPKit API and webhooks

MAUI exposes the same kit helper surface as expo-iap and react-native-iap, with C# naming conventions:

using OpenIap;
using OpenIap.Maui;

var kit = OpenIapClient.KitApi(new KitApiOptions
{
    ApiKey = "openiap-kit_pk_<your-publishable-key>",
    BaseUrl = "https://kit.openiap.dev",
});

var status = await kit.StatusAsync("user-123");
var entitlements = await kit.EntitlementsAsync("user-123");
string? cursor = null;
do
{
    var page = await kit.ProductsAsync(new KitProductsOptions
    {
        Platform = KitProductPlatform.IOS, // required with IncludeClientPayload
        IncludeClientPayload = true,
        Limit = 25,                        // default 25, maximum 50
        Cursor = cursor,
    });
    foreach (var product in page.Products)
    {
        // Consume product.ClientPayload when present.
    }
    cursor = page.HasMore == true ? page.NextCursor : null;
} while (cursor is not null);
var payload = await kit.ClientPayloadAsync(
    "premium.monthly",
    KitProductPlatform.IOS);
await kit.BindUserAsync(purchaseToken: "token", userId: "user-123");

Publishable keys are intentionally app-readable. Never embed an openiap-kit_sk_ secret key in a shipped app; reserve it for trusted backends, CI, and MCP administration.

Client payloads are public app-readable metadata. Keep secrets and server-only rules out of them; catalog responses omit payload bodies unless explicitly requested. Payload-inclusive catalog reads require a platform and return bounded cursor pages (HasMore / NextCursor). Limit and Cursor are ignored by the legacy non-payload catalog path. If catalog churn returns INVALID_CURSOR, restart without Cursor.

IAPKit accepts store-to-server lifecycle webhooks but does not expose an outbound event stream to MAUI or other mobile SDKs. Apps should use purchase verification, scoped entitlement reads, and bounded lifecycle refreshes.

Example app

cd /path/to/openiap

# Android source runs need every store's Google AAR plus the MAUI-owned module AAR.
(cd packages/google && ./gradlew :openiap:assemblePlayRelease :openiap:assembleHorizonRelease :openiap:assembleAmazonRelease)
(cd libraries/maui-iap/android && ../../../packages/google/gradlew :openiap:assembleRelease)

cd libraries/maui-iap/example/OpenIap.Maui.Example
adb uninstall dev.hyo.martie || true
dotnet build -t:Run -f net10.0-android

dotnet build -t:Run -f net10.0-ios
dotnet build -t:Run -f net10.0-maccatalyst

VS Code launch configurations are in libraries/maui-iap/.vscode/launch.json. The Android launcher builds the AARs and passes its device to the build.

Android store

A Debug build links the store of the device it deploys to — the IDE's target (AdbTarget), else the one ANDROID_SERIAL names, else the only one attached: a Quest gets Meta Horizon, a Fire device the Amazon Appstore, anything else Google Play. Only the Debug configuration looks at a device, so pin every build that ships to another store:

dotnet publish -f net10.0-android -c Release -p:OpenIapStore=horizon

The aliases google/gplay/googleplay/google-play/gms, meta/quest, and fire/fireos/fire-os work too, and a value that names no store fails the build. OpenIapAndroidStore is deprecated: it still pins, with a warning, until the next major release, and fails the build against a different OpenIapStore.

MAUI only: NuGet fixes dependencies before the build knows the store, so every build also carries Play Services and DataTransport (about 3.1 MB, with their manifest entries) and kotlinx-serialization-json (up to 0.9 MB); the store SDK itself is linked for the chosen store only. The MAUI setup guide lists the manifest entries.

What's generated vs. hand-written

Regenerate types with:

cd specs/client && bun run generate

Built something with OpenIap.Maui?

List your app on the OpenIAP showcase.

Questions and feedback go to Discussions.

If OpenIap.Maui saves you time, a ⭐ on hyodotdev/openiap helps.

Sponsors

<p align="center"> <a href="https://meta.com"> <img src="https://openiap.dev/meta.svg" alt="Meta" height="80" align="middle"> </a>        <a href="https://developer.amazon.com/"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://openiap.dev/sponsors/amazon-dark.webp"> <img src="https://openiap.dev/sponsors/amazon.webp" alt="Amazon Developer" height="44" align="middle"> </picture> </a> </p>

Thank you to Meta and Amazon Developer for supporting OpenIAP. View sponsorship options.

OpenCollective

We also recognize sponsors and backers through OpenCollective. The original react-native-iap collective now supports the broader OpenIAP ecosystem and is managed separately from the main sponsor program.

Sponsors: <a href="https://opencollective.com/openiap#sponsors"><img src="https://opencollective.com/openiap/sponsors.svg?width=890&cache=20260706" alt="OpenCollective sponsors" /></a>

Backers: <a href="https://opencollective.com/openiap#backers"><img src="https://opencollective.com/openiap/backers.svg?width=890&cache=20260706" alt="OpenCollective backers" /></a>

Become a sponsor | Become a backer

Past supporters

Supported the project before the OpenIAP sponsor program.

<p align="center"> <a href="https://namiml.com"> <img src="https://openiap.dev/sponsors/nami.webp" alt="Nami" height="32" align="middle"> </a>      <a href="https://www.courier.com/?utm_source=react-native-iap&utm_campaign=osssponsors"> <img src="https://openiap.dev/sponsors/courier.webp" alt="Courier" height="32" align="middle"> </a> </p>

License

MIT - (c) hyodotdev

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-ios26.0 is compatible.  net10.0-maccatalyst was computed.  net10.0-maccatalyst26.0 is compatible.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.1 48 10/12/2026
3.0.0 117 10/9/2026
3.0.0-rc.1 44 10/8/2026
2.6.3 87 10/7/2026
2.6.2 181 9/30/2026
2.6.1 155 9/26/2026
2.6.0 132 9/26/2026
2.5.0 620 8/31/2026
2.4.1 249 8/29/2026
2.4.0 142 8/26/2026
2.3.2 178 8/21/2026
2.3.1 267 8/14/2026
2.3.0 126 8/11/2026
2.2.2 126 8/11/2026
2.2.1 125 8/10/2026
2.2.0 112 8/9/2026
2.1.0 146 8/8/2026
2.0.2 163 8/3/2026
2.0.1 136 8/1/2026
2.0.0 136 7/30/2026
Loading failed