Help me een functie-rijke in-app aankoop systeem implementeren in mijn Flutter app.
description
Door het implementeren van een functie-rijke in-app aankoop systeem, kun je de inkomsten verhogen, de betrokkenheid van gebruikers verbeteren en gebruikers waardevolle inhoud en functies bieden.
prompt
try_prompt
Ik wil een uitgebreid in-app aankoop systeem integreren in mijn Flutter app dat functies ondersteunt zoals abonnementbeheer, verbruikbare en niet-verbruikbare pr ... more
generate_helper
...
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Het integreren van een uitgebreid in-app aankoop systeem in je Flutter app vereist een gestructureerde aanpak. Hier is een overzicht van de stappen, inclusief uitleg en voorbeeldcode:
1. Plugin installeren en configureren
2. Producten beheren in de Google Play Console / App Store Connect
3. Aankooptransacties afhandelen
4. Voorbeeldimplementatie in Flutter
---
### 1. Plugin installeren en configureren
Gebruik de `in_app_purchase` plugin van Flutter:
```yaml
dependencies:
flutter:
sdk: flutter
in_app_purchase: ^3.0.7
```
Voer daarna uit:
```bash
flutter pub get
```
### 2. Producten beheren
- **Niet-verbruikbare producten en abonnementen** (bv. premium lidmaatschap)
- **Verbruikbare producten** (bv. in-game munten)
Beheer deze producten in de Google Play Console en/of App Store Connect door hun product-ID's te definiëren.
### 3. Aankooptransacties afhandelen
De plugin biedt methoden om producten op te halen, aankopen te initiëren, en aankoopstatussen te controleren.
### 4. Voorbeeldcode
Hier is een basisvoorbeeld van het ophalen van producten, aankoop starten en afhandelen:
```dart
import 'package:flutter/material.dart';
import 'package:in_app_purchase/in_app_purchase.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final InAppPurchase _inAppPurchase = InAppPurchase.instance;
final String _productIDSubscription = 'premium_subscription';
final String _productIDConsumable = 'coins_100';
late Stream<List<PurchaseDetails>> _subscription;
List<ProductDetails> _products = [];
bool _available = false;
@override
void initState() {
final purchaseUpdated = _inAppPurchase.purchaseStream;
purchaseUpdated.listen(_listenToPurchaseUpdated);
_initialize();
super.initState();
}
Future<void> _initialize() async {
// Check of in-app aankopen beschikbaar zijn
_available = await _inAppPurchase.isAvailable();
if (_available) {
// Producten ophalen
ProductDetailsResponse response = await _inAppPurchase.queryProductDetails({
_productIDSubscription,
_productIDConsumable,
});
if (response.error == null) {
setState(() {
_products = response.productDetails;
});
}
}
}
void _listenToPurchaseUpdated(List<PurchaseDetails> purchases) {
for (var purchase in purchases) {
if (purchase.status == PurchaseStatus.purchased) {
// Verwerk aankoop
_verifyAndDeliverProduct(purchase);
} else if (purchase.status == PurchaseStatus.error) {
// Foutafhandeling
print('Fout bij aankoop: ${purchase.error}');
}
if (purchase.pendingCompletePurchase) {
_inAppPurchase.completePurchase(purchase);
}
}
}
void _verifyAndDeliverProduct(PurchaseDetails purchase) {
// Hier kun je aankoop verificatie implementeren
if (purchase.productID == _productIDSubscription) {
// Abonnement activeren
print('Abonnement geactiveerd!');
} else if (purchase.productID == _productIDConsumable) {
// Verbruikbare items toevoegen
print('100 munten toegevoegd!');
}
}
void _buyProduct(ProductDetails product) {
final purchaseParam = PurchaseParam(productDetails: product);
if (product.id == _productIDConsumable) {
_inAppPurchase.buyConsumable(purchaseParam: purchaseParam);
} else {
_inAppPurchase.buyNonConsumable(purchaseParam: purchaseParam);
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('In-App Aankopen Demo')),
body: _available
? ListView.builder(
itemCount: _products.length,
itemBuilder: (context, index) {
final product = _products[index];
return ListTile(
title: Text(product.title),
subtitle: Text(product.description),
trailing: TextButton(
child: Text(product.price),
onPressed: () => _buyProduct(product),
),
);
},
)
: Center(child: Text('In-app aankopen niet beschikbaar')),
),
);
}
}
```
---
### Samenvatting
- Installeer en configureer de `in_app_purchase` plugin.
- Beheer productaanbiedingen via app stores.
- Haal producten op en start aankopen met de plugin.
- Verwerk en verifieer aankopen, activeer functies of geef verbruikbare items.
Voor een volledige implementatie en veiligheid, kun je ook server-side verificatie overwegen en extra functies zoals abonnementshandelingen en vervalcontrole integreren.
provider: deepseek
model: deepseek-chat
Hier is een uitgebreide handleiding voor het implementeren van in-app aankopen in Flutter:
## 1. Plugin Setup en Configuratie
### Benodigde dependencies
Voeg toe aan `pubspec.yaml`:
```yaml
dependencies:
in_app_purchase: ^5.1.1
flutter:
sdk: flutter
```
### Basis initialisatie
```dart
import 'package:in_app_purchase/in_app_purchase.dart';
class IAPService {
static final IAPService _instance = IAPService._internal();
factory IAPService() => _instance;
IAPService._internal();
final InAppPurchase _iap = InAppPurchase.instance;
late StreamSubscription<List<PurchaseDetails>> _subscription;
Future<void> initialize() async {
// Controleer of in-app aankopen beschikbaar zijn
final bool available = await _iap.isAvailable();
if (!available) {
throw Exception('In-app aankopen niet beschikbaar');
}
// Luister naar aankoopupdates
_subscription = _iap.purchaseStream.listen(
_handlePurchaseUpdate,
onDone: () => _subscription.cancel(),
onError: (error) => print('Aankoop fout: $error'),
);
}
}
```
## 2. Productaanbiedingen Beheren
### Producten ophalen en weergeven
```dart
class ProductRepository {
final InAppPurchase _iap = InAppPurchase.instance;
Future<List<ProductDetails>> getProducts() async {
const Set<String> _productIds = {
'premium_monthly_subscription',
'premium_yearly_subscription',
'coins_100',
'remove_ads',
};
try {
ProductDetailsResponse response = await _iap.queryProductDetails(_productIds);
return response.productDetails;
} catch (e) {
print('Fout bij ophalen producten: $e');
return [];
}
}
Widget buildProductList(List<ProductDetails> products) {
return ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
final product = products[index];
return ListTile(
title: Text(product.title),
subtitle: Text(product.description),
trailing: Column(
children: [
Text(product.price),
ElevatedButton(
onPressed: () => _purchaseProduct(product),
child: Text('Kopen'),
),
],
),
);
},
);
}
}
```
## 3. Aankooptransacties Afhandelen
### Aankoop logica
```dart
class PurchaseHandler {
final InAppPurchase _iap = InAppPurchase.instance;
Future<void> purchaseProduct(ProductDetails product) async {
try {
final PurchaseParam purchaseParam = PurchaseParam(
productDetails: product,
applicationUserName: null, // Optioneel: gebruikers-ID
);
await _iap.buyConsumable(
purchaseParam: purchaseParam,
autoConsume: true, // Automatisch verbruikbare producten verwerken
);
} catch (e) {
print('Aankoop mislukt: $e');
// Toon foutmelding aan gebruiker
}
}
void _handlePurchaseUpdate(List<PurchaseDetails> purchases) {
for (final purchase in purchases) {
_verifyAndProcessPurchase(purchase);
}
}
Future<void> _verifyAndProcessPurchase(PurchaseDetails purchase) async {
if (purchase.status == PurchaseStatus.purchased) {
// Verifieer aankoop (belangrijk voor beveiliging)
final bool valid = await _verifyPurchase(purchase);
if (valid) {
await _processValidPurchase(purchase);
await _iap.completePurchase(purchase);
}
} else if (purchase.status == PurchaseStatus.error) {
_handlePurchaseError(purchase);
} else if (purchase.status == PurchaseStatus.pending) {
_handlePendingPurchase(purchase);
}
}
Future<bool> _verifyPurchase(PurchaseDetails purchase) async {
// Implementeer server-side validatie voor beveiliging
// Voor demo: retourneer true
return true;
}
Future<void> _processValidPurchase(PurchaseDetails purchase) async {
final String productId = purchase.productID;
// Verwerk op basis van producttype
switch (productId) {
case 'premium_monthly_subscription':
case 'premium_yearly_subscription':
await _activateSubscription(purchase);
break;
case 'coins_100':
await _addCoins(100);
break;
case 'remove_ads':
await _removeAds();
break;
}
// Update UI of lokale status
_updatePurchaseStatus();
}
}
```
## 4. Abonnementbeheer
### Abonnementen controleren en beheren
```dart
class SubscriptionService {
Future<void> checkSubscriptionStatus() async {
// Controleer actieve abonnementen
final QueryPurchaseDetailsResponse response =
await InAppPurchase.instance.queryPastPurchases();
for (final purchase in response.pastPurchases) {
if (purchase.status == PurchaseStatus.purchased) {
await _validateAndUpdateSubscription(purchase);
}
}
}
Future<void> _validateAndUpdateSubscription(PurchaseDetails purchase) async {
// Controleer abonnementsstatus (vereist server-side validatie)
final bool isActive = await _checkSubscriptionActive(purchase);
if (isActive) {
await _enablePremiumFeatures();
} else {
await _disablePremiumFeatures();
}
}
Future<bool> _checkSubscriptionActive(PurchaseDetails purchase) async {
// Implementeer echte validatie met receipt data
// Dit zou normaal gesproken naar je server gaan
return true; // Tijdelijke implementatie
}
}
```
## 5. Complete Implementatie Voorbeeld
### Hoofd IAP Service
```dart
class InAppPurchaseService {
static final InAppPurchaseService _instance = InAppPurchaseService._internal();
factory InAppPurchaseService() => _instance;
InAppPurchaseService._internal();
final InAppPurchase _iap = InAppPurchase.instance;
StreamSubscription<List<PurchaseDetails>>? _subscription;
final List<ProductDetails> _products = [];
final Map<String, PurchaseDetails> _purchases = {};
Future<void> initialize() async {
// Controleer beschikbaarheid
if (!await _iap.isAvailable()) {
throw Exception('In-app aankopen niet beschikbaar op dit apparaat');
}
// Luister naar aankoopupdates
_subscription = _iap.purchaseStream.listen(_handlePurchaseUpdate);
// Laad producten
await _loadProducts();
// Herstel eerdere aankopen
await _restorePurchases();
}
Future<void> _loadProducts() async {
const productIds = {
'premium_monthly_subscription',
'premium_yearly_subscription',
'coins_100',
'coins_500',
'remove_ads',
};
final response = await _iap.queryProductDetails(productIds);
_products.clear();
_products.addAll(response.productDetails);
}
Future<void> _restorePurchases() async {
final response = await _iap.queryPastPurchases();
for (final purchase in response.pastPurchases) {
if (purchase.status == PurchaseStatus.purchased) {
_purchases[purchase.productID] = purchase;
}
}
}
void _handlePurchaseUpdate(List<PurchaseDetails> purchases) {
for (final purchase in purchases) {
_processPurchase(purchase);
}
}
Future<void> _processPurchase(PurchaseDetails purchase) async {
if (purchase.status == PurchaseStatus.purchased) {
// Verifieer en verwerk aankoop
await _verifyAndDeliverProduct(purchase);
await _iap.completePurchase(purchase);
}
}
Future<void> _verifyAndDeliverProduct(PurchaseDetails purchase) async {
// Server-side validatie zou hier komen
switch (purchase.productID) {
case 'coins_100':
await _deliverCoins(100);
break;
case 'coins_500':
await _deliverCoins(500);
break;
case 'remove_ads':
await _enableAdRemoval();
break;
case 'premium_monthly_subscription':
case 'premium_yearly_subscription':
await _activateSubscription(purchase);
break;
}
_purchases[purchase.productID] = purchase;
}
// Implementeer leveringsmethoden
Future<void> _deliverCoins(int amount) async {
// Update coin balans in app
}
Future<void> _enableAdRemoval() async {
// Schakel advertenties uit
}
Future<void> _activateSubscription(PurchaseDetails purchase) async {
// Activeer premium features
}
void dispose() {
_subscription?.cancel();
}
}
```
## 6. Platform-specifieke Configuratie
### iOS (Info.plist)
```xml
<key>SKPaymentQueueShouldAddStorePayment</key>
<true/>
```
### Android (build.gradle)
```gradle
android {
defaultConfig {
applicationId "com.jouw.app.id"
minSdkVersion 21
targetSdkVersion 33
}
}
```
## Belangrijke Beveiligingsoverwegingen
1. **Server-side validatie**: Verifieer alle aankopen op je server
2. **Receipt validatie**: Controleer aankoopbewijzen bij Apple/Google
3. **Lokale opslag**: Sla aankoopstatus veilig op
4. **Restore functionaliteit**: Implementeer "Herstel aankopen"
Deze implementatie biedt een solide basis voor in-app aankopen in je Flutter app. Pas de code aan naar je specifieke gebruiksscenario's en voeg server-side validatie toe voor productiegebruik.

