Flutter plugin for Microsoft Store in-app purchases on Windows. Wraps
Windows.Services.Store.StoreContext
via a C++/WinRT platform channel — no third-party dependencies, no server-side
validation required for non-consumables.
| Platform | Supported |
|---|---|
| Windows | ✅ |
| Android / iOS / macOS / Linux / Web | ❌ |
| Method | Description |
|---|---|
queryProducts(skuIds) |
Fetch product metadata (title, description, price) for one or more Store SKU IDs |
purchase(skuId) |
Open the native Microsoft Store purchase dialog for a single SKU |
restorePurchases() |
Return all owned non-consumable SKU IDs for the current Microsoft account |
- Windows 10 version 1607 (build 14393) or later — minimum for
Windows.Services.Store - App must be packaged as MSIX and distributed through the Microsoft Store
dependencies:
flutter_windows_iap: ^0.1.0This plugin only activates on Windows; it is safe to include in a multi-platform
pubspec.yaml as long as your code guards IAP calls with a platform check.
import 'dart:io' show Platform;
import 'package:flutter_windows_iap/flutter_windows_iap.dart';
final iap = Platform.isWindows ? FlutterWindowsIap.instance : null;Call this on the paywall screen to display localised titles and prices. Unknown SKU IDs are silently omitted by the Store.
final products = await iap!.queryProducts(['rm_ads', 'pu_custom']);
for (final p in products) {
print('${p.title} ${p.formattedPrice} (${p.currencyCode})');
}final result = await iap!.purchase('rm_ads');
switch (result.status) {
case WinIapPurchaseStatus.succeeded:
// SKU is now owned — grant the entitlement.
break;
case WinIapPurchaseStatus.alreadyPurchased:
// User already owns this — grant entitlement silently.
break;
case WinIapPurchaseStatus.userCancelled:
// User dismissed the Store dialog — no action needed.
break;
case WinIapPurchaseStatus.failed:
final code = result.extendedError?.toRadixString(16) ?? '?';
print('Purchase failed: HRESULT 0x$code');
break;
}Always call this at app startup to reinstate entitlements for users who reinstall or switch devices.
final owned = await iap!.restorePurchases();
// owned is a List<String> of SKU IDs the current account has purchased.
if (owned.contains('rm_ads')) {
removeAds();
}| Field | Type | Description |
|---|---|---|
skuId |
String |
Microsoft Store product ID |
title |
String |
Localised product title |
description |
String |
Localised product description |
formattedPrice |
String |
Localised price string, e.g. "$0.99" |
currencyCode |
String |
ISO 4217 code, e.g. "USD" |
| Field | Type | Description |
|---|---|---|
skuId |
String |
The SKU that was purchased |
status |
WinIapPurchaseStatus |
succeeded, alreadyPurchased, userCancelled, or failed |
extendedError |
int? |
HRESULT from RequestPurchaseAsync when status is failed |
| Value | Meaning |
|---|---|
succeeded |
Purchase completed; SKU is now owned |
alreadyPurchased |
Non-consumable was already owned by this account |
userCancelled |
User closed the Store dialog without purchasing |
failed |
Store returned an error; check extendedError for the HRESULT |
All three methods throw a PlatformException if the Store layer itself fails
(e.g. the Store service is unavailable, or IInitializeWithWindow fails).
try {
final result = await iap!.purchase('rm_ads');
// ...
} on PlatformException catch (e) {
// e.code == 'STORE_ERROR'
// e.message == WinRT error message
// e.details == HRESULT as int (when available)
}- In Partner Center, open your app submission.
- Under In-app products, create a Durable add-on for each SKU.
- Note the Store ID (e.g.
9NBLGGH4TNMP) — this is theskuIdyou pass to the plugin. - During development, use the Store testing guide to test purchases without real charges.
- Non-consumables (Durable add-ons) only. Consumable and subscription add-ons are
not yet supported; calling
purchaseon one will returnfailed. - Requires MSIX packaging.
Windows.Services.Storeis unavailable in unpackaged Win32 apps. - No offline license verification. License state is always fetched live from the Store; there is no local cache.
MIT — see LICENSE.