๐ง 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:
Parameter | Type | Description |
---|---|---|
productIds | List<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:
Parameter | Type | Description |
---|---|---|
subscriptionIds | List<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:
Parameter | Type | Description |
---|---|---|
request | RequestPurchase | Platform-specific purchase request |
type | PurchaseType | Type 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:
Parameter | Type | Required | Description |
---|---|---|---|
productId | String | โ | Product ID to purchase |
type | PurchaseType | โ | Purchase type |
applicationUsername | String? | โ | iOS: Application username |
obfuscatedAccountId | String? | โ | Android: Obfuscated account ID |
obfuscatedProfileId | String? | โ | 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:
Parameter | Type | Required | Description |
---|---|---|---|
purchase | PurchasedItem | โ | Purchase to finish |
isConsumable | bool? | โ | 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 Code | Description | Action |
---|---|---|
ErrorCode.eUserCancelled | User cancelled purchase | No action needed |
ErrorCode.eNetworkError | Network error | Offer retry |
ErrorCode.eItemUnavailable | Product not available | Check product setup |
ErrorCode.eAlreadyOwned | User already owns product | Restore or acknowledge |
ErrorCode.eDeveloperError | Configuration error | Check 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โ
- Always initialize connection before making purchases
- Handle all error cases appropriately
- Verify purchases server-side before granting content
- Complete transactions after verification
- Clean up streams in dispose methods
- Test thoroughly on both platforms
๐ Related Documentationโ
- ๐ Getting Started - Setup and configuration
- ๐ Purchase Guide - Step-by-step purchase implementation
- ๐ Error Handling - Comprehensive error handling
- ๐งช Testing - Testing strategies