Kebechet.Maui.RevenueCat.InAppBilling
5.5.0
Prefix Reserved
dotnet add package Kebechet.Maui.RevenueCat.InAppBilling --version 5.5.0
NuGet\Install-Package Kebechet.Maui.RevenueCat.InAppBilling -Version 5.5.0
<PackageReference Include="Kebechet.Maui.RevenueCat.InAppBilling" Version="5.5.0" />
<PackageVersion Include="Kebechet.Maui.RevenueCat.InAppBilling" Version="5.5.0" />
<PackageReference Include="Kebechet.Maui.RevenueCat.InAppBilling" />
paket add Kebechet.Maui.RevenueCat.InAppBilling --version 5.5.0
#r "nuget: Kebechet.Maui.RevenueCat.InAppBilling, 5.5.0"
#:package Kebechet.Maui.RevenueCat.InAppBilling@5.5.0
#addin nuget:?package=Kebechet.Maui.RevenueCat.InAppBilling&version=5.5.0
#tool nuget:?package=Kebechet.Maui.RevenueCat.InAppBilling&version=5.5.0
Maui.RevenueCat.InAppBilling
A .NET MAUI wrapper library for RevenueCat in-app purchases. Provides a unified C# API that abstracts away the need for you to use platform-specific code from Android and iOS native bindings.
Features
- Unified API for iOS and Android in-app purchases
- Subscription and one-time purchase support
- User authentication (anonymous and identified users)
- Subscription status and entitlement checking
- Trial/intro discount eligibility
- Subscriber attributes management
- Stub implementations for Windows and MacCatalyst (for development convenience)
Installation
dotnet add package Kebechet.Maui.RevenueCat.InAppBilling
Quick Start
1. Register the service
In your MauiProgram.cs:
builder.Services.AddRevenueCatBilling();
2. Inject and initialize
In App.xaml.cs, inject IRevenueCatBilling and initialize in OnStart():
public partial class App : Application
{
private readonly IRevenueCatBilling _revenueCat;
public App(IRevenueCatBilling revenueCat)
{
InitializeComponent();
_revenueCat = revenueCat;
}
protected override void OnStart()
{
var revenueCatApiKey = string.Empty;
#if __ANDROID__
revenueCatApiKey = "<your-android-api-key>";
#elif __IOS__
revenueCatApiKey = "<your-ios-api-key>";
#endif
_revenueCat.Initialize(revenueCatApiKey);
base.OnStart();
}
}
Important: Initialize must be called in
OnStart(), not in the constructor.
API Reference
Initialization & State
| Method | Description |
|---|---|
Initialize(string apiKey) |
Initialize RevenueCat with your platform-specific API key |
IsInitialized() |
Check if the SDK has been initialized |
IsAnonymous() |
Check if current user is anonymous |
GetAppUserId() |
Get the current user ID |
Offerings & Products
| Method | Description |
|---|---|
GetOfferings(bool forceRefresh = false) |
Fetch available offerings and packages |
CheckTrialOrIntroDiscountEligibility(List<string> identifiers) |
Check eligibility for trials/intro pricing |
Purchases
| Method | Description |
|---|---|
PurchaseProduct(PackageDto package) |
Initiate a purchase flow |
GetActiveSubscriptions() |
Get list of active subscription identifiers |
GetAllPurchasedIdentifiers() |
Get all purchased product identifiers |
GetPurchaseDateForProductIdentifier(string productSku) |
Get purchase date for a specific product |
RestoreTransactions() |
Restore previous purchases |
User Management
| Method | Description |
|---|---|
Login(string appUserId) |
Log in an identified user |
Logout() |
Log out and create anonymous user |
GetCustomerInfo() |
Get current customer info and entitlements |
GetManagementSubscriptionUrl() |
Get URL for subscription management |
Subscriber Attributes
| Method | Description |
|---|---|
SetEmail(string email) |
Set user's email |
SetDisplayName(string name) |
Set user's display name |
SetPhoneNumber(string phone) |
Set user's phone number |
SetAttributes(IDictionary<string, string> attributes) |
Set custom attributes |
Example: Complete Purchase Flow
public class PurchaseService
{
private readonly IRevenueCatBilling _revenueCat;
public PurchaseService(IRevenueCatBilling revenueCat)
{
_revenueCat = revenueCat;
}
public async Task<bool> PurchaseSubscription()
{
var offerings = await _revenueCat.GetOfferings();
if (offerings.Count == 0)
return false;
var defaultOffering = offerings.FirstOrDefault(o => o.IsCurrent);
var monthlyPackage = defaultOffering?.AvailablePackages
.FirstOrDefault(p => p.Identifier == "monthly");
if (monthlyPackage == null)
return false;
var result = await _revenueCat.PurchaseProduct(monthlyPackage);
if (result.IsSuccess)
{
// Purchase successful
return true;
}
if (result.ErrorStatus == PurchaseErrorStatus.PurchaseCancelledError)
{
// User cancelled - not an error
return false;
}
// Handle other errors
Console.WriteLine($"Purchase failed: {result.ErrorStatus}");
return false;
}
public async Task<bool> HasActiveSubscription(string entitlementId)
{
var customerInfo = await _revenueCat.GetCustomerInfo();
return customerInfo?.ActiveEntitlements
.Any(e => e.Identifier == entitlementId) ?? false;
}
}
Platform Support
| Platform | Support |
|---|---|
| Android | Full implementation |
| iOS | Full implementation |
| Windows | Stub (returns defaults) |
| MacCatalyst | Stub (returns defaults) |
Stub implementations return:
truefor boolean methods- Empty collections for list methods
string.Emptyfor string methodsnullfor nullable types
This allows you to build and test on Windows/Mac without platform conditionals.
Error Handling
The library follows a non-throwing approach for runtime errors:
- Exceptions are thrown only for developer mistakes (e.g., calling methods before
Initialize()) - Runtime errors (network issues, store problems, etc.) return:
ErrorStatusin result DTOs (e.g.,PurchaseResultDto.ErrorStatus)- Empty collections for list returns
nullfor nullable types
This design ensures your app never crashes due to store-related issues.
Common Error Codes
| Error | Description |
|---|---|
PurchaseCancelledError |
User cancelled the purchase |
StoreProblemError |
Issue with the app store |
NetworkError |
Network connectivity issue |
ProductAlreadyPurchasedError |
Product was already purchased |
PaymentPendingError |
Payment is pending (e.g., awaiting approval) |
See PurchaseErrorStatus for the complete list.
Credits
- Native bindings for Android and iOS inspired by thisisthekap's Xamarin bindings
- Abstraction layer based on RevenueCatXamarin by BillFulton
Contributing
Feel free to create an issue or pull request. For major changes, please open an issue first to discuss your proposal - large PRs without prior discussion may be rejected.
License
This project is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-android35.0 is compatible. net9.0-browser was computed. net9.0-ios was computed. net9.0-ios18.0 is compatible. net9.0-maccatalyst was computed. net9.0-maccatalyst18.0 is compatible. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net9.0-windows10.0.19041 is compatible. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Kebechet.Extensions.IsNullOrEmpty (>= 1.0.1)
- Microsoft.Maui.Controls (>= 9.0.0)
-
net9.0-android35.0
- Kebechet.Extensions.IsNullOrEmpty (>= 1.0.1)
- Kebechet.Maui.RevenueCat.Android (>= 9.2.0.2)
- Microsoft.Maui.Controls (>= 9.0.0)
-
net9.0-ios18.0
- Kebechet.Extensions.IsNullOrEmpty (>= 1.0.1)
- Kebechet.Maui.RevenueCat.iOS (>= 5.34.0.1)
- Microsoft.Maui.Controls (>= 9.0.0)
-
net9.0-maccatalyst18.0
- Kebechet.Extensions.IsNullOrEmpty (>= 1.0.1)
- Microsoft.Maui.Controls (>= 9.0.0)
-
net9.0-windows10.0.19041
- Kebechet.Extensions.IsNullOrEmpty (>= 1.0.1)
- Microsoft.Maui.Controls (>= 9.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Kebechet.Maui.RevenueCat.InAppBilling:
| Package | Downloads |
|---|---|
|
benxu.AppPlatform.Billing.RevenueCat
RevenueCat integration for in-app subscriptions in .NET MAUI. Provides real SDK integration for Android/iOS with optional simulator mode for testing. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 5.5.0 | 480 | 2/8/2026 |
| 5.4.4 | 748 | 1/10/2026 |
| 5.4.3 | 172 | 1/4/2026 |
| 5.4.2 | 619 | 12/7/2025 |
| 5.4.1 | 483 | 11/3/2025 |
| 5.4.0 | 217 | 11/2/2025 |
| 5.3.2 | 472 | 10/11/2025 |
| 5.3.1 | 178 | 10/11/2025 |
| 5.3.0 | 721 | 8/21/2025 |
| 5.2.1 | 265 | 8/18/2025 |
| 5.2.0 | 248 | 8/11/2025 |
| 5.1.0 | 1,097 | 3/26/2025 |
| 5.0.1 | 301 | 3/2/2025 |
| 5.0.0 | 553 | 2/8/2025 |
| 4.5.4 | 784 | 12/16/2024 |
| 4.5.3 | 1,576 | 10/14/2024 |
| 4.5.2 | 436 | 9/30/2024 |
| 4.5.1 | 220 | 9/29/2024 |
| 4.5.0 | 292 | 9/11/2024 |
| 4.4.2 | 825 | 8/8/2024 |
Added new API CanMakePayments