Skip to main content

๐Ÿ”ง FlutterInappPurchase API

The main class for handling in-app purchases across iOS and Android platforms.

๐Ÿ“ฆ Importโ€‹

import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';

๐Ÿ—๏ธ Instance Accessโ€‹

// Access the singleton instance
final iap = FlutterInappPurchase.instance;

๐Ÿ”— Connection Managementโ€‹

initConnection()โ€‹

Initialize the connection to the platform billing service.

Future<void> initConnection()

Example:

try {
await FlutterInappPurchase.instance.initConnection();
print('Connection initialized successfully');
} catch (e) {
print('Failed to initialize connection: $e');
}

Platform Notes:

  • iOS: Calls canMakePayments and registers transaction observers
  • Android: Connects to Google Play Billing service

endConnection()โ€‹

End the connection to the platform billing service.

Future<void> endConnection()

Example:


void dispose() {
FlutterInappPurchase.instance.endConnection();
super.dispose();
}

Important: Always call this in your app's dispose method to prevent memory leaks.

๐Ÿ›๏ธ Product Managementโ€‹

getProducts()โ€‹

Retrieve a list of consumable and non-consumable products.

Future<List<IAPItem>> getProducts(List<String> productIds)

Parameters:

ParameterTypeDescription
productIdsList<String>List of product IDs to fetch

Returns: Future<List<IAPItem>> - List of available products

Example:

final products = await FlutterInappPurchase.instance.getProducts([
'premium_upgrade',
'remove_ads',
'extra_lives'
]);

for (var product in products) {
print('Product: ${product.title} - ${product.localizedPrice}');
}

getSubscriptions()โ€‹

Retrieve a list of subscription products.

Future<List<IAPItem>> getSubscriptions(List<String> subscriptionIds)

Parameters:

ParameterTypeDescription
subscriptionIdsList<String>List of subscription IDs to fetch

Returns: Future<List<IAPItem>> - List of available subscriptions

Example:

final subscriptions = await FlutterInappPurchase.instance.getSubscriptions([
'monthly_premium',
'yearly_premium'
]);

๐Ÿ’ณ Purchase Managementโ€‹

requestPurchase()โ€‹

Request a purchase using the new unified API.

Future<void> requestPurchase({
required RequestPurchase request,
required PurchaseType type,
})

Parameters:

ParameterTypeDescription
requestRequestPurchasePlatform-specific purchase request
typePurchaseTypeType of purchase (inapp or subs)

Example:

await FlutterInappPurchase.instance.requestPurchase(
request: RequestPurchase(
ios: RequestPurchaseIosProps(sku: 'premium_upgrade'),
android: RequestPurchaseAndroidProps(skus: ['premium_upgrade']),
),
type: PurchaseType.inapp,
);

requestPurchaseSimple()โ€‹

Simplified purchase request for cross-platform products.

Future<void> requestPurchaseSimple({
required String productId,
required PurchaseType type,
String? applicationUsername,
String? obfuscatedAccountId,
String? obfuscatedProfileId,
})

Parameters:

ParameterTypeRequiredDescription
productIdStringโœ…Product ID to purchase
typePurchaseTypeโœ…Purchase type
applicationUsernameString?โŒiOS: Application username
obfuscatedAccountIdString?โŒAndroid: Obfuscated account ID
obfuscatedProfileIdString?โŒAndroid: Obfuscated profile ID

Example:

await FlutterInappPurchase.instance.requestPurchaseSimple(
productId: 'premium_upgrade',
type: PurchaseType.inapp,
);

๐Ÿ“‹ Purchase Historyโ€‹

getAvailablePurchases()โ€‹

Get all non-consumed purchases (restore purchases).

Future<List<PurchasedItem>?> getAvailablePurchases()

Returns: Future<List<PurchasedItem>?> - List of available purchases

Example:

final purchases = await FlutterInappPurchase.instance.getAvailablePurchases();
if (purchases != null) {
for (var purchase in purchases) {
print('Purchase: ${purchase.productId}');
}
}

getPurchaseHistory()โ€‹

Get purchase history (including consumed purchases on Android).

Future<List<PurchasedItem>?> getPurchaseHistory()

Returns: Future<List<PurchasedItem>?> - List of purchase history

โœ… Transaction Completionโ€‹

finishTransaction()โ€‹

Complete a transaction (cross-platform).

Future<String?> finishTransaction(PurchasedItem purchase, {bool? isConsumable})

Parameters:

ParameterTypeRequiredDescription
purchasePurchasedItemโœ…Purchase to finish
isConsumablebool?โŒWhether the purchase is consumable (Android)

Example:

// Listen for purchase updates
FlutterInappPurchase.purchaseUpdated.listen((purchase) async {
if (purchase != null) {
// Verify the purchase on your server first
await verifyPurchaseOnServer(purchase);

// Complete the transaction
await FlutterInappPurchase.instance.finishTransaction(
purchase,
isConsumable: true, // for consumable products
);
}
});

๐Ÿ“ฑ Platform-Specific Methodsโ€‹

iOS Methodsโ€‹

syncIOS()โ€‹

Sync pending iOS transactions.

Future<bool> syncIOS()

presentCodeRedemptionSheetIOS()โ€‹

Present the code redemption sheet (iOS 14+).

Future<void> presentCodeRedemptionSheetIOS()

showManageSubscriptionsIOS()โ€‹

Show the subscription management interface.

Future<void> showManageSubscriptionsIOS()

Android Methodsโ€‹

deepLinkToSubscriptionsAndroid()โ€‹

Deep link to subscription management.

Future<void> deepLinkToSubscriptionsAndroid({String? sku})

getConnectionStateAndroid()โ€‹

Get the billing client connection state.

Future<BillingClientState> getConnectionStateAndroid()

๐ŸŽง Event Streamsโ€‹

purchaseUpdatedโ€‹

Stream of purchase updates.

Stream<PurchasedItem?> get purchaseUpdated

Example:

late StreamSubscription _purchaseSubscription;


void initState() {
super.initState();
_purchaseSubscription = FlutterInappPurchase.purchaseUpdated.listen(
(purchase) async {
if (purchase != null) {
// Handle successful purchase
await handlePurchase(purchase);
}
},
);
}


void dispose() {
_purchaseSubscription.cancel();
super.dispose();
}

purchaseErrorโ€‹

Stream of purchase errors.

Stream<PurchaseResult?> get purchaseError

Example:

FlutterInappPurchase.purchaseError.listen((error) {
if (error != null) {
print('Purchase error: ${error.message}');

// Handle specific error codes
if (error.code == ErrorCode.eUserCancelled) {
// User cancelled - no action needed
} else if (error.code == ErrorCode.eNetworkError) {
// Show retry option
showRetryDialog();
}
}
});

๐Ÿ” Error Handlingโ€‹

Common error codes you should handle:

Error CodeDescriptionAction
ErrorCode.eUserCancelledUser cancelled purchaseNo action needed
ErrorCode.eNetworkErrorNetwork errorOffer retry
ErrorCode.eItemUnavailableProduct not availableCheck product setup
ErrorCode.eAlreadyOwnedUser already owns productRestore or acknowledge
ErrorCode.eDeveloperErrorConfiguration errorCheck setup

Example Error Handling:

FlutterInappPurchase.purchaseError.listen((error) {
if (error == null) return;

switch (error.code) {
case ErrorCode.eUserCancelled:
// User cancelled - no UI needed
break;
case ErrorCode.eNetworkError:
showSnackBar('Network error. Please check your connection and try again.');
break;
case ErrorCode.eItemUnavailable:
showSnackBar('This item is currently unavailable.');
break;
case ErrorCode.eAlreadyOwned:
showSnackBar('You already own this item.');
break;
default:
showSnackBar('Purchase failed: ${error.message}');
}
});

๐ŸŽฏ Best Practicesโ€‹

  1. Always initialize connection before making purchases
  2. Handle all error cases appropriately
  3. Verify purchases server-side before granting content
  4. Complete transactions after verification
  5. Clean up streams in dispose methods
  6. Test thoroughly on both platforms